浏览代码

Changed: IndentCommand will indent/outdent multiple items if multiple items are selected.

Szymon Cofalik 8 年之前
父节点
当前提交
44a6883110

+ 7 - 8
packages/ckeditor5-list/src/indentcommand.js

@@ -51,18 +51,16 @@ export default class IndentCommand extends Command {
 	_doExecute() {
 		const doc = this.editor.document;
 		const batch = doc.batch();
-		const element = getClosestListItem( doc.selection.getFirstPosition() );
+		let itemsToChange = Array.from( doc.selection.getSelectedBlocks() );
 
 		doc.enqueueChanges( () => {
-			const oldIndent = element.getAttribute( 'indent' );
-
-			let itemsToChange = [ element ];
+			const lastItem = itemsToChange[ itemsToChange.length - 1 ];
 
 			// Indenting a list item should also indent all the items that are already sub-items of indented item.
-			let next = element.nextSibling;
+			let next = lastItem.nextSibling;
 
-			// Check all items as long as their indent is bigger than indent of changed list item.
-			while ( next && next.name == 'listItem' && next.getAttribute( 'indent' ) > oldIndent ) {
+			// Check all items after last indented item, as long as their indent is bigger than indent of that item.
+			while ( next && next.name == 'listItem' && next.getAttribute( 'indent' ) > lastItem.getAttribute( 'indent' ) ) {
 				itemsToChange.push( next );
 
 				next = next.nextSibling;
@@ -84,7 +82,8 @@ export default class IndentCommand extends Command {
 				if ( indent < 0 ) {
 					// To keep the model as correct as possible, first rename listItem, then remove attributes,
 					// as listItem without attributes is very incorrect and will cause problems in converters.
-					batch.rename( item, 'paragraph' ).removeAttribute( item, 'indent' ).removeAttribute( item, 'type' );
+					// No need to remove attributes, will be removed by post fixer.
+					batch.rename( item, 'paragraph' );
 				} else {
 					// If indent is >= 0, just change the attribute value.
 					batch.setAttribute( item, 'indent', indent );

+ 34 - 15
packages/ckeditor5-list/tests/indentcommand.js

@@ -85,27 +85,27 @@ describe( 'IndentCommand', () => {
 				);
 			} );
 
-			it( 'should increment indent of only first selected item when multiple items are selected', () => {
-				doc.selection.setRanges( [ new Range(
-					new Position( root.getChild( 4 ), [ 0 ] ),
-					new Position( root.getChild( 6 ), [ 0 ] )
-				) ] );
+			it( 'should increment indent of all sub-items of indented item', () => {
+				doc.selection.collapse( root.getChild( 1 ) );
 
 				command._doExecute();
 
 				expect( getData( doc, { withoutSelection: true } ) ).to.equal(
 					'<listItem indent="0" type="bulleted">a</listItem>' +
-					'<listItem indent="0" type="bulleted">b</listItem>' +
-					'<listItem indent="1" type="bulleted">c</listItem>' +
-					'<listItem indent="2" type="bulleted">d</listItem>' +
+					'<listItem indent="1" type="bulleted">b</listItem>' +
+					'<listItem indent="2" type="bulleted">c</listItem>' +
+					'<listItem indent="3" type="bulleted">d</listItem>' +
 					'<listItem indent="3" type="bulleted">e</listItem>' +
-					'<listItem indent="1" type="bulleted">f</listItem>' +
+					'<listItem indent="2" type="bulleted">f</listItem>' +
 					'<listItem indent="0" type="bulleted">g</listItem>'
 				);
 			} );
 
-			it( 'should increment indent of all sub-items of indented item', () => {
-				doc.selection.collapse( root.getChild( 1 ) );
+			it( 'should increment indent of all selected item when multiple items are selected', () => {
+				doc.selection.setRanges( [ new Range(
+					new Position( root.getChild( 1 ), [ 0 ] ),
+					new Position( root.getChild( 3 ), [ 0 ] )
+				) ] );
 
 				command._doExecute();
 
@@ -114,8 +114,8 @@ describe( 'IndentCommand', () => {
 					'<listItem indent="1" type="bulleted">b</listItem>' +
 					'<listItem indent="2" type="bulleted">c</listItem>' +
 					'<listItem indent="3" type="bulleted">d</listItem>' +
-					'<listItem indent="3" type="bulleted">e</listItem>' +
-					'<listItem indent="2" type="bulleted">f</listItem>' +
+					'<listItem indent="2" type="bulleted">e</listItem>' +
+					'<listItem indent="1" type="bulleted">f</listItem>' +
 					'<listItem indent="0" type="bulleted">g</listItem>'
 				);
 			} );
@@ -178,7 +178,7 @@ describe( 'IndentCommand', () => {
 				command._doExecute();
 
 				expect( getData( doc, { withoutSelection: true } ) ).to.equal(
-					'<paragraph>a</paragraph>' +
+					'<paragraph indent="0" type="bulleted">a</paragraph>' +
 					'<listItem indent="0" type="bulleted">b</listItem>' +
 					'<listItem indent="1" type="bulleted">c</listItem>' +
 					'<listItem indent="2" type="bulleted">d</listItem>' +
@@ -195,7 +195,7 @@ describe( 'IndentCommand', () => {
 
 				expect( getData( doc, { withoutSelection: true } ) ).to.equal(
 					'<listItem indent="0" type="bulleted">a</listItem>' +
-					'<paragraph>b</paragraph>' +
+					'<paragraph indent="0" type="bulleted">b</paragraph>' +
 					'<listItem indent="0" type="bulleted">c</listItem>' +
 					'<listItem indent="1" type="bulleted">d</listItem>' +
 					'<listItem indent="1" type="bulleted">e</listItem>' +
@@ -203,6 +203,25 @@ describe( 'IndentCommand', () => {
 					'<listItem indent="0" type="bulleted">g</listItem>'
 				);
 			} );
+
+			it( 'should outdent all selected item when multiple items are selected', () => {
+				doc.selection.setRanges( [ new Range(
+					new Position( root.getChild( 1 ), [ 0 ] ),
+					new Position( root.getChild( 3 ), [ 0 ] )
+				) ] );
+
+				command._doExecute();
+
+				expect( getData( doc, { withoutSelection: true } ) ).to.equal(
+					'<listItem indent="0" type="bulleted">a</listItem>' +
+					'<paragraph indent="0" type="bulleted">b</paragraph>' +
+					'<listItem indent="0" type="bulleted">c</listItem>' +
+					'<listItem indent="1" type="bulleted">d</listItem>' +
+					'<listItem indent="2" type="bulleted">e</listItem>' +
+					'<listItem indent="1" type="bulleted">f</listItem>' +
+					'<listItem indent="0" type="bulleted">g</listItem>'
+				);
+			} );
 		} );
 	} );
 } );

+ 0 - 12
packages/ckeditor5-list/tests/list.js

@@ -151,18 +151,6 @@ describe( 'List', () => {
 			expect( editor.execute.calledWithExactly( 'indentList' ) ).to.be.true;
 		} );
 
-		it( 'should execute indentList command on tab key for non-collapsed selection and indent only first item', () => {
-			editor.setData( '<ul><li>foo</li><li>bar</li><li>xyz</li></ul>' );
-			editor.document.selection.collapse( editor.document.getRoot().getChild( 1 ) );
-			editor.document.selection.setFocus( editor.document.getRoot().getChild( 2 ) );
-
-			editor.editing.view.fire( 'keydown', domEvtDataStub );
-
-			expect( editor.execute.calledOnce ).to.be.true;
-			expect( editor.execute.calledWithExactly( 'indentList' ) ).to.be.true;
-			expect( editor.getData() ).to.equal( '<ul><li>foo<ul><li>bar</li></ul></li><li>xyz</li></ul>' );
-		} );
-
 		it( 'should execute outdentList command on shift+tab keystroke', () => {
 			domEvtDataStub.keystroke += getCode( 'shift' );