浏览代码

Fix: The list style attribute will be inherited when switching the "listType" attribue for existing the "listItem" element.

Kamil Piechaczek 5 年之前
父节点
当前提交
76014e5a35
共有 2 个文件被更改,包括 110 次插入32 次删除
  1. 41 32
      packages/ckeditor5-list/src/liststyleediting.js
  2. 69 0
      packages/ckeditor5-list/tests/liststyleediting.js

+ 41 - 32
packages/ckeditor5-list/src/liststyleediting.js

@@ -429,16 +429,12 @@ function fixListAfterOutdentListCommand( editor ) {
 function fixListStyleAttributeOnListItemElements( editor ) {
 	return writer => {
 		let wasFixed = false;
-		let insertedListItems = [];
 
-		for ( const change of editor.model.document.differ.getChanges() ) {
-			if ( change.type == 'insert' && change.name == 'listItem' ) {
-				insertedListItems.push( change.position.nodeAfter );
-			}
-		}
-
-		// Don't touch todo lists.
-		insertedListItems = insertedListItems.filter( item => item.getAttribute( 'listType' ) !== 'todo' );
+		const insertedListItems = getChangedListItems( editor.model.document.differ.getChanges() )
+			.filter( item => {
+				// Don't touch todo lists. They are handled in another post-fixer.
+				return item.getAttribute( 'listType' ) !== 'todo';
+			} );
 
 		if ( !insertedListItems.length ) {
 			return wasFixed;
@@ -524,17 +520,11 @@ function fixListStyleAttributeOnListItemElements( editor ) {
 // @returns {Function}
 function removeListStyleAttributeFromTodoList( editor ) {
 	return writer => {
-		let todoListItems = [];
-
-		for ( const change of editor.model.document.differ.getChanges() ) {
-			const item = getItemFromChange( change );
-
-			if ( item && item.is( 'element', 'listItem' ) && item.getAttribute( 'listType' ) === 'todo' ) {
-				todoListItems.push( item );
-			}
-		}
-
-		todoListItems = todoListItems.filter( item => item.hasAttribute( 'listStyle' ) );
+		const todoListItems = getChangedListItems( editor.model.document.differ.getChanges() )
+			.filter( item => {
+				// Handle the todo lists only. The rest is handled in another post-fixer.
+				return item.getAttribute( 'listType' ) === 'todo' && item.hasAttribute( 'listStyle' );
+			} );
 
 		if ( !todoListItems.length ) {
 			return false;
@@ -546,18 +536,6 @@ function removeListStyleAttributeFromTodoList( editor ) {
 
 		return true;
 	};
-
-	function getItemFromChange( change ) {
-		if ( change.type === 'attribute' ) {
-			return change.range.start.nodeAfter;
-		}
-
-		if ( change.type === 'insert' ) {
-			return change.position.nodeAfter;
-		}
-
-		return null;
-	}
 }
 
 // Restores the `listStyle` attribute after changing the list type.
@@ -577,3 +555,34 @@ function restoreDefaultListStyle( editor ) {
 		} );
 	};
 }
+
+// Returns `listItem` that were inserted or changed.
+//
+// @private
+// @param {Array.<Object>} changes The changes list returned by the differ.
+// @returns {Array.<module:engine/model/element~Element>}
+function getChangedListItems( changes ) {
+	const items = [];
+
+	for ( const change of changes ) {
+		const item = getItemFromChange( change );
+
+		if ( item && item.is( 'element', 'listItem' ) ) {
+			items.push( item );
+		}
+	}
+
+	return items;
+
+	function getItemFromChange( change ) {
+		if ( change.type === 'attribute' ) {
+			return change.range.start.nodeAfter;
+		}
+
+		if ( change.type === 'insert' ) {
+			return change.position.nodeAfter;
+		}
+
+		return null;
+	}
+}

+ 69 - 0
packages/ckeditor5-list/tests/liststyleediting.js

@@ -522,6 +522,75 @@ describe( 'ListStyleEditing', () => {
 			);
 		} );
 
+		describe( 'modifying "listType" attribute', () => {
+			it( 'should inherit the list style attribute when the modified list is the same kind of the list as next sibling', () => {
+				setModelData( model,
+					'<listItem listIndent="0" listStyle="default" listType="numbered">Foo Bar.[]</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>'
+				);
+
+				editor.execute( 'bulletedList' );
+
+				expect( getModelData( model ) ).to.equal(
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo Bar.[]</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>'
+				);
+			} );
+
+			it( 'should inherit the list style attribute when the modified list is the same kind of the list as previous sibling', () => {
+				setModelData( model,
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>' +
+					'<listItem listIndent="0" listStyle="default" listType="numbered">Foo Bar.[]</listItem>'
+				);
+
+				editor.execute( 'bulletedList' );
+
+				expect( getModelData( model ) ).to.equal(
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo Bar.[]</listItem>'
+				);
+			} );
+
+			it( 'should not inherit the list style attribute when the modified list already has defined it (next sibling check)', () => {
+				setModelData( model,
+					'<listItem listIndent="0" listStyle="default" listType="bulleted">Foo Bar.[]</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>'
+				);
+
+				editor.execute( 'listStyle', { type: 'disc' } );
+
+				expect( getModelData( model ) ).to.equal(
+					'<listItem listIndent="0" listStyle="disc" listType="bulleted">Foo Bar.[]</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+					'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>'
+				);
+			} );
+
+			it(
+				'should not inherit the list style attribute when the modified list already has defined it (previous sibling check)',
+				() => {
+					setModelData( model,
+						'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+						'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>' +
+						'<listItem listIndent="0" listStyle="default" listType="bulleted">Foo Bar.[]</listItem>'
+					);
+
+					editor.execute( 'listStyle', { type: 'disc' } );
+
+					expect( getModelData( model ) ).to.equal(
+						'<listItem listIndent="0" listStyle="circle" listType="bulleted">Foo</listItem>' +
+						'<listItem listIndent="0" listStyle="circle" listType="bulleted">Bar</listItem>' +
+						'<listItem listIndent="0" listStyle="disc" listType="bulleted">Foo Bar.[]</listItem>'
+					);
+				}
+			);
+		} );
+
 		describe( 'indenting lists', () => {
 			it( 'should restore the default value for the list style attribute when indenting a single item', () => {
 				setModelData( model,