@@ -55,10 +55,16 @@ addTransformationCase( AttributeDelta, SplitDelta, ( a, b, context ) => {
5555 return defaultTransform ( a , b , context ) ;
5656 }
5757
58+ const undoMode = context . aWasUndone || context . bWasUndone ;
5859 const splitPosition = new Position ( b . position . root , b . position . path . slice ( 0 , - 1 ) ) ;
5960
6061 const deltas = defaultTransform ( a , b , context ) ;
6162
63+ // Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).
64+ if ( undoMode || ! ( b . _cloneOperation instanceof InsertOperation ) ) {
65+ return deltas ;
66+ }
67+
6268 for ( const operation of a . operations ) {
6369 // If a node that has been split has it's attribute updated, we should also update attribute of
6470 // the node created during splitting.
@@ -292,21 +298,25 @@ addTransformationCase( SplitDelta, AttributeDelta, ( a, b, context ) => {
292298
293299 a = a . clone ( ) ;
294300
301+ const undoMode = context . aWasUndone || context . bWasUndone ;
295302 const splitPosition = new Position ( a . position . root , a . position . path . slice ( 0 , - 1 ) ) ;
296303
297- if ( a . _cloneOperation instanceof InsertOperation ) {
298- // If element to split had it's attribute changed, we have to reflect this change in an element
299- // that is in SplitDelta's InsertOperation.
300- for ( const operation of b . operations ) {
301- if ( operation . range . containsPosition ( splitPosition ) || operation . range . start . isEqual ( splitPosition ) ) {
302- if ( operation . newValue !== null ) {
303- a . _cloneOperation . nodes . getNode ( 0 ) . setAttribute ( operation . key , operation . newValue ) ;
304- } else {
305- a . _cloneOperation . nodes . getNode ( 0 ) . removeAttribute ( operation . key ) ;
306- }
307-
308- break ;
304+ // Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).
305+ if ( undoMode || ! ( a . _cloneOperation instanceof InsertOperation ) ) {
306+ return [ a ] ;
307+ }
308+
309+ // If element to split had it's attribute changed, we have to reflect this change in an element
310+ // that is in SplitDelta's InsertOperation.
311+ for ( const operation of b . operations ) {
312+ if ( operation . range . containsPosition ( splitPosition ) || operation . range . start . isEqual ( splitPosition ) ) {
313+ if ( operation . newValue !== null ) {
314+ a . _cloneOperation . nodes . getNode ( 0 ) . setAttribute ( operation . key , operation . newValue ) ;
315+ } else {
316+ a . _cloneOperation . nodes . getNode ( 0 ) . removeAttribute ( operation . key ) ;
309317 }
318+
319+ break ;
310320 }
311321 }
312322
@@ -383,18 +393,16 @@ addTransformationCase( WrapDelta, SplitDelta, ( a, b, context ) => {
383393// Add special case for RenameDelta x SplitDelta transformation.
384394addTransformationCase ( RenameDelta , SplitDelta , ( a , b , context ) => {
385395 const undoMode = context . aWasUndone || context . bWasUndone ;
396+ const deltas = defaultTransform ( a , b , context ) ;
386397
387- // The "clone operation" may be `InsertOperation`, `ReinsertOperation`, `MoveOperation` or `NoOperation`.
388- // `MoveOperation` has `targetPosition` which we want to use. `NoOperation` has no `position` and we don't use special case then.
389- let insertPosition = b . _cloneOperation . position || b . _cloneOperation . targetPosition ;
390-
391- if ( insertPosition ) {
392- insertPosition = insertPosition . getShiftedBy ( - 1 ) ;
398+ // Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).
399+ if ( undoMode || ! ( b . _cloneOperation instanceof InsertOperation ) ) {
400+ return deltas ;
393401 }
394402
395- const deltas = defaultTransform ( a , b , context ) ;
403+ const insertPosition = b . _cloneOperation . position . getShiftedBy ( - 1 ) ;
396404
397- if ( insertPosition && ! undoMode && a . operations [ 0 ] . position . isEqual ( insertPosition ) ) {
405+ if ( insertPosition && a . operations [ 0 ] . position . isEqual ( insertPosition ) ) {
398406 // If a node that has been split has it's name changed, we should also change name of
399407 // the node created during splitting.
400408 const additionalRenameDelta = a . clone ( ) ;
@@ -408,31 +416,27 @@ addTransformationCase( RenameDelta, SplitDelta, ( a, b, context ) => {
408416
409417// Add special case for SplitDelta x RenameDelta transformation.
410418addTransformationCase ( SplitDelta , RenameDelta , ( a , b , context ) => {
411- const undoMode = context . aWasUndone || context . bWasUndone ;
419+ a = a . clone ( ) ;
412420
413- // The "clone operation" may be `InsertOperation`, `ReinsertOperation`, `MoveOperation` or `NoOperation`.
414- // `MoveOperation` has `targetPosition` which we want to use. `NoOperation` has no `position` and we don't use special case then.
415- let insertPosition = a . _cloneOperation . position || a . _cloneOperation . targetPosition ;
421+ const undoMode = context . aWasUndone || context . bWasUndone ;
416422
417- if ( insertPosition ) {
418- insertPosition = insertPosition . getShiftedBy ( - 1 ) ;
423+ // Special case applies only if undo is not a context and only if `SplitDelta` has `InsertOperation` (not `ReinsertOperation`).
424+ if ( undoMode || ! ( a . _cloneOperation instanceof InsertOperation ) ) {
425+ return [ a ] ;
419426 }
420427
428+ const insertPosition = a . _cloneOperation . position . getShiftedBy ( - 1 ) ;
429+
421430 // If element to split had it's name changed, we have to reflect this by creating additional rename operation.
422431 if ( insertPosition && ! undoMode && b . operations [ 0 ] . position . isEqual ( insertPosition ) ) {
423432 const additionalRenameDelta = b . clone ( ) ;
424433 additionalRenameDelta . operations [ 0 ] . position = insertPosition . getShiftedBy ( 1 ) ;
425-
426- // `nodes` is a property that is available only if `SplitDelta` `a` has `InsertOperation`.
427- // `SplitDelta` may have `ReinsertOperation` instead of `InsertOperation`.
428- // However, such delta is only created when `MergeDelta` is reversed.
429- // So if this is not undo mode, it means that `SplitDelta` has `InsertOperation`.
430434 additionalRenameDelta . operations [ 0 ] . oldName = a . _cloneOperation . nodes . getNode ( 0 ) . name ;
431435
432- return [ a . clone ( ) , additionalRenameDelta ] ;
436+ return [ a , additionalRenameDelta ] ;
433437 }
434438
435- return [ a . clone ( ) ] ;
439+ return [ a ] ;
436440} ) ;
437441
438442// Add special case for RemoveDelta x SplitDelta transformation.
@@ -446,6 +450,13 @@ addTransformationCase( RemoveDelta, SplitDelta, ( a, b, context ) => {
446450 return defaultTransform ( a , b , context ) ;
447451 }
448452
453+ const undoMode = context . aWasUndone || context . bWasUndone ;
454+
455+ // Special case applies only if undo is not a context.
456+ if ( undoMode ) {
457+ return deltas ;
458+ }
459+
449460 // In case if `defaultTransform` returned more than one delta.
450461 for ( const delta of deltas ) {
451462 // "No delta" may be returned in some cases.
@@ -464,6 +475,13 @@ addTransformationCase( RemoveDelta, SplitDelta, ( a, b, context ) => {
464475
465476// Add special case for SplitDelta x RemoveDelta transformation.
466477addTransformationCase ( SplitDelta , RemoveDelta , ( a , b , context ) => {
478+ const undoMode = context . aWasUndone || context . bWasUndone ;
479+
480+ // Special case applies only if undo is not a context.
481+ if ( undoMode ) {
482+ return defaultTransform ( a , b , context ) ;
483+ }
484+
467485 // This case is very trickily solved.
468486 // Instead of fixing `a` delta, we change `b` delta for a while and fire default transformation with fixed `b` delta.
469487 // Thanks to that fixing `a` delta will be differently (correctly) transformed.
0 commit comments