Skip to content

Commit 29cfccc

Browse files
committed
bundle diffs in findInner better together by only submitting and thereby reinitiating the diff mechanism when really needed
1 parent b16850a commit 29cfccc

File tree

1 file changed

+98
-104
lines changed

1 file changed

+98
-104
lines changed

diffDOM.js

Lines changed: 98 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,11 @@
156156
if (e1Attributes.length != e2Attributes.length) {
157157
return false;
158158
}
159-
if (!e1Attributes.every(function(attribute){
160-
if (e1.attributes[attribute] !== e2.attributes[attribute]) {
161-
return false;
162-
}
163-
})) {
159+
if (!e1Attributes.every(function(attribute) {
160+
if (e1.attributes[attribute] !== e2.attributes[attribute]) {
161+
return false;
162+
}
163+
})) {
164164
return false;
165165
}
166166
}
@@ -561,21 +561,21 @@
561561
}
562562
}
563563
diffs = this.findNextDiff(t1, t2, []);
564-
if (diffs.length === 0 || !diffs) {
564+
if (diffs.length === 0) {
565565
// Last check if the elements really are the same now.
566566
// If not, remove all info about being done and start over.
567567
// Somtimes a node can be marked as done, but the creation of subsequent diffs means that it has to be changed anyway.
568568
if (!isEqual(t1, t2)) {
569569
removeDone(t1);
570-
diffs = this.findNextDiff(t1, t2, []);
570+
diffs = this.findNextDiff(t1, t2, []);
571571
}
572572
}
573573

574574
if (diffs.length > 0) {
575575
this.tracker.add(diffs);
576576
this.applyVirtual(t1, diffs);
577577
}
578-
} while (diffs);
578+
} while (diffs.length > 0);
579579
return this.tracker.list;
580580
},
581581
findNextDiff: function(t1, t2, route) {
@@ -617,11 +617,12 @@
617617
}
618618

619619
// no differences
620-
return false;
620+
return [];
621621
},
622622
findOuterDiff: function(t1, t2, route) {
623623

624-
var diffs = [], attr1, attr2;
624+
var diffs = [],
625+
attr1, attr2;
625626

626627
if (t1.nodeName !== t2.nodeName) {
627628
return [new Diff({
@@ -635,19 +636,19 @@
635636
if (t1.data !== t2.data) {
636637
// Comment or text node.
637638
if (t1.nodeName === '#text') {
638-
return [new Diff({
639-
action: 'modifyComment',
640-
route: route,
641-
oldValue: t1.data,
642-
newValue: t2.data
643-
})];
639+
return [new Diff({
640+
action: 'modifyComment',
641+
route: route,
642+
oldValue: t1.data,
643+
newValue: t2.data
644+
})];
644645
} else {
645-
return [new Diff({
646-
action: 'modifyTextElement',
647-
route: route,
648-
oldValue: t1.data,
649-
newValue: t2.data
650-
})];
646+
return [new Diff({
647+
action: 'modifyTextElement',
648+
route: route,
649+
oldValue: t1.data,
650+
newValue: t2.data
651+
})];
651652
}
652653

653654
}
@@ -698,100 +699,93 @@
698699
var subtrees = (t1.childNodes && t2.childNodes) ? markSubTrees(t1, t2) : [],
699700
t1_child_nodes = t1.childNodes ? t1.childNodes : [],
700701
t2_child_nodes = t2.childNodes ? t2.childNodes : [],
701-
childNodesLengthDifference, diffs, i, last, e1, e2;
702+
childNodesLengthDifference, diffs = [],
703+
i, last, e1, e2;
702704

703705
if (subtrees.length > 1) {
704706
/* Two or more groups have been identified among the childnodes of t1
705-
* and t2.
706-
*/
707+
* and t2.
708+
*/
707709
return this.attemptGroupRelocation(t1, t2, subtrees, route);
708710
}
709711

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-
} */
712+
/* 0 or 1 groups of similar child nodes have been found
713+
* for t1 and t2. 1 If there is 1, it could be a sign that the
714+
* contents are the same. When the number of groups is below 2,
715+
* t1 and t2 are made to have the same length and each of the
716+
* pairs of child nodes are diffed.
717+
*/
729718

730719

731-
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-
736-
for (i = 0; i < last; i += 1) {
737-
e1 = t1_child_nodes[i];
738-
e2 = t2_child_nodes[i];
720+
last = Math.max(t1_child_nodes.length, t2_child_nodes.length);
721+
if (t1_child_nodes.length !== t2_child_nodes.length) {
722+
childNodesLengthDifference = true;
723+
}
739724

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-
}
751-
return [new Diff({
752-
action: 'removeElement',
725+
for (i = 0; i < last; i += 1) {
726+
e1 = t1_child_nodes[i];
727+
e2 = t2_child_nodes[i];
728+
729+
if (childNodesLengthDifference) {
730+
/* t1 and t2 have different amounts of childNodes. Add
731+
* and remove as necessary to obtain the same length */
732+
if (e1 && !e2) {
733+
if (e1.nodeName === '#text') {
734+
diffs.push(new Diff({
735+
action: 'removeTextElement',
753736
route: route.concat(i),
754-
element: cloneObj(e1)
755-
})];
737+
value: e1.data
738+
}));
739+
return diffs;
756740
}
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-
}
765-
return [new Diff({
766-
action: 'addElement',
741+
diffs.push(new Diff({
742+
action: 'removeElement',
743+
route: route.concat(i),
744+
element: cloneObj(e1)
745+
}));
746+
return diffs;
747+
}
748+
if (e2 && !e1) {
749+
if (e2.nodeName === '#text') {
750+
diffs.push(new Diff({
751+
action: 'addTextElement',
767752
route: route.concat(i),
768-
element: cloneObj(e2)
769-
})];
753+
value: e2.data
754+
}));
755+
return diffs;
770756
}
771-
}
772-
/* We are now guaranteed that childNodes e1 and e2 exist,
773-
* and that they can be diffed.
774-
*/
775-
776-
diffs = this.findNextDiff(e1, e2, route.concat(i));
777-
if (diffs && diffs.length > 0) {
757+
diffs.push(new Diff({
758+
action: 'addElement',
759+
route: route.concat(i),
760+
element: cloneObj(e2)
761+
}));
778762
return diffs;
779763
}
780-
781764
}
765+
/* We are now guaranteed that childNodes e1 and e2 exist,
766+
* and that they can be diffed.
767+
*/
768+
diffs = diffs.concat(this.findNextDiff(e1, e2, route.concat(i)));
782769

783-
return [];
770+
/* Diffs in child nodes should not affect the parent node,
771+
* so we let these diffs be submitted together with other
772+
* diffs.
773+
*/
774+
775+
}
776+
777+
return diffs;
784778

785779
},
786780

787781
attemptGroupRelocation: function(t1, t2, subtrees, route) {
788782
/* 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.
794-
*/
783+
* there are at least two groups of similar elements can be found.
784+
* attempts are made at equalizing t1 with t2. First all initial
785+
* elements with no group affiliation (gaps=true) are removed (if
786+
* only in t1) or added (if only in t2). Then the creation of a group
787+
* relocation diff is attempted.
788+
*/
795789

796790
var gapInformation = getGapInformation(t1, t2, subtrees),
797791
gaps1 = gapInformation.gaps1,
@@ -920,12 +914,12 @@
920914
return true;
921915
}
922916
diffs.forEach(function(diff) {
923-
// console.log(JSON.stringify(diff));
924-
// console.log(JSON.stringify(tree));
925-
// console.log(objToNode(tree).outerHTML);
917+
// console.log(JSON.stringify(diff));
918+
// console.log(JSON.stringify(tree));
919+
// console.log(objToNode(tree).outerHTML);
926920
dobj.applyVirtualDiff(tree, diff);
927-
// console.log(JSON.stringify(tree));
928-
// console.log(objToNode(tree).outerHTML);
921+
// console.log(JSON.stringify(tree));
922+
// console.log(objToNode(tree).outerHTML);
929923
});
930924
return true;
931925
},
@@ -1023,9 +1017,9 @@
10231017
break;
10241018
case 'relocateGroup':
10251019
node.childNodes.splice(diff.from, diff.groupLength).reverse()
1026-
.forEach(function(movedNode){
1020+
.forEach(function(movedNode) {
10271021
node.childNodes.splice(diff.to, 0, movedNode);
1028-
});
1022+
});
10291023
break;
10301024
case 'removeElement':
10311025
parentNode.childNodes.splice(nodeIndex, 1);
@@ -1171,11 +1165,11 @@
11711165
case 'relocateGroup':
11721166
Array.apply(null, new Array(diff.groupLength)).map(function() {
11731167
return node.removeChild(node.childNodes[diff.from]);
1174-
}).forEach(function(childNode, index){
1175-
if(index===0) {
1168+
}).forEach(function(childNode, index) {
1169+
if (index === 0) {
11761170
reference = node.childNodes[diff.to];
11771171
}
1178-
node.insertBefore(childNode,reference);
1172+
node.insertBefore(childNode, reference);
11791173
});
11801174
break;
11811175
case 'removeElement':

0 commit comments

Comments
 (0)