Explorar o código

Improvements for the tests and refactored the "model.Position#getCommonAncestor()" method.

Kamil Piechaczek %!s(int64=8) %!d(string=hai) anos
pai
achega
e19c56bac7

+ 7 - 5
packages/ckeditor5-engine/src/model/position.js

@@ -330,14 +330,16 @@ export default class Position {
 			return null;
 		}
 
-		const node = this.root.getNodeByPath( this.getCommonPath( position ) );
+		const ancestorsA = this.getAncestors();
+		const ancestorsB = position.getAncestors();
 
-		// Although paths can indicate a text node, text node is not an ancestor of a position.
-		if ( node.is( 'text' ) ) {
-			return node.parent;
+		let i = 0;
+
+		while ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {
+			i++;
 		}
 
-		return node;
+		return i === 0 ? null : ancestorsA[ i - 1 ];
 	}
 
 	/**

+ 27 - 1
packages/ckeditor5-engine/tests/model/position.js

@@ -853,13 +853,26 @@ describe( 'Position', () => {
 			test( pos1, pos2, null );
 		} );
 
-		it( 'for two the same positions returns the parent element', () => {
+		it( 'for two the same positions returns the parent element #1', () => {
 			const fPosition = new Position( root, [ 1, 0, 0 ] );
 			const otherPosition = new Position( root, [ 1, 0, 0 ] );
 
 			test( fPosition, otherPosition, li1 );
 		} );
 
+		it( 'for two the same positions returns the parent element #2', () => {
+			const doc = new Document();
+			const root = doc.createRoot();
+
+			const p = new Element( 'p', null, 'foobar' );
+
+			root.appendChildren( p );
+
+			const postion = new Position( root, [ 0, 3 ] ); // <p>foo^bar</p>
+
+			test( postion, postion, p );
+		} );
+
 		it( 'for two positions in the same element returns the element', () => {
 			const fPosition = new Position( root, [ 1, 0, 0 ] );
 			const zPosition = new Position( root, [ 1, 0, 2 ] );
@@ -874,6 +887,19 @@ describe( 'Position', () => {
 			test( liPosition, zPosition, ul );
 		} );
 
+		it( 'works if position is hooked before an empty element', () => {
+			const doc = new Document();
+			const root = doc.createRoot();
+
+			const p = new Element( 'p', null, new Element( 'a', null, [] ) );
+
+			root.appendChildren( p );
+
+			const postion = new Position( root, [ 0, 0 ] ); // <p>^<a></a></p>
+
+			test( postion, postion, p );
+		} );
+
 		it( 'works fine with positions hooked in `DocumentFragment`', () => {
 			const docFrag = new DocumentFragment( [ p, ul ] );
 			const zPosition = new Position( docFrag, [ 1, 0, 2 ] );

+ 48 - 33
packages/ckeditor5-engine/tests/view/position.js

@@ -521,62 +521,77 @@ describe( 'Position', () => {
 	} );
 
 	describe( 'getCommonAncestor()', () => {
-		let div, section, article, p, ul, li1, li2, foz, bar, lipsum;
+		let div, ul, liUl1, liUl2, texts, section, article, ol, liOl1, liOl2, p;
 
 		// |- div
 		//   |- ul
 		//   |  |- li
-		//   |  |  |- f
-		//   |  |  |- o
-		//   |  |  |- z
+		//   |  |  |- foz
 		//   |  |- li
-		//   |     |- b
-		//   |     |- a
-		//   |     |- r
+		//   |     |- bar
 		//   |- section
+		//      |- Sed id libero at libero tristique
 		//      |- article
-		//         |- p
-		//            |- l
-		//            |- i
-		//            |- p
-		//            |- s
-		//            |- u
-		//            |- m
+		//      |  |- ol
+		//      |  |  |- li
+		//      |  |  |  |- Lorem ipsum dolor sit amet.
+		//      |  |  |- li
+		//      |  |     |- Mauris tincidunt tincidunt leo ac rutrum.
+		//      |  |- p
+		//      |  |  |- Maecenas accumsan tellus.
 
 		beforeEach( () => {
-			foz = new Text( 'foz' );
-			bar = new Text( 'bar' );
-			li1 = new Element( 'li', null, foz );
-			li2 = new Element( 'li', null, bar );
-			ul = new Element( 'ul', null, [ li1, li2 ] );
+			texts = {
+				foz: new Text( 'foz' ),
+				bar: new Text( 'bar' ),
+				lorem: new Text( 'Lorem ipsum dolor sit amet.' ),
+				mauris: new Text( 'Mauris tincidunt tincidunt leo ac rutrum.' ),
+				maecenas: new Text( 'Maecenas accumsan tellus.' ),
+				sed: new Text( 'Sed id libero at libero tristique.' )
+			};
 
-			lipsum = new Text( 'lipsum' );
-			p = new Element( 'p', null, lipsum );
-			article = new Element( 'article', null, p );
-			section = new Element( 'section', null, article );
+			liUl1 = new Element( 'li', null, texts.foz );
+			liUl2 = new Element( 'li', null, texts.bar );
+			ul = new Element( 'ul', null, [ liUl1, liUl2 ] );
+
+			liOl1 = new Element( 'li', null, texts.lorem );
+			liOl2 = new Element( 'li', null, texts.mauris );
+			ol = new Element( 'ol', null, [ liOl1, liOl2 ] );
+
+			p = new Element( 'p', null, texts.maecenas );
+
+			article = new Element( 'article', null, [ ol, p ] );
+			section = new Element( 'section', null, [ texts.sed, article ] );
 
 			div = new Element( 'div', null, [ ul, section ] );
 		} );
 
 		it( 'for two the same positions returns the parent element', () => {
-			const fPosition = new Position( li1, 0 );
-			const otherPosition = Position.createFromPosition( fPosition );
+			const afterLoremPosition = new Position( liOl1, 5 );
+			const otherPosition = Position.createFromPosition( afterLoremPosition );
 
-			test( fPosition, otherPosition, li1 );
+			test( afterLoremPosition, otherPosition, liOl1 );
 		} );
 
 		it( 'for two positions in the same element returns the element', () => {
-			const fPosition = new Position( li1, 0 );
-			const zPosition = new Position( li1, 2 );
+			const startMaecenasPosition = Position.createAt( liOl2 );
+			const beforeTellusPosition = new Position( liOl2, 18 );
+
+			test( startMaecenasPosition, beforeTellusPosition, liOl2 );
+		} );
+
+		it( 'works when one of the positions is nested deeper than the other #1', () => {
+			const firstPosition = new Position( liUl1, 1 );
+			const secondPosition = new Position( p, 3 );
 
-			test( fPosition, zPosition, li1 );
+			test( firstPosition, secondPosition, div );
 		} );
 
-		it( 'works when one positions is nested deeper than the other', () => {
-			const zPosition = new Position( li1, 2 );
-			const iPosition = Position.createAt( lipsum, 'start' );
+		it( 'works when one of the positions is nested deeper than the other #2', () => {
+			const firstPosition = new Position( liOl2, 10 );
+			const secondPosition = new Position( section, 1 );
 
-			test( iPosition, zPosition, div );
+			test( firstPosition, secondPosition, section );
 		} );
 
 		function test( positionA, positionB, lca ) {