fontsizeediting.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 font/fontsize/fontsizeediting
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import FontSizeCommand from './fontsizecommand';
  10. import { normalizeOptions } from './utils';
  11. import { buildDefinition, FONT_SIZE } from '../utils';
  12. import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
  13. /**
  14. * The font size editing feature.
  15. *
  16. * It introduces the {@link module:font/fontsize/fontsizecommand~FontSizeCommand command} and the `fontSize`
  17. * attribute in the {@link module:engine/model/model~Model model} which renders in the {@link module:engine/view/view view}
  18. * as a `<span>` element with either:
  19. * * a style attribute (`<span style="font-size:12px">...</span>`),
  20. * * or a class attribute (`<span class="text-small">...</span>`)
  21. *
  22. * depending on the {@link module:font/fontsize~FontSizeConfig configuration}.
  23. *
  24. * @extends module:core/plugin~Plugin
  25. */
  26. export default class FontSizeEditing extends Plugin {
  27. /**
  28. * @inheritDoc
  29. */
  30. static get pluginName() {
  31. return 'FontSizeEditing';
  32. }
  33. /**
  34. * @inheritDoc
  35. */
  36. constructor( editor ) {
  37. super( editor );
  38. // Define default configuration using named presets.
  39. editor.config.define( FONT_SIZE, {
  40. options: [
  41. 'tiny',
  42. 'small',
  43. 'default',
  44. 'big',
  45. 'huge'
  46. ],
  47. supportAllValues: false
  48. } );
  49. }
  50. /**
  51. * @inheritDoc
  52. */
  53. init() {
  54. const editor = this.editor;
  55. // Allow fontSize attribute on text nodes.
  56. editor.model.schema.extend( '$text', { allowAttributes: FONT_SIZE } );
  57. editor.model.schema.setAttributeProperties( FONT_SIZE, {
  58. isFormatting: true,
  59. copyOnEnter: true
  60. } );
  61. const supportAllValues = editor.config.get( 'fontSize.supportAllValues' );
  62. // Define view to model conversion.
  63. const options = normalizeOptions( this.editor.config.get( 'fontSize.options' ) )
  64. .filter( item => item.model );
  65. const definition = buildDefinition( FONT_SIZE, options );
  66. // Set-up the two-way conversion.
  67. if ( supportAllValues ) {
  68. this._prepareAnyValueConverters( definition );
  69. } else {
  70. editor.conversion.attributeToElement( definition );
  71. }
  72. // Add FontSize command.
  73. editor.commands.add( FONT_SIZE, new FontSizeCommand( editor ) );
  74. }
  75. /**
  76. * These converters enable keeping any value found as `style="font-size: *"` as a value of an attribute on a text even
  77. * if it is not defined in the plugin configuration.
  78. *
  79. * @param {Object} definition {@link module:engine/conversion/conversion~ConverterDefinition Converter definition} out of input data.
  80. * @private
  81. */
  82. _prepareAnyValueConverters( definition ) {
  83. const editor = this.editor;
  84. // If `fontSize.supportAllValues=true`, we do not allow to use named presets in the plugin's configuration.
  85. const presets = definition.model.values.filter( value => !String( value ).match( /[\d.]+[\w%]+/ ) );
  86. if ( presets.length ) {
  87. /**
  88. * If {@link module:font/fontsize~FontSizeConfig#supportAllValues `config.fontSize.supportAllValues`} is `true`,
  89. * you need to use numerical values as font size options.
  90. *
  91. * See valid examples described in the {@link module:font/fontsize~FontSizeConfig#options plugin configuration}.
  92. *
  93. * @error font-size-invalid-use-of-named-presets
  94. * @param {Array.<String>} presets Invalid values.
  95. */
  96. throw new CKEditorError(
  97. 'font-size-invalid-use-of-named-presets: ' +
  98. 'If config.fontSize.supportAllValues is set to true, you need to use numerical values as font size options.',
  99. null, { presets }
  100. );
  101. }
  102. editor.conversion.for( 'downcast' ).attributeToElement( {
  103. model: FONT_SIZE,
  104. view: ( attributeValue, { writer } ) => {
  105. if ( !attributeValue ) {
  106. return;
  107. }
  108. return writer.createAttributeElement( 'span', { style: 'font-size:' + attributeValue }, { priority: 7 } );
  109. }
  110. } );
  111. editor.conversion.for( 'upcast' ).attributeToAttribute( {
  112. model: {
  113. key: FONT_SIZE,
  114. value: viewElement => viewElement.getStyle( 'font-size' )
  115. },
  116. view: {
  117. name: 'span'
  118. }
  119. } );
  120. }
  121. }