Browse Source

Added: model.Node#getAncestors.

Szymon Cofalik 9 years ago
parent
commit
c3a709c3a2

+ 21 - 0
packages/ckeditor5-engine/src/model/node.js

@@ -242,6 +242,27 @@ export default class Node {
 	}
 
 	/**
+	 * Returns ancestors array of this node.
+	 *
+	 * @param {Object} options Options object.
+	 * @param {Boolean} [options.includeNode=false] When set to `true` this node will be also included in parent's array.
+	 * @param {Boolean} [options.parentFirst=false] When set to `true`, array will be sorted from node's parent to root element,
+	 * otherwise root element will be the first item in the array.
+	 * @returns {Array} Array with ancestors.
+	 */
+	getAncestors( options = { includeNode: false, parentFirst: false } ) {
+		const ancestors = [];
+		let parent = options.includeNode ? this : this.parent;
+
+		while ( parent ) {
+			ancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );
+			parent = parent.parent;
+		}
+
+		return ancestors;
+	}
+
+	/**
 	 * Removes this node from it's parent.
 	 */
 	remove() {

+ 24 - 0
packages/ckeditor5-engine/tests/model/node.js

@@ -220,6 +220,30 @@ describe( 'Node', () => {
 		} );
 	} );
 
+	describe( 'getAncestors', () => {
+		it( 'should return proper array of ancestor nodes', () => {
+			expect( root.getAncestors() ).to.deep.equal( [] );
+			expect( two.getAncestors() ).to.deep.equal( [ root ] );
+			expect( textBA.getAncestors() ).to.deep.equal( [ root, two ] );
+		} );
+
+		it( 'should include itself if includeNode option is set to true', () => {
+			expect( root.getAncestors( { includeNode: true } ) ).to.deep.equal( [ root ] );
+			expect( two.getAncestors( { includeNode: true } ) ).to.deep.equal( [ root, two ] );
+			expect( textBA.getAncestors( { includeNode: true } ) ).to.deep.equal( [ root, two, textBA ] );
+			expect( img.getAncestors( { includeNode: true } ) ).to.deep.equal( [ root, two, img ] );
+			expect( textR.getAncestors( { includeNode: true } ) ).to.deep.equal( [ root, two, textR ] );
+		} );
+
+		it( 'should reverse order if parentFirst option is set to true', () => {
+			expect( root.getAncestors( { includeNode: true, parentFirst: true } ) ).to.deep.equal( [ root ] );
+			expect( two.getAncestors( { includeNode: true, parentFirst: true } ) ).to.deep.equal( [ two, root ] );
+			expect( textBA.getAncestors( { includeNode: true, parentFirst: true } ) ).to.deep.equal( [ textBA, two, root ] );
+			expect( img.getAncestors( { includeNode: true, parentFirst: true } ) ).to.deep.equal( [ img, two, root ] );
+			expect( textR.getAncestors( { includeNode: true, parentFirst: true } ) ).to.deep.equal( [ textR, two, root ] );
+		} );
+	} );
+
 	describe( 'attributes interface', () => {
 		let node = new Node( { foo: 'bar' } );