瀏覽代碼

Reintroduced loose option for Range#getJoined() in more intuitive way.

Kuba Niegowski 5 年之前
父節點
當前提交
353340bb8c

+ 6 - 3
packages/ckeditor5-engine/src/model/range.js

@@ -299,16 +299,19 @@ export default class Range {
 	 *		transformed = range.getJoined( otherRange ); // range from [ 2, 7 ] to [ 5 ]
 	 *
 	 * @param {module:engine/model/range~Range} otherRange Range to be joined.
+	 * @param {Boolean} [loose=false] Whether the intersection check is loose or strict. If the check is strict (`false`),
+	 * ranges are tested for intersection or whether start/end positions are equal. If the check is loose (`true`),
+	 * compared range is also checked if it's "touching" current range.
 	 * @returns {module:engine/model/range~Range|null} A sum of given ranges or `null` if ranges have no common part.
 	 */
-	getJoined( otherRange ) {
+	getJoined( otherRange, loose = false ) {
 		let shouldJoin = this.isIntersecting( otherRange );
 
 		if ( !shouldJoin ) {
 			if ( this.start.isBefore( otherRange.start ) ) {
-				shouldJoin = this.end.isTouching( otherRange.start );
+				shouldJoin = loose ? this.end.isTouching( otherRange.start ) : this.end.isEqual( otherRange.start );
 			} else {
-				shouldJoin = otherRange.end.isTouching( this.start );
+				shouldJoin = loose ? otherRange.end.isTouching( this.start ) : otherRange.end.isEqual( this.start );
 			}
 		}
 

+ 29 - 6
packages/ckeditor5-engine/tests/model/range.js

@@ -796,6 +796,29 @@ describe( 'Range', () => {
 			range = new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 5, 4 ] ) );
 		} );
 
+		it( 'should return null if ranges do not intersect nor have equal start/end', () => {
+			const otherRange = new Range( new Position( root, [ 5, 5 ] ), new Position( root, [ 7 ] ) );
+			const sum = range.getJoined( otherRange );
+
+			expect( sum ).to.be.null;
+		} );
+
+		it( 'should return a range spanning both of the ranges if the ranges have equal start/end positions', () => {
+			const otherRange = new Range( new Position( root, [ 5, 4 ] ), new Position( root, [ 7 ] ) );
+			const sum = range.getJoined( otherRange );
+
+			expect( sum.start.path ).to.deep.equal( [ 3, 2 ] );
+			expect( sum.end.path ).to.deep.equal( [ 7 ] );
+		} );
+
+		it( 'should return a range spanning both of the ranges if the ranges have equal start/end positions (different order)', () => {
+			const otherRange = new Range( new Position( root, [ 1, 4 ] ), new Position( root, [ 3, 2 ] ) );
+			const sum = range.getJoined( otherRange );
+
+			expect( sum.start.path ).to.deep.equal( [ 1, 4 ] );
+			expect( sum.end.path ).to.deep.equal( [ 5, 4 ] );
+		} );
+
 		it( 'should return a range spanning both of the ranges - original range contains the other range', () => {
 			const otherRange = new Range( new Position( root, [ 4 ] ), new Position( root, [ 5 ] ) );
 			const sum = range.getJoined( otherRange );
@@ -825,7 +848,7 @@ describe( 'Range', () => {
 			expect( sum.isEqual( range ) ).to.be.true;
 		} );
 
-		describe( 'with ranges "touching"', () => {
+		describe( 'with `loose` option enabled', () => {
 			beforeEach( () => {
 				prepareRichRoot( root );
 			} );
@@ -833,7 +856,7 @@ describe( 'Range', () => {
 			it( 'should return null if ranges are not intersecting nor touching', () => {
 				const range = new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 3 ] ) );
 				const otherRange = new Range( new Position( root, [ 3, 1 ] ), new Position( root, [ 3, 2 ] ) );
-				const sum = range.getJoined( otherRange );
+				const sum = range.getJoined( otherRange, true );
 
 				expect( sum ).to.be.null;
 			} );
@@ -841,7 +864,7 @@ describe( 'Range', () => {
 			it( 'should return a range spanning both of the ranges - original range end is equal to other range start position', () => {
 				const range = new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 3 ] ) );
 				const otherRange = new Range( new Position( root, [ 3 ] ), new Position( root, [ 3, 2 ] ) );
-				const sum = range.getJoined( otherRange );
+				const sum = range.getJoined( otherRange, true );
 
 				expect( sum.start.path ).to.deep.equal( [ 0, 1 ] );
 				expect( sum.end.path ).to.deep.equal( [ 3, 2 ] );
@@ -850,7 +873,7 @@ describe( 'Range', () => {
 			it( 'should return a range spanning both of the ranges - original range start is equal to other range end position', () => {
 				const range = new Range( new Position( root, [ 3 ] ), new Position( root, [ 3, 2 ] ) );
 				const otherRange = new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 3 ] ) );
-				const sum = range.getJoined( otherRange );
+				const sum = range.getJoined( otherRange, true );
 
 				expect( sum.start.path ).to.deep.equal( [ 0, 1 ] );
 				expect( sum.end.path ).to.deep.equal( [ 3, 2 ] );
@@ -859,7 +882,7 @@ describe( 'Range', () => {
 			it( 'should return a range spanning both of the ranges - original range is touching other range on the right side', () => {
 				const range = new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 3 ] ) );
 				const otherRange = new Range( new Position( root, [ 3, 0 ] ), new Position( root, [ 3, 2 ] ) );
-				const sum = range.getJoined( otherRange );
+				const sum = range.getJoined( otherRange, true );
 
 				expect( sum.start.path ).to.deep.equal( [ 0, 1 ] );
 				expect( sum.end.path ).to.deep.equal( [ 3, 2 ] );
@@ -868,7 +891,7 @@ describe( 'Range', () => {
 			it( 'should return a range spanning both of the ranges - original range is touching other range on the left side', () => {
 				const range = new Range( new Position( root, [ 1, 0 ] ), new Position( root, [ 3, 2 ] ) );
 				const otherRange = new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 2 ] ) );
-				const sum = range.getJoined( otherRange );
+				const sum = range.getJoined( otherRange, true );
 
 				expect( sum.start.path ).to.deep.equal( [ 0, 1 ] );
 				expect( sum.end.path ).to.deep.equal( [ 3, 2 ] );

+ 1 - 1
packages/ckeditor5-undo/src/basecommand.js

@@ -186,7 +186,7 @@ function normalizeRanges( ranges ) {
 
 	for ( let i = 1; i < ranges.length; i++ ) {
 		const previousRange = ranges[ i - 1 ];
-		const joinedRange = previousRange.getJoined( ranges[ i ] );
+		const joinedRange = previousRange.getJoined( ranges[ i ], true );
 
 		if ( joinedRange ) {
 			// Replace the ranges on the list with the new joined range.