tablepropertiesediting.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module table/tableproperties/tablepropertiesediting
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import { addBorderRules } from '@ckeditor/ckeditor5-engine/src/view/styles/border';
  10. import { addBackgroundRules } from '@ckeditor/ckeditor5-engine/src/view/styles/background';
  11. import TableEditing from '../tableediting';
  12. import {
  13. downcastAttributeToStyle,
  14. downcastTableAttribute,
  15. upcastBorderStyles,
  16. upcastStyleToAttribute
  17. } from '../converters/tableproperties';
  18. import TableBackgroundColorCommand from './commands/tablebackgroundcolorcommand';
  19. import TableBorderColorCommand from './commands/tablebordercolorcommand';
  20. import TableBorderStyleCommand from './commands/tableborderstylecommand';
  21. import TableBorderWidthCommand from './commands/tableborderwidthcommand';
  22. import TableWidthCommand from './commands/tablewidthcommand';
  23. import TableHeightCommand from './commands/tableheightcommand';
  24. import TableAlignmentCommand from './commands/tablealignmentcommand';
  25. // RegExp used for matching margin style in converters.
  26. const MARGIN_REG_EXP = /^(auto|0(%|[a-z]{2,4})?)$/;
  27. const ALIGN_VALUES_REG_EXP = /^(left|right|center)$/;
  28. /**
  29. * The table properties editing feature.
  30. *
  31. * Introduces table's model attributes and their conversion:
  32. *
  33. * - border: `borderStyle`, `borderColor` and `borderWidth`
  34. * - background color: `backgroundColor`
  35. * - horizontal alignment: `alignment`
  36. * - width & height: `width` & `height`
  37. *
  38. * It also registers commands used to manipulate the above attributes:
  39. *
  40. * - border: `'tableBorderStyle'`, `'tableBorderColor'` and `'tableBorderWidth'` commands
  41. * - background color: `'tableBackgroundColor'`
  42. * - horizontal alignment: `'tableAlignment'`
  43. * - width & height: `'tableWidth'` & `'tableHeight'`
  44. *
  45. * @extends module:core/plugin~Plugin
  46. */
  47. export default class TablePropertiesEditing extends Plugin {
  48. /**
  49. * @inheritDoc
  50. */
  51. static get pluginName() {
  52. return 'TablePropertiesEditing';
  53. }
  54. /**
  55. * @inheritDoc
  56. */
  57. static get requires() {
  58. return [ TableEditing ];
  59. }
  60. /**
  61. * @inheritDoc
  62. */
  63. init() {
  64. const editor = this.editor;
  65. const schema = editor.model.schema;
  66. const conversion = editor.conversion;
  67. const viewDoc = editor.editing.view.document;
  68. viewDoc.addStyleProcessorRules( addBorderRules );
  69. enableBorderProperties( schema, conversion );
  70. editor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor ) );
  71. editor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor ) );
  72. editor.commands.add( 'tableBorderWidth', new TableBorderWidthCommand( editor ) );
  73. enableAlignmentProperty( schema, conversion );
  74. editor.commands.add( 'tableAlignment', new TableAlignmentCommand( editor ) );
  75. enableTableToFigureProperty( schema, conversion, 'width', 'width' );
  76. editor.commands.add( 'tableWidth', new TableWidthCommand( editor ) );
  77. enableTableToFigureProperty( schema, conversion, 'height', 'height' );
  78. editor.commands.add( 'tableHeight', new TableHeightCommand( editor ) );
  79. viewDoc.addStyleProcessorRules( addBackgroundRules );
  80. enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
  81. editor.commands.add( 'tableBackgroundColor', new TableBackgroundColorCommand( editor ) );
  82. }
  83. }
  84. // Enables `'borderStyle'`, `'borderColor'` and `'borderWidth'` attributes for table.
  85. //
  86. // @param {module:engine/model/schema~Schema} schema
  87. // @param {module:engine/conversion/conversion~Conversion} conversion
  88. function enableBorderProperties( schema, conversion ) {
  89. schema.extend( 'table', {
  90. allowAttributes: [ 'borderWidth', 'borderColor', 'borderStyle' ]
  91. } );
  92. upcastBorderStyles( conversion, 'table' );
  93. downcastTableAttribute( conversion, 'borderColor', 'border-color' );
  94. downcastTableAttribute( conversion, 'borderStyle', 'border-style' );
  95. downcastTableAttribute( conversion, 'borderWidth', 'border-width' );
  96. }
  97. // Enables the `'alignment'` attribute for table.
  98. //
  99. // @param {module:engine/model/schema~Schema} schema
  100. // @param {module:engine/conversion/conversion~Conversion} conversion
  101. function enableAlignmentProperty( schema, conversion ) {
  102. schema.extend( 'table', {
  103. allowAttributes: [ 'alignment' ]
  104. } );
  105. conversion.for( 'upcast' )
  106. .attributeToAttribute( {
  107. view: {
  108. styles: {
  109. 'margin-right': MARGIN_REG_EXP,
  110. 'margin-left': MARGIN_REG_EXP
  111. }
  112. },
  113. model: {
  114. name: 'table',
  115. key: 'alignment',
  116. value: viewElement => {
  117. // At this point we only have auto or 0 value (with a unit).
  118. if ( viewElement.getStyle( 'margin-right' ) != 'auto' ) {
  119. return 'right';
  120. }
  121. if ( viewElement.getStyle( 'margin-left' ) != 'auto' ) {
  122. return 'left';
  123. }
  124. return 'center';
  125. }
  126. }
  127. } )
  128. // Support for backwards compatibility and pasting from other sources.
  129. .attributeToAttribute( {
  130. view: {
  131. attributes: {
  132. align: ALIGN_VALUES_REG_EXP
  133. }
  134. },
  135. model: {
  136. name: 'table',
  137. key: 'alignment',
  138. value: viewElement => viewElement.getAttribute( 'align' )
  139. }
  140. } );
  141. conversion.for( 'downcast' ).add( dispatcher => dispatcher.on( 'attribute:alignment:table', ( evt, data, conversionApi ) => {
  142. const { item, attributeNewValue } = data;
  143. const { mapper, writer } = conversionApi;
  144. const table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'table' ) );
  145. if ( !attributeNewValue ) {
  146. writer.removeStyle( 'margin-left', table );
  147. writer.removeStyle( 'margin-right', table );
  148. return;
  149. }
  150. const styles = {
  151. 'margin-right': 'auto',
  152. 'margin-left': 'auto'
  153. };
  154. if ( attributeNewValue == 'left' ) {
  155. styles[ 'margin-left' ] = '0';
  156. }
  157. if ( attributeNewValue == 'right' ) {
  158. styles[ 'margin-right' ] = '0';
  159. }
  160. writer.setStyle( styles, table );
  161. } ) );
  162. }
  163. // Enables conversion for an attribute for simple view-model mappings.
  164. //
  165. // @param {String} modelAttribute
  166. // @param {String} styleName
  167. // @param {module:engine/model/schema~Schema} schema
  168. // @param {module:engine/conversion/conversion~Conversion} conversion
  169. function enableProperty( schema, conversion, modelAttribute, styleName ) {
  170. schema.extend( 'table', {
  171. allowAttributes: [ modelAttribute ]
  172. } );
  173. upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
  174. downcastTableAttribute( conversion, modelAttribute, styleName );
  175. }
  176. // Enables conversion for an attribute for simple view (figure) to model (table) mappings.
  177. //
  178. // @param {String} modelAttribute
  179. // @param {String} styleName
  180. // @param {module:engine/model/schema~Schema} schema
  181. // @param {module:engine/conversion/conversion~Conversion} conversion
  182. function enableTableToFigureProperty( schema, conversion, modelAttribute, styleName ) {
  183. schema.extend( 'table', {
  184. allowAttributes: [ modelAttribute ]
  185. } );
  186. upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
  187. downcastAttributeToStyle( conversion, 'table', modelAttribute, styleName );
  188. }