@@ -505,6 +505,12 @@ class ContextFactory {
505505
506506 break ;
507507 }
508+
509+ case SplitOperation : {
510+ if ( opA . sourcePosition . isEqual ( opB . splitPosition ) ) {
511+ this . _setRelation ( opA , opB , 'splitAtSource' ) ;
512+ }
513+ }
508514 }
509515
510516 break ;
@@ -1159,7 +1165,10 @@ setTransformation( MergeOperation, MergeOperation, ( a, b, context ) => {
11591165 //
11601166 // If neither or both operations point to graveyard, then let `aIsStrong` decide.
11611167 //
1162- if ( a . sourcePosition . isEqual ( b . sourcePosition ) && ! a . targetPosition . isEqual ( b . targetPosition ) && ! context . bWasUndone ) {
1168+ if (
1169+ a . sourcePosition . isEqual ( b . sourcePosition ) && ! a . targetPosition . isEqual ( b . targetPosition ) &&
1170+ ! context . bWasUndone && context . abRelation != 'splitAtSource'
1171+ ) {
11631172 const aToGraveyard = a . targetPosition . root . rootName == '$graveyard' ;
11641173 const bToGraveyard = b . targetPosition . root . rootName == '$graveyard' ;
11651174
@@ -1338,7 +1347,7 @@ setTransformation( MergeOperation, SplitOperation, ( a, b, context ) => {
13381347 // In this scenario the merge operation is now transformed by the split which has undone the previous merge operation.
13391348 // So now we are fixing situation which was skipped in `MergeOperation` x `MergeOperation` case.
13401349 //
1341- if ( a . sourcePosition . isEqual ( b . splitPosition ) && context . abRelation == 'mergeSameElement' ) {
1350+ if ( a . sourcePosition . isEqual ( b . splitPosition ) && ( context . abRelation == 'mergeSameElement' || a . sourcePosition . offset > 0 ) ) {
13421351 a . sourcePosition = Position . createFromPosition ( b . moveTargetPosition ) ;
13431352 a . targetPosition = a . targetPosition . _getTransformedBySplitOperation ( b ) ;
13441353
@@ -1396,9 +1405,9 @@ setTransformation( MoveOperation, MoveOperation, ( a, b, context ) => {
13961405 let insertBefore = ! context . aIsStrong ;
13971406
13981407 // If the relation is set, then use it to decide nodes order.
1399- if ( context . abRelation == 'insertBefore' ) {
1408+ if ( context . abRelation == 'insertBefore' || context . baRelation == 'insertAfter' ) {
14001409 insertBefore = true ;
1401- } else if ( context . abRelation == 'insertAfter' ) {
1410+ } else if ( context . abRelation == 'insertAfter' || context . baRelation == 'insertBefore' ) {
14021411 insertBefore = false ;
14031412 }
14041413
@@ -1683,7 +1692,16 @@ setTransformation( MoveOperation, MergeOperation, ( a, b, context ) => {
16831692 // removed nodes might be unexpected. This means that in this scenario we will reverse merging and remove the element.
16841693 //
16851694 if ( ! context . aWasUndone ) {
1686- return [ b . getReversed ( ) , a ] ;
1695+ const gyMoveTarget = Position . createFromPosition ( b . graveyardPosition ) ;
1696+ const gyMove = new MoveOperation ( b . graveyardPosition , 1 , gyMoveTarget , 0 ) ;
1697+
1698+ const targetPositionPath = b . graveyardPosition . path . slice ( ) ;
1699+ targetPositionPath . push ( 0 ) ;
1700+
1701+ return [
1702+ gyMove ,
1703+ new MoveOperation ( b . targetPosition , b . howMany , new Position ( a . targetPosition . root , targetPositionPath ) , 0 )
1704+ ] ;
16871705 }
16881706 } else {
16891707 // Case 2:
@@ -1911,11 +1929,25 @@ setTransformation( SplitOperation, MergeOperation, ( a, b, context ) => {
19111929} ) ;
19121930
19131931setTransformation ( SplitOperation , MoveOperation , ( a , b , context ) => {
1932+ const rangeToMove = Range . createFromPositionAndShift ( b . sourcePosition , b . howMany ) ;
1933+
19141934 if ( a . graveyardPosition ) {
1935+ // Case 1:
1936+ //
1937+ // Split operation graveyard node was moved. In this case move operation is stronger and the split insertion position
1938+ // should be corrected.
1939+ //
1940+ if ( rangeToMove . containsPosition ( a . graveyardPosition ) || rangeToMove . start . isEqual ( a . graveyardPosition ) ) {
1941+ a . insertionPosition = Position . createFromPosition ( b . targetPosition ) ;
1942+ a . splitPosition = a . splitPosition . _getTransformedByMoveOperation ( b ) ;
1943+
1944+ return [ a ] ;
1945+ }
1946+
19151947 a . graveyardPosition = a . graveyardPosition . _getTransformedByMoveOperation ( b ) ;
19161948 }
19171949
1918- // Case 1 :
1950+ // Case 2 :
19191951 //
19201952 // If the split position is inside the moved range, we need to shift the split position to a proper place.
19211953 // The position cannot be moved together with moved range because that would result in splitting of an incorrect element.
@@ -1932,8 +1964,6 @@ setTransformation( SplitOperation, MoveOperation, ( a, b, context ) => {
19321964 // After split:
19331965 // <paragraph>A</paragraph><paragraph>d</paragraph><paragraph>Xbcyz</paragraph>
19341966 //
1935- const rangeToMove = Range . createFromPositionAndShift ( b . sourcePosition , b . howMany ) ;
1936-
19371967 if ( a . splitPosition . hasSameParentAs ( b . sourcePosition ) && rangeToMove . containsPosition ( a . splitPosition ) ) {
19381968 const howManyRemoved = b . howMany - ( a . splitPosition . offset - b . sourcePosition . offset ) ;
19391969 a . howMany -= howManyRemoved ;
@@ -1948,7 +1978,7 @@ setTransformation( SplitOperation, MoveOperation, ( a, b, context ) => {
19481978 return [ a ] ;
19491979 }
19501980
1951- // Case 2 :
1981+ // Case 3 :
19521982 //
19531983 // Split is at a position where nodes were moved.
19541984 //
@@ -1966,13 +1996,16 @@ setTransformation( SplitOperation, MoveOperation, ( a, b, context ) => {
19661996 }
19671997
19681998 // The default case.
1999+ // Don't change `howMany` if move operation does not really move anything.
19692000 //
1970- if ( a . splitPosition . hasSameParentAs ( b . sourcePosition ) && a . splitPosition . offset <= b . sourcePosition . offset ) {
1971- a . howMany -= b . howMany ;
1972- }
2001+ if ( ! b . sourcePosition . isEqual ( b . targetPosition ) ) {
2002+ if ( a . splitPosition . hasSameParentAs ( b . sourcePosition ) && a . splitPosition . offset <= b . sourcePosition . offset ) {
2003+ a . howMany -= b . howMany ;
2004+ }
19732005
1974- if ( a . splitPosition . hasSameParentAs ( b . targetPosition ) && a . splitPosition . offset < b . targetPosition . offset ) {
1975- a . howMany += b . howMany ;
2006+ if ( a . splitPosition . hasSameParentAs ( b . targetPosition ) && a . splitPosition . offset < b . targetPosition . offset ) {
2007+ a . howMany += b . howMany ;
2008+ }
19762009 }
19772010
19782011 // Change position stickiness to force a correct transformation.
0 commit comments