From 9bdbd32a2188edff7d9db0f3f0617c6612a00822 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Tue, 27 Oct 2020 10:19:29 +0100 Subject: [PATCH 1/5] List styles will be inherited correctly when pasting a list into another list. --- packages/ckeditor5-list/package.json | 2 +- .../ckeditor5-list/src/liststyleediting.js | 49 +++++- .../ckeditor5-list/tests/liststyleediting.js | 153 +++++++++++++++++- 3 files changed, 198 insertions(+), 6 deletions(-) diff --git a/packages/ckeditor5-list/package.json b/packages/ckeditor5-list/package.json index f2be642e8cb..87848377747 100644 --- a/packages/ckeditor5-list/package.json +++ b/packages/ckeditor5-list/package.json @@ -10,6 +10,7 @@ "ckeditor5-plugin" ], "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^23.0.0", "@ckeditor/ckeditor5-core": "^23.0.0", "@ckeditor/ckeditor5-engine": "^23.0.0", "@ckeditor/ckeditor5-paragraph": "^23.0.0", @@ -19,7 +20,6 @@ "devDependencies": { "@ckeditor/ckeditor5-basic-styles": "^23.0.0", "@ckeditor/ckeditor5-block-quote": "^23.0.0", - "@ckeditor/ckeditor5-clipboard": "^23.0.0", "@ckeditor/ckeditor5-essentials": "^23.0.0", "@ckeditor/ckeditor5-editor-classic": "^23.0.0", "@ckeditor/ckeditor5-enter": "^23.0.0", diff --git a/packages/ckeditor5-list/src/liststyleediting.js b/packages/ckeditor5-list/src/liststyleediting.js index 1ccdd4909e7..417fe38199a 100644 --- a/packages/ckeditor5-list/src/liststyleediting.js +++ b/packages/ckeditor5-list/src/liststyleediting.js @@ -8,6 +8,7 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard'; import ListEditing from './listediting'; import ListStyleCommand from './liststylecommand'; import { getSiblingListItem, getSiblingNodes } from './utils'; @@ -29,7 +30,7 @@ export default class ListStyleEditing extends Plugin { * @inheritDoc */ static get requires() { - return [ ListEditing ]; + return [ ListEditing, Clipboard ]; } /** @@ -437,6 +438,13 @@ function fixListAfterOutdentListCommand( editor ) { // @param {module:core/editor/editor~Editor} editor // @returns {Function} function fixListStyleAttributeOnListItemElements( editor ) { + // A flag that determines whether the inserted content comes from the clipboard. + let contentFromClipboard; + + editor.listenTo( editor.plugins.get( Clipboard ), 'inputTransformation', () => { + contentFromClipboard = true; + } ); + return writer => { let wasFixed = false; @@ -450,6 +458,45 @@ function fixListStyleAttributeOnListItemElements( editor ) { return wasFixed; } + // Adjust the `listStyle` attribute for inserted (pasted) items. See #8160. + // + // ■ List item 1. // [listStyle="square", listType="bulleted"] + // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] + // ○ [] (selection is here) + // + // Then, pasting a list with different attributes (listStyle, listType): + // + // 1. First. // [listStyle="decimal", listType="numbered"] + // 2. Second // [listStyle="decimal", listType="numbered"] + // + // The `listType` attribute will be corrected by the `ListEditing` converters. + // We need to adjust the `listStyle` attribute. Expected structure: + // + // ■ List item 1. // [listStyle="square", listType="bulleted"] + // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] + // ○ First. // [listStyle="circle", listType="bulleted"] + // ○ Second // [listStyle="circle", listType="bulleted"] + const firstPreviousSibling = insertedListItems[ 0 ].previousSibling; + + if ( firstPreviousSibling && contentFromClipboard ) { + contentFromClipboard = false; + + const listIndent = firstPreviousSibling.getAttribute( 'listIndent' ); + const listStyle = firstPreviousSibling.getAttribute( 'listStyle' ); + + const itemsToUpdate = insertedListItems.filter( i => { + return i.getAttribute( 'listIndent' ) === listIndent && i.getAttribute( 'listStyle' ) !== listStyle; + } ); + + if ( itemsToUpdate.length ) { + for ( const item of itemsToUpdate ) { + writer.setAttribute( 'listStyle', listStyle, item ); + } + + return true; + } + } + // Check whether the last inserted element is next to the `listItem` element. // // ■ Paragraph[] // <-- The inserted item. diff --git a/packages/ckeditor5-list/tests/liststyleediting.js b/packages/ckeditor5-list/tests/liststyleediting.js index 06f6eed13af..ccc8517d446 100644 --- a/packages/ckeditor5-list/tests/liststyleediting.js +++ b/packages/ckeditor5-list/tests/liststyleediting.js @@ -3,6 +3,8 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ +/* global document */ + import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Typing from '@ckeditor/ckeditor5-typing/src/typing'; @@ -13,13 +15,17 @@ import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils import ListStyleEditing from '../src/liststyleediting'; import TodoListEditing from '../src/todolistediting'; import ListStyleCommand from '../src/liststylecommand'; +import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; describe( 'ListStyleEditing', () => { - let editor, model, view; + let editor, model, view, element; beforeEach( () => { - return VirtualTestEditor - .create( { + element = document.createElement( 'div' ); + document.body.append( element ); + + return ClassicTestEditor + .create( element, { plugins: [ Paragraph, ListStyleEditing, UndoEditing ] } ) .then( newEditor => { @@ -30,7 +36,10 @@ describe( 'ListStyleEditing', () => { } ); afterEach( () => { - return editor.destroy(); + return editor.destroy() + .then( () => { + element.remove(); + } ); } ); it( 'should have pluginName', () => { @@ -1459,5 +1468,141 @@ describe( 'ListStyleEditing', () => { } ); } } ); + + // #8160 + describe( 'pasting a into another list', () => { + it( 'should inherit attributes from the previous sibling element (collapsed selection)', () => { + setModelData( model, + 'Foo' + + 'Foo Bar' + + '[]' + + 'Bar' + ); + + pasteHtml( editor, + '' + ); + + expect( getModelData( model ) ).to.equal( + 'Foo' + + 'Foo Bar' + + 'Foo 1' + + 'Foo 2[]' + + 'Bar' + ); + } ); + + it( 'should inherit attributes from the previous sibling element (non-collapsed selection)', () => { + setModelData( model, + 'Foo' + + 'Foo Bar' + + '[Foo]' + + 'Bar' + ); + + pasteHtml( editor, + '' + ); + + expect( getModelData( model ) ).to.equal( + 'Foo' + + 'Foo Bar' + + 'Foo 1' + + 'Foo 2[]' + + 'Bar' + ); + } ); + + it( 'should inherit attributes from the previous sibling element (non-collapsed selection over a few elements)', () => { + setModelData( model, + 'Foo' + + 'Foo Bar' + + '[Foo 1.' + + 'Foo 2.' + + 'Foo 3.]' + + 'Bar' + ); + + pasteHtml( editor, + '' + ); + + expect( getModelData( model ) ).to.equal( + 'Foo' + + 'Foo Bar' + + 'Foo 1' + + 'Foo 2[]' + + 'Bar' + ); + } ); + + it( 'should do nothing when pasting the similar list', () => { + setModelData( model, + 'Foo' + + 'Foo Bar' + + '[]' + + 'Bar' + ); + + pasteHtml( editor, + '
    ' + + '
  1. Foo
  2. ' + + '
' + ); + + expect( getModelData( model ) ).to.equal( + 'Foo' + + 'Foo Bar' + + 'Foo[]' + + 'Bar' + ); + } ); + + it( 'should replace the entire list if selected', () => { + setModelData( model, + 'Foo' + + '[Foo Bar]' + + 'Bar' + ); + + pasteHtml( editor, + '' + ); + + expect( getModelData( model ) ).to.equal( + 'Foo' + + 'Foo[]' + + 'Bar' + ); + } ); + + function pasteHtml( editor, html ) { + editor.editing.view.document.fire( 'paste', { + dataTransfer: createDataTransfer( { 'text/html': html } ), + stopPropagation() {}, + preventDefault() {} + } ); + } + + function createDataTransfer( data ) { + return { + getData( type ) { + return data[ type ]; + }, + setData() {} + }; + } + } ); } ); } ); From 363ea0c2257aa0b46c07f93d48fea4764f5e704e Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Tue, 27 Oct 2020 13:41:41 +0100 Subject: [PATCH 2/5] Improved the implementation. --- packages/ckeditor5-list/package.json | 2 +- .../ckeditor5-list/src/liststyleediting.js | 78 +++++++------------ .../ckeditor5-list/tests/liststylecommand.js | 4 +- .../ckeditor5-list/tests/liststyleediting.js | 40 +++++++--- 4 files changed, 61 insertions(+), 63 deletions(-) diff --git a/packages/ckeditor5-list/package.json b/packages/ckeditor5-list/package.json index 87848377747..f2be642e8cb 100644 --- a/packages/ckeditor5-list/package.json +++ b/packages/ckeditor5-list/package.json @@ -10,7 +10,6 @@ "ckeditor5-plugin" ], "dependencies": { - "@ckeditor/ckeditor5-clipboard": "^23.0.0", "@ckeditor/ckeditor5-core": "^23.0.0", "@ckeditor/ckeditor5-engine": "^23.0.0", "@ckeditor/ckeditor5-paragraph": "^23.0.0", @@ -20,6 +19,7 @@ "devDependencies": { "@ckeditor/ckeditor5-basic-styles": "^23.0.0", "@ckeditor/ckeditor5-block-quote": "^23.0.0", + "@ckeditor/ckeditor5-clipboard": "^23.0.0", "@ckeditor/ckeditor5-essentials": "^23.0.0", "@ckeditor/ckeditor5-editor-classic": "^23.0.0", "@ckeditor/ckeditor5-enter": "^23.0.0", diff --git a/packages/ckeditor5-list/src/liststyleediting.js b/packages/ckeditor5-list/src/liststyleediting.js index 417fe38199a..fea4a455fc4 100644 --- a/packages/ckeditor5-list/src/liststyleediting.js +++ b/packages/ckeditor5-list/src/liststyleediting.js @@ -8,7 +8,6 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard'; import ListEditing from './listediting'; import ListStyleCommand from './liststylecommand'; import { getSiblingListItem, getSiblingNodes } from './utils'; @@ -30,7 +29,7 @@ export default class ListStyleEditing extends Plugin { * @inheritDoc */ static get requires() { - return [ ListEditing, Clipboard ]; + return [ ListEditing ]; } /** @@ -438,13 +437,6 @@ function fixListAfterOutdentListCommand( editor ) { // @param {module:core/editor/editor~Editor} editor // @returns {Function} function fixListStyleAttributeOnListItemElements( editor ) { - // A flag that determines whether the inserted content comes from the clipboard. - let contentFromClipboard; - - editor.listenTo( editor.plugins.get( Clipboard ), 'inputTransformation', () => { - contentFromClipboard = true; - } ); - return writer => { let wasFixed = false; @@ -458,45 +450,6 @@ function fixListStyleAttributeOnListItemElements( editor ) { return wasFixed; } - // Adjust the `listStyle` attribute for inserted (pasted) items. See #8160. - // - // ■ List item 1. // [listStyle="square", listType="bulleted"] - // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] - // ○ [] (selection is here) - // - // Then, pasting a list with different attributes (listStyle, listType): - // - // 1. First. // [listStyle="decimal", listType="numbered"] - // 2. Second // [listStyle="decimal", listType="numbered"] - // - // The `listType` attribute will be corrected by the `ListEditing` converters. - // We need to adjust the `listStyle` attribute. Expected structure: - // - // ■ List item 1. // [listStyle="square", listType="bulleted"] - // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] - // ○ First. // [listStyle="circle", listType="bulleted"] - // ○ Second // [listStyle="circle", listType="bulleted"] - const firstPreviousSibling = insertedListItems[ 0 ].previousSibling; - - if ( firstPreviousSibling && contentFromClipboard ) { - contentFromClipboard = false; - - const listIndent = firstPreviousSibling.getAttribute( 'listIndent' ); - const listStyle = firstPreviousSibling.getAttribute( 'listStyle' ); - - const itemsToUpdate = insertedListItems.filter( i => { - return i.getAttribute( 'listIndent' ) === listIndent && i.getAttribute( 'listStyle' ) !== listStyle; - } ); - - if ( itemsToUpdate.length ) { - for ( const item of itemsToUpdate ) { - writer.setAttribute( 'listStyle', listStyle, item ); - } - - return true; - } - } - // Check whether the last inserted element is next to the `listItem` element. // // ■ Paragraph[] // <-- The inserted item. @@ -537,8 +490,35 @@ function fixListStyleAttributeOnListItemElements( editor ) { } else { writer.setAttribute( 'listStyle', DEFAULT_LIST_TYPE, item ); } - wasFixed = true; + } else { + // Adjust the `listStyle` attribute for inserted (pasted) items. See #8160. + // + // ■ List item 1. // [listStyle="square", listType="bulleted"] + // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] + // ○ [] (selection is here) + // + // Then, pasting a list with different attributes (listStyle, listType): + // + // 1. First. // [listStyle="decimal", listType="numbered"] + // 2. Second // [listStyle="decimal", listType="numbered"] + // + // The `listType` attribute will be corrected by the `ListEditing` converters. + // We need to adjust the `listStyle` attribute. Expected structure: + // + // ■ List item 1. // [listStyle="square", listType="bulleted"] + // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] + // ○ First. // [listStyle="circle", listType="bulleted"] + // ○ Second // [listStyle="circle", listType="bulleted"] + const prevSibling = item.previousSibling; + + if ( prevSibling && + prevSibling.getAttribute( 'listIndent' ) > 0 && + prevSibling.getAttribute( 'listIndent' ) === item.getAttribute( 'listIndent' ) && + shouldInheritListType( prevSibling, item ) + ) { + writer.setAttribute( 'listStyle', prevSibling.getAttribute( 'listStyle' ), item ); + } } } diff --git a/packages/ckeditor5-list/tests/liststylecommand.js b/packages/ckeditor5-list/tests/liststylecommand.js index 642203822b7..34d8ecec064 100644 --- a/packages/ckeditor5-list/tests/liststylecommand.js +++ b/packages/ckeditor5-list/tests/liststylecommand.js @@ -96,7 +96,7 @@ describe( 'ListStyleCommand', () => { it( 'should return the value of `listStyle` attribute for the selection inside a nested list', () => { setData( model, '1.' + - '1.1.[]' + + '1.1.[]' + '2.' ); @@ -106,7 +106,7 @@ describe( 'ListStyleCommand', () => { it( 'should return the value of `listStyle` attribute from a list where the selection starts (selection over nested list)', () => { setData( model, '1.' + - '1.1.[' + + '1.1.[' + '2.]' ); diff --git a/packages/ckeditor5-list/tests/liststyleediting.js b/packages/ckeditor5-list/tests/liststyleediting.js index ccc8517d446..4edc314c403 100644 --- a/packages/ckeditor5-list/tests/liststyleediting.js +++ b/packages/ckeditor5-list/tests/liststyleediting.js @@ -9,23 +9,21 @@ import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtest import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Typing from '@ckeditor/ckeditor5-typing/src/typing'; import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting'; +import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; +import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard'; import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view'; import ListStyleEditing from '../src/liststyleediting'; import TodoListEditing from '../src/todolistediting'; import ListStyleCommand from '../src/liststylecommand'; -import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; describe( 'ListStyleEditing', () => { - let editor, model, view, element; + let editor, model, view; beforeEach( () => { - element = document.createElement( 'div' ); - document.body.append( element ); - - return ClassicTestEditor - .create( element, { + return VirtualTestEditor + .create( { plugins: [ Paragraph, ListStyleEditing, UndoEditing ] } ) .then( newEditor => { @@ -36,10 +34,7 @@ describe( 'ListStyleEditing', () => { } ); afterEach( () => { - return editor.destroy() - .then( () => { - element.remove(); - } ); + return editor.destroy(); } ); it( 'should have pluginName', () => { @@ -1471,6 +1466,29 @@ describe( 'ListStyleEditing', () => { // #8160 describe( 'pasting a into another list', () => { + let element; + + beforeEach( () => { + element = document.createElement( 'div' ); + document.body.append( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ Paragraph, Clipboard, ListStyleEditing, UndoEditing ] + } ) + .then( newEditor => { + editor = newEditor; + model = editor.model; + } ); + } ); + + afterEach( () => { + return editor.destroy() + .then( () => { + element.remove(); + } ); + } ); + it( 'should inherit attributes from the previous sibling element (collapsed selection)', () => { setModelData( model, 'Foo' + From 00610fd2e36c3015524c8e0c14a00048ae49acff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Wed, 28 Oct 2020 07:20:48 +0100 Subject: [PATCH 3/5] Refactor check for inheriting list style from previous list item. --- .../ckeditor5-list/src/liststyleediting.js | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/packages/ckeditor5-list/src/liststyleediting.js b/packages/ckeditor5-list/src/liststyleediting.js index fea4a455fc4..611ab7db6a5 100644 --- a/packages/ckeditor5-list/src/liststyleediting.js +++ b/packages/ckeditor5-list/src/liststyleediting.js @@ -510,14 +510,12 @@ function fixListStyleAttributeOnListItemElements( editor ) { // ○ List item 1.1. // [listStyle="circle", listType="bulleted"] // ○ First. // [listStyle="circle", listType="bulleted"] // ○ Second // [listStyle="circle", listType="bulleted"] - const prevSibling = item.previousSibling; - - if ( prevSibling && - prevSibling.getAttribute( 'listIndent' ) > 0 && - prevSibling.getAttribute( 'listIndent' ) === item.getAttribute( 'listIndent' ) && - shouldInheritListType( prevSibling, item ) - ) { - writer.setAttribute( 'listStyle', prevSibling.getAttribute( 'listStyle' ), item ); + const previousSibling = item.previousSibling; + + if ( shouldInheritListTypeFromPreviousItem( previousSibling, item ) ) { + writer.setAttribute( 'listStyle', previousSibling.getAttribute( 'listStyle' ), item ); + + wasFixed = true; } } } @@ -554,6 +552,38 @@ function fixListStyleAttributeOnListItemElements( editor ) { return true; } + + // Checks whether the `listStyle` attribute should be copied from previous list item. + // + // The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list. + // Top-level lists are not normalized as we allow side-by-side list of different types. + // + // @param {module:engine/model/element~Element|null} previousItem + // @param {module:engine/model/element~Element} itemToChange + // @returns {Boolean} + function shouldInheritListTypeFromPreviousItem( previousItem, itemToChange ) { + if ( !previousItem || !previousItem.is( 'element', 'listItem' ) ) { + return false; + } + + if ( itemToChange.getAttribute( 'listType' ) !== previousItem.getAttribute( 'listType' ) ) { + return false; + } + + const previousItemIndent = previousItem.getAttribute( 'listIndent' ); + + if ( previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute( 'listIndent' ) ) { + return false; + } + + const previousItemListStyle = previousItem.getAttribute( 'listStyle' ); + + if ( !previousItemListStyle || previousItemListStyle === itemToChange.getAttribute( 'listStyle' ) ) { + return false; + } + + return true; + } } // Removes the `listStyle` attribute from "todo" list items. From df18a0ffe480b7feccf1376c89603669f563f732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Wed, 28 Oct 2020 07:27:00 +0100 Subject: [PATCH 4/5] The fixListStyleAttributeOnListItemElements() should not re-create internal functions. --- .../ckeditor5-list/src/liststyleediting.js | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/packages/ckeditor5-list/src/liststyleediting.js b/packages/ckeditor5-list/src/liststyleediting.js index 611ab7db6a5..8764b72e73b 100644 --- a/packages/ckeditor5-list/src/liststyleediting.js +++ b/packages/ckeditor5-list/src/liststyleediting.js @@ -522,68 +522,68 @@ function fixListStyleAttributeOnListItemElements( editor ) { return wasFixed; }; +} - // Checks whether the `listStyle` attribute should be copied from the `baseItem` element. - // - // The attribute should be copied if the inserted element does not have defined it and - // the value for the element is other than default in the base element. - // - // @param {module:engine/model/element~Element|null} baseItem - // @param {module:engine/model/element~Element} itemToChange - // @returns {Boolean} - function shouldInheritListType( baseItem, itemToChange ) { - if ( !baseItem ) { - return false; - } +// Checks whether the `listStyle` attribute should be copied from the `baseItem` element. +// +// The attribute should be copied if the inserted element does not have defined it and +// the value for the element is other than default in the base element. +// +// @param {module:engine/model/element~Element|null} baseItem +// @param {module:engine/model/element~Element} itemToChange +// @returns {Boolean} +function shouldInheritListType( baseItem, itemToChange ) { + if ( !baseItem ) { + return false; + } - const baseListStyle = baseItem.getAttribute( 'listStyle' ); + const baseListStyle = baseItem.getAttribute( 'listStyle' ); - if ( !baseListStyle ) { - return false; - } - - if ( baseListStyle === DEFAULT_LIST_TYPE ) { - return false; - } + if ( !baseListStyle ) { + return false; + } - if ( baseItem.getAttribute( 'listType' ) !== itemToChange.getAttribute( 'listType' ) ) { - return false; - } + if ( baseListStyle === DEFAULT_LIST_TYPE ) { + return false; + } - return true; + if ( baseItem.getAttribute( 'listType' ) !== itemToChange.getAttribute( 'listType' ) ) { + return false; } - // Checks whether the `listStyle` attribute should be copied from previous list item. - // - // The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list. - // Top-level lists are not normalized as we allow side-by-side list of different types. - // - // @param {module:engine/model/element~Element|null} previousItem - // @param {module:engine/model/element~Element} itemToChange - // @returns {Boolean} - function shouldInheritListTypeFromPreviousItem( previousItem, itemToChange ) { - if ( !previousItem || !previousItem.is( 'element', 'listItem' ) ) { - return false; - } + return true; +} - if ( itemToChange.getAttribute( 'listType' ) !== previousItem.getAttribute( 'listType' ) ) { - return false; - } +// Checks whether the `listStyle` attribute should be copied from previous list item. +// +// The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list. +// Top-level lists are not normalized as we allow side-by-side list of different types. +// +// @param {module:engine/model/element~Element|null} previousItem +// @param {module:engine/model/element~Element} itemToChange +// @returns {Boolean} +function shouldInheritListTypeFromPreviousItem( previousItem, itemToChange ) { + if ( !previousItem || !previousItem.is( 'element', 'listItem' ) ) { + return false; + } - const previousItemIndent = previousItem.getAttribute( 'listIndent' ); + if ( itemToChange.getAttribute( 'listType' ) !== previousItem.getAttribute( 'listType' ) ) { + return false; + } - if ( previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute( 'listIndent' ) ) { - return false; - } + const previousItemIndent = previousItem.getAttribute( 'listIndent' ); - const previousItemListStyle = previousItem.getAttribute( 'listStyle' ); + if ( previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute( 'listIndent' ) ) { + return false; + } - if ( !previousItemListStyle || previousItemListStyle === itemToChange.getAttribute( 'listStyle' ) ) { - return false; - } + const previousItemListStyle = previousItem.getAttribute( 'listStyle' ); - return true; + if ( !previousItemListStyle || previousItemListStyle === itemToChange.getAttribute( 'listStyle' ) ) { + return false; } + + return true; } // Removes the `listStyle` attribute from "todo" list items. From 21b9591a650003bd38167a33da3d08e2367bf4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Wed, 28 Oct 2020 07:29:07 +0100 Subject: [PATCH 5/5] Typo fix. --- packages/ckeditor5-list/tests/liststyleediting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ckeditor5-list/tests/liststyleediting.js b/packages/ckeditor5-list/tests/liststyleediting.js index 4edc314c403..4061f86d45c 100644 --- a/packages/ckeditor5-list/tests/liststyleediting.js +++ b/packages/ckeditor5-list/tests/liststyleediting.js @@ -1465,7 +1465,7 @@ describe( 'ListStyleEditing', () => { } ); // #8160 - describe( 'pasting a into another list', () => { + describe( 'pasting a list into another list', () => { let element; beforeEach( () => {