From dee2f87466794ac8a454fb311098fc52637954f5 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Thu, 5 Mar 2020 11:31:29 +0100 Subject: [PATCH 01/17] Introduced "the fontFamily.disableValueMatching" option that allows keeping fonts that are not defined in the plugins configuration. --- src/fontfamily/fontfamilyediting.js | 31 ++++++++++++++++-- tests/manual/font-family.html | 11 +++++++ tests/manual/font-family.js | 51 ++++++++++++++++++++++------- tests/manual/font-family.md | 11 ++++++- 4 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/fontfamily/fontfamilyediting.js b/src/fontfamily/fontfamilyediting.js index 39e522f..31ffa76 100644 --- a/src/fontfamily/fontfamilyediting.js +++ b/src/fontfamily/fontfamilyediting.js @@ -49,7 +49,8 @@ export default class FontFamilyEditing extends Plugin { 'Times New Roman, Times, serif', 'Trebuchet MS, Helvetica, sans-serif', 'Verdana, Geneva, sans-serif' - ] + ], + disableValueMatching: false } ); } @@ -71,8 +72,34 @@ export default class FontFamilyEditing extends Plugin { const definition = buildDefinition( FONT_FAMILY, options ); // Set-up the two-way conversion. - editor.conversion.attributeToElement( definition ); + if ( editor.config.get( 'fontFamily.disableValueMatching' ) ) { + this._setupGenericConverters(); + } else { + editor.conversion.attributeToElement( definition ); + } editor.commands.add( FONT_FAMILY, new FontFamilyCommand( editor ) ); } + + /** + * @private + */ + _setupGenericConverters() { + const editor = this.editor; + + editor.conversion.for( 'downcast' ).attributeToElement( { + model: FONT_FAMILY, + view: ( attributeValue, writer ) => writer.createAttributeElement( 'span', { style: 'font-family:' + attributeValue } ) + } ); + + editor.conversion.for( 'upcast' ).attributeToAttribute( { + model: { + key: FONT_FAMILY, + value: viewElement => viewElement.getStyle( 'font-family' ) + }, + view: { + name: 'span' + } + } ); + } } diff --git a/tests/manual/font-family.html b/tests/manual/font-family.html index e35a8fd..7654e1d 100644 --- a/tests/manual/font-family.html +++ b/tests/manual/font-family.html @@ -1,6 +1,17 @@ +

+ Font-family converters mode: + + +

+

Font Family feature sample.

+

Docs-Roboto, Arial:

+

+ This font will be removed after changing the font-family converters to restricted value matching. +

+

Arial, Helvetica, sans-serif:

Topping cheesecake cotton candy toffee cookie cookie lemon drops cotton candy. Carrot cake dessert jelly beans powder cake cupcake tiramisu pastry gummi bears. diff --git a/tests/manual/font-family.js b/tests/manual/font-family.js index 0e1b9e8..5f1a33f 100644 --- a/tests/manual/font-family.js +++ b/tests/manual/font-family.js @@ -3,22 +3,51 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ -/* globals console, window, document */ +/* globals window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; import FontFamily from '../../src/fontfamily'; -ClassicEditor - .create( document.querySelector( '#editor' ), { +const restrictedModeButton = document.getElementById( 'mode-restricted-values' ); +const standardModeButton = document.getElementById( 'mode-disable-value-matching' ); + +restrictedModeButton.addEventListener( 'change', handleModeChange ); +standardModeButton.addEventListener( 'change', handleModeChange ); + +// When page loaded. +startMode( document.querySelector( 'input[name="mode"]:checked' ).value ); + +// When a user changed a mode. +async function handleModeChange( evt ) { + await startMode( evt.target.value ); +} + +// Starts the editor. +async function startMode( selectedMode ) { + if ( selectedMode === 'restricted-values' ) { + await reloadEditor(); + } else { + await reloadEditor( { disableValueMatching: true } ); + } +} + +async function reloadEditor( options = {} ) { + if ( window.editor ) { + await window.editor.destroy(); + } + + const config = { plugins: [ ArticlePluginSet, FontFamily ], toolbar: [ 'heading', '|', 'fontFamily', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' - ] - } ) - .then( editor => { - window.editor = editor; - } ) - .catch( err => { - console.error( err.stack ); - } ); + ], + fontFamily: {} + }; + + if ( options.disableValueMatching ) { + config.fontFamily.disableValueMatching = true; + } + + window.editor = await ClassicEditor.create( document.querySelector( '#editor' ), config ); +} diff --git a/tests/manual/font-family.md b/tests/manual/font-family.md index bdd7ecb..30d8bd6 100644 --- a/tests/manual/font-family.md +++ b/tests/manual/font-family.md @@ -1,7 +1,7 @@ ### Loading The data should be loaded with paragraphs, each with different font. -Also the image caption should have "changed font" string with different font. +Also the image caption should have "changed font" string with different font. ### Testing @@ -10,3 +10,12 @@ Try to: - Change font size by selecting some text. - Change to default font size by selecting many paragraphs. - Change to default font size by selecting some text. + +### Converters mode + +The "Restricted value matching" option means that all font-family values that aren't defined in the plugin's configuration will be removed (e.g. when pasted from Google Docs). +This behaviour can be disabled by selecting the "Disabled value matching" option. + +The `Docs-Roboto, Arial` font-family is not specified in the plugin's configuration and should be restored to default font when the "Restricted value matching" option is selected. + +By default editor should load with the "Disabled value matching" option. From 0850b0524c4a1b17826d14708e376f7d20600e16 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 13:43:51 +0100 Subject: [PATCH 02/17] Tests for FontFamily improvements. --- src/fontfamily/fontfamilyediting.js | 16 ++++++-- tests/fontfamily/fontfamilyediting.js | 58 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/fontfamily/fontfamilyediting.js b/src/fontfamily/fontfamilyediting.js index 31ffa76..255cbce 100644 --- a/src/fontfamily/fontfamilyediting.js +++ b/src/fontfamily/fontfamilyediting.js @@ -73,7 +73,7 @@ export default class FontFamilyEditing extends Plugin { // Set-up the two-way conversion. if ( editor.config.get( 'fontFamily.disableValueMatching' ) ) { - this._setupGenericConverters(); + this._prepareAnyValueConverters(); } else { editor.conversion.attributeToElement( definition ); } @@ -82,14 +82,19 @@ export default class FontFamilyEditing extends Plugin { } /** + * Those converters enable keeping any value found as `style="font-family: *"` as a value of an attribute on a text even + * if it isn't defined in the plugin configuration. + * * @private */ - _setupGenericConverters() { + _prepareAnyValueConverters() { const editor = this.editor; editor.conversion.for( 'downcast' ).attributeToElement( { model: FONT_FAMILY, - view: ( attributeValue, writer ) => writer.createAttributeElement( 'span', { style: 'font-family:' + attributeValue } ) + view: ( attributeValue, writer ) => { + return writer.createAttributeElement( 'span', { style: 'font-family:' + attributeValue }, { priority: 7 } ); + } } ); editor.conversion.for( 'upcast' ).attributeToAttribute( { @@ -98,7 +103,10 @@ export default class FontFamilyEditing extends Plugin { value: viewElement => viewElement.getStyle( 'font-family' ) }, view: { - name: 'span' + name: 'span', + styles: { + 'font-family': /.*/ + } } } ); } diff --git a/tests/fontfamily/fontfamilyediting.js b/tests/fontfamily/fontfamilyediting.js index 72fc73f..5e2d300 100644 --- a/tests/fontfamily/fontfamilyediting.js +++ b/tests/fontfamily/fontfamilyediting.js @@ -66,6 +66,64 @@ describe( 'FontFamilyEditing', () => { 'Trebuchet MS, Helvetica, sans-serif', 'Verdana, Geneva, sans-serif' ] ); + + expect( editor.config.get( 'fontFamily.disableValueMatching' ) ).to.equal( false ); + } ); + } ); + + describe( 'disableValueMatching=true', () => { + beforeEach( () => { + return VirtualTestEditor + .create( { + plugins: [ FontFamilyEditing, Paragraph ], + fontFamily: { + options: [ + 'Arial', + ], + disableValueMatching: true + } + } ) + .then( newEditor => { + editor = newEditor; + + doc = editor.model; + } ); + } ); + + describe( 'editing pipeline conversion', () => { + it( 'should convert unknown fontFamily attribute values', () => { + setModelData( doc, 'f<$text fontFamily="foo-bar">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + it( 'should convert defined fontFamily attribute values', () => { + setModelData( doc, 'f<$text fontFamily="Arial">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + } ); + + describe( 'data pipeline conversions', () => { + it( 'should convert from an element with defined style when with other styles', () => { + const data = '

foo

'; + + editor.setData( data ); + + expect( getModelData( doc ) ).to.equal( '[]f<$text fontFamily="Other">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + it( 'should convert from a complex definition', () => { + const data = '

foo

'; + + editor.setData( data ); + + expect( getModelData( doc ) ).to.equal( '[]f<$text fontFamily="Arial,sans-serif">oo' ); + + expect( editor.getData() ).to.equal( data ); + } ); } ); } ); } ); From 1ac4d62c391852b46b61c48814c52c7385bcb934 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 15:57:36 +0100 Subject: [PATCH 03/17] Support for keeping any value as fontSize attribute. --- src/fontsize/fontsizeediting.js | 76 ++++++++++++++++++++++++++---- tests/fontsize/fontsizeediting.js | 77 +++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 9 deletions(-) diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index 6780199..325d96e 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -48,7 +48,22 @@ export default class FontSizeEditing extends Plugin { 'default', 'big', 'huge' - ] + ], + disableValueMatching: false + } ); + } + + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + + // Allow fontSize attribute on text nodes. + editor.model.schema.extend( '$text', { allowAttributes: FONT_SIZE } ); + editor.model.schema.setAttributeProperties( FONT_SIZE, { + isFormatting: true, + copyOnEnter: true } ); // Define view to model conversion. @@ -56,23 +71,66 @@ export default class FontSizeEditing extends Plugin { const definition = buildDefinition( FONT_SIZE, options ); // Set-up the two-way conversion. - editor.conversion.attributeToElement( definition ); + if ( editor.config.get( 'fontSize.disableValueMatching' ) ) { + this._prepareAnyValueConverters(); + } else { + editor.conversion.attributeToElement( definition ); + } // Add FontSize command. editor.commands.add( FONT_SIZE, new FontSizeCommand( editor ) ); } /** - * @inheritDoc + * Those converters enable keeping any value found as `style="font-size: *"` as a value of an attribute on a text even + * if it isn't defined in the plugin configuration. + * + * @private */ - init() { + _prepareAnyValueConverters() { const editor = this.editor; - // Allow fontSize attribute on text nodes. - editor.model.schema.extend( '$text', { allowAttributes: FONT_SIZE } ); - editor.model.schema.setAttributeProperties( FONT_SIZE, { - isFormatting: true, - copyOnEnter: true + editor.conversion.for( 'downcast' ).attributeToElement( { + model: FONT_SIZE, + view: ( attributeValue, writer ) => { + if ( !attributeValue ) { + return; + } + + if ( String( attributeValue ).match( /^\d+/ ) ) { + if ( typeof attributeValue == 'number' ) { + attributeValue = `${ attributeValue }px`; + } + + return writer.createAttributeElement( 'span', { style: 'font-size:' + attributeValue }, { priority: 7 } ); + } + + return writer.createAttributeElement( 'span', { class: 'text-' + attributeValue }, { priority: 7 } ); + } + } ); + + editor.conversion.for( 'upcast' ).attributeToAttribute( { + model: { + key: FONT_SIZE, + value: viewElement => { + const fontSize = viewElement.getStyle( 'font-size' ); + + if ( fontSize ) { + return fontSize; + } + + for ( const className of viewElement.getClassNames() ) { + if ( className.startsWith( 'text-' ) ) { + return className.replace( /^text-/, '' ); + } + } + + return null; + } + }, + view: { + name: 'span' + } } ); } } diff --git a/tests/fontsize/fontsizeediting.js b/tests/fontsize/fontsizeediting.js index 7f8e0a1..469234e 100644 --- a/tests/fontsize/fontsizeediting.js +++ b/tests/fontsize/fontsizeediting.js @@ -56,6 +56,83 @@ describe( 'FontSizeEditing', () => { describe( 'default value', () => { it( 'should be set', () => { expect( editor.config.get( 'fontSize.options' ) ).to.deep.equal( [ 'tiny', 'small', 'default', 'big', 'huge' ] ); + expect( editor.config.get( 'fontSize.disableValueMatching' ) ).to.equal( false ); + } ); + } ); + + describe( 'disableValueMatching=true', () => { + let editor, doc; + + beforeEach( () => { + return VirtualTestEditor + .create( { + plugins: [ FontSizeEditing, Paragraph ], + fontSize: { + options: [ + 'default', + ], + disableValueMatching: true + } + } ) + .then( newEditor => { + editor = newEditor; + + doc = editor.model; + } ); + } ); + + afterEach( () => { + return editor.destroy(); + } ); + + describe( 'editing pipeline conversion', () => { + it( 'should pass fontSize to data', () => { + setModelData( doc, 'f<$text fontSize="10px">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + it( 'should add a unit to value if missing', () => { + setModelData( doc, 'f<$text fontSize="10">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + it( 'should convert a text value as a class', () => { + setModelData( doc, 'f<$text fontSize="large">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + } ); + + describe( 'data pipeline conversions', () => { + it( 'should convert from an element with defined style when with other styles', () => { + const data = '

foo

'; + + editor.setData( data ); + + expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="18px">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + it( 'should convert an element if it has a class that starts with "text-"', () => { + const data = '

foo

'; + + editor.setData( data ); + + expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="huge">oo' ); + + expect( editor.getData() ).to.equal( data ); + } ); + + it( 'should ignore an element if does not have a class that starts with "text-"', () => { + editor.setData( '

foo

' ); + + expect( getModelData( doc ) ).to.equal( '[]foo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); } ); } ); } ); From 8163ed73b3dae04d854645aa461ec0180883fa4a Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 15:57:53 +0100 Subject: [PATCH 04/17] Clean after tests. --- tests/fontfamily/fontfamilyediting.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/fontfamily/fontfamilyediting.js b/tests/fontfamily/fontfamilyediting.js index 5e2d300..638189c 100644 --- a/tests/fontfamily/fontfamilyediting.js +++ b/tests/fontfamily/fontfamilyediting.js @@ -72,6 +72,8 @@ describe( 'FontFamilyEditing', () => { } ); describe( 'disableValueMatching=true', () => { + let editor, doc; + beforeEach( () => { return VirtualTestEditor .create( { @@ -90,6 +92,10 @@ describe( 'FontFamilyEditing', () => { } ); } ); + afterEach( () => { + return editor.destroy(); + } ); + describe( 'editing pipeline conversion', () => { it( 'should convert unknown fontFamily attribute values', () => { setModelData( doc, 'f<$text fontFamily="foo-bar">oo' ); From 9c102bdef1c1425e7a0cb56b6604bb679b9078eb Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 16:02:48 +0100 Subject: [PATCH 05/17] Extended the font-size-numeric manual test. --- tests/manual/font-size-numeric.html | 9 ++++++ tests/manual/font-size-numeric.js | 48 +++++++++++++++++++++++------ tests/manual/font-size-numeric.md | 9 ++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/tests/manual/font-size-numeric.html b/tests/manual/font-size-numeric.html index 6ef262a..295b9eb 100644 --- a/tests/manual/font-size-numeric.html +++ b/tests/manual/font-size-numeric.html @@ -1,3 +1,9 @@ +

+ Font-size converters mode: + + +

+

Font Size feature sample.

@@ -8,4 +14,7 @@

Font Size feature sample.

Some text with font-size set to: 18px.

Some text with font-size set to: 20px.

Some text with font-size set to: 22px.

+

Some text with font-size set to: 36px.

+

Some text with font-size set to: 48px.

+

Some text with font-size set to: 64px.

diff --git a/tests/manual/font-size-numeric.js b/tests/manual/font-size-numeric.js index c6015e2..adeed5a 100644 --- a/tests/manual/font-size-numeric.js +++ b/tests/manual/font-size-numeric.js @@ -3,23 +3,51 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ -/* globals console, window, document */ +/* globals window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; import FontSize from '../../src/fontsize'; -ClassicEditor - .create( document.querySelector( '#editor' ), { +const restrictedModeButton = document.getElementById( 'mode-restricted-values' ); +const standardModeButton = document.getElementById( 'mode-disable-value-matching' ); + +restrictedModeButton.addEventListener( 'change', handleModeChange ); +standardModeButton.addEventListener( 'change', handleModeChange ); + +// When page loaded. +startMode( document.querySelector( 'input[name="mode"]:checked' ).value ); + +// When a user changed a mode. +async function handleModeChange( evt ) { + await startMode( evt.target.value ); +} + +// Starts the editor. +async function startMode( selectedMode ) { + if ( selectedMode === 'restricted-values' ) { + await reloadEditor(); + } else { + await reloadEditor( { disableValueMatching: true } ); + } +} + +async function reloadEditor( options = {} ) { + if ( window.editor ) { + await window.editor.destroy(); + } + + const config = { plugins: [ ArticlePluginSet, FontSize ], toolbar: [ 'heading', '|', 'fontSize', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' ], fontSize: { options: [ 10, 12, 14, 'default', 18, 20, 22 ] } - } ) - .then( editor => { - window.editor = editor; - } ) - .catch( err => { - console.error( err.stack ); - } ); + }; + + if ( options.disableValueMatching ) { + config.fontSize.disableValueMatching = true; + } + + window.editor = await ClassicEditor.create( document.querySelector( '#editor' ), config ); +} diff --git a/tests/manual/font-size-numeric.md b/tests/manual/font-size-numeric.md index bf60baf..e0f6605 100644 --- a/tests/manual/font-size-numeric.md +++ b/tests/manual/font-size-numeric.md @@ -10,3 +10,12 @@ Try to: - Change font by selecting some text. - Change to default font by selecting many paragraphs. - Change to default font by selecting some text. + +### Converters mode + +The "Restricted value matching" option means that all font-size values that aren't defined in the plugin's configuration will be removed (e.g. when pasted from Google Docs). +This behaviour can be disabled by selecting the "Disabled value matching" option. + +All font-size above 22 aren't specified in the plugin's configuration and should be restored to default size when the "Restricted value matching" option is selected. + +By default editor should load with the "Disabled value matching" option. From f4ccde7725743702a6a0cfd39e65bc91938da8c7 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 16:12:18 +0100 Subject: [PATCH 06/17] Added a note about "disableValueMatching" option for FontFamily and FontSize plugins. --- docs/features/font.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/features/font.md b/docs/features/font.md index e84cace..60ecd4d 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -47,6 +47,25 @@ ClassicEditor {@snippet features/custom-font-family-options} +### Prevent removing non-specified values + +By default, all not specified values of `font-family` are removing during the conversion. You can disable this behaviour using `disableValueMatching` option. + +```js +ClassicEditor + .create( document.querySelector( '#editor' ), { + fontFamily: { + options: [ + // ... + ], + disableValueMatching: true + }, + // ... + } ) + .then( ... ) + .catch( ... ); +``` + ## Configuring the font size feature It is possible to configure which font size options are supported by the WYSIWYG editor. Use the {@link module:font/fontsize~FontSizeConfig#options `fontSize.options`} configuration option to do so. @@ -150,6 +169,25 @@ ClassicEditor {@snippet features/custom-font-size-numeric-options} +### Prevent removing non-specified values + +By default, all not specified values of `font-size` are removing during the conversion. You can disable this behaviour using `disableValueMatching` option. + +```js +ClassicEditor + .create( document.querySelector( '#editor' ), { + fontSize: { + options: [ + // ... + ], + disableValueMatching: true + }, + // ... + } ) + .then( ... ) + .catch( ... ); +``` + ## Configuring the font color and font background color features Both font color and font background color features are configurable and share the same configuration format. From 2064643612c8d11b8ed3abeed21a8deb6859e5b3 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 16:46:33 +0100 Subject: [PATCH 07/17] When "fontSize.disableValueMatching=true", values in the model will be kept as units instead of preset names. --- src/fontsize/fontsizeediting.js | 15 +++++++++++---- src/fontsize/utils.js | 28 ++++++++++++++++++++++++---- tests/fontsize/fontsizeediting.js | 17 ++++++++++------- tests/fontsize/utils.js | 20 +++++++++++++++++++- tests/manual/font-size-presets.js | 5 ++++- theme/fontsize.css | 1 + 6 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index 325d96e..5465322 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -10,7 +10,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontSizeCommand from './fontsizecommand'; -import { normalizeOptions } from './utils'; +import { normalizeOptions, FONT_SIZE_PRESET_UNITS } from './utils'; import { buildDefinition, FONT_SIZE } from '../utils'; /** @@ -66,12 +66,15 @@ export default class FontSizeEditing extends Plugin { copyOnEnter: true } ); + const disableValueMatching = editor.config.get( 'fontSize.disableValueMatching' ); + // Define view to model conversion. - const options = normalizeOptions( this.editor.config.get( 'fontSize.options' ) ).filter( item => item.model ); + const options = normalizeOptions( this.editor.config.get( 'fontSize.options' ), { disableValueMatching } ) + .filter( item => item.model ); const definition = buildDefinition( FONT_SIZE, options ); // Set-up the two-way conversion. - if ( editor.config.get( 'fontSize.disableValueMatching' ) ) { + if ( disableValueMatching ) { this._prepareAnyValueConverters(); } else { editor.conversion.attributeToElement( definition ); @@ -121,7 +124,11 @@ export default class FontSizeEditing extends Plugin { for ( const className of viewElement.getClassNames() ) { if ( className.startsWith( 'text-' ) ) { - return className.replace( /^text-/, '' ); + const presetName = className.replace( /^text-/, '' ); + + if ( FONT_SIZE_PRESET_UNITS[ presetName ] ) { + return FONT_SIZE_PRESET_UNITS[ presetName ]; + } } } diff --git a/src/fontsize/utils.js b/src/fontsize/utils.js index d41cb21..e049e71 100644 --- a/src/fontsize/utils.js +++ b/src/fontsize/utils.js @@ -12,16 +12,28 @@ * to the {@link module:font/fontsize~FontSizeOption} format. * * @param {Array.} configuredOptions An array of options taken from the configuration. + * @param {Object} [options={}] + * @param {Boolean} [options.disableValueMatching=false] * @returns {Array.} */ -export function normalizeOptions( configuredOptions ) { +export function normalizeOptions( configuredOptions, options = {} ) { + const disableValueMatching = options.disableValueMatching || false; + // Convert options to objects. return configuredOptions - .map( getOptionDefinition ) + .map( item => getOptionDefinition( item, disableValueMatching ) ) // Filter out undefined values that `getOptionDefinition` might return. .filter( option => !!option ); } +// The values should be synchronized with "/theme/fontsize.css" file. +export const FONT_SIZE_PRESET_UNITS = { + tiny: '0.7em', + small: '0.85em', + big: '1.4em', + huge: '1.8em' +}; + // Default named presets map. const namedPresets = { tiny: { @@ -64,10 +76,12 @@ const namedPresets = { // Returns an option definition either from preset or creates one from number shortcut. // If object is passed then this method will return it without alternating it. Returns undefined for item than cannot be parsed. +// If disableValueMatching=true, model will be set to a specified unit value instead of text. // // @param {String|Number|Object} item +// @param {Boolean} disableValueMatching // @returns {undefined|module:font/fontsize~FontSizeOption} -function getOptionDefinition( option ) { +function getOptionDefinition( option, disableValueMatching ) { // Treat any object as full item definition provided by user in configuration. if ( typeof option === 'object' ) { return option; @@ -75,7 +89,13 @@ function getOptionDefinition( option ) { // Item is a named preset. if ( namedPresets[ option ] ) { - return namedPresets[ option ]; + const preset = namedPresets[ option ]; + + if ( disableValueMatching ) { + preset.model = FONT_SIZE_PRESET_UNITS[ option ]; + } + + return preset; } // 'Default' font size. It will be used to remove the fontSize attribute. diff --git a/tests/fontsize/fontsizeediting.js b/tests/fontsize/fontsizeediting.js index 469234e..bd4e477 100644 --- a/tests/fontsize/fontsizeediting.js +++ b/tests/fontsize/fontsizeediting.js @@ -68,9 +68,6 @@ describe( 'FontSizeEditing', () => { .create( { plugins: [ FontSizeEditing, Paragraph ], fontSize: { - options: [ - 'default', - ], disableValueMatching: true } } ) @@ -117,13 +114,19 @@ describe( 'FontSizeEditing', () => { } ); it( 'should convert an element if it has a class that starts with "text-"', () => { - const data = '

foo

'; + editor.setData( '

foo

' ); - editor.setData( data ); + expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="1.8em">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); - expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="huge">oo' ); + it( 'should ignore an element if it has a class starts with "text-" but does not match to any preset', () => { + editor.setData( '

foo

' ); - expect( editor.getData() ).to.equal( data ); + expect( getModelData( doc ) ).to.equal( '[]foo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); } ); it( 'should ignore an element if does not have a class that starts with "text-"', () => { diff --git a/tests/fontsize/utils.js b/tests/fontsize/utils.js index e8523b0..56e7ed7 100644 --- a/tests/fontsize/utils.js +++ b/tests/fontsize/utils.js @@ -3,7 +3,7 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ -import { normalizeOptions } from '../../src/fontsize/utils'; +import { normalizeOptions, FONT_SIZE_PRESET_UNITS } from '../../src/fontsize/utils'; describe( 'FontSizeEditing Utils', () => { describe( 'normalizeOptions()', () => { @@ -35,6 +35,18 @@ describe( 'FontSizeEditing Utils', () => { { title: 'Huge', model: 'huge', view: { name: 'span', classes: 'text-huge', priority: 7 } } ] ); } ); + + it( 'should return defined presets with units in model values', () => { + const options = normalizeOptions( [ 'tiny', 'small', 'default', 'big', 'huge' ], { disableValueMatching: true } ); + + expect( options ).to.deep.equal( [ + { title: 'Tiny', model: '0.7em', view: { name: 'span', classes: 'text-tiny', priority: 7 } }, + { title: 'Small', model: '0.85em', view: { name: 'span', classes: 'text-small', priority: 7 } }, + { title: 'Default', model: undefined }, + { title: 'Big', model: '1.4em', view: { name: 'span', classes: 'text-big', priority: 7 } }, + { title: 'Huge', model: '1.8em', view: { name: 'span', classes: 'text-huge', priority: 7 } } + ] ); + } ); } ); describe( 'numerical presets', () => { @@ -49,4 +61,10 @@ describe( 'FontSizeEditing Utils', () => { } ); } ); } ); + + describe( 'FONT_SIZE_PRESET_UNITS', () => { + it( 'provides default values', () => { + expect( Object.keys( FONT_SIZE_PRESET_UNITS ).length ).to.equal( 4 ); + } ); + } ); } ); diff --git a/tests/manual/font-size-presets.js b/tests/manual/font-size-presets.js index 1786a5c..231920d 100644 --- a/tests/manual/font-size-presets.js +++ b/tests/manual/font-size-presets.js @@ -14,7 +14,10 @@ ClassicEditor plugins: [ ArticlePluginSet, FontSize ], toolbar: [ 'heading', '|', 'fontSize', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' - ] + ], + fontSize: { + disableValueMatching: true + } } ) .then( editor => { window.editor = editor; diff --git a/theme/fontsize.css b/theme/fontsize.css index 677b6ef..298b6e9 100644 --- a/theme/fontsize.css +++ b/theme/fontsize.css @@ -3,6 +3,7 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ +/* The values should be synchronized with the "FONT_SIZE_PRESET_UNITS" constant in the "/src/fontsize/utils.js" file. */ .text-tiny { font-size: .7em; } From fd2101f10d832f15ebb5c9f0e3049486c55c9ba3 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Mon, 9 Mar 2020 17:06:08 +0100 Subject: [PATCH 08/17] Lint. --- tests/fontfamily/fontfamilyediting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fontfamily/fontfamilyediting.js b/tests/fontfamily/fontfamilyediting.js index 638189c..731c666 100644 --- a/tests/fontfamily/fontfamilyediting.js +++ b/tests/fontfamily/fontfamilyediting.js @@ -80,7 +80,7 @@ describe( 'FontFamilyEditing', () => { plugins: [ FontFamilyEditing, Paragraph ], fontFamily: { options: [ - 'Arial', + 'Arial' ], disableValueMatching: true } From d16e9200cdbba79995090e0ab76221ea6f20661e Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Tue, 10 Mar 2020 10:29:45 +0100 Subject: [PATCH 09/17] Simplified the implementation. --- src/fontsize/fontsizeediting.js | 10 +++------- tests/fontsize/fontsizeediting.js | 6 ------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index 5465322..7aeec48 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -100,15 +100,11 @@ export default class FontSizeEditing extends Plugin { return; } - if ( String( attributeValue ).match( /^\d+/ ) ) { - if ( typeof attributeValue == 'number' ) { - attributeValue = `${ attributeValue }px`; - } - - return writer.createAttributeElement( 'span', { style: 'font-size:' + attributeValue }, { priority: 7 } ); + if ( typeof attributeValue == 'number' ) { + attributeValue = `${ attributeValue }px`; } - return writer.createAttributeElement( 'span', { class: 'text-' + attributeValue }, { priority: 7 } ); + return writer.createAttributeElement( 'span', { style: 'font-size:' + attributeValue }, { priority: 7 } ); } } ); diff --git a/tests/fontsize/fontsizeediting.js b/tests/fontsize/fontsizeediting.js index bd4e477..071823e 100644 --- a/tests/fontsize/fontsizeediting.js +++ b/tests/fontsize/fontsizeediting.js @@ -94,12 +94,6 @@ describe( 'FontSizeEditing', () => { expect( editor.getData() ).to.equal( '

foo

' ); } ); - - it( 'should convert a text value as a class', () => { - setModelData( doc, 'f<$text fontSize="large">oo' ); - - expect( editor.getData() ).to.equal( '

foo

' ); - } ); } ); describe( 'data pipeline conversions', () => { From 0ecb10bef43b1890675c19f129926669cdab8cd8 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 11 Mar 2020 15:03:56 +0100 Subject: [PATCH 10/17] Improved documentation of the plugin. --- src/fontfamily.js | 16 ++++++++++++++++ src/fontsize.js | 32 ++++++++++++++++++++++++++++++++ src/fontsize/utils.js | 2 +- theme/fontsize.css | 2 +- 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/fontfamily.js b/src/fontfamily.js index cbea666..dc91ba6 100644 --- a/src/fontfamily.js +++ b/src/fontfamily.js @@ -112,3 +112,19 @@ export default class FontFamily extends Plugin { * * @member {Array.} module:font/fontfamily~FontFamilyConfig#options */ + +/** + * By default the plugin removes any `font-family` value that does not match to the plugin's configuration. It means if you paste a content + * with font families that the editor does not understand, the font-family attribute will be removed and the content will be displayed + * with the font. + * + * You can preserve pasted font family values by switching the option: + * + * const fontSizeConfig = { + * disableValueMatching: true + * }; + * + * Now, the font families, not specified in the editor's configuration, won't be removed when pasting the content. + * + * @member {Boolean} module:font/fontfamily~FontFamilyConfig#disableValueMatching + */ diff --git a/src/fontsize.js b/src/fontsize.js index 5a8c86a..5a48528 100644 --- a/src/fontsize.js +++ b/src/fontsize.js @@ -105,6 +105,22 @@ export default class FontSize extends Plugin { * options: [ 9, 10, 11, 12, 13, 14, 15 ] * }; * + * Also, you can define a label in the dropdown for numerical values: + * + * const fontSizeConfig = { + * options: [ + * { + * title: 'Small', + * model: '8px + * }, + * 'default', + * { + * title: 'Big', + * model: '14px + * } + * ] + * }; + * * Font size can be applied using the command API. To do that, use the `'fontSize'` command and pass the desired font size as a `value`. * For example, the following code will apply the `fontSize` attribute with the **tiny** value to the current selection: * @@ -114,3 +130,19 @@ export default class FontSize extends Plugin { * * @member {Array.} module:font/fontsize~FontSizeConfig#options */ + +/** + * By default the plugin removes any `font-size` value that does not match to the plugin's configuration. It means if you paste a content + * with font sizes that the editor does not understand, the font-size attribute will be removed and the content will be displayed + * with the default size. + * + * You can preserve pasted font size values by switching the option: + * + * const fontSizeConfig = { + * disableValueMatching: true + * }; + * + * Now, the font sizes, not specified in the editor's configuration, won't be removed when pasting the content. + * + * @member {Boolean} module:font/fontsize~FontSizeConfig#disableValueMatching + */ diff --git a/src/fontsize/utils.js b/src/fontsize/utils.js index e049e71..c2236cc 100644 --- a/src/fontsize/utils.js +++ b/src/fontsize/utils.js @@ -26,7 +26,7 @@ export function normalizeOptions( configuredOptions, options = {} ) { .filter( option => !!option ); } -// The values should be synchronized with "/theme/fontsize.css" file. +// The values should be synchronized with values specified in the "/theme/fontsize.css" file. export const FONT_SIZE_PRESET_UNITS = { tiny: '0.7em', small: '0.85em', diff --git a/theme/fontsize.css b/theme/fontsize.css index 298b6e9..85c9313 100644 --- a/theme/fontsize.css +++ b/theme/fontsize.css @@ -3,7 +3,7 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ -/* The values should be synchronized with the "FONT_SIZE_PRESET_UNITS" constant in the "/src/fontsize/utils.js" file. */ +/* The values should be synchronized with the "FONT_SIZE_PRESET_UNITS" object in the "/src/fontsize/utils.js" file. */ .text-tiny { font-size: .7em; } From 20a30510a589172369b881f9c935ae9d64b38325 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 11 Mar 2020 15:06:02 +0100 Subject: [PATCH 11/17] Simplified the implementation and extended configuration options. --- src/fontsize/fontsizeediting.js | 26 +---- src/fontsize/utils.js | 188 ++++++++++++++++++++++---------- 2 files changed, 133 insertions(+), 81 deletions(-) diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index 7aeec48..a87377b 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -10,7 +10,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontSizeCommand from './fontsizecommand'; -import { normalizeOptions, FONT_SIZE_PRESET_UNITS } from './utils'; +import { normalizeOptions } from './utils'; import { buildDefinition, FONT_SIZE } from '../utils'; /** @@ -100,10 +100,6 @@ export default class FontSizeEditing extends Plugin { return; } - if ( typeof attributeValue == 'number' ) { - attributeValue = `${ attributeValue }px`; - } - return writer.createAttributeElement( 'span', { style: 'font-size:' + attributeValue }, { priority: 7 } ); } } ); @@ -111,25 +107,7 @@ export default class FontSizeEditing extends Plugin { editor.conversion.for( 'upcast' ).attributeToAttribute( { model: { key: FONT_SIZE, - value: viewElement => { - const fontSize = viewElement.getStyle( 'font-size' ); - - if ( fontSize ) { - return fontSize; - } - - for ( const className of viewElement.getClassNames() ) { - if ( className.startsWith( 'text-' ) ) { - const presetName = className.replace( /^text-/, '' ); - - if ( FONT_SIZE_PRESET_UNITS[ presetName ] ) { - return FONT_SIZE_PRESET_UNITS[ presetName ]; - } - } - } - - return null; - } + value: viewElement => viewElement.getStyle( 'font-size' ), }, view: { name: 'span' diff --git a/src/fontsize/utils.js b/src/fontsize/utils.js index c2236cc..f74a811 100644 --- a/src/fontsize/utils.js +++ b/src/fontsize/utils.js @@ -7,6 +7,8 @@ * @module font/fontsize/utils */ +import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; + /** * Normalizes and translates the {@link module:font/fontsize~FontSizeConfig#options configuration options} * to the {@link module:font/fontsize~FontSizeOption} format. @@ -34,43 +36,51 @@ export const FONT_SIZE_PRESET_UNITS = { huge: '1.8em' }; -// Default named presets map. +// Default named presets map. Always create a new instance of the preset object in order to avoid modifying references. const namedPresets = { - tiny: { - title: 'Tiny', - model: 'tiny', - view: { - name: 'span', - classes: 'text-tiny', - priority: 7 - } + get tiny() { + return { + title: 'Tiny', + model: 'tiny', + view: { + name: 'span', + classes: 'text-tiny', + priority: 7 + } + }; }, - small: { - title: 'Small', - model: 'small', - view: { - name: 'span', - classes: 'text-small', - priority: 7 - } + get small() { + return { + title: 'Small', + model: 'small', + view: { + name: 'span', + classes: 'text-small', + priority: 7 + } + }; }, - big: { - title: 'Big', - model: 'big', - view: { - name: 'span', - classes: 'text-big', - priority: 7 - } + get big() { + return { + title: 'Big', + model: 'big', + view: { + name: 'span', + classes: 'text-big', + priority: 7 + } + }; }, - huge: { - title: 'Huge', - model: 'huge', - view: { - name: 'span', - classes: 'text-huge', - priority: 7 - } + get huge() { + return { + title: 'Huge', + model: 'huge', + view: { + name: 'span', + classes: 'text-huge', + priority: 7 + } + }; } }; @@ -82,20 +92,20 @@ const namedPresets = { // @param {Boolean} disableValueMatching // @returns {undefined|module:font/fontsize~FontSizeOption} function getOptionDefinition( option, disableValueMatching ) { - // Treat any object as full item definition provided by user in configuration. - if ( typeof option === 'object' ) { - return option; + // Check whether passed option is a full item definition provided by user in configuration. + if ( isFullItemDefinition( option ) ) { + return attachPriority( option ); } - // Item is a named preset. - if ( namedPresets[ option ] ) { - const preset = namedPresets[ option ]; + const preset = findPreset( option ); + // Item is a named preset. + if ( preset ) { if ( disableValueMatching ) { preset.model = FONT_SIZE_PRESET_UNITS[ option ]; } - return preset; + return attachPriority( preset ); } // 'Default' font size. It will be used to remove the fontSize attribute. @@ -107,33 +117,97 @@ function getOptionDefinition( option, disableValueMatching ) { } // At this stage we probably have numerical value to generate a preset so parse it's value. - const sizePreset = parseFloat( option ); - // Discard any faulty values. - if ( isNaN( sizePreset ) ) { + if ( isNumericalDefinition( option ) ) { return; } // Return font size definition from size value. - return generatePixelPreset( sizePreset ); + return generatePixelPreset( option ); } // Creates a predefined preset for pixel size. // -// @param {Number} size Font size in pixels. +// @param {Number} definition Font size in pixels. // @returns {module:font/fontsize~FontSizeOption} -function generatePixelPreset( size ) { - const sizeName = String( size ); - - return { - title: sizeName, - model: size, - view: { - name: 'span', - styles: { - 'font-size': `${ size }px` - }, - priority: 7 +function generatePixelPreset( definition ) { + // Extend a short (numeric value) definition. + if ( typeof definition === 'number' || typeof definition === 'string' ) { + definition = { + title: String( definition ), + model: `${ parseFloat( definition ) }px` + }; + } + + definition.view = { + name: 'span', + styles: { + 'font-size': definition.model } }; + + return attachPriority( definition ); +} + +// Adds the priority to the view element definition if missing. It's required due to ckeditor/ckeditor5#2291 +// +// @param {Object} definition +// @param {Object} definition.title +// @param {Object} definition.model +// @param {Object} definition.view +// @returns {Object} +function attachPriority( definition ) { + if ( !definition.view.priority ) { + definition.view.priority = 7; + } + + return definition; +} + +// Returns a prepared preset definition. If passed an object, a name of preset should be defined as `model` value. +// +// @param {String|Object} definition +// @param {String} definition.model A preset name. +// @returns {Object|undefined} +function findPreset( definition ) { + return namedPresets[ definition ] || namedPresets[ definition.model ]; +} + +// We treat `definition` as completed if it is an object that contains `title`, `model` and `view` values. +// +// @param {Object} definition +// @param {String} definition.title +// @param {String} definition.model +// @param {Object} definition.view +// @returns {Boolean} +function isFullItemDefinition( definition ) { + return typeof definition === 'object' && definition.title && definition.model && definition.view; +} + +// We treat `definition` as numerical if it is a number, number-like (string) or an object with the `title` key. +// +// @param {Object|Number|String} definition +// @param {Object} definition.title +// @returns {Boolean} +function isNumericalDefinition( definition ) { + let numberValue; + + if ( typeof definition === 'object' ) { + if ( !definition.model ) { + /** + * Provided value as an option for {@link module:font/fontsize~FontSize} seems to invalid. + * + * See valid examples described in the {@link module:font/fontsize~FontSizeConfig#options plugin configuration}. + * + * @error font-size-invalid-definition + */ + throw new CKEditorError( 'font-size-invalid-definition: Provided font size definition is invalid.', null, definition ); + } else { + numberValue = parseFloat( definition.model ); + } + } else { + numberValue = parseFloat( definition ); + } + + return isNaN( numberValue ); } From a6aa6e8cfd16ec17a00b60da615897e6d2cfa2cd Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 11 Mar 2020 15:07:24 +0100 Subject: [PATCH 12/17] Tests. --- tests/fontsize/fontsizeediting.js | 36 +-------- tests/fontsize/utils.js | 120 ++++++++++++++++++++++++++++-- tests/integration.js | 114 ++++++++++++++++++++++------ 3 files changed, 206 insertions(+), 64 deletions(-) diff --git a/tests/fontsize/fontsizeediting.js b/tests/fontsize/fontsizeediting.js index 071823e..fec4699 100644 --- a/tests/fontsize/fontsizeediting.js +++ b/tests/fontsize/fontsizeediting.js @@ -88,12 +88,6 @@ describe( 'FontSizeEditing', () => { expect( editor.getData() ).to.equal( '

foo

' ); } ); - - it( 'should add a unit to value if missing', () => { - setModelData( doc, 'f<$text fontSize="10">oo' ); - - expect( editor.getData() ).to.equal( '

foo

' ); - } ); } ); describe( 'data pipeline conversions', () => { @@ -106,30 +100,6 @@ describe( 'FontSizeEditing', () => { expect( editor.getData() ).to.equal( '

foo

' ); } ); - - it( 'should convert an element if it has a class that starts with "text-"', () => { - editor.setData( '

foo

' ); - - expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="1.8em">oo' ); - - expect( editor.getData() ).to.equal( '

foo

' ); - } ); - - it( 'should ignore an element if it has a class starts with "text-" but does not match to any preset', () => { - editor.setData( '

foo

' ); - - expect( getModelData( doc ) ).to.equal( '[]foo' ); - - expect( editor.getData() ).to.equal( '

foo

' ); - } ); - - it( 'should ignore an element if does not have a class that starts with "text-"', () => { - editor.setData( '

foo

' ); - - expect( getModelData( doc ) ).to.equal( '[]foo' ); - - expect( editor.getData() ).to.equal( '

foo

' ); - } ); } ); } ); } ); @@ -176,7 +146,7 @@ describe( 'FontSizeEditing', () => { } ); it( 'should convert fontSize attribute to predefined pixel size preset', () => { - setModelData( doc, 'f<$text fontSize="18">oo' ); + setModelData( doc, 'f<$text fontSize="18px">oo' ); expect( editor.getData() ).to.equal( '

foo

' ); } ); @@ -262,7 +232,7 @@ describe( 'FontSizeEditing', () => { editor.setData( data ); - expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="18">oo' ); + expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="18px">oo' ); expect( editor.getData() ).to.equal( data ); } ); @@ -272,7 +242,7 @@ describe( 'FontSizeEditing', () => { editor.setData( data ); - expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="18">oo' ); + expect( getModelData( doc ) ).to.equal( '[]f<$text fontSize="18px">oo' ); expect( editor.getData() ).to.equal( '

foo

' ); } ); diff --git a/tests/fontsize/utils.js b/tests/fontsize/utils.js index 56e7ed7..4f4d140 100644 --- a/tests/fontsize/utils.js +++ b/tests/fontsize/utils.js @@ -4,6 +4,7 @@ */ import { normalizeOptions, FONT_SIZE_PRESET_UNITS } from '../../src/fontsize/utils'; +import { expectToThrowCKEditorError } from '@ckeditor/ckeditor5-utils/tests/_utils/utils'; describe( 'FontSizeEditing Utils', () => { describe( 'normalizeOptions()', () => { @@ -15,12 +16,12 @@ describe( 'FontSizeEditing Utils', () => { expect( normalizeOptions( [ { title: 'My Size', model: 'my-size', - view: { name: 'span', styles: 'font-size: 12em;' } + view: { name: 'span', styles: 'font-size: 12em;', priority: 7 } } ] ) ).to.deep.equal( [ { title: 'My Size', model: 'my-size', - view: { name: 'span', styles: 'font-size: 12em;' } + view: { name: 'span', styles: 'font-size: 12em;', priority: 7 } } ] ); } ); @@ -36,7 +37,7 @@ describe( 'FontSizeEditing Utils', () => { ] ); } ); - it( 'should return defined presets with units in model values', () => { + it( 'should return defined presets with units in model values if disableValueMatching=true', () => { const options = normalizeOptions( [ 'tiny', 'small', 'default', 'big', 'huge' ], { disableValueMatching: true } ); expect( options ).to.deep.equal( [ @@ -47,18 +48,121 @@ describe( 'FontSizeEditing Utils', () => { { title: 'Huge', model: '1.8em', view: { name: 'span', classes: 'text-huge', priority: 7 } } ] ); } ); + + it( 'should add "view" definition if missing', () => { + const tinyOption = { + title: 'Tiny', + model: 'tiny' + }; + + expect( normalizeOptions( [ tinyOption ] ) ).to.deep.equal( [ + { title: 'Tiny', model: 'tiny', view: { name: 'span', classes: 'text-tiny', priority: 7 } }, + ] ); + } ); + + it( 'should add "view.priority" to returned definition if missing', () => { + const tinyOption = { + title: 'Tiny', + model: 'tiny', + view: { + name: 'span', + classes: 'text-tiny' + } + }; + + expect( normalizeOptions( [ tinyOption ] ) ).to.deep.equal( [ + { title: 'Tiny', model: 'tiny', view: { name: 'span', classes: 'text-tiny', priority: 7 } } + ] ); + } ); + + it( 'should not modify "view.priority" if already specified', () => { + const tinyOption = { + title: 'Tiny', + model: 'tiny', + view: { + name: 'span', + classes: 'text-tiny', + priority: 10 + } + }; + + expect( normalizeOptions( [ tinyOption ] ) ).to.deep.equal( [ + { title: 'Tiny', model: 'tiny', view: { name: 'span', classes: 'text-tiny', priority: 10 } } + ] ); + } ); } ); describe( 'numerical presets', () => { it( 'should return generated presets', () => { - expect( normalizeOptions( [ '10', 12, 'default', '14.1', 18.3 ] ) ).to.deep.equal( [ - { title: '10', model: 10, view: { name: 'span', styles: { 'font-size': '10px' }, priority: 7 } }, - { title: '12', model: 12, view: { name: 'span', styles: { 'font-size': '12px' }, priority: 7 } }, + expect( normalizeOptions( [ '10', '12', 'default', '14.1', 18.3 ] ) ).to.deep.equal( [ + { title: '10', model: '10px', view: { name: 'span', styles: { 'font-size': '10px' }, priority: 7 } }, + { title: '12', model: '12px', view: { name: 'span', styles: { 'font-size': '12px' }, priority: 7 } }, { title: 'Default', model: undefined }, - { title: '14.1', model: 14.1, view: { name: 'span', styles: { 'font-size': '14.1px' }, priority: 7 } }, - { title: '18.3', model: 18.3, view: { name: 'span', styles: { 'font-size': '18.3px' }, priority: 7 } } + { title: '14.1', model: '14.1px', view: { name: 'span', styles: { 'font-size': '14.1px' }, priority: 7 } }, + { title: '18.3', model: '18.3px', view: { name: 'span', styles: { 'font-size': '18.3px' }, priority: 7 } } ] ); } ); + + it( 'should add "view" definition if missing', () => { + const numericOption = { + title: '18', + model: '18px' + }; + + expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [ + { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 7 } }, + ] ); + } ); + + it( 'should discard incomprehensible value', () => { + const numericOption = { + title: '18', + model: 'unknown' + }; + + expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [] ); + } ); + + it( 'should add "view.priority" to returned definition if missing', () => { + const numericOption = { + title: '18', + model: '18px', + view: { + name: 'span', + styles: { 'font-size': '18px' }, + } + }; + + expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [ + { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 7 } }, + ] ); + } ); + + it( 'should not modify "view.priority" if already specified', () => { + const numericOption = { + title: '18', + model: '18px', + view: { + name: 'span', + styles: { 'font-size': '18px' }, + priority: 10 + } + }; + + expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [ + { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 10 } }, + ] ); + } ); + + it( 'should throw an error if definition misses "model" value', () => { + const definition = { + title: '18' + }; + + expectToThrowCKEditorError( () => { + normalizeOptions( [ definition ] ); + }, /font-size-invalid-definition/, null, definition ); + } ); } ); } ); diff --git a/tests/integration.js b/tests/integration.js index 08a71c1..bd9c48f 100644 --- a/tests/integration.js +++ b/tests/integration.js @@ -9,7 +9,6 @@ import Font from '../src/font'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; -import env from '@ckeditor/ckeditor5-utils/src/env'; describe( 'Integration test Font', () => { let element, editor, model; @@ -42,28 +41,57 @@ describe( 'Integration test Font', () => { '' ); - if ( !env.isEdge ) { - expect( editor.getData() ).to.equal( - '

' + - 'foo' + - '' + - '

' - ); - } else { - // Edge sorts attributes of an element. - expect( editor.getData() ).to.equal( - '

' + - 'foo' + - '' + - '

' - ); - } + expect( editor.getData() ).to.equal( + '

' + + 'foo' + + '' + + '

' + ); + } ); + + it( 'should render one span element for all types of font features (disableValueMatching=true)', () => { + const element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ Font, ArticlePluginSet ], + fontFamily: { + disableValueMatching: true + }, + fontSize: { + disableValueMatching: true + } + } ) + .then( editor => { + const model = editor.model; + + setModelData( model, + '' + + '<$text fontColor="#123456" fontBackgroundColor="rgb(10,20,30)" ' + + 'fontSize="48px" fontFamily="docs-Roboto"' + + '>foo' + + '' + + '' + ); + + expect( editor.getData() ).to.equal( + '

' + + 'foo' + + '' + + '

' + ); + + return editor.destroy(); + } ) + .then( () => { + element.remove(); + } ); } ); } ); @@ -85,5 +113,45 @@ describe( 'Integration test Font', () => { '

' ); } ); + + it( 'should render elements wrapped in proper order (disableValueMatching=true)', () => { + const element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ Font, ArticlePluginSet ], + fontFamily: { + disableValueMatching: true + }, + fontSize: { + disableValueMatching: true + } + } ) + .then( editor => { + const model = editor.model; + + setModelData( model, + '' + + '<$text bold="true" linkHref="foo" fontColor="red" fontSize="18px">foo' + + '' + ); + + expect( editor.getData() ).to.equal( + '

' + + '' + + '' + + 'foo' + + '' + + '' + + '

' + ); + + return editor.destroy(); + } ) + .then( () => { + element.remove(); + } ); + } ); } ); } ); From 7d65c73199a583e95ed859579715e819b07cfc8d Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 11 Mar 2020 15:16:00 +0100 Subject: [PATCH 13/17] Disabled the new option in MT for pressets. --- tests/manual/font-size-presets.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/manual/font-size-presets.js b/tests/manual/font-size-presets.js index 231920d..1786a5c 100644 --- a/tests/manual/font-size-presets.js +++ b/tests/manual/font-size-presets.js @@ -14,10 +14,7 @@ ClassicEditor plugins: [ ArticlePluginSet, FontSize ], toolbar: [ 'heading', '|', 'fontSize', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' - ], - fontSize: { - disableValueMatching: true - } + ] } ) .then( editor => { window.editor = editor; From 8d22f03861bc6abd64f4bcc7b0342c2056e097c6 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 11 Mar 2020 15:59:29 +0100 Subject: [PATCH 14/17] Fixed code style in docs. --- docs/features/font.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/font.md b/docs/features/font.md index 60ecd4d..ebb141c 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -58,7 +58,7 @@ ClassicEditor options: [ // ... ], - disableValueMatching: true + disableValueMatching: true }, // ... } ) From 70ab8871c3d250a9b69c20913f504290367cf7df Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 11 Mar 2020 16:00:19 +0100 Subject: [PATCH 15/17] Font-family dropdown will try to match the current value with items in dropdown. --- src/fontfamily/fontfamilyui.js | 13 +++++++++++- tests/fontfamily/fontfamilyui.js | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/fontfamily/fontfamilyui.js b/src/fontfamily/fontfamilyui.js index 49976b1..0c4d035 100644 --- a/src/fontfamily/fontfamilyui.js +++ b/src/fontfamily/fontfamilyui.js @@ -109,7 +109,18 @@ function _prepareListOptions( options, command ) { } ) }; - def.model.bind( 'isOn' ).to( command, 'value', value => value === option.model ); + def.model.bind( 'isOn' ).to( command, 'value', value => { + // "Default" or check in strict font-family converters mode. + if ( value === option.model ) { + return true; + } + + if ( !value || !option.model ) { + return false; + } + + return value.split( ',' )[ 0 ].replace( /'/g, '' ).toLowerCase() === option.model.toLowerCase(); + } ); // Try to set a dropdown list item style. if ( option.view && option.view.styles ) { diff --git a/tests/fontfamily/fontfamilyui.js b/tests/fontfamily/fontfamilyui.js index ab66a2f..5f19ad6 100644 --- a/tests/fontfamily/fontfamilyui.js +++ b/tests/fontfamily/fontfamilyui.js @@ -104,6 +104,42 @@ describe( 'FontFamilyUI', () => { .to.deep.equal( [ false, true, false, false, false, false, false, false, false ] ); } ); + it( 'should activate current option in dropdown for full font family definitions', () => { + const element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ FontFamilyEditing, FontFamilyUI ], + fontSize: { + disableValueMatching: true + } + } ) + .then( editor => { + const command = editor.commands.get( 'fontFamily' ); + const dropdown = editor.ui.componentFactory.create( 'fontFamily' ); + + const listView = dropdown.listView; + + command.value = undefined; + + // The first item is 'default' font family. + expect( listView.items.map( item => item.children.first.isOn ) ) + .to.deep.equal( [ true, false, false, false, false, false, false, false, false ] ); + + command.value = '\'Courier New\', Courier, monospace'; + + // The third item is 'Courier New' font family. + expect( listView.items.map( item => item.children.first.isOn ) ) + .to.deep.equal( [ false, false, true, false, false, false, false, false, false ] ); + + return editor.destroy(); + } ) + .then( () => { + element.remove(); + } ); + } ); + describe( 'model to command binding', () => { it( 'isEnabled', () => { command.isEnabled = false; From 4eb7a2024247d9f450288cdde0d08fead8feb3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Koszuli=C5=84ski?= Date: Wed, 25 Mar 2020 09:59:38 +0100 Subject: [PATCH 16/17] Aligned code to new linter rules. --- src/fontsize/fontsizeediting.js | 2 +- tests/fontsize/utils.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index a87377b..c067bb6 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -107,7 +107,7 @@ export default class FontSizeEditing extends Plugin { editor.conversion.for( 'upcast' ).attributeToAttribute( { model: { key: FONT_SIZE, - value: viewElement => viewElement.getStyle( 'font-size' ), + value: viewElement => viewElement.getStyle( 'font-size' ) }, view: { name: 'span' diff --git a/tests/fontsize/utils.js b/tests/fontsize/utils.js index 4f4d140..825ce74 100644 --- a/tests/fontsize/utils.js +++ b/tests/fontsize/utils.js @@ -56,7 +56,7 @@ describe( 'FontSizeEditing Utils', () => { }; expect( normalizeOptions( [ tinyOption ] ) ).to.deep.equal( [ - { title: 'Tiny', model: 'tiny', view: { name: 'span', classes: 'text-tiny', priority: 7 } }, + { title: 'Tiny', model: 'tiny', view: { name: 'span', classes: 'text-tiny', priority: 7 } } ] ); } ); @@ -110,7 +110,7 @@ describe( 'FontSizeEditing Utils', () => { }; expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [ - { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 7 } }, + { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 7 } } ] ); } ); @@ -129,12 +129,12 @@ describe( 'FontSizeEditing Utils', () => { model: '18px', view: { name: 'span', - styles: { 'font-size': '18px' }, + styles: { 'font-size': '18px' } } }; expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [ - { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 7 } }, + { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 7 } } ] ); } ); @@ -150,7 +150,7 @@ describe( 'FontSizeEditing Utils', () => { }; expect( normalizeOptions( [ numericOption ] ) ).to.deep.equal( [ - { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 10 } }, + { title: '18', model: '18px', view: { name: 'span', styles: { 'font-size': '18px' }, priority: 10 } } ] ); } ); From 14ec7fca876dd13fcde5e0d71c280107df288a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Koszuli=C5=84ski?= Date: Wed, 25 Mar 2020 10:33:49 +0100 Subject: [PATCH 17/17] Renamed the option and improved the docs. --- docs/features/font.md | 27 ++++++++++++++------------- src/fontfamily.js | 4 ++-- src/fontfamily/fontfamilyediting.js | 4 ++-- src/fontsize.js | 4 ++-- src/fontsize/fontsizeediting.js | 8 ++++---- src/fontsize/utils.js | 14 +++++++------- tests/fontfamily/fontfamilyediting.js | 6 +++--- tests/fontfamily/fontfamilyui.js | 2 +- tests/fontsize/fontsizeediting.js | 6 +++--- tests/fontsize/utils.js | 4 ++-- tests/integration.js | 12 ++++++------ tests/manual/font-family.js | 6 +++--- tests/manual/font-size-numeric.html | 2 ++ tests/manual/font-size-numeric.js | 6 +++--- 14 files changed, 54 insertions(+), 51 deletions(-) diff --git a/docs/features/font.md b/docs/features/font.md index ebb141c..e63fdba 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -21,7 +21,7 @@ The {@link module:font/font~Font} plugin enables the following features in the r ## Configuring the font family feature -It is possible to configure which font family options are supported by the WYSIWYG editor. Use the {@link module:font/fontfamily~FontFamilyConfig#options `fontFamily.options`} configuration option to do so. +It is possible to configure which font family options are supported by the WYSIWYG editor. Use the {@link module:font/fontfamily~FontFamilyConfig#options `config.fontFamily.options`} configuration option to do so. Use the special `'default'` keyword to use the default font family defined in the web page styles. It removes any custom font family. @@ -47,9 +47,9 @@ ClassicEditor {@snippet features/custom-font-family-options} -### Prevent removing non-specified values +### Accept all font names -By default, all not specified values of `font-family` are removing during the conversion. You can disable this behaviour using `disableValueMatching` option. +By default, all `font-family` values that are not specified in the `config.fontFamily.options` are stripped. You can enable support for all font names by using the {@link module:font/fontfamily~FontFamilyConfig#supportAllValues `config.fontFamily.supportAllValues`} option. ```js ClassicEditor @@ -58,7 +58,7 @@ ClassicEditor options: [ // ... ], - disableValueMatching: true + supportAllValues: true }, // ... } ) @@ -68,7 +68,7 @@ ClassicEditor ## Configuring the font size feature -It is possible to configure which font size options are supported by the WYSIWYG editor. Use the {@link module:font/fontsize~FontSizeConfig#options `fontSize.options`} configuration option to do so. +It is possible to configure which font size options are supported by the WYSIWYG editor. Use the {@link module:font/fontsize~FontSizeConfig#options `config.fontSize.options`} configuration option to do so. Use the special `'default'` keyword to use the default font size defined in the web page styles. It removes any custom font size. @@ -171,7 +171,8 @@ ClassicEditor ### Prevent removing non-specified values -By default, all not specified values of `font-size` are removing during the conversion. You can disable this behaviour using `disableValueMatching` option. +By default, all `font-size` values that are not specified in the `config.fontSize.options` are stripped. You can enable support for all font sizes by using the {@link module:font/fontfamily~FontSizeConfig#supportAllValues `config.fontSize.supportAllValues`} option. + ```js ClassicEditor @@ -180,7 +181,7 @@ ClassicEditor options: [ // ... ], - disableValueMatching: true + supportAllValues: true }, // ... } ) @@ -202,7 +203,7 @@ Check out the WYSIWYG editor below with both features customized using the edito ### Specifying available colors -It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontcolor~FontColorConfig#colors `fontColor.colors`} and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors `fontBackgroundColor.colors`} configuration options to do so. +It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontcolor~FontColorConfig#colors `config.fontColor.colors`} and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors `config.fontBackgroundColor.colors`} configuration options to do so. ```js ClassicEditor @@ -270,7 +271,7 @@ ClassicEditor ### Changing the geometry of the color grid -You can configure the number of columns in the color dropdown by setting the {@link module:font/fontcolor~FontColorConfig#columns `fontColor.columns`} and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns `fontBackgroundColor.columns`} configuration options. +You can configure the number of columns in the color dropdown by setting the {@link module:font/fontcolor~FontColorConfig#columns `config.fontColor.columns`} and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns `config.fontBackgroundColor.columns`} configuration options. Usually, you will want to use this option when changing the number of [available colors](#specifying-available-colors). @@ -303,7 +304,7 @@ ClassicEditor The font and font background color dropdowns contain the "Document colors" section. It lists the colors already used in the document for the users to be able to easily reuse them (for consistency purposes). -By default, the number of displayed document colors is limited to one row, but you can adjust it (or remove the whole section) by using the {@link module:font/fontcolor~FontColorConfig#documentColors `fontColor.documentColors`} or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#documentColors `fontBackgroundColor.documentColors`} options. +By default, the number of displayed document colors is limited to one row, but you can adjust it (or remove the whole section) by using the {@link module:font/fontcolor~FontColorConfig#documentColors `config.fontColor.documentColors`} or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#documentColors `config.fontBackgroundColor.documentColors`} options. ```js ClassicEditor @@ -378,7 +379,7 @@ The {@link module:font/fontfamily~FontFamily} plugin registers the following com * The `'fontFamily'` dropdown. * The {@link module:font/fontfamily/fontfamilycommand~FontFamilyCommand `'fontFamily'`} command. - The number of options and their names correspond to the {@link module:font/fontfamily~FontFamilyConfig#options `fontFamily.options`} configuration option. + The number of options and their names correspond to the {@link module:font/fontfamily~FontFamilyConfig#options `config.fontFamily.options`} configuration option. You can change the font family of the current selection by executing the command with a desired value: @@ -424,7 +425,7 @@ The {@link module:font/fontsize~FontSize} plugin registers the following compone * The `'fontSize'` dropdown. * The {@link module:font/fontsize/fontsizecommand~FontSizeCommand `'fontSize'`} command. - The number of options and their names correspond to the {@link module:font/fontsize~FontSizeConfig#options `fontSize.options`} configuration option. + The number of options and their names correspond to the {@link module:font/fontsize~FontSizeConfig#options `config.fontSize.options`} configuration option. You can change the font size of the current selection by executing the command with a desired value: @@ -436,7 +437,7 @@ The {@link module:font/fontsize~FontSize} plugin registers the following compone editor.execute( 'fontSize', { value: 'small' } ); ``` - Passing an empty value will remove any `fontSize` set: + Passing an empty value will remove any `config.fontSize` set: ```js editor.execute( 'fontSize' ); diff --git a/src/fontfamily.js b/src/fontfamily.js index dc91ba6..dc7912d 100644 --- a/src/fontfamily.js +++ b/src/fontfamily.js @@ -121,10 +121,10 @@ export default class FontFamily extends Plugin { * You can preserve pasted font family values by switching the option: * * const fontSizeConfig = { - * disableValueMatching: true + * supportAllValues: true * }; * * Now, the font families, not specified in the editor's configuration, won't be removed when pasting the content. * - * @member {Boolean} module:font/fontfamily~FontFamilyConfig#disableValueMatching + * @member {Boolean} module:font/fontfamily~FontFamilyConfig#supportAllValues */ diff --git a/src/fontfamily/fontfamilyediting.js b/src/fontfamily/fontfamilyediting.js index 255cbce..3faea51 100644 --- a/src/fontfamily/fontfamilyediting.js +++ b/src/fontfamily/fontfamilyediting.js @@ -50,7 +50,7 @@ export default class FontFamilyEditing extends Plugin { 'Trebuchet MS, Helvetica, sans-serif', 'Verdana, Geneva, sans-serif' ], - disableValueMatching: false + supportAllValues: false } ); } @@ -72,7 +72,7 @@ export default class FontFamilyEditing extends Plugin { const definition = buildDefinition( FONT_FAMILY, options ); // Set-up the two-way conversion. - if ( editor.config.get( 'fontFamily.disableValueMatching' ) ) { + if ( editor.config.get( 'fontFamily.supportAllValues' ) ) { this._prepareAnyValueConverters(); } else { editor.conversion.attributeToElement( definition ); diff --git a/src/fontsize.js b/src/fontsize.js index 5a48528..5047d11 100644 --- a/src/fontsize.js +++ b/src/fontsize.js @@ -139,10 +139,10 @@ export default class FontSize extends Plugin { * You can preserve pasted font size values by switching the option: * * const fontSizeConfig = { - * disableValueMatching: true + * supportAllValues: true * }; * * Now, the font sizes, not specified in the editor's configuration, won't be removed when pasting the content. * - * @member {Boolean} module:font/fontsize~FontSizeConfig#disableValueMatching + * @member {Boolean} module:font/fontsize~FontSizeConfig#supportAllValues */ diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index c067bb6..b44b10b 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -49,7 +49,7 @@ export default class FontSizeEditing extends Plugin { 'big', 'huge' ], - disableValueMatching: false + supportAllValues: false } ); } @@ -66,15 +66,15 @@ export default class FontSizeEditing extends Plugin { copyOnEnter: true } ); - const disableValueMatching = editor.config.get( 'fontSize.disableValueMatching' ); + const supportAllValues = editor.config.get( 'fontSize.supportAllValues' ); // Define view to model conversion. - const options = normalizeOptions( this.editor.config.get( 'fontSize.options' ), { disableValueMatching } ) + const options = normalizeOptions( this.editor.config.get( 'fontSize.options' ), { supportAllValues } ) .filter( item => item.model ); const definition = buildDefinition( FONT_SIZE, options ); // Set-up the two-way conversion. - if ( disableValueMatching ) { + if ( supportAllValues ) { this._prepareAnyValueConverters(); } else { editor.conversion.attributeToElement( definition ); diff --git a/src/fontsize/utils.js b/src/fontsize/utils.js index f74a811..86635d8 100644 --- a/src/fontsize/utils.js +++ b/src/fontsize/utils.js @@ -15,15 +15,15 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; * * @param {Array.} configuredOptions An array of options taken from the configuration. * @param {Object} [options={}] - * @param {Boolean} [options.disableValueMatching=false] + * @param {Boolean} [options.supportAllValues=false] * @returns {Array.} */ export function normalizeOptions( configuredOptions, options = {} ) { - const disableValueMatching = options.disableValueMatching || false; + const supportAllValues = options.supportAllValues || false; // Convert options to objects. return configuredOptions - .map( item => getOptionDefinition( item, disableValueMatching ) ) + .map( item => getOptionDefinition( item, supportAllValues ) ) // Filter out undefined values that `getOptionDefinition` might return. .filter( option => !!option ); } @@ -86,12 +86,12 @@ const namedPresets = { // Returns an option definition either from preset or creates one from number shortcut. // If object is passed then this method will return it without alternating it. Returns undefined for item than cannot be parsed. -// If disableValueMatching=true, model will be set to a specified unit value instead of text. +// If supportAllValues=true, model will be set to a specified unit value instead of text. // // @param {String|Number|Object} item -// @param {Boolean} disableValueMatching +// @param {Boolean} supportAllValues // @returns {undefined|module:font/fontsize~FontSizeOption} -function getOptionDefinition( option, disableValueMatching ) { +function getOptionDefinition( option, supportAllValues ) { // Check whether passed option is a full item definition provided by user in configuration. if ( isFullItemDefinition( option ) ) { return attachPriority( option ); @@ -101,7 +101,7 @@ function getOptionDefinition( option, disableValueMatching ) { // Item is a named preset. if ( preset ) { - if ( disableValueMatching ) { + if ( supportAllValues ) { preset.model = FONT_SIZE_PRESET_UNITS[ option ]; } diff --git a/tests/fontfamily/fontfamilyediting.js b/tests/fontfamily/fontfamilyediting.js index 731c666..a973996 100644 --- a/tests/fontfamily/fontfamilyediting.js +++ b/tests/fontfamily/fontfamilyediting.js @@ -67,11 +67,11 @@ describe( 'FontFamilyEditing', () => { 'Verdana, Geneva, sans-serif' ] ); - expect( editor.config.get( 'fontFamily.disableValueMatching' ) ).to.equal( false ); + expect( editor.config.get( 'fontFamily.supportAllValues' ) ).to.equal( false ); } ); } ); - describe( 'disableValueMatching=true', () => { + describe( 'supportAllValues=true', () => { let editor, doc; beforeEach( () => { @@ -82,7 +82,7 @@ describe( 'FontFamilyEditing', () => { options: [ 'Arial' ], - disableValueMatching: true + supportAllValues: true } } ) .then( newEditor => { diff --git a/tests/fontfamily/fontfamilyui.js b/tests/fontfamily/fontfamilyui.js index 5f19ad6..7d6e0b1 100644 --- a/tests/fontfamily/fontfamilyui.js +++ b/tests/fontfamily/fontfamilyui.js @@ -112,7 +112,7 @@ describe( 'FontFamilyUI', () => { .create( element, { plugins: [ FontFamilyEditing, FontFamilyUI ], fontSize: { - disableValueMatching: true + supportAllValues: true } } ) .then( editor => { diff --git a/tests/fontsize/fontsizeediting.js b/tests/fontsize/fontsizeediting.js index fec4699..469b32b 100644 --- a/tests/fontsize/fontsizeediting.js +++ b/tests/fontsize/fontsizeediting.js @@ -56,11 +56,11 @@ describe( 'FontSizeEditing', () => { describe( 'default value', () => { it( 'should be set', () => { expect( editor.config.get( 'fontSize.options' ) ).to.deep.equal( [ 'tiny', 'small', 'default', 'big', 'huge' ] ); - expect( editor.config.get( 'fontSize.disableValueMatching' ) ).to.equal( false ); + expect( editor.config.get( 'fontSize.supportAllValues' ) ).to.equal( false ); } ); } ); - describe( 'disableValueMatching=true', () => { + describe( 'supportAllValues=true', () => { let editor, doc; beforeEach( () => { @@ -68,7 +68,7 @@ describe( 'FontSizeEditing', () => { .create( { plugins: [ FontSizeEditing, Paragraph ], fontSize: { - disableValueMatching: true + supportAllValues: true } } ) .then( newEditor => { diff --git a/tests/fontsize/utils.js b/tests/fontsize/utils.js index 825ce74..cf60643 100644 --- a/tests/fontsize/utils.js +++ b/tests/fontsize/utils.js @@ -37,8 +37,8 @@ describe( 'FontSizeEditing Utils', () => { ] ); } ); - it( 'should return defined presets with units in model values if disableValueMatching=true', () => { - const options = normalizeOptions( [ 'tiny', 'small', 'default', 'big', 'huge' ], { disableValueMatching: true } ); + it( 'should return defined presets with units in model values if supportAllValues=true', () => { + const options = normalizeOptions( [ 'tiny', 'small', 'default', 'big', 'huge' ], { supportAllValues: true } ); expect( options ).to.deep.equal( [ { title: 'Tiny', model: '0.7em', view: { name: 'span', classes: 'text-tiny', priority: 7 } }, diff --git a/tests/integration.js b/tests/integration.js index bd9c48f..99828e4 100644 --- a/tests/integration.js +++ b/tests/integration.js @@ -52,7 +52,7 @@ describe( 'Integration test Font', () => { ); } ); - it( 'should render one span element for all types of font features (disableValueMatching=true)', () => { + it( 'should render one span element for all types of font features (supportAllValues=true)', () => { const element = document.createElement( 'div' ); document.body.appendChild( element ); @@ -60,10 +60,10 @@ describe( 'Integration test Font', () => { .create( element, { plugins: [ Font, ArticlePluginSet ], fontFamily: { - disableValueMatching: true + supportAllValues: true }, fontSize: { - disableValueMatching: true + supportAllValues: true } } ) .then( editor => { @@ -114,7 +114,7 @@ describe( 'Integration test Font', () => { ); } ); - it( 'should render elements wrapped in proper order (disableValueMatching=true)', () => { + it( 'should render elements wrapped in proper order (supportAllValues=true)', () => { const element = document.createElement( 'div' ); document.body.appendChild( element ); @@ -122,10 +122,10 @@ describe( 'Integration test Font', () => { .create( element, { plugins: [ Font, ArticlePluginSet ], fontFamily: { - disableValueMatching: true + supportAllValues: true }, fontSize: { - disableValueMatching: true + supportAllValues: true } } ) .then( editor => { diff --git a/tests/manual/font-family.js b/tests/manual/font-family.js index 5f1a33f..c4c87dc 100644 --- a/tests/manual/font-family.js +++ b/tests/manual/font-family.js @@ -28,7 +28,7 @@ async function startMode( selectedMode ) { if ( selectedMode === 'restricted-values' ) { await reloadEditor(); } else { - await reloadEditor( { disableValueMatching: true } ); + await reloadEditor( { supportAllValues: true } ); } } @@ -45,8 +45,8 @@ async function reloadEditor( options = {} ) { fontFamily: {} }; - if ( options.disableValueMatching ) { - config.fontFamily.disableValueMatching = true; + if ( options.supportAllValues ) { + config.fontFamily.supportAllValues = true; } window.editor = await ClassicEditor.create( document.querySelector( '#editor' ), config ); diff --git a/tests/manual/font-size-numeric.html b/tests/manual/font-size-numeric.html index 295b9eb..49f171b 100644 --- a/tests/manual/font-size-numeric.html +++ b/tests/manual/font-size-numeric.html @@ -17,4 +17,6 @@

Font Size feature sample.

Some text with font-size set to: 36px.

Some text with font-size set to: 48px.

Some text with font-size set to: 64px.

+

Some text with font-size set to: 2em.

+

Some text with font-size set to: 15.5pt.

diff --git a/tests/manual/font-size-numeric.js b/tests/manual/font-size-numeric.js index adeed5a..c4e88d5 100644 --- a/tests/manual/font-size-numeric.js +++ b/tests/manual/font-size-numeric.js @@ -28,7 +28,7 @@ async function startMode( selectedMode ) { if ( selectedMode === 'restricted-values' ) { await reloadEditor(); } else { - await reloadEditor( { disableValueMatching: true } ); + await reloadEditor( { supportAllValues: true } ); } } @@ -45,8 +45,8 @@ async function reloadEditor( options = {} ) { fontSize: { options: [ 10, 12, 14, 'default', 18, 20, 22 ] } }; - if ( options.disableValueMatching ) { - config.fontSize.disableValueMatching = true; + if ( options.supportAllValues ) { + config.fontSize.supportAllValues = true; } window.editor = await ClassicEditor.create( document.querySelector( '#editor' ), config );