Procházet zdrojové kódy

Merge branch t/ckeditor5-engine/532

Internal: Aligned Schema API use to the new Schema API.
Piotrek Koszuliński před 8 roky
rodič
revize
7553bf62ed

+ 11 - 3
packages/ckeditor5-list/src/converters.js

@@ -365,8 +365,14 @@ export function viewModelConverter( evt, data, consumable, conversionApi ) {
 		const type = data.input.parent && data.input.parent.name == 'ol' ? 'numbered' : 'bulleted';
 		writer.setAttribute( 'type', type, listItem );
 
-		// 3. Handle `<li>` children.
-		data.context.push( listItem );
+		let alteredContext = false;
+
+		// See https://github.com/ckeditor/ckeditor5-list/issues/87
+		if ( data.context[ data.context.length - 1 ].name != 'listItem' ) {
+			// 3. Handle `<li>` children.
+			data.context.push( listItem );
+			alteredContext = true;
+		}
 
 		// `listItem`s created recursively should have bigger indent.
 		data.indent++;
@@ -394,7 +400,9 @@ export function viewModelConverter( evt, data, consumable, conversionApi ) {
 		}
 
 		data.indent--;
-		data.context.pop();
+		if ( alteredContext ) {
+			data.context.pop();
+		}
 
 		data.output = items;
 	}

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

@@ -8,7 +8,6 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 import first from '@ckeditor/ckeditor5-utils/src/first';
 
 /**
@@ -308,9 +307,5 @@ function _fixType( blocks, isBackward, lowestIndent ) {
 // @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 )
-	} );
+	return schema.checkChild( block.parent, 'listItem' ) && !schema.isObject( block );
 }

+ 4 - 9
packages/ckeditor5-list/src/listengine.js

@@ -50,18 +50,13 @@ export default class ListEngine extends Plugin {
 		const editor = this.editor;
 
 		// Schema.
-		// Note: in case `$block` will be ever allowed in `listItem`, keep in mind that this feature
+		// Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature
 		// uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.
 		// If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.
-		const schema = editor.model.schema;
-		schema.registerItem( 'listItem', '$block' );
-		schema.allow( {
-			name: 'listItem',
-			inside: '$root',
-			coinside: '$root',
-			attributes: [ 'type', 'indent' ]
+		editor.model.schema.register( 'listItem', {
+			inheritAllFrom: '$block',
+			allowAttributes: [ 'type', 'indent' ]
 		} );
-		schema.requireAttributes( 'listItem', [ 'type', 'indent' ] );
 
 		// Converters.
 		const data = editor.data;

+ 6 - 7
packages/ckeditor5-list/tests/indentcommand.js

@@ -21,12 +21,11 @@ describe( 'IndentCommand', () => {
 		doc = model.document;
 		root = doc.createRoot();
 
-		model.schema.registerItem( 'listItem', '$block' );
-		model.schema.registerItem( 'paragraph', '$block' );
-
-		model.schema.allow( { name: '$block', inside: '$root' } );
-		model.schema.allow( { name: 'listItem', attributes: [ 'type', 'indent' ], inside: '$root' } );
-		model.schema.allow( { name: 'paragraph', inside: '$root' } );
+		model.schema.register( 'listItem', {
+			inheritAllFrom: '$block',
+			allowAttributes: [ 'type', 'indent' ]
+		} );
+		model.schema.register( 'paragraph', { inheritAllFrom: '$block' } );
 
 		setData(
 			model,
@@ -117,7 +116,7 @@ describe( 'IndentCommand', () => {
 			// Edge case but may happen that some other blocks will also use the indent attribute
 			// and before we fixed it the command was enabled in such a case.
 			it( 'should be false if selection starts in a paragraph with indent attribute', () => {
-				model.schema.allow( { name: 'paragraph', attributes: [ 'indent' ], inside: '$root' } );
+				model.schema.extend( 'paragraph', { allowAttributes: 'indent' } );
 
 				setData( model, '<listItem indent="0">a</listItem><paragraph indent="0">b[]</paragraph>' );
 

+ 45 - 13
packages/ckeditor5-list/tests/listcommand.js

@@ -23,14 +23,24 @@ describe( 'ListCommand', () => {
 
 		command = new ListCommand( editor, 'bulleted' );
 
-		model.schema.registerItem( 'listItem', '$block' );
-		model.schema.registerItem( 'paragraph', '$block' );
-		model.schema.registerItem( 'widget', '$block' );
+		model.schema.register( 'listItem', {
+			inheritAllFrom: '$block',
+			allowAttributes: [ 'type', 'indent' ]
+		} );
+		model.schema.register( 'paragraph', {
+			inheritAllFrom: '$block',
+			allowIn: 'widget'
+		} );
+		model.schema.register( 'widget', { inheritAllFrom: '$block' } );
 
-		model.schema.allow( { name: '$block', inside: '$root' } );
-		model.schema.allow( { name: 'paragraph', inside: 'widget' } );
-		model.schema.allow( { name: 'listItem', attributes: [ 'type', 'indent' ], inside: '$root' } );
-		model.schema.disallow( { name: 'listItem', attributes: [ 'type', 'indent' ], inside: 'widget' } );
+		model.schema.on( 'checkChild', ( evt, args ) => {
+			const def = model.schema.getDefinition( args[ 1 ] );
+
+			if ( args[ 0 ].endsWith( 'widget' ) && def.name == 'listItem' ) {
+				evt.stop();
+				evt.return = false;
+			}
+		} );
 
 		setData(
 			model,
@@ -247,13 +257,12 @@ describe( 'ListCommand', () => {
 				} );
 
 				// https://github.com/ckeditor/ckeditor5-list/issues/62
-				it( 'should not rename blocks which cannot become listItems', () => {
-					model.schema.registerItem( 'restricted' );
-					model.schema.allow( { name: 'restricted', inside: '$root' } );
-					model.schema.disallow( { name: 'paragraph', inside: 'restricted' } );
+				it( 'should not rename blocks which cannot become listItems (list item is not allowed in their parent)', () => {
+					model.schema.register( 'restricted' );
+					model.schema.extend( 'restricted', { allowIn: '$root' } );
 
-					model.schema.registerItem( 'fooBlock', '$block' );
-					model.schema.allow( { name: 'fooBlock', inside: 'restricted' } );
+					model.schema.register( 'fooBlock', { inheritAllFrom: '$block' } );
+					model.schema.extend( 'fooBlock', { allowIn: 'restricted' } );
 
 					setData(
 						model,
@@ -271,6 +280,29 @@ describe( 'ListCommand', () => {
 					);
 				} );
 
+				it( 'should not rename blocks which cannot become listItems (block is an object)', () => {
+					model.schema.register( 'image', {
+						isBlock: true,
+						isObject: true,
+						allowIn: '$root'
+					} );
+
+					setData(
+						model,
+						'<paragraph>a[bc</paragraph>' +
+						'<image></image>' +
+						'<paragraph>de]f</paragraph>'
+					);
+
+					command.execute();
+
+					expect( getData( model ) ).to.equal(
+						'<listItem indent="0" type="bulleted">a[bc</listItem>' +
+						'<image></image>' +
+						'<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.

+ 8 - 9
packages/ckeditor5-list/tests/listengine.js

@@ -51,17 +51,16 @@ describe( 'ListEngine', () => {
 	} );
 
 	it( 'should set proper schema rules', () => {
-		expect( model.schema.hasItem( 'listItem' ) );
-		expect( model.schema.itemExtends( 'listItem', '$block' ) );
+		expect( model.schema.isRegistered( 'listItem' ) );
+		expect( model.schema.isBlock( 'listItem' ) );
 
-		expect( model.schema.check( { name: '$inline', inside: 'listItem' } ) ).to.be.true;
-		expect( model.schema.check( { name: 'listItem', inside: 'listItem' } ) ).to.be.false;
-		expect( model.schema.check( { name: '$block', inside: 'listItem' } ) ).to.be.false;
+		expect( model.schema.checkChild( [ '$root' ], 'listItem' ) ).to.be.true;
+		expect( model.schema.checkChild( [ '$root', 'listItem' ], '$text' ) ).to.be.true;
+		expect( model.schema.checkChild( [ '$root', 'listItem' ], 'listItem' ) ).to.be.false;
+		expect( model.schema.checkChild( [ '$root', 'listItem' ], '$block' ) ).to.be.false;
 
-		expect( model.schema.check( { name: 'listItem', inside: '$root' } ) ).to.be.false;
-		expect( model.schema.check( { name: 'listItem', inside: '$root', attributes: [ 'indent' ] } ) ).to.be.false;
-		expect( model.schema.check( { name: 'listItem', inside: '$root', attributes: [ 'type' ] } ) ).to.be.false;
-		expect( model.schema.check( { name: 'listItem', inside: '$root', attributes: [ 'indent', 'type' ] } ) ).to.be.true;
+		expect( model.schema.checkAttribute( [ '$root', 'listItem' ], 'indent' ) ).to.be.true;
+		expect( model.schema.checkAttribute( [ '$root', 'listItem' ], 'type' ) ).to.be.true;
 	} );
 
 	describe( 'commands', () => {