Skip to content

Commit b16850a

Browse files
committed
better explanations and reordering of findInnerDiff
1 parent 14993fb commit b16850a

File tree

2 files changed

+72
-44
lines changed

2 files changed

+72
-44
lines changed

diffDOM.js

Lines changed: 69 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -695,89 +695,114 @@
695695
},
696696
findInnerDiff: function(t1, t2, route) {
697697

698-
var subtrees = markSubTrees(t1, t2),
699-
mappings = subtrees.length,
698+
var subtrees = (t1.childNodes && t2.childNodes) ? markSubTrees(t1, t2) : [],
700699
t1_child_nodes = t1.childNodes ? t1.childNodes : [],
701700
t2_child_nodes = t2.childNodes ? t2.childNodes : [],
702-
diffs, i, last, e1, e2;
701+
childNodesLengthDifference, diffs, i, last, e1, e2;
703702

704-
// no correspondence whatsoever
705-
if (mappings === 0) {
706-
// two text nodes with differences
707-
if (t1.nodeName === '#text' && t2.nodeName === '#text' && t1.data !== t2.data) {
708-
return [new Diff({
709-
action: 'modiFyTextElement',
710-
oldValue: t1.data,
711-
newValue: t2.data,
712-
route: route
713-
})];
714-
}
703+
if (subtrees.length > 1) {
704+
/* Two or more groups have been identified among the childnodes of t1
705+
* and t2.
706+
*/
707+
return this.attemptGroupRelocation(t1, t2, subtrees, route);
715708
}
716-
// possibly identical content: verify
717-
if (mappings < 2) {
709+
710+
/* 0 or 1 groups of similar child nodes have been found
711+
* for t1 and t2. 1 If there is 1, it could be a sign that the
712+
* contents are the same. When the number of groups is below 2,
713+
* t1 and t2 are made to have the same length and each of the
714+
* pairs of child nodes are diffed.
715+
*/
716+
717+
/* if (subtrees.length === 0) {
718+
// No subtrees - could text nodes as they won't have any childNodes.
719+
//
720+
if (t1.nodeName === '#text' && t2.nodeName === '#text' && t1.data !== t2.data) {
721+
return [new Diff({
722+
action: 'modiFyTextElement',
723+
oldValue: t1.data,
724+
newValue: t2.data,
725+
route: route
726+
})];
727+
}
728+
} */
729+
730+
718731
last = Math.max(t1_child_nodes.length, t2_child_nodes.length);
732+
if (t1_child_nodes.length !== t2_child_nodes.length) {
733+
childNodesLengthDifference = true;
734+
}
735+
719736
for (i = 0; i < last; i += 1) {
720737
e1 = t1_child_nodes[i];
721738
e2 = t2_child_nodes[i];
722739

723-
if (e1 && !e2) {
724-
if (e1.nodeName === '#text') {
740+
if (childNodesLengthDifference) {
741+
/* t1 and t2 have different amounts of childNodes. Add
742+
* and remove as necessary to obtain the same length */
743+
if (e1 && !e2) {
744+
if (e1.nodeName === '#text') {
745+
return [new Diff({
746+
action: 'removeTextElement',
747+
route: route.concat(i),
748+
value: e1.data
749+
})];
750+
}
725751
return [new Diff({
726-
action: 'removeTextElement',
752+
action: 'removeElement',
727753
route: route.concat(i),
728-
value: e1.data
754+
element: cloneObj(e1)
729755
})];
730756
}
731-
return [new Diff({
732-
action: 'removeElement',
733-
route: route.concat(i),
734-
element: cloneObj(e1)
735-
})];
736-
}
737-
if (e2 && !e1) {
738-
if (e2.nodeName === '#text') {
757+
if (e2 && !e1) {
758+
if (e2.nodeName === '#text') {
759+
return [new Diff({
760+
action: 'addTextElement',
761+
route: route.concat(i),
762+
value: e2.data
763+
})];
764+
}
739765
return [new Diff({
740-
action: 'addTextElement',
766+
action: 'addElement',
741767
route: route.concat(i),
742-
value: e2.data
768+
element: cloneObj(e2)
743769
})];
744770
}
745-
return [new Diff({
746-
action: 'addElement',
747-
route: route.concat(i),
748-
element: cloneObj(e2)
749-
})];
750771
}
772+
/* We are now guaranteed that childNodes e1 and e2 exist,
773+
* and that they can be diffed.
774+
*/
751775

752776
diffs = this.findNextDiff(e1, e2, route.concat(i));
753777
if (diffs && diffs.length > 0) {
754778
return diffs;
755779
}
756780

757781
}
758-
}
759782

760-
// one or more differences: find first diff
761-
return this.attemptGroupRelocation(t1, t2, subtrees, route);
783+
return [];
784+
762785
},
763786

764787
attemptGroupRelocation: function(t1, t2, subtrees, route) {
765-
/* Once t1.childNodes and t2.childNodes have the same length,
766-
* attempts are made at equalizing the two. First all initial elements
767-
* with no group affiliation (gaps=true) are removed (if in t1) or
768-
* added (if in t2). Then the creation of a group relocation diff is
769-
* attempted.
788+
/* Either t1.childNodes and t2.childNodes have the same length, or
789+
* there are at least two groups of similar elements can be found.
790+
* attempts are made at equalizing t1 with t2. First all initial
791+
* elements with no group affiliation (gaps=true) are removed (if
792+
* only in t1) or added (if only in t2). Then the creation of a group
793+
* relocation diff is attempted.
770794
*/
771795

772796
var gapInformation = getGapInformation(t1, t2, subtrees),
773797
gaps1 = gapInformation.gaps1,
774798
gaps2 = gapInformation.gaps2,
799+
shortest = Math.min(gaps1.length, gaps2.length),
775800
destinationDifferent, toGroup,
776801
group, node, similarNode, testI,
777802
i, j;
778803

779804
// group relocation
780-
for (i = 0; i < gaps1.length; i += 1) {
805+
for (i = 0; i < shortest; i += 1) {
781806
if (gaps1[i] === true) {
782807
node = t1.childNodes[i];
783808
if (node.nodeName === '#text') {

tests/basic.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
<h1>Test for diffDOM</h1>
2424

2525
<!-- Add all divs to be compared here two by two -->
26+
<div><img><img><p></p><i></i><canvas></div>
27+
<div><p></p><img><img><canvas></div>
28+
2629
<div><img><img><i></i></div>
2730
<div><i></i><img><img></div>
2831

0 commit comments

Comments
 (0)