@@ -547,6 +547,24 @@ export default class Differ {
547
547
* @param {Array.<Object> } changes An array containing all the changes done on that element.
548
548
*/
549
549
_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
+
550
568
for ( const old of changes ) {
551
569
const incEnd = inc . offset + inc . howMany ;
552
570
const oldEnd = old . offset + old . howMany ;
@@ -556,8 +574,8 @@ export default class Differ {
556
574
if ( inc . offset <= old . offset ) {
557
575
old . offset += inc . howMany ;
558
576
} else if ( inc . offset < oldEnd ) {
559
- old . howMany += inc . howMany ;
560
- inc . howMany = 0 ;
577
+ old . howMany += inc . nodesToHandle ;
578
+ inc . nodesToHandle = 0 ;
561
579
}
562
580
}
563
581
@@ -608,20 +626,20 @@ export default class Differ {
608
626
old . offset = inc . offset ;
609
627
610
628
old . howMany -= intersectionLength ;
611
- inc . howMany -= intersectionLength ;
629
+ inc . nodesToHandle -= intersectionLength ;
612
630
} else {
613
- old . howMany -= inc . howMany ;
614
- inc . howMany = 0 ;
631
+ old . howMany -= inc . nodesToHandle ;
632
+ inc . nodesToHandle = 0 ;
615
633
}
616
634
} else {
617
635
if ( inc . offset <= old . offset ) {
618
- inc . howMany = inc . howMany - old . howMany ;
636
+ inc . nodesToHandle -= old . howMany ;
619
637
old . howMany = 0 ;
620
638
} else if ( inc . offset < oldEnd ) {
621
639
const intersectionLength = oldEnd - inc . offset ;
622
640
623
641
old . howMany -= intersectionLength ;
624
- inc . howMany -= intersectionLength ;
642
+ inc . nodesToHandle -= intersectionLength ;
625
643
}
626
644
}
627
645
}
@@ -631,9 +649,9 @@ export default class Differ {
631
649
old . offset -= inc . howMany ;
632
650
} else if ( inc . offset < old . offset ) {
633
651
old . offset = inc . offset ;
634
- old . howMany += inc . howMany ;
652
+ old . howMany += inc . nodesToHandle ;
635
653
636
- inc . howMany = 0 ;
654
+ inc . nodesToHandle = 0 ;
637
655
}
638
656
}
639
657
@@ -656,7 +674,7 @@ export default class Differ {
656
674
657
675
old . howMany = inc . offset - old . offset ;
658
676
659
- const howManyAfter = howMany - old . howMany - inc . howMany ;
677
+ const howManyAfter = howMany - old . howMany - inc . nodesToHandle ;
660
678
661
679
// Add the second part of attribute change to the beginning of processed array so it won't
662
680
// be processed again in this loop.
@@ -695,24 +713,27 @@ export default class Differ {
695
713
changes . push ( attributePart ) ;
696
714
}
697
715
698
- inc . howMany = old . offset - inc . offset ;
716
+ inc . nodesToHandle = old . offset - inc . offset ;
699
717
} else if ( inc . offset >= old . offset && inc . offset < oldEnd ) {
700
718
if ( incEnd > oldEnd ) {
701
- inc . howMany = incEnd - oldEnd ;
719
+ inc . nodesToHandle = incEnd - oldEnd ;
702
720
inc . offset = oldEnd ;
703
721
} else {
704
- inc . howMany = 0 ;
722
+ inc . nodesToHandle = 0 ;
705
723
}
706
724
}
707
725
}
708
726
709
727
if ( old . type == 'attribute' ) {
710
728
if ( inc . offset >= old . offset && incEnd <= oldEnd ) {
711
- inc . howMany = 0 ;
729
+ inc . nodesToHandle = 0 ;
712
730
}
713
731
}
714
732
}
715
733
}
734
+
735
+ inc . howMany = inc . nodesToHandle ;
736
+ delete inc . nodesToHandle ;
716
737
}
717
738
718
739
/**
0 commit comments