Browse Source

Simplified the implementation.

Piotrek Koszuliński 8 years ago
parent
commit
e00a151f52

+ 5 - 10
packages/ckeditor5-engine/src/model/schema.js

@@ -13,7 +13,6 @@ import clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone';
 import isArray from '@ckeditor/ckeditor5-utils/src/lib/lodash/isArray';
 import isString from '@ckeditor/ckeditor5-utils/src/lib/lodash/isString';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
-import TreeWalker from './treewalker';
 import Range from './range';
 
 /**
@@ -354,27 +353,23 @@ export default class Schema {
 		const validRanges = [];
 
 		for ( const range of ranges ) {
-			const walker = new TreeWalker( { boundaries: range, mergeCharacters: true } );
-			let step = walker.next();
-
 			let last = range.start;
 			let from = range.start;
 			const to = range.end;
 
-			while ( !step.done ) {
-				const name = step.value.item.name || '$text';
-				const itemPosition = Position.createBefore( step.value.item );
+			for ( const value of range.getWalker() ) {
+				const name = value.item.name || '$text';
+				const itemPosition = Position.createBefore( value.item );
 
 				if ( !this.check( { name, inside: itemPosition, attributes: attribute } ) ) {
 					if ( !from.isEqual( last ) ) {
 						validRanges.push( new Range( from, last ) );
 					}
 
-					from = walker.position;
+					from = value.nextPosition;
 				}
 
-				last = walker.position;
-				step = walker.next();
+				last = value.nextPosition;
 			}
 
 			if ( from && !from.isEqual( to ) ) {

+ 32 - 10
packages/ckeditor5-engine/tests/model/schema/schema.js

@@ -545,12 +545,12 @@ describe( 'Schema', () => {
 
 	describe( 'getValidRanges()', () => {
 		const attribute = 'bold';
-		let document, root, schema, ranges;
+		let doc, root, schema, ranges;
 
 		beforeEach( () => {
-			document = new Document();
-			schema = document.schema;
-			root = document.createRoot();
+			doc = new Document();
+			schema = doc.schema;
+			root = doc.createRoot();
 
 			schema.registerItem( 'p', '$block' );
 			schema.registerItem( 'h1', '$block' );
@@ -559,7 +559,7 @@ describe( 'Schema', () => {
 			schema.allow( { name: '$text', attributes: 'bold', inside: 'p' } );
 			schema.allow( { name: 'p', attributes: 'bold', inside: '$root' } );
 
-			setData( document, '<p>foo<img />bar</p>' );
+			setData( doc, '<p>foo<img />bar</p>' );
 			ranges = [ Range.createOn( root.getChild( 0 ) ) ];
 		} );
 
@@ -580,9 +580,9 @@ describe( 'Schema', () => {
 			schema.allow( { name: 'img', attributes: 'bold', inside: 'p' } );
 			schema.allow( { name: '$text', inside: 'img' } );
 
-			setData( document, '<p>foo<img>xxx</img>bar</p>' );
+			setData( doc, '[<p>foo<img>xxx</img>bar</p>]' );
 
-			const validRanges = schema.getValidRanges( ranges, attribute );
+			const validRanges = schema.getValidRanges( doc.selection.getRanges(), attribute );
 			const sel = new Selection();
 			sel.setRanges( validRanges );
 
@@ -593,18 +593,40 @@ describe( 'Schema', () => {
 			schema.allow( { name: '$text', inside: 'img' } );
 			schema.allow( { name: '$text', attributes: 'bold', inside: 'img' } );
 
-			setData( document, '<p>foo<img>xxx</img>bar</p>' );
+			setData( doc, '[<p>foo<img>xxx</img>bar</p>]' );
 
-			const validRanges = schema.getValidRanges( ranges, attribute );
+			const validRanges = schema.getValidRanges( doc.selection.getRanges(), attribute );
 			const sel = new Selection();
 			sel.setRanges( validRanges );
 
 			expect( stringify( root, sel ) ).to.equal( '[<p>foo]<img>[xxx]</img>[bar</p>]' );
 		} );
 
+		it( 'should not leak beyond the given ranges', () => {
+			setData( doc, '<p>[foo<img></img>bar]x[bar<img></img>foo]</p>' );
+
+			const validRanges = schema.getValidRanges( doc.selection.getRanges(), attribute );
+			const sel = new Selection();
+			sel.setRanges( validRanges );
+
+			expect( stringify( root, sel ) ).to.equal( '<p>[foo]<img></img>[bar]x[bar]<img></img>[foo]</p>' );
+		} );
+
+		it( 'should correctly handle a range which ends in a disallowed position', () => {
+			schema.allow( { name: '$text', inside: 'img' } );
+
+			setData( doc, '<p>[foo<img>bar]</img>bom</p>' );
+
+			const validRanges = schema.getValidRanges( doc.selection.getRanges(), attribute );
+			const sel = new Selection();
+			sel.setRanges( validRanges );
+
+			expect( stringify( root, sel ) ).to.equal( '<p>[foo]<img>bar</img>bom</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' } );
+			doc.schema.disallow( { name: 'img', attributes: 'bold', inside: 'p' } );
 
 			const result = schema.getValidRanges( ranges, attribute );