@@ -547,6 +547,24 @@ export default class Differ {
547547 * @param {Array.<Object> } changes An array containing all the changes done on that element.
548548 */
549549 _handleChange ( inc , changes ) {
550+ // We need a helper variable that will store how many nodes are to be still handled for this change item.
551+ // `nodesToHandle` (how many nodes still need to be handled) and `howMany` (how many nodes were affected)
552+ // needs to be differentiated.
553+ //
554+ // This comes up when there are multiple changes that are affected by `inc` change item.
555+ //
556+ // For example: assume two insert changes: `{ offset: 2, howMany: 1 }` and `{ offset: 5, howMany: 1 }`.
557+ // Assume that `inc` change is remove `{ offset: 2, howMany: 2, nodesToHandle: 2 }`.
558+ //
559+ // Then, we:
560+ // - "forget" about first insert change (it is "eaten" by remove),
561+ // - because of that, at the end we will want to remove only one node (`nodesToHandle = 1`),
562+ // - but still we have to change offset of the second insert change from `5` to `3`!
563+ //
564+ // So, `howMany` does not change throughout items transformation and keeps information about how many nodes were affected,
565+ // while `nodesToHandle` means how many nodes need to be handled after the change item is transformed by other changes.
566+ inc . nodesToHandle = inc . howMany ;
567+
550568 for ( const old of changes ) {
551569 const incEnd = inc . offset + inc . howMany ;
552570 const oldEnd = old . offset + old . howMany ;
@@ -556,8 +574,8 @@ export default class Differ {
556574 if ( inc . offset <= old . offset ) {
557575 old . offset += inc . howMany ;
558576 } else if ( inc . offset < oldEnd ) {
559- old . howMany += inc . howMany ;
560- inc . howMany = 0 ;
577+ old . howMany += inc . nodesToHandle ;
578+ inc . nodesToHandle = 0 ;
561579 }
562580 }
563581
@@ -608,20 +626,20 @@ export default class Differ {
608626 old . offset = inc . offset ;
609627
610628 old . howMany -= intersectionLength ;
611- inc . howMany -= intersectionLength ;
629+ inc . nodesToHandle -= intersectionLength ;
612630 } else {
613- old . howMany -= inc . howMany ;
614- inc . howMany = 0 ;
631+ old . howMany -= inc . nodesToHandle ;
632+ inc . nodesToHandle = 0 ;
615633 }
616634 } else {
617635 if ( inc . offset <= old . offset ) {
618- inc . howMany = inc . howMany - old . howMany ;
636+ inc . nodesToHandle -= old . howMany ;
619637 old . howMany = 0 ;
620638 } else if ( inc . offset < oldEnd ) {
621639 const intersectionLength = oldEnd - inc . offset ;
622640
623641 old . howMany -= intersectionLength ;
624- inc . howMany -= intersectionLength ;
642+ inc . nodesToHandle -= intersectionLength ;
625643 }
626644 }
627645 }
@@ -631,9 +649,9 @@ export default class Differ {
631649 old . offset -= inc . howMany ;
632650 } else if ( inc . offset < old . offset ) {
633651 old . offset = inc . offset ;
634- old . howMany += inc . howMany ;
652+ old . howMany += inc . nodesToHandle ;
635653
636- inc . howMany = 0 ;
654+ inc . nodesToHandle = 0 ;
637655 }
638656 }
639657
@@ -656,7 +674,7 @@ export default class Differ {
656674
657675 old . howMany = inc . offset - old . offset ;
658676
659- const howManyAfter = howMany - old . howMany - inc . howMany ;
677+ const howManyAfter = howMany - old . howMany - inc . nodesToHandle ;
660678
661679 // Add the second part of attribute change to the beginning of processed array so it won't
662680 // be processed again in this loop.
@@ -695,24 +713,27 @@ export default class Differ {
695713 changes . push ( attributePart ) ;
696714 }
697715
698- inc . howMany = old . offset - inc . offset ;
716+ inc . nodesToHandle = old . offset - inc . offset ;
699717 } else if ( inc . offset >= old . offset && inc . offset < oldEnd ) {
700718 if ( incEnd > oldEnd ) {
701- inc . howMany = incEnd - oldEnd ;
719+ inc . nodesToHandle = incEnd - oldEnd ;
702720 inc . offset = oldEnd ;
703721 } else {
704- inc . howMany = 0 ;
722+ inc . nodesToHandle = 0 ;
705723 }
706724 }
707725 }
708726
709727 if ( old . type == 'attribute' ) {
710728 if ( inc . offset >= old . offset && incEnd <= oldEnd ) {
711- inc . howMany = 0 ;
729+ inc . nodesToHandle = 0 ;
712730 }
713731 }
714732 }
715733 }
734+
735+ inc . howMany = inc . nodesToHandle ;
736+ delete inc . nodesToHandle ;
716737 }
717738
718739 /**
0 commit comments