@@ -539,17 +539,10 @@ class ContextFactory {
539
539
}
540
540
} else if ( opA instanceof MergeOperation ) {
541
541
if ( opB instanceof MergeOperation ) {
542
- // There can be only relation set for a pair of operations, but it is fine for these cases here.
543
- // There is only one scenario when a pair can fulfill two cases -- `mergeSameTarget` and `mergeSameElement` which happens
544
- // if operations are equal. But in this case it is okay that `mergeSameElement` overwrites `mergeSameTarget`.
545
542
if ( ! opA . targetPosition . isEqual ( opB . sourcePosition ) ) {
546
543
this . _setRelation ( opA , opB , 'mergeTargetNotMoved' ) ;
547
544
}
548
545
549
- if ( opA . targetPosition . isEqual ( opB . targetPosition ) ) {
550
- this . _setRelation ( opA , opB , 'mergeSameTarget' ) ;
551
- }
552
-
553
546
if ( opA . sourcePosition . isEqual ( opB . targetPosition ) ) {
554
547
this . _setRelation ( opA , opB , 'mergeSourceNotMoved' ) ;
555
548
}
@@ -566,10 +559,6 @@ class ContextFactory {
566
559
this . _setRelation ( opA , opB , 'mergeSourceAffected' ) ;
567
560
}
568
561
569
- // After changes introduced for issue #17267 this branch was not covered anymore by our tests, as the introduced fixes
570
- // covered the test that was earlier covered by this `if`. However, it is not 100% clear, that this cannot happen anymore,
571
- // hence it was decided to keep handling this scenario anyway.
572
- /* istanbul ignore next -- @preserve */
573
562
if ( opA . targetPosition . isEqual ( opB . sourcePosition ) ) {
574
563
this . _setRelation ( opA , opB , 'mergeTargetWasBefore' ) ;
575
564
}
@@ -1392,32 +1381,14 @@ setTransformation( MergeOperation, MergeOperation, ( a, b, context ) => {
1392
1381
}
1393
1382
1394
1383
// The default case.
1384
+ // TODO: Possibly, there's a missing case for same `targetPosition` but different `sourcePosition`.
1395
1385
//
1396
1386
if ( a . sourcePosition . hasSameParentAs ( b . targetPosition ) ) {
1397
1387
a . howMany += b . howMany ;
1398
1388
}
1399
1389
1400
1390
a . sourcePosition = a . sourcePosition . _getTransformedByMergeOperation ( b ) ;
1401
-
1402
- if ( a . targetPosition . isEqual ( b . targetPosition ) ) {
1403
- // Case 3:
1404
- //
1405
- // Operations target to the same position (merge something into the same element). But unlike case 1, the operations are not equal,
1406
- // because they have different source position.
1407
- //
1408
- // In most cases, when operations point to the same merge target, the operations are equal (i.e. they also have the same source).
1409
- // However, in some more complex undo cases (including multiple steps) it happens that two different elements are merged into
1410
- // the same element. It only happens "temporarily" as the operation is being transformed during undo process.
1411
- // It doesn't seem that this can happen in real-time collaboration.
1412
- //
1413
- // In this case, simply move the `a` merge target position, so it still points to the end of the target element.
1414
- //
1415
- a . targetPosition = a . targetPosition . getShiftedBy ( b . howMany ) ;
1416
- } else {
1417
- // The default case.
1418
- //
1419
- a . targetPosition = a . targetPosition . _getTransformedByMergeOperation ( b ) ;
1420
- }
1391
+ a . targetPosition = a . targetPosition . _getTransformedByMergeOperation ( b ) ;
1421
1392
1422
1393
// Handle positions in graveyard.
1423
1394
// If graveyard positions are same and `a` operation is strong - do not transform.
@@ -1467,10 +1438,6 @@ setTransformation( MergeOperation, MoveOperation, ( a, b, context ) => {
1467
1438
// [] is move operation, } is merge source position (sticks to previous by default):
1468
1439
// <p>A[b]}c</p> -> <p>A }c</p>
1469
1440
//
1470
- // After changes introduced for issue #17267 two of the else-if branches were not covered anymore by our tests, as the introduced fixes
1471
- // covered the test that was earlier covered by these branches. However, it is not 100% clear, that this cannot happen anymore,
1472
- // hence it was decided to keep handling these scenarios anyway.
1473
- /* istanbul ignore next -- @preserve */
1474
1441
if ( b . sourcePosition . getShiftedBy ( b . howMany ) . isEqual ( a . sourcePosition ) ) {
1475
1442
a . sourcePosition . stickiness = 'toNone' ;
1476
1443
}
@@ -1642,10 +1609,11 @@ setTransformation( MergeOperation, SplitOperation, ( a, b, context ) => {
1642
1609
}
1643
1610
1644
1611
// This merge operation might have been earlier transformed by a merge operation which both merged the same element.
1645
- // See that case in `MergeOperation` x `MergeOperation` transformation.
1612
+ // See that case in `MergeOperation` x `MergeOperation` transformation. In that scenario, if the merge operation has been undone,
1613
+ // the special case is not applied.
1646
1614
//
1647
- // Now, the merge operation is transformed by the split which has undone that previous merge operation. Make sure to set
1648
- // correct properties on merge operation `a`, just like the earlier merge and this split did not happen .
1615
+ // Now, the merge operation is transformed by the split which has undone that previous merge operation.
1616
+ // So now we are fixing situation which was skipped in `MergeOperation` x `MergeOperation` case .
1649
1617
//
1650
1618
if ( context . abRelation == 'mergeSameElement' || a . sourcePosition . offset > 0 ) {
1651
1619
a . sourcePosition = b . moveTargetPosition . clone ( ) ;
@@ -1658,31 +1626,11 @@ setTransformation( MergeOperation, SplitOperation, ( a, b, context ) => {
1658
1626
// The default case.
1659
1627
//
1660
1628
if ( a . sourcePosition . hasSameParentAs ( b . splitPosition ) ) {
1661
- if ( b . splitPosition . offset >= a . sourcePosition . offset ) {
1662
- a . howMany = b . splitPosition . offset - a . sourcePosition . offset ;
1663
- }
1629
+ a . howMany = b . splitPosition . offset ;
1664
1630
}
1665
1631
1666
1632
a . sourcePosition = a . sourcePosition . _getTransformedBySplitOperation ( b ) ;
1667
-
1668
- if ( a . targetPosition . hasSameParentAs ( b . splitPosition ) && context . abRelation == 'mergeSameTarget' ) {
1669
- // Case 3:
1670
- //
1671
- // Merge operation targets into an element which is being split, but unlike case 1, the split happens at different (earlier)
1672
- // position. This is a regular case. By default, the merge target position is moved to the right-hand split part of the split
1673
- // element: <p>Foobar^</p><p>XYZ</p> --> <p>Foo</p><p>bar^</p><p>XYZ</p>. This happens in the default handling below.
1674
- //
1675
- // However, in some cases, we need to do something different. If this split operation is undoing a merge operation, and both
1676
- // `a` merge operation and the undone merge operation were targeting to the same element, we will acknowledge, that this
1677
- // `a` merge operation at the very beginning was supposed to merge into the original element. We will keep the target position in
1678
- // the original element, to ensure proper processing during undo: <p>Foobar^</p><p>XYZ</p> --> <p>Foo^</p><p>bar</p><p>XYZ</p>.
1679
- //
1680
- a . targetPosition = a . targetPosition . getShiftedBy ( - b . howMany ) ;
1681
- } else {
1682
- // The default case.
1683
- //
1684
- a . targetPosition = a . targetPosition . _getTransformedBySplitOperation ( b ) ;
1685
- }
1633
+ a . targetPosition = a . targetPosition . _getTransformedBySplitOperation ( b ) ;
1686
1634
1687
1635
return [ a ] ;
1688
1636
} ) ;
0 commit comments