Przeglądaj źródła

Fixed: `SplitDelta` x `RemoveDelta` transformation - do not use special case in undo mode.

Szymon Cofalik 8 lat temu
rodzic
commit
4969e4261d

+ 14 - 0
packages/ckeditor5-engine/src/model/delta/basic-transformations.js

@@ -409,6 +409,13 @@ addTransformationCase( RemoveDelta, SplitDelta, ( a, b, context ) => {
 	const deltas = defaultTransform( a, b, context );
 	const insertPosition = b._cloneOperation.position;
 
+	const undoMode = context.aWasUndone || context.bWasUndone;
+
+	// Special case applies only if undo is not a context.
+	if ( undoMode ) {
+		return deltas;
+	}
+
 	// In case if `defaultTransform` returned more than one delta.
 	for ( const delta of deltas ) {
 		// "No delta" may be returned in some cases.
@@ -427,6 +434,13 @@ addTransformationCase( RemoveDelta, SplitDelta, ( a, b, context ) => {
 
 // Add special case for SplitDelta x RemoveDelta transformation.
 addTransformationCase( SplitDelta, RemoveDelta, ( a, b, context ) => {
+	const undoMode = context.aWasUndone || context.bWasUndone;
+
+	// Special case applies only if undo is not a context.
+	if ( undoMode ) {
+		return defaultTransform( a, b, context );
+	}
+
 	// This case is very trickily solved.
 	// Instead of fixing `a` delta, we change `b` delta for a while and fire default transformation with fixed `b` delta.
 	// Thanks to that fixing `a` delta will be differently (correctly) transformed.

+ 29 - 0
packages/ckeditor5-engine/tests/model/delta/transform/removedelta.js

@@ -184,6 +184,35 @@ describe( 'transform', () => {
 					]
 				} );
 			} );
+
+			it( 'removed node has been split - undo context', () => {
+				const sourcePosition = new Position( root, [ 3, 3, 1 ] );
+				const removeDelta = getRemoveDelta( sourcePosition, 1, baseVersion );
+
+				const splitPosition = new Position( root, [ 3, 3, 1, 2 ] );
+				const nodeCopy = new Element( 'x' );
+				const splitDelta = getSplitDelta( splitPosition, nodeCopy, 2, baseVersion );
+
+				context.bWasUndone = true;
+
+				const transformed = transform( removeDelta, splitDelta, context );
+
+				expect( transformed.length ).to.equal( 1 );
+
+				baseVersion = splitDelta.operations.length;
+
+				expectDelta( transformed[ 0 ], {
+					type: RemoveDelta,
+					operations: [
+						{
+							type: RemoveOperation,
+							sourcePosition,
+							howMany: 1,
+							baseVersion
+						}
+					]
+				} );
+			} );
 		} );
 	} );
 } );

+ 31 - 0
packages/ckeditor5-engine/tests/model/delta/transform/splitdelta.js

@@ -814,6 +814,37 @@ describe( 'transform', () => {
 					]
 				} );
 			} );
+
+			it( 'split node has been removed - undo context', () => {
+				const removePosition = new Position( root, [ 3, 3, 3 ] );
+				const removeDelta = getRemoveDelta( removePosition, 1, baseVersion );
+
+				context.bWasUndone = true;
+
+				const transformed = transform( splitDelta, removeDelta, context );
+
+				expect( transformed.length ).to.equal( 1 );
+
+				baseVersion = removeDelta.operations.length;
+
+				expectDelta( transformed[ 0 ], {
+					type: SplitDelta,
+					operations: [
+						{
+							type: InsertOperation,
+							position: splitDelta.operations[ 0 ].position.getShiftedBy( -1 ),
+							baseVersion
+						},
+						{
+							type: ReinsertOperation,
+							sourcePosition: new Position( gy, [ 0, 3 ] ),
+							howMany: splitDelta.operations[ 1 ].howMany,
+							targetPosition: new Position( root, [ 3, 3, 3, 0 ] ),
+							baseVersion: baseVersion + 1
+						}
+					]
+				} );
+			} );
 		} );
 	} );
 } );