Browse Source

Range.*getNodes introduced.

Szymon Cofalik 10 years ago
parent
commit
eb8c2e0d2c

+ 20 - 0
packages/ckeditor5-engine/src/document/range.js

@@ -173,6 +173,26 @@ CKEDITOR.define( [ 'document/position', 'document/positioniterator', 'utils' ],
 			return null;
 		}
 
+		/**
+		 * Returns an iterator that iterates over all {@link document.Node nodes} that are in this range and returns them.
+		 * A node is in the range when it is after a {@link document.Position position} contained in this range.
+		 * In other words, this iterates over all {@link document.Character}s that are inside the range and
+		 * all the {@link document.Element}s we enter into when iterating over this range.
+		 *
+		 * Note, that this method will not return a parent node of start position. This is in contrary to {@link document.PositionIterator}
+		 * which will return that node with {@link document.PositionIterator#ELEMENT_LEAVE} type.
+		 *
+		 * @see {document.PositionIterator}
+		 * @returns {document.Node}
+		 */
+		*getNodes() {
+			for ( let value of this ) {
+				if ( value.type != PositionIterator.ELEMENT_LEAVE ) {
+					yield value.node;
+				}
+			}
+		}
+
 		/**
 		 * Returns an array containing one or two {document.Range ranges} that are a result of transforming this
 		 * {@link document.Range range} by inserting `howMany` nodes at `insertPosition`. Two {@link document.Range ranges} are

+ 34 - 10
packages/ckeditor5-engine/tests/document/range.js

@@ -17,7 +17,6 @@ const modules = bender.amd.require(
 
 describe( 'Range', () => {
 	let Range, Position, Element, Character, Document;
-	let start, end, root;
 
 	before( () => {
 		Position = modules[ 'document/position' ];
@@ -25,17 +24,17 @@ describe( 'Range', () => {
 		Element = modules[ 'document/element' ];
 		Character = modules[ 'document/character' ];
 		Document = modules[ 'document/document' ];
+	} );
+
+	let range, start, end, root;
 
+	beforeEach( () => {
 		let doc = new Document();
 		root = doc.createRoot( 'root' );
 
 		start = new Position( root, [ 0 ] );
 		end = new Position( root, [ 1 ] );
-	} );
-
-	let range;
 
-	beforeEach( () => {
 		range = new Range( start, end );
 	} );
 
@@ -78,7 +77,7 @@ describe( 'Range', () => {
 	} );
 
 	describe( 'static constructors', () => {
-		let doc, root, p, f, o, z;
+		let p, f, o, z;
 
 		// root
 		//  |- p
@@ -86,10 +85,6 @@ describe( 'Range', () => {
 		//     |- o
 		//     |- z
 		before( () => {
-			doc = new Document();
-
-			root = doc.createRoot( 'root' );
-
 			f = new Character( 'f' );
 			o = new Character( 'o' );
 			z = new Character( 'z' );
@@ -130,6 +125,35 @@ describe( 'Range', () => {
 		} );
 	} );
 
+	describe( 'getNodes', () => {
+		it( 'should iterate over all nodes which "starts" in the range', () => {
+			let nodes = [];
+
+			const a = new Character( 'a' );
+			const b = new Character( 'b' );
+			const x = new Character( 'x' );
+			const y = new Character( 'y' );
+
+			const e1 = new Element( 'e1' );
+			const e2 = new Element( 'e2' );
+
+			e1.insertChildren( 0, [ a, b ] );
+			e2.insertChildren( 0, [ x, y ] );
+			root.insertChildren( 0, [ e1, e2 ] );
+
+			let range = new Range(
+				new Position( root, [ 0, 1 ] ),
+				new Position( root, [ 1, 1 ] )
+			);
+
+			for ( let node of range.getNodes() ) {
+				nodes.push( node );
+			}
+
+			expect( nodes ).to.deep.equal( [ b, e2, x ] );
+		} );
+	} );
+
 	describe( 'clone', () => {
 		it( 'should return a new, equal position', () => {
 			const clone = range.clone();