浏览代码

"Schema#getLimitElement()" will work with the multi-selection ranges if one of them has the root as the limit element.

Kamil Piechaczek 7 年之前
父节点
当前提交
826aab8325
共有 2 个文件被更改,包括 46 次插入4 次删除
  1. 14 4
      packages/ckeditor5-engine/src/model/schema.js
  2. 32 0
      packages/ckeditor5-engine/tests/model/schema.js

+ 14 - 4
packages/ckeditor5-engine/src/model/schema.js

@@ -581,12 +581,22 @@ export default class Schema {
 	getLimitElement( selection ) {
 		// Find the common ancestor for all selection's ranges.
 		let element = Array.from( selection.getRanges() )
-			.reduce( ( node, range ) => {
-				if ( !node ) {
-					return range.getCommonAncestor();
+			.reduce( ( element, range ) => {
+				const rangeCommonAncestor = range.getCommonAncestor();
+
+				if ( !element ) {
+					return rangeCommonAncestor;
+				}
+
+				// If the element or the common ancestor for the selection's range is a root element, use it
+				// because the root element is on the top of the tree and it's the common ancestor for all selection's ranges.
+				if ( element.is( 'rootElement' ) ) {
+					return element;
+				} else if  ( rangeCommonAncestor.is( 'rootElement' ) ) {
+					return rangeCommonAncestor;
 				}
 
-				return node.getCommonAncestor( range.getCommonAncestor() );
+				return element.getCommonAncestor( rangeCommonAncestor );
 			}, null );
 
 		while ( !this.isLimit( element ) ) {

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

@@ -933,6 +933,38 @@ describe( 'Schema', () => {
 
 			expect( schema.getLimitElement( doc.selection ) ).to.equal( root );
 		} );
+
+		it( 'works fine with multi-range selections if the first one has the root element as a limit element', () => {
+			setData(
+				model,
+				'<image>' +
+					'<caption>[Foo</caption>' +
+				'</image>' +
+				'<article>' +
+					'<paragraph>Paragraph in article]</paragraph>' +
+				'</article>' +
+				'<paragraph>Paragraph item 1</paragraph>' +
+				'<paragraph>Paragraph [item 2]</paragraph>'
+			);
+
+			expect( schema.getLimitElement( doc.selection ) ).to.equal( root );
+		} );
+
+		it( 'works fine with multi-range selections if the second one has the root element as a limit element', () => {
+			setData(
+				model,
+				'<paragraph>Paragraph item 1</paragraph>' +
+				'<paragraph>Paragraph [item 2]</paragraph>' +
+				'<image>' +
+					'<caption>[Foo</caption>' +
+				'</image>' +
+				'<article>' +
+					'<paragraph>Paragraph in article]</paragraph>' +
+				'</article>'
+			);
+
+			expect( schema.getLimitElement( doc.selection ) ).to.equal( root );
+		} );
 	} );
 
 	describe( 'checkAttributeInSelection()', () => {