|
15 | 15 | })(this, function() { |
16 | 16 | "use strict"; |
17 | 17 |
|
18 | | - var diffcount; |
| 18 | + var diffcount, foundAll = false; |
19 | 19 |
|
20 | 20 | var Diff = function(options) { |
21 | 21 | var diff = this; |
|
150 | 150 | if (Boolean(e1.childNodes) !== Boolean(e2.childNodes)) { |
151 | 151 | return false; |
152 | 152 | } |
153 | | - |
154 | 153 | if (e1.attributes) { |
155 | 154 | e1Attributes = Object.keys(e1.attributes); |
156 | 155 | e2Attributes = Object.keys(e2.attributes); |
|
162 | 161 | if (e1.attributes[attribute] !== e2.attributes[attribute]) { |
163 | 162 | return false; |
164 | 163 | } |
| 164 | + return true; |
165 | 165 | })) { |
166 | 166 | return false; |
167 | 167 | } |
168 | 168 | } |
169 | | - |
170 | 169 | if (e1.childNodes) { |
171 | 170 | if (e1.childNodes.length !== e2.childNodes.length) { |
172 | 171 | return false; |
|
449 | 448 | debug: false, |
450 | 449 | diffcap: 10, // Limit for how many diffs are accepting when debugging. Inactive when debug is false. |
451 | 450 | maxDepth: false, // False or a numeral. If set to a numeral, limits the level of depth that the the diff mechanism looks for differences. If false, goes through the entire tree. |
| 451 | + maxChildCount: false, // False or a numeral. If set to a numeral, does not try to diff the contents of nodes with more children if there are more than maxChildCountDiffCount differences among child nodes. |
| 452 | + maxChildCountDiffCount: 3, // Numeral. See maxChildCount. |
452 | 453 | valueDiffing: true, // Whether to take into consideration the values of forms that differ from auto assigned values (when a user fills out a form). |
453 | 454 | // syntax: textDiff: function (node, currentValue, expectedValue, newValue) |
454 | 455 | textDiff: function() { |
|
555 | 556 | } |
556 | 557 | } |
557 | 558 | diffs = this.findNextDiff(t1, t2, []); |
| 559 | + |
558 | 560 | if (diffs.length === 0) { |
559 | 561 | // Last check if the elements really are the same now. |
560 | 562 | // If not, remove all info about being done and start over. |
561 | | - // Somtimes a node can be marked as done, but the creation of subsequent diffs means that it has to be changed anyway. |
| 563 | + // Sometimes a node can be marked as done, but the creation of subsequent diffs means that it has to be changed again. |
562 | 564 | if (!isEqual(t1, t2)) { |
563 | | - removeDone(t1); |
564 | | - diffs = this.findNextDiff(t1, t2, []); |
| 565 | + if (foundAll) { |
| 566 | + console.error('Could not find remaining diffs!'); |
| 567 | + console.log({t1, t2}); |
| 568 | + } else { |
| 569 | + foundAll = true; |
| 570 | + removeDone(t1); |
| 571 | + diffs = this.findNextDiff(t1, t2, []); |
| 572 | + } |
565 | 573 | } |
566 | 574 | } |
567 | | - |
568 | 575 | if (diffs.length > 0) { |
| 576 | + foundAll = false |
569 | 577 | this.tracker.add(diffs); |
570 | 578 | this.applyVirtual(t1, diffs); |
571 | 579 | } |
|
632 | 640 | ]; |
633 | 641 | } |
634 | 642 |
|
| 643 | + if (this.maxChildCount && t1.childNodes && t2.childNodes && t1.childNodes.length > this.maxChildCount && t2.childNodes.length > this.maxChildCount) { |
| 644 | + var childNodesLength = t1.childNodes.length < t2.childNodes.length ? t1.childNodes.length : t2.childNodes.length, childDiffCount = 0, j = 0; |
| 645 | + while (childDiffCount < this.maxChildCountDiffCount && j < childNodesLength) { |
| 646 | + if (!isEqual(t1.childNodes[j], t2.childNodes[j])) { |
| 647 | + childDiffCount++; |
| 648 | + } |
| 649 | + j++; |
| 650 | + } |
| 651 | + if (childDiffCount === this.maxChildCountDiffCount) { |
| 652 | + return [new Diff() |
| 653 | + .setValue(t._const.action, t._const.replaceElement) |
| 654 | + .setValue(t._const.oldValue, cloneObj(t1)) |
| 655 | + .setValue(t._const.newValue, cloneObj(t2)) |
| 656 | + .setValue(t._const.route, route) |
| 657 | + ]; |
| 658 | + } |
| 659 | + } |
| 660 | + |
635 | 661 | if (t1.data !== t2.data) { |
636 | 662 | // Comment or text node. |
637 | 663 | if (t1.nodeName === '#text') { |
|
0 commit comments