Browse Source

Fix: ListCommand should check whether it can be applied to the selection. Closes #62.

Aleksander Nowodzinski 8 years ago
parent
commit
2b0f1e9c03

+ 17 - 6
packages/ckeditor5-list/src/listcommand.js

@@ -61,7 +61,8 @@ export default class ListCommand extends Command {
 	 */
 	execute( options = {} ) {
 		const document = this.editor.document;
-		const blocks = Array.from( document.selection.getSelectedBlocks() );
+		const blocks = Array.from( document.selection.getSelectedBlocks() )
+			.filter( block => checkCanBecomeListItem( block, document.schema ) );
 
 		// Whether we are turning off some items.
 		const turnOff = this.value === true;
@@ -252,11 +253,7 @@ export default class ListCommand extends Command {
 		}
 
 		// Otherwise, check if list item can be inserted at the position start.
-		return schema.check( {
-			name: 'listItem',
-			attributes: [ 'type', 'indent' ],
-			inside: Position.createBefore( firstBlock )
-		} );
+		return checkCanBecomeListItem( firstBlock, schema );
 	}
 }
 
@@ -306,3 +303,17 @@ function _fixType( blocks, isBackward, lowestIndent ) {
 		}
 	}
 }
+
+// Checks whether the given block can be replaced by a listItem.
+//
+// @private
+// @param {module:engine/model/element~Element} block A block to be tested.
+// @param {module:engine/model/schema~Schema} schema The schema of the document.
+// @returns {Boolean}
+function checkCanBecomeListItem( block, schema ) {
+	return schema.check( {
+		name: 'listItem',
+		attributes: [ 'type', 'indent' ],
+		inside: Position.createBefore( block )
+	} );
+}

+ 25 - 0
packages/ckeditor5-list/tests/listcommand.js

@@ -247,6 +247,31 @@ describe( 'ListCommand', () => {
 					);
 				} );
 
+				// https://github.com/ckeditor/ckeditor5-list/issues/62
+				it( 'should not rename blocks which cannot become listItems', () => {
+					doc.schema.registerItem( 'restricted' );
+					doc.schema.allow( { name: 'restricted', inside: '$root' } );
+					doc.schema.disallow( { name: 'paragraph', inside: 'restricted' } );
+
+					doc.schema.registerItem( 'fooBlock', '$block' );
+					doc.schema.allow( { name: 'fooBlock', inside: 'restricted' } );
+
+					setData(
+						doc,
+						'<paragraph>a[bc</paragraph>' +
+						'<restricted><fooBlock></fooBlock></restricted>' +
+						'<paragraph>de]f</paragraph>'
+					);
+
+					command.execute();
+
+					expect( getData( doc ) ).to.equal(
+						'<listItem indent="0" type="bulleted">a[bc</listItem>' +
+						'<restricted><fooBlock></fooBlock></restricted>' +
+						'<listItem indent="0" type="bulleted">de]f</listItem>'
+					);
+				} );
+
 				it( 'should rename closest block to listItem and set correct attributes', () => {
 					// From first paragraph to second paragraph.
 					// Command value=false, we are turning on list items.