diff --git a/packages/ckeditor5-alignment/docs/features/text-alignment.md b/packages/ckeditor5-alignment/docs/features/text-alignment.md index 7e67892de00..309e2b96237 100644 --- a/packages/ckeditor5-alignment/docs/features/text-alignment.md +++ b/packages/ckeditor5-alignment/docs/features/text-alignment.md @@ -139,6 +139,12 @@ The {@link module:alignment/alignment~Alignment} plugin registers: We recommend using the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector} for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more. +## Content compatibility + +The {@link module:alignment/alignment~Alignment} plugin provides support for the deprecated `align` attribute. + +Block elements such as `

` with the `align` attribute are accepted by the plugin, but the editor always returns the markup in a modern format, so the transformation is one way only. + ## Contribute The source code of the feature is available on GitHub in https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-alignment. diff --git a/packages/ckeditor5-alignment/src/alignmentediting.js b/packages/ckeditor5-alignment/src/alignmentediting.js index 6da914b9de2..2191de9a044 100644 --- a/packages/ckeditor5-alignment/src/alignmentediting.js +++ b/packages/ckeditor5-alignment/src/alignmentediting.js @@ -72,6 +72,13 @@ export default class AlignmentEditing extends Plugin { editor.conversion.for( 'upcast' ).attributeToAttribute( definition ); } + const upcastCompatibilityDefinitions = buildUpcastCompatibilityDefinitions( optionsToConvert ); + + // Always upcast from deprecated `align` attribute. + for ( const definition of upcastCompatibilityDefinitions ) { + editor.conversion.for( 'upcast' ).attributeToAttribute( definition ); + } + editor.commands.add( 'alignment', new AlignmentCommand( editor ) ); } } @@ -122,6 +129,27 @@ function buildUpcastInlineDefinitions( options ) { return definitions; } +// Prepare upcast definitions for deprecated `align` attribute. +// @private +function buildUpcastCompatibilityDefinitions( options ) { + const definitions = []; + + for ( const { name } of options ) { + definitions.push( { + view: { + key: 'align', + value: name + }, + model: { + key: 'alignment', + value: name + } + } ); + } + + return definitions; +} + // Prepare conversion definitions for upcast and downcast alignment with classes. // @private function buildClassDefinition( options ) { diff --git a/packages/ckeditor5-alignment/tests/alignmentediting.js b/packages/ckeditor5-alignment/tests/alignmentediting.js index 3eacd9dbe65..f807d1e6a80 100644 --- a/packages/ckeditor5-alignment/tests/alignmentediting.js +++ b/packages/ckeditor5-alignment/tests/alignmentediting.js @@ -556,6 +556,78 @@ describe( 'AlignmentEditing', () => { } ); } ); + describe( 'deprecated `align` attribute', () => { + it( 'should support allowed `align` values in LTR content', () => { + const data = '

A

' + + '

B

' + + '

C

' + + '

D

'; + + editor.setData( data ); + + const expectedModelData = '[]A' + + 'B' + + 'C' + + 'D'; + + const expectedData = '

A

' + + '

B

' + + '

C

' + + '

D

'; + + expect( getModelData( model ) ).to.equal( expectedModelData ); + expect( editor.getData() ).to.equal( expectedData ); + } ); + + it( 'should support allowed `align` values in RTL content', async () => { + const newEditor = await VirtualTestEditor + .create( { + language: { + content: 'ar' + }, + plugins: [ AlignmentEditing, Paragraph ] + } ); + const model = newEditor.model; + const data = '

A

' + + '

B

' + + '

C

' + + '

D

'; + + newEditor.setData( data ); + + const expectedModelData = '[]A' + + 'B' + + 'C' + + 'D'; + + const expectedData = '

A

' + + '

B

' + + '

C

' + + '

D

'; + + expect( getModelData( model ) ).to.equal( expectedModelData ); + expect( newEditor.getData() ).to.equal( expectedData ); + + return newEditor.destroy(); + } ); + + it( 'should ignore invalid values', () => { + const data = '

A

' + + '

B

'; + + editor.setData( data ); + + const expectedModelData = '[]A' + + 'B'; + + const expectedData = '

A

' + + '

B

'; + + expect( getModelData( model ) ).to.equal( expectedModelData ); + expect( editor.getData() ).to.equal( expectedData ); + } ); + } ); + describe( 'should be extensible', () => { it( 'converters in the data pipeline', () => { blockDefaultConversion( editor.data.downcastDispatcher );