Skip to content

Commit aa8e335

Browse files
Merge pull request #16 from WebReflection/issue-15
Fix #15 - avoid removing nodes that do not belong to their parent
2 parents ee7840f + 4bedda7 commit aa8e335

File tree

6 files changed

+78
-29
lines changed

6 files changed

+78
-29
lines changed

cjs/utils.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,8 @@ const next = (get, list, i, length, before) => i < length ?
8787
exports.next = next;
8888

8989
const remove = (get, parent, children, start, end) => {
90-
if ((end - start) < 2)
91-
parent.removeChild(get(children[start], -1));
92-
else {
93-
const range = parent.ownerDocument.createRange();
94-
range.setStartBefore(get(children[start], -1));
95-
range.setEndAfter(get(children[end - 1], -1));
96-
range.deleteContents();
97-
}
90+
while (start < end)
91+
removeChild(get(children[start++], -1), parent);
9892
};
9993
exports.remove = remove;
10094

@@ -386,3 +380,20 @@ const smartDiff = (
386380
);
387381
};
388382
exports.smartDiff = smartDiff;
383+
384+
let removeChild = (child, parentNode) => {
385+
/* istanbul ignore if */
386+
if ('remove' in child) {
387+
removeChild = child => {
388+
child.remove();
389+
};
390+
}
391+
else {
392+
removeChild = (child, parentNode) => {
393+
/* istanbul ignore else */
394+
if (child.parentNode === parentNode)
395+
parentNode.removeChild(child);
396+
};
397+
}
398+
removeChild(child, parentNode);
399+
};

esm/utils.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,8 @@ export const next = (get, list, i, length, before) => i < length ?
8080
before);
8181

8282
export const remove = (get, parent, children, start, end) => {
83-
if ((end - start) < 2)
84-
parent.removeChild(get(children[start], -1));
85-
else {
86-
const range = parent.ownerDocument.createRange();
87-
range.setStartBefore(get(children[start], -1));
88-
range.setEndAfter(get(children[end - 1], -1));
89-
range.deleteContents();
90-
}
83+
while (start < end)
84+
removeChild(get(children[start++], -1), parent);
9185
};
9286

9387
// - - - - - - - - - - - - - - - - - - -
@@ -377,3 +371,20 @@ export const smartDiff = (
377371
before
378372
);
379373
};
374+
375+
let removeChild = (child, parentNode) => {
376+
/* istanbul ignore if */
377+
if ('remove' in child) {
378+
removeChild = child => {
379+
child.remove();
380+
};
381+
}
382+
else {
383+
removeChild = (child, parentNode) => {
384+
/* istanbul ignore else */
385+
if (child.parentNode === parentNode)
386+
parentNode.removeChild(child);
387+
};
388+
}
389+
removeChild(child, parentNode);
390+
};

index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,8 @@ var next = function next(get, list, i, length, before) {
9999
};
100100

101101
var remove = function remove(get, parent, children, start, end) {
102-
if (end - start < 2) parent.removeChild(get(children[start], -1));else {
103-
var range = parent.ownerDocument.createRange();
104-
range.setStartBefore(get(children[start], -1));
105-
range.setEndAfter(get(children[end - 1], -1));
106-
range.deleteContents();
102+
while (start < end) {
103+
_removeChild(get(children[start++], -1), parent);
107104
}
108105
};
109106

@@ -296,6 +293,21 @@ var smartDiff = function smartDiff(get, parentNode, futureNodes, futureStart, fu
296293
applyDiff(OND(futureNodes, futureStart, futureChanges, currentNodes, currentStart, currentChanges, compare) || HS(futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges), get, parentNode, futureNodes, futureStart, currentNodes, currentStart, currentLength, before);
297294
};
298295

296+
var _removeChild = function removeChild(child, parentNode) {
297+
/* istanbul ignore if */
298+
if ('remove' in child) {
299+
_removeChild = function removeChild(child) {
300+
child.remove();
301+
};
302+
} else {
303+
_removeChild = function removeChild(child, parentNode) {
304+
/* istanbul ignore else */
305+
if (child.parentNode === parentNode) parentNode.removeChild(child);
306+
};
307+
}
308+
_removeChild(child, parentNode);
309+
};
310+
299311
/*! (c) 2018 Andrea Giammarchi (ISC) */
300312

301313
var domdiff = function domdiff(parentNode, // where changes happen

min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/node.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,24 @@ global.document = {
1818
var cn = [];
1919
return {
2020
appendChild: function (node) {
21+
node.parentNode = this;
2122
cn.push(node);
2223
}
2324
};
24-
},
25-
createRange: function () {
26-
return {
27-
setStartBefore: function () {},
28-
setEndAfter: function () {},
29-
deleteContents: function () {}
30-
};
3125
}
3226
},
3327
childNodes: [],
3428
insertBefore: function (before, after) {
3529
var cn = this.childNodes;
3630
var i = cn.indexOf(before);
3731
if (-1 < i) cn.splice(i, 1);
32+
before.parentNode = this;
3833
if (after == null) cn.push(before);
3934
else cn.splice(cn.indexOf(after), 0, before);
4035
},
4136
removeChild: function (child) {
4237
var cn = this.childNodes;
38+
delete child.parentNode;
4339
cn.splice(cn.indexOf(child), 1);
4440
}
4541
}

test/test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,25 @@ newState = domdiff(
12661266
);
12671267
console.assert(document.body.selectedIndex === 2, 'partial selectedIndex is OK');
12681268

1269+
var parent1 = document.createDocumentFragment();
1270+
var parent2 = document.createDocumentFragment();
1271+
var nodeA = document.createTextNode('option');
1272+
var nodeB = document.createTextNode('option');
1273+
var nodeC = document.createTextNode('option');
1274+
var nodeD = document.createTextNode('option');
1275+
1276+
domdiff(
1277+
parent1,
1278+
[nodeA, nodeB],
1279+
[nodeA, nodeB, nodeC]
1280+
);
1281+
1282+
domdiff(
1283+
parent2,
1284+
[nodeC, nodeD],
1285+
[nodeD]
1286+
);
1287+
12691288
// */
12701289

12711290
tressa.end();

0 commit comments

Comments
 (0)