UNPKG

@ckeditor/ckeditor5-table

Version:

Table feature for CKEditor 5.

248 lines (247 loc) • 10.8 kB
/** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ /** * @module table/tablecellproperties/tablecellpropertiesediting */ import { Plugin } from 'ckeditor5/src/core.js'; import { addBorderRules, addPaddingRules, addBackgroundRules } from 'ckeditor5/src/engine.js'; import { downcastAttributeToStyle, upcastBorderStyles } from './../converters/tableproperties.js'; import TableEditing from './../tableediting.js'; import TableCellWidthEditing from '../tablecellwidth/tablecellwidthediting.js'; import TableCellPaddingCommand from './commands/tablecellpaddingcommand.js'; import TableCellHeightCommand from './commands/tablecellheightcommand.js'; import TableCellBackgroundColorCommand from './commands/tablecellbackgroundcolorcommand.js'; import TableCellVerticalAlignmentCommand from './commands/tablecellverticalalignmentcommand.js'; import TableCellHorizontalAlignmentCommand from './commands/tablecellhorizontalalignmentcommand.js'; import TableCellBorderStyleCommand from './commands/tablecellborderstylecommand.js'; import TableCellBorderColorCommand from './commands/tablecellbordercolorcommand.js'; import TableCellBorderWidthCommand from './commands/tablecellborderwidthcommand.js'; import { getNormalizedDefaultCellProperties } from '../utils/table-properties.js'; import { enableProperty } from '../utils/common.js'; const VALIGN_VALUES_REG_EXP = /^(top|middle|bottom)$/; const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/; /** * The table cell properties editing feature. * * Introduces table cell model attributes and their conversion: * * - border: `tableCellBorderStyle`, `tableCellBorderColor` and `tableCellBorderWidth` * - background color: `tableCellBackgroundColor` * - cell padding: `tableCellPadding` * - horizontal and vertical alignment: `tableCellHorizontalAlignment`, `tableCellVerticalAlignment` * - cell width and height: `tableCellWidth`, `tableCellHeight` * * It also registers commands used to manipulate the above attributes: * * - border: the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` commands * - background color: the `'tableCellBackgroundColor'` command * - cell padding: the `'tableCellPadding'` command * - horizontal and vertical alignment: the `'tableCellHorizontalAlignment'` and `'tableCellVerticalAlignment'` commands * - width and height: the `'tableCellWidth'` and `'tableCellHeight'` commands */ export default class TableCellPropertiesEditing extends Plugin { /** * @inheritDoc */ static get pluginName() { return 'TableCellPropertiesEditing'; } /** * @inheritDoc */ static get isOfficialPlugin() { return true; } /** * @inheritDoc */ static get requires() { return [TableEditing, TableCellWidthEditing]; } /** * @inheritDoc */ init() { const editor = this.editor; const schema = editor.model.schema; const conversion = editor.conversion; editor.config.define('table.tableCellProperties.defaultProperties', {}); const defaultTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'), { includeVerticalAlignmentProperty: true, includeHorizontalAlignmentProperty: true, includePaddingProperty: true, isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl' }); editor.data.addStyleProcessorRules(addBorderRules); enableBorderProperties(schema, conversion, { color: defaultTableCellProperties.borderColor, style: defaultTableCellProperties.borderStyle, width: defaultTableCellProperties.borderWidth }); editor.commands.add('tableCellBorderStyle', new TableCellBorderStyleCommand(editor, defaultTableCellProperties.borderStyle)); editor.commands.add('tableCellBorderColor', new TableCellBorderColorCommand(editor, defaultTableCellProperties.borderColor)); editor.commands.add('tableCellBorderWidth', new TableCellBorderWidthCommand(editor, defaultTableCellProperties.borderWidth)); enableProperty(schema, conversion, { modelAttribute: 'tableCellHeight', styleName: 'height', defaultValue: defaultTableCellProperties.height }); editor.commands.add('tableCellHeight', new TableCellHeightCommand(editor, defaultTableCellProperties.height)); editor.data.addStyleProcessorRules(addPaddingRules); enableProperty(schema, conversion, { modelAttribute: 'tableCellPadding', styleName: 'padding', reduceBoxSides: true, defaultValue: defaultTableCellProperties.padding }); editor.commands.add('tableCellPadding', new TableCellPaddingCommand(editor, defaultTableCellProperties.padding)); editor.data.addStyleProcessorRules(addBackgroundRules); enableProperty(schema, conversion, { modelAttribute: 'tableCellBackgroundColor', styleName: 'background-color', defaultValue: defaultTableCellProperties.backgroundColor }); editor.commands.add('tableCellBackgroundColor', new TableCellBackgroundColorCommand(editor, defaultTableCellProperties.backgroundColor)); enableHorizontalAlignmentProperty(schema, conversion, defaultTableCellProperties.horizontalAlignment); editor.commands.add('tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand(editor, defaultTableCellProperties.horizontalAlignment)); enableVerticalAlignmentProperty(schema, conversion, defaultTableCellProperties.verticalAlignment); editor.commands.add('tableCellVerticalAlignment', new TableCellVerticalAlignmentCommand(editor, defaultTableCellProperties.verticalAlignment)); } } /** * Enables the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` attributes for table cells. * * @param defaultBorder The default border values. * @param defaultBorder.color The default `tableCellBorderColor` value. * @param defaultBorder.style The default `tableCellBorderStyle` value. * @param defaultBorder.width The default `tableCellBorderWidth` value. */ function enableBorderProperties(schema, conversion, defaultBorder) { const modelAttributes = { width: 'tableCellBorderWidth', color: 'tableCellBorderColor', style: 'tableCellBorderStyle' }; schema.extend('tableCell', { allowAttributes: Object.values(modelAttributes) }); upcastBorderStyles(conversion, 'td', modelAttributes, defaultBorder); upcastBorderStyles(conversion, 'th', modelAttributes, defaultBorder); downcastAttributeToStyle(conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.style, styleName: 'border-style' }); downcastAttributeToStyle(conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.color, styleName: 'border-color' }); downcastAttributeToStyle(conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.width, styleName: 'border-width' }); } /** * Enables the `'tableCellHorizontalAlignment'` attribute for table cells. * * @param defaultValue The default horizontal alignment value. */ function enableHorizontalAlignmentProperty(schema, conversion, defaultValue) { schema.extend('tableCell', { allowAttributes: ['tableCellHorizontalAlignment'] }); conversion.for('downcast') .attributeToAttribute({ model: { name: 'tableCell', key: 'tableCellHorizontalAlignment' }, view: alignment => ({ key: 'style', value: { 'text-align': alignment } }) }); conversion.for('upcast') // Support for the `text-align:*;` CSS definition for the table cell alignment. .attributeToAttribute({ view: { name: /^(td|th)$/, styles: { 'text-align': ALIGN_VALUES_REG_EXP } }, model: { key: 'tableCellHorizontalAlignment', value: (viewElement) => { const align = viewElement.getStyle('text-align'); return align === defaultValue ? null : align; } } }) // Support for the `align` attribute as the backward compatibility while pasting from other sources. .attributeToAttribute({ view: { name: /^(td|th)$/, attributes: { align: ALIGN_VALUES_REG_EXP } }, model: { key: 'tableCellHorizontalAlignment', value: (viewElement) => { const align = viewElement.getAttribute('align'); return align === defaultValue ? null : align; } } }); } /** * Enables the `'verticalAlignment'` attribute for table cells. * * @param defaultValue The default vertical alignment value. */ function enableVerticalAlignmentProperty(schema, conversion, defaultValue) { schema.extend('tableCell', { allowAttributes: ['tableCellVerticalAlignment'] }); conversion.for('downcast') .attributeToAttribute({ model: { name: 'tableCell', key: 'tableCellVerticalAlignment' }, view: alignment => ({ key: 'style', value: { 'vertical-align': alignment } }) }); conversion.for('upcast') // Support for the `vertical-align:*;` CSS definition for the table cell alignment. .attributeToAttribute({ view: { name: /^(td|th)$/, styles: { 'vertical-align': VALIGN_VALUES_REG_EXP } }, model: { key: 'tableCellVerticalAlignment', value: (viewElement) => { const align = viewElement.getStyle('vertical-align'); return align === defaultValue ? null : align; } } }) // Support for the `align` attribute as the backward compatibility while pasting from other sources. .attributeToAttribute({ view: { name: /^(td|th)$/, attributes: { valign: VALIGN_VALUES_REG_EXP } }, model: { key: 'tableCellVerticalAlignment', value: (viewElement) => { const valign = viewElement.getAttribute('valign'); return valign === defaultValue ? null : valign; } } }); }