tablepropertiesediting.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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/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 { downcastTableAttribute, upcastStyleToAttribute, upcastBorderStyles } from './converters/tableproperties';
  12. import TableEditing from './tableediting';
  13. import TableBackgroundColorCommand from './commands/tablebackgroundcolorcommand';
  14. /**
  15. * The table properties editing feature.
  16. *
  17. * @extends module:core/plugin~Plugin
  18. */
  19. export default class TablePropertiesEditing extends Plugin {
  20. /**
  21. * @inheritDoc
  22. */
  23. static get pluginName() {
  24. return 'TablePropertiesEditing';
  25. }
  26. /**
  27. * @inheritDoc
  28. */
  29. static get requires() {
  30. return [ TableEditing ];
  31. }
  32. /**
  33. * @inheritDoc
  34. */
  35. init() {
  36. const editor = this.editor;
  37. const schema = editor.model.schema;
  38. const conversion = editor.conversion;
  39. const viewDoc = editor.editing.view.document;
  40. viewDoc.addStyleProcessorRules( addBorderRules );
  41. viewDoc.addStyleProcessorRules( addBackgroundRules );
  42. enableBorderProperties( schema, conversion );
  43. enableAlignmentProperty( schema, conversion );
  44. enableProperty( schema, conversion, 'width', 'width' );
  45. enableProperty( schema, conversion, 'height', 'height' );
  46. enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
  47. editor.commands.add( 'tableBackgroundColor', new TableBackgroundColorCommand( editor ) );
  48. }
  49. }
  50. // Enables `'borderStyle'`, `'borderColor'` and `'borderWidth'` attributes for table.
  51. //
  52. // @param {module:engine/model/schema~Schema} schema
  53. // @param {module:engine/conversion/conversion~Conversion} conversion
  54. function enableBorderProperties( schema, conversion ) {
  55. schema.extend( 'table', {
  56. allowAttributes: [ 'borderWidth', 'borderColor', 'borderStyle' ]
  57. } );
  58. upcastBorderStyles( conversion, 'table' );
  59. downcastTableAttribute( conversion, 'borderColor', 'border-color' );
  60. downcastTableAttribute( conversion, 'borderStyle', 'border-style' );
  61. downcastTableAttribute( conversion, 'borderWidth', 'border-width' );
  62. }
  63. // Enables `'alignment'` attribute for table.
  64. //
  65. // @param {module:engine/model/schema~Schema} schema
  66. // @param {module:engine/conversion/conversion~Conversion} conversion
  67. function enableAlignmentProperty( schema, conversion ) {
  68. schema.extend( 'table', {
  69. allowAttributes: [ 'alignment' ]
  70. } );
  71. conversion.for( 'upcast' )
  72. .attributeToAttribute( {
  73. view: {
  74. styles: {
  75. 'margin-right': /^(auto|0(%|[a-z]{2,4})?)$/,
  76. 'margin-left': /^(auto|0(%|[a-z]{2,4})?)$/
  77. }
  78. },
  79. model: {
  80. name: 'table',
  81. key: 'alignment',
  82. value: viewElement => {
  83. // At this point we only have auto or 0 value (with a unit).
  84. if ( viewElement.getStyle( 'margin-right' ) != 'auto' ) {
  85. return 'right';
  86. }
  87. if ( viewElement.getStyle( 'margin-left' ) != 'auto' ) {
  88. return 'left';
  89. }
  90. return 'center';
  91. }
  92. }
  93. } )
  94. // Support for backwards compatibility and pasting from other sources.
  95. .attributeToAttribute( {
  96. view: {
  97. attributes: {
  98. align: /^(left|right|center)$/
  99. }
  100. },
  101. model: {
  102. name: 'table',
  103. key: 'alignment',
  104. value: viewElement => viewElement.getAttribute( 'align' )
  105. }
  106. } );
  107. conversion.for( 'downcast' ).add( dispatcher => dispatcher.on( 'attribute:alignment:table', ( evt, data, conversionApi ) => {
  108. const { item, attributeNewValue } = data;
  109. const { mapper, writer } = conversionApi;
  110. const table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'table' ) );
  111. if ( !attributeNewValue ) {
  112. writer.removeStyle( 'margin-left', table );
  113. writer.removeStyle( 'margin-right', table );
  114. return;
  115. }
  116. const styles = {
  117. 'margin-right': 'auto',
  118. 'margin-left': 'auto'
  119. };
  120. if ( attributeNewValue == 'left' ) {
  121. styles[ 'margin-left' ] = '0';
  122. }
  123. if ( attributeNewValue == 'right' ) {
  124. styles[ 'margin-right' ] = '0';
  125. }
  126. writer.setStyle( styles, table );
  127. } ) );
  128. }
  129. // Enables conversion for an attribute for simple view-model mappings.
  130. //
  131. // @param {String} modelAttribute
  132. // @param {String} styleName
  133. // @param {module:engine/model/schema~Schema} schema
  134. // @param {module:engine/conversion/conversion~Conversion} conversion
  135. function enableProperty( schema, conversion, modelAttribute, styleName ) {
  136. schema.extend( 'table', {
  137. allowAttributes: [ modelAttribute ]
  138. } );
  139. upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
  140. downcastTableAttribute( conversion, modelAttribute, styleName );
  141. }