Browse Source

Added: added special case for transforming collapsed range by merge delta.

Szymon Cofalik 8 years ago
parent
commit
d4df23569c

+ 8 - 2
packages/ckeditor5-engine/src/model/range.js

@@ -453,8 +453,14 @@ export default class Range {
 			const ranges = this._getTransformedByMove( sourcePosition, targetPosition, howMany );
 
 			if ( deltaType == 'split' && this.containsPosition( sourcePosition ) ) {
+				// Special case for splitting element inside range.
+				// <p>f[ooba]r</p> -> <p>f[oo</p><p>ba]r</p>
 				ranges[ 0 ].end = ranges[ 1 ].end;
 				ranges.pop();
+			} else if ( deltaType == 'merge' && type == 'move' && this.isCollapsed && ranges[ 0 ].start.isEqual( sourcePosition ) ) {
+				// Special case when collapsed range is in merged element.
+				// <p>foo</p><p>[]bar{}</p> -> <p>foo[]bar{}</p>
+				ranges[ 0 ] = new Range( targetPosition.getShiftedBy( this.start.offset ) );
 			}
 
 			return ranges;
@@ -549,7 +555,7 @@ export default class Range {
 		const common = this.getIntersection( moveRange );
 
 		if ( differenceSet.length == 1 ) {
-			// `moveRange` and this range intersects.
+			// `moveRange` and this range may intersect.
 			difference = new Range(
 				differenceSet[ 0 ].start._getTransformedByDeletion( sourcePosition, howMany ),
 				differenceSet[ 0 ].end._getTransformedByDeletion( sourcePosition, howMany )
@@ -560,7 +566,7 @@ export default class Range {
 				this.start,
 				this.end._getTransformedByDeletion( sourcePosition, howMany )
 			);
-		} // else, `moveRange` wholly contains this range.
+		} // else, `moveRange` contains this range.
 
 		const insertPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany );
 

+ 20 - 1
packages/ckeditor5-engine/tests/model/range.js

@@ -18,7 +18,8 @@ import {
 	getMoveDelta,
 	getRemoveDelta,
 	getRenameDelta,
-	getSplitDelta
+	getSplitDelta,
+	getMergeDelta
 } from '../../tests/model/delta/transform/_utils/utils';
 
 describe( 'Range', () => {
@@ -838,6 +839,24 @@ describe( 'Range', () => {
 				expect( transformed[ 0 ].start.path ).to.deep.equal( [ 0, 2 ] );
 				expect( transformed[ 0 ].end.path ).to.deep.equal( [ 1, 1 ] );
 			} );
+
+			describe( 'by MergeDelta', () => {
+				it( 'merge element with collapsed range', () => {
+					root.removeChildren( root.childCount );
+					root.appendChildren( [ new Element( 'p', null, new Text( 'foo' ) ), new Element( 'p', null, new Text( 'bar' ) ) ] );
+
+					range.start = new Position( root, [ 1, 0 ] );
+					range.end = new Position( root, [ 1, 0 ] );
+
+					const delta = getMergeDelta( new Position( root, [ 1 ] ), 3, 3, 1 );
+
+					const transformed = range.getTransformedByDelta( delta );
+
+					expect( transformed.length ).to.equal( 1 );
+					expect( transformed[ 0 ].start.path ).to.deep.equal( [ 0, 3 ] );
+					expect( transformed[ 0 ].end.path ).to.deep.equal( [ 0, 3 ] );
+				} );
+			} );
 		} );
 	} );