@@ -563,15 +563,15 @@ export class DiffFinder {
563563 const gapInformation = getGapInformation ( t1 , t2 , subtrees )
564564 const gaps1 = gapInformation . gaps1
565565 const gaps2 = gapInformation . gaps2
566+ const t1ChildNodes = t1 . childNodes . slice ( )
567+ const t2ChildNodes = t2 . childNodes . slice ( )
566568 let shortest = Math . min ( gaps1 . length , gaps2 . length )
567569 let destinationDifferent
568570 let toGroup
569571 let group
570572 let node
571573 let similarNode
572- let testI
573574 const diffs = [ ]
574-
575575 for (
576576 let index2 = 0 , index1 = 0 ;
577577 index2 < shortest ;
@@ -582,24 +582,25 @@ export class DiffFinder {
582582 ( gaps1 [ index2 ] === true || gaps2 [ index2 ] === true )
583583 ) {
584584 // pass
585- } else if ( gaps1 [ index2 ] === true ) {
586- node = t1 . childNodes [ index1 ]
585+ } else if ( gaps1 [ index1 ] === true ) {
586+ node = t1ChildNodes [ index1 ]
587587 if ( node . nodeName === "#text" ) {
588- if ( t2 . childNodes [ index2 ] . nodeName === "#text" ) {
588+ if ( t2ChildNodes [ index2 ] . nodeName === "#text" ) {
589589 if (
590590 ( node as textDiffNodeType ) . data !==
591- ( t2 . childNodes [ index2 ] as textDiffNodeType ) . data
591+ ( t2ChildNodes [ index2 ] as textDiffNodeType ) . data
592592 ) {
593- testI = index1
593+ // Check whether a text node with the same value follows later on.
594+ let testI = index1
594595 while (
595- t1 . childNodes . length > testI + 1 &&
596- t1 . childNodes [ testI + 1 ] . nodeName === "#text"
596+ t1ChildNodes . length > testI + 1 &&
597+ t1ChildNodes [ testI + 1 ] . nodeName === "#text"
597598 ) {
598599 testI += 1
599600 if (
600- ( t2 . childNodes [ index2 ] as textDiffNodeType )
601+ ( t2ChildNodes [ index2 ] as textDiffNodeType )
601602 . data ===
602- ( t1 . childNodes [ testI ] as textDiffNodeType )
603+ ( t1ChildNodes [ testI ] as textDiffNodeType )
603604 . data
604605 ) {
605606 similarNode = true
@@ -616,7 +617,7 @@ export class DiffFinder {
616617 )
617618 . setValue (
618619 this . options . _const . route ,
619- route . concat ( index2 )
620+ route . concat ( index1 )
620621 )
621622 . setValue (
622623 this . options . _const . oldValue ,
@@ -625,13 +626,14 @@ export class DiffFinder {
625626 . setValue (
626627 this . options . _const . newValue ,
627628 (
628- t2 . childNodes [
629+ t2ChildNodes [
629630 index2
630631 ] as textDiffNodeType
631632 ) . data
632633 )
634+ // t1ChildNodes at position index1 is not up-to-date, but that does not matter as
635+ // index1 will increase +1
633636 )
634- return diffs
635637 }
636638 }
637639 } else {
@@ -643,14 +645,40 @@ export class DiffFinder {
643645 )
644646 . setValue (
645647 this . options . _const . route ,
646- route . concat ( index2 )
648+ route . concat ( index1 )
647649 )
648650 . setValue ( this . options . _const . value , node . data )
649651 )
650- gaps1 . splice ( index2 , 1 )
652+ gaps1 . splice ( index1 , 1 )
653+ t1ChildNodes . splice ( index1 , 1 )
651654 shortest = Math . min ( gaps1 . length , gaps2 . length )
655+ index1 -= 1
652656 index2 -= 1
653657 }
658+ } else if ( gaps2 [ index2 ] === true ) {
659+ // both gaps1[index1] and gaps2[index2] are true.
660+ // We replace one element with another.
661+ diffs . push (
662+ new Diff ( )
663+ . setValue (
664+ this . options . _const . action ,
665+ this . options . _const . replaceElement
666+ )
667+ . setValue (
668+ this . options . _const . oldValue ,
669+ cleanNode ( node )
670+ )
671+ . setValue (
672+ this . options . _const . newValue ,
673+ cleanNode ( t2ChildNodes [ index2 ] )
674+ )
675+ . setValue (
676+ this . options . _const . route ,
677+ route . concat ( index1 )
678+ )
679+ )
680+ // t1ChildNodes at position index1 is not up-to-date, but that does not matter as
681+ // index1 will increase +1
654682 } else {
655683 diffs . push (
656684 new Diff ( )
@@ -660,19 +688,21 @@ export class DiffFinder {
660688 )
661689 . setValue (
662690 this . options . _const . route ,
663- route . concat ( index2 )
691+ route . concat ( index1 )
664692 )
665693 . setValue (
666694 this . options . _const . element ,
667695 cleanNode ( node )
668696 )
669697 )
670- gaps1 . splice ( index2 , 1 )
698+ gaps1 . splice ( index1 , 1 )
699+ t1ChildNodes . splice ( index1 , 1 )
671700 shortest = Math . min ( gaps1 . length , gaps2 . length )
701+ index1 -= 1
672702 index2 -= 1
673703 }
674704 } else if ( gaps2 [ index2 ] === true ) {
675- node = t2 . childNodes [ index2 ]
705+ node = t2ChildNodes [ index2 ]
676706 if ( node . nodeName === "#text" ) {
677707 diffs . push (
678708 new Diff ( )
@@ -682,13 +712,17 @@ export class DiffFinder {
682712 )
683713 . setValue (
684714 this . options . _const . route ,
685- route . concat ( index2 )
715+ route . concat ( index1 )
686716 )
687717 . setValue ( this . options . _const . value , node . data )
688718 )
689- gaps1 . splice ( index2 , 0 , true )
719+ gaps1 . splice ( index1 , 0 , true )
720+ t1ChildNodes . splice ( index1 , 0 , {
721+ nodeName : "#text" ,
722+ data : node . data ,
723+ } )
690724 shortest = Math . min ( gaps1 . length , gaps2 . length )
691- index1 - = 1
725+ // index1 + = 1
692726 } else {
693727 diffs . push (
694728 new Diff ( )
@@ -698,35 +732,36 @@ export class DiffFinder {
698732 )
699733 . setValue (
700734 this . options . _const . route ,
701- route . concat ( index2 )
735+ route . concat ( index1 )
702736 )
703737 . setValue (
704738 this . options . _const . element ,
705739 cleanNode ( node )
706740 )
707741 )
708- gaps1 . splice ( index2 , 0 , true )
742+ gaps1 . splice ( index1 , 0 , true )
743+ t1ChildNodes . splice ( index1 , 0 , cleanNode ( node ) )
709744 shortest = Math . min ( gaps1 . length , gaps2 . length )
710- index1 - = 1
745+ // index1 + = 1
711746 }
712- } else if ( gaps1 [ index2 ] !== gaps2 [ index2 ] ) {
747+ } else if ( gaps1 [ index1 ] !== gaps2 [ index2 ] ) {
713748 if ( diffs . length > 0 ) {
714749 return diffs
715750 }
716751 // group relocation
717- group = subtrees [ gaps1 [ index2 ] as number ]
752+ group = subtrees [ gaps1 [ index1 ] as number ]
718753 toGroup = Math . min (
719754 group . newValue ,
720- t1 . childNodes . length - group . length
755+ t1ChildNodes . length - group . length
721756 )
722757 if ( toGroup !== group . oldValue ) {
723758 // Check whether destination nodes are different than originating ones.
724759 destinationDifferent = false
725760 for ( let j = 0 ; j < group . length ; j += 1 ) {
726761 if (
727762 ! roughlyEqual (
728- t1 . childNodes [ toGroup + j ] ,
729- t1 . childNodes [ group . oldValue + j ] ,
763+ t1ChildNodes [ toGroup + j ] ,
764+ t1ChildNodes [ group . oldValue + j ] ,
730765 { } ,
731766 false ,
732767 true
0 commit comments