Parcourir la source

Merge pull request #53 from ckeditor/t/52

Fix getSchemaValidRanges schema query.
Piotrek Koszuliński il y a 9 ans
Parent
commit
fb306c2251

+ 3 - 1
packages/ckeditor5-core/src/command/helpers/getschemavalidranges.js

@@ -9,6 +9,7 @@
 
 import TreeWalker from '../../../engine/model/treewalker.js';
 import Range from '../../../engine/model/range.js';
+import Position from '../../../engine/model/position.js';
 
 /**
  * Walks through given array of ranges and removes parts of them that are not allowed by passed schema to have the
@@ -32,8 +33,9 @@ export default function getSchemaValidRanges( attribute, ranges, schema ) {
 
 		while ( !step.done ) {
 			const name = step.value.item.name || '$text';
+			const itemPosition = Position.createBefore( step.value.item );
 
-			if ( !schema.check( { name: name, inside: last, attributes: attribute } ) ) {
+			if ( !schema.check( { name: name, inside: itemPosition, attributes: attribute } ) ) {
 				if ( !from.isEqual( last ) ) {
 					validRanges.push( new Range( from, last ) );
 				}

+ 36 - 4
packages/ckeditor5-core/tests/command/helpers/getschemavalidranges.js

@@ -5,8 +5,9 @@
 
 import Document from 'ckeditor5/engine/model/document.js';
 import Range from 'ckeditor5/engine/model/range.js';
+import Selection from 'ckeditor5/engine/model/selection.js';
 import getSchemaValidRanges from 'ckeditor5/core/command/helpers/getschemavalidranges.js';
-import { setData } from 'ckeditor5/engine/dev-utils/model.js';
+import { setData, stringify } from 'ckeditor5/engine/dev-utils/model.js';
 
 describe( 'getSchemaValidRanges', () => {
 	const attribute = 'bold';
@@ -21,7 +22,6 @@ describe( 'getSchemaValidRanges', () => {
 		schema.registerItem( 'h1', '$block' );
 		schema.registerItem( 'img', '$inline' );
 
-		// Allow bold on p
 		schema.allow( { name: '$text', attributes: 'bold', inside: 'p' } );
 		schema.allow( { name: 'p', attributes: 'bold', inside: '$root' } );
 
@@ -29,13 +29,45 @@ describe( 'getSchemaValidRanges', () => {
 		ranges = [ Range.createOn( root.getChild( 0 ) ) ];
 	} );
 
-	it( 'should return unmodified ranges when attribute is allowed on each element', () => {
-		// Allow bold on img
+	it( 'should return unmodified ranges when attribute is allowed on each item (v1 – text is not allowed in img)', () => {
 		schema.allow( { name: 'img', attributes: 'bold', inside: 'p' } );
 
 		expect( getSchemaValidRanges( attribute, ranges, schema ) ).to.deep.equal( ranges );
 	} );
 
+	it( 'should return unmodified ranges when attribute is allowed on each item (v2 – text is allowed in img)', () => {
+		schema.allow( { name: 'img', attributes: 'bold', inside: 'p' } );
+		schema.allow( { name: '$text', inside: 'img' } );
+
+		expect( getSchemaValidRanges( attribute, ranges, schema ) ).to.deep.equal( ranges );
+	} );
+
+	it( 'should return two ranges when attribute is not allowed on one item', () => {
+		schema.allow( { name: 'img', attributes: 'bold', inside: 'p' } );
+		schema.allow( { name: '$text', inside: 'img' } );
+
+		setData( document, '<p>foo<img>xxx</img>bar</p>' );
+
+		const validRanges = getSchemaValidRanges( attribute, ranges, schema );
+		const sel = new Selection();
+		sel.setRanges( validRanges );
+
+		expect( stringify( root, sel ) ).to.equal( '[<p>foo<img>]xxx[</img>bar</p>]' );
+	} );
+
+	it( 'should return three ranges when attribute is not allowed on one element but is allowed on its child', () => {
+		schema.allow( { name: '$text', inside: 'img' } );
+		schema.allow( { name: '$text', attributes: 'bold', inside: 'img' } );
+
+		setData( document, '<p>foo<img>xxx</img>bar</p>' );
+
+		const validRanges = getSchemaValidRanges( attribute, ranges, schema );
+		const sel = new Selection();
+		sel.setRanges( validRanges );
+
+		expect( stringify( root, sel ) ).to.equal( '[<p>foo]<img>[xxx]</img>[bar</p>]' );
+	} );
+
 	it( 'should split range into two ranges and omit disallowed element', () => {
 		// Disallow bold on img.
 		document.schema.disallow( { name: 'img', attributes: 'bold', inside: 'p' } );

+ 2 - 2
packages/ckeditor5-core/tests/command/toggleattributecommand.js

@@ -158,14 +158,14 @@ describe( 'ToggleAttributeCommand', () => {
 
 		it( 'should not apply attribute change where it would invalid schema', () => {
 			modelDoc.schema.registerItem( 'image', '$block' );
-			setData( modelDoc, '<p>ab[c<image></image><$text bold="true">foobar</$text>xy<image></image>]z</p>' );
+			setData( modelDoc, '<p>ab[c<img></img><$text bold="true">foobar</$text>xy<img></img>]z</p>' );
 
 			expect( command.isEnabled ).to.be.true;
 
 			command._doExecute();
 
 			expect( getData( modelDoc ) )
-				.to.equal( '<p>ab[<$text bold="true">c</$text><image></image><$text bold="true">foobarxy</$text><image></image>]z</p>' );
+				.to.equal( '<p>ab[<$text bold="true">c</$text><img></img><$text bold="true">foobarxy</$text><img></img>]z</p>' );
 		} );
 
 		it( 'should use provided batch for storing undo steps', () => {