8
0

alignmentediting.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module alignment/alignmentediting
  7. */
  8. import AlignmentCommand, { commandNameFromStyle } from './alignmentcommand';
  9. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  10. import buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter';
  11. /**
  12. * @extends module:core/plugin~Plugin
  13. */
  14. export default class AlignmentEditing extends Plugin {
  15. /**
  16. * @inheritDoc
  17. */
  18. constructor( editor ) {
  19. super( editor );
  20. editor.config.define( 'alignment', { styles: [ ...this.constructor.supportedStyles ] } );
  21. }
  22. /**
  23. * List of supported alignment styles:
  24. *
  25. * * `'left'`,
  26. * * `'right'`,
  27. * * `'center'`,
  28. * * `'justify'`
  29. *
  30. * @static
  31. * @readonly
  32. * @member {Array.<String>} module:alignment/alignmentediting~AlignmentEditing.supportedStyles
  33. */
  34. static get supportedStyles() {
  35. return [ 'left', 'right', 'center', 'justify' ];
  36. }
  37. /**
  38. * @inheritDoc
  39. */
  40. init() {
  41. const editor = this.editor;
  42. const schema = editor.model.schema;
  43. const data = editor.data;
  44. const editing = editor.editing;
  45. const enabledStyles = editor.config.get( 'alignment.styles' );
  46. // Allow alignment attribute on all blocks.
  47. schema.extend( '$block', { allowAttributes: 'alignment' } );
  48. data.modelToView.on( 'attribute:alignment', convertStyle() );
  49. editing.modelToView.on( 'attribute:alignment', convertStyle() );
  50. // Convert `text-align` style property from element to model attribute alignment.
  51. buildViewConverter()
  52. .for( data.viewToModel )
  53. .fromAttribute( 'style', /text-align/ )
  54. .toAttribute( viewElement => {
  55. const textAlign = viewElement.getStyle( 'text-align' );
  56. // Do not convert empty, default or unknown alignment values.
  57. if ( !textAlign || isDefault( textAlign ) || !enabledStyles.includes( textAlign ) ) {
  58. return;
  59. }
  60. return { key: 'alignment', value: textAlign };
  61. } );
  62. // Add only enabled & supported commands.
  63. enabledStyles
  64. .filter( isSupported )
  65. .forEach( style => {
  66. editor.commands.add( commandNameFromStyle( style ), new AlignmentCommand( editor, style, isDefault( style ) ) );
  67. } );
  68. }
  69. }
  70. /**
  71. * Checks whether passed style is supported by {@link module:alignment/alignmentediting~AlignmentEditing}.
  72. *
  73. * @param {String} style Style value to check.
  74. * @returns {Boolean}
  75. */
  76. export function isSupported( style ) {
  77. return AlignmentEditing.supportedStyles.includes( style );
  78. }
  79. // Dispatcher handler responsible for setting style to a view element.
  80. // @private
  81. function convertStyle() {
  82. return ( evt, data, consumable, conversionApi ) => {
  83. if ( !consumable.consume( data.item, evt.name ) ) {
  84. return;
  85. }
  86. if ( data.attributeNewValue ) { // Set style.
  87. conversionApi.mapper.toViewElement( data.item ).setStyle( { 'text-align': data.attributeNewValue } );
  88. } else { // Remove style.
  89. conversionApi.mapper.toViewElement( data.item ).removeStyle( 'text-align' );
  90. }
  91. };
  92. }
  93. // Check whether alignment is default one.
  94. // @private
  95. function isDefault( textAlign ) {
  96. // Right now only RTL is supported so 'left' value is always default one.
  97. return textAlign === 'left';
  98. }
  99. /**
  100. * The configuration of the {@link module:alignment/alignmentediting~AlignmentEditing Alignment feature}.
  101. *
  102. * Read more in {@link module:alignment/alignmentediting~AlignmentEditingConfig}.
  103. *
  104. * @member {module:alignment/alignmentediting~AlignmentEditingConfig} module:core/editor/editorconfig~EditorConfig#alignment
  105. */
  106. /**
  107. * The configuration of the {@link module:alignment/alignmentediting~AlignmentEditing Alignment feature}.
  108. *
  109. * ClassicEditor
  110. * .create( editorElement, {
  111. * alignment: {
  112. * styles: [ 'left', 'right' ]
  113. * }
  114. * } )
  115. * .then( ... )
  116. * .catch( ... );
  117. *
  118. * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
  119. *
  120. * @interface AlignmentEditingConfig
  121. */
  122. /**
  123. * Enabled alignment styles from supported styles: `left`, `right`, `center` and `justify`. Other values are ignored.
  124. *
  125. * @member {String} module:alignment/alignmentediting~AlignmentEditingConfig#styles
  126. */