8
0
Эх сурвалжийг харах

Added merging characters for PositionIterator.previous().

Szymon Cofalik 10 жил өмнө
parent
commit
95864521ca

+ 19 - 7
packages/ckeditor5-engine/src/treemodel/positioniterator.js

@@ -11,7 +11,6 @@ import Position from './position.js';
 import Text from './text.js';
 import Range from './range.js';
 
-
 const ELEMENT_ENTER = 0;
 const ELEMENT_LEAVE = 1;
 const CHARACTER = 2;
@@ -96,9 +95,6 @@ export default class PositionIterator {
 		const position = this.position;
 		const parent = position.parent;
 
-		// Ugh... added here because of circular deps in AMD ;<.
-		Element = CKEDITOR.require( 'treemodel/element' );
-
 		// We are at the end of the root.
 		if ( parent.parent === null && position.offset === parent.getChildCount() ) {
 			return { done: true };
@@ -171,9 +167,25 @@ export default class PositionIterator {
 
 			return formatReturnValue( ELEMENT_LEAVE, nodeBefore );
 		} else if ( nodeBefore instanceof Character ) {
-			this.position = Position.createFromParentAndOffset( parent, position.offset - 1 );
+			if ( this.mergeCharacters ) {
+				let text = '';
+				let node = this.position.nodeBefore;
+
+				while ( !this.position.isEqual( this.boundaries.start ) && node instanceof Character && node.attrs.isEqual( nodeBefore.attrs ) ) {
+					text = this.position.nodeBefore.character + text;
+					this.position.offset--;
+
+					node = this.position.nodeBefore;
+				}
+				// This is so this.position is always a new object after each iterator step.
+				this.position = Position.createFromPosition( position );
 
-			return formatReturnValue( CHARACTER, nodeBefore );
+				return formatReturnValue( TEXT, new Text( text, this.position.nodeAfter.attrs ) );
+			} else {
+				this.position = Position.createFromParentAndOffset( parent, position.offset - 1 );
+
+				return formatReturnValue( CHARACTER, nodeBefore );
+			}
 		} else {
 			this.position = Position.createFromParentAndOffset( parent.parent, parent.getIndex() );
 
@@ -226,4 +238,4 @@ PositionIterator.ELEMENT_LEAVE = ELEMENT_LEAVE;
  * @readonly
  * @property {Number}
  */
-PositionIterator.TEXT = TEXT;
+PositionIterator.TEXT = TEXT;

+ 19 - 1
packages/ckeditor5-engine/tests/treemodel/positioniterator.js

@@ -141,7 +141,7 @@ describe( 'range iterator', () => {
 		expect( i ).to.equal( expectedItems.length );
 	} );
 
-	it( 'should merge characters when iterating over the range', () => {
+	it( 'should merge characters when iterating over the range using next', () => {
 		let start = new Position( root, [ 0 ] ); // beginning of root
 		let end = new Position( root, [ 2 ] ); // ending of root
 		let range = new Range( start, end );
@@ -158,4 +158,22 @@ describe( 'range iterator', () => {
 
 		expect( i ).to.equal( expectedItemsMerged.length );
 	} );
+
+	it( 'should merge characters when iterating over the range using previous', () => {
+		let start = new Position( root, [ 0 ] ); // beginning of root
+		let end = new Position( root, [ 2 ] ); // ending of root
+		let range = new Range( start, end );
+
+		let iterator = new PositionIterator( range, range.end, true );
+		let step = iterator.previous();
+		let i = expectedItemsMerged.length;
+
+		while ( !step.done ) {
+			i--;
+			expect( step.value ).to.deep.equal( expectedItemsMerged[ i ] );
+			step = iterator.previous();
+		}
+
+		expect( i ).to.equal( 0 );
+	} );
 } );