8
0
Просмотр исходного кода

Fixed: text node with 'elementEnd' returned by view.TreeWalker if start position is at the end of text node.

Szymon Cofalik 9 лет назад
Родитель
Сommit
421e4908f5

+ 21 - 1
packages/ckeditor5-engine/src/view/treewalker.js

@@ -129,6 +129,8 @@ export default class TreeWalker {
 		 * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryEndParent
 		 */
 		this._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;
+
+		this._fixStartPositionInText();
 	}
 
 	/**
@@ -365,7 +367,7 @@ export default class TreeWalker {
 	 * @returns {module:engine/view/treewalker~TreeWalkerValue}
 	 */
 	_formatReturnValue( type, item, previousPosition, nextPosition, length ) {
-		// Text is a specific parent, because contains string instead of childs.
+		// Text is a specific parent, because contains string instead of children.
 		// Walker doesn't enter to the Text except situations when walker is iterating over every single character,
 		// or the bound starts/ends inside the Text. So when the position is at the beginning or at the end of the Text
 		// we move it just before or just after Text.
@@ -404,6 +406,24 @@ export default class TreeWalker {
 			}
 		};
 	}
+
+	/**
+	 * Fixes tree walker start position if it is at the beginning or at the end of a {@link module:engine/view/text~Text text node}.
+	 *
+	 * Without the fix, the first returned value by tree walker would have type `elementEnd` or `elementStart` but the
+	 * item would be a {@link module:engine/view/text~Text text node}.
+	 *
+	 * @private
+	 */
+	_fixStartPositionInText() {
+		const parent = this.position.parent;
+
+		if ( parent instanceof Text && this.position.isAtStart ) {
+			this.position = Position.createBefore( parent );
+		} else if ( parent instanceof Text && this.position.isAtEnd ) {
+			this.position = Position.createAfter( parent );
+		}
+	}
 }
 
 /**

+ 11 - 0
packages/ckeditor5-engine/tests/view/treewalker.js

@@ -979,6 +979,17 @@ describe( 'TreeWalker', () => {
 		} );
 	} );
 
+	it( 'should not return elementEnd for a text node when iteration begins at the start or the end of that text node', () => {
+		let iterator = new TreeWalker( {
+			startPosition: Position.createAt( textAbcd, 'end' )
+		} );
+
+		const step = iterator.next();
+
+		expect( step.value.type ).to.equal( 'elementEnd' );
+		expect( step.value.item ).to.equal( bold );
+	} );
+
 	it( 'should iterate over document fragment', () => {
 		const foo = new Text( 'foo' );
 		const bar = new Text( 'bar' );