Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit c6d5693

Browse files
committed
Make sure we adopt the child that we are inserting
Even in the case where the real dom does not have a parent it is important to do the adoption for the ownerDocument to stay correct.
1 parent e4c51df commit c6d5693

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

src/wrappers/Node.js

+21-17
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,31 @@
6060
return nodes;
6161
}
6262

63-
function adoptIfNeeded(node, doc) {
64-
if (doc !== node.ownerDocument)
65-
scope.adoptNodeNoRemove(node, doc);
63+
function adoptNodesIfNeeded(owner, nodes) {
64+
if (!nodes.length)
65+
return;
66+
67+
var ownerDoc = owner.ownerDocument;
68+
69+
// All nodes have the same ownerDocument when we get here.
70+
if (ownerDoc === nodes[0].ownerDocument)
71+
return;
72+
73+
for (var i = 0; i < nodes.length; i++) {
74+
scope.adoptNodeNoRemove(nodes[i], ownerDoc);
75+
}
6676
}
6777

6878
function unwrapNodesForInsertion(owner, nodes) {
79+
adoptNodesIfNeeded(owner, nodes);
6980
var length = nodes.length;
7081

71-
if (length === 1) {
72-
var node = nodes[0];
73-
adoptIfNeeded(node, owner.ownerDocument);
74-
return unwrap(node);
75-
}
82+
if (length === 1)
83+
return unwrap(nodes[0]);
7684

77-
var ownerDoc = owner.ownerDocument;
78-
var df = unwrap(ownerDoc.createDocumentFragment());
85+
var df = unwrap(owner.ownerDocument.createDocumentFragment());
7986
for (var i = 0; i < length; i++) {
80-
var node = nodes[i];
81-
adoptIfNeeded(node, ownerDoc);
82-
df.appendChild(unwrap(node));
87+
df.appendChild(unwrap(nodes[i]));
8388
}
8489
return df;
8590
}
@@ -170,10 +175,6 @@
170175
if (!previousNode)
171176
this.firstChild_ = nodes[0];
172177

173-
// TODO(arv): It is unclear if we need to update the visual DOM here.
174-
// A better aproach might be to make sure we only get here for nodes that
175-
// are related to a shadow host and then invalidate that and re-render
176-
// the host (on reflow?).
177178
originalAppendChild.call(this.impl, unwrapNodesForInsertion(this, nodes));
178179

179180
return childWrapper;
@@ -201,11 +202,14 @@
201202
// insertBefore refWrapper no matter what the parent is?
202203
var refNode = unwrap(refWrapper);
203204
var parentNode = refNode.parentNode;
205+
204206
if (parentNode) {
205207
originalInsertBefore.call(
206208
parentNode,
207209
unwrapNodesForInsertion(this, nodes),
208210
refNode);
211+
} else {
212+
adoptNodesIfNeeded(this, nodes);
209213
}
210214

211215
return childWrapper;

test/js/paralleltrees.js

+54
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,60 @@ suite('Parallel Trees', function() {
926926
});
927927
});
928928

929+
test('insertBefore with different documents', function() {
930+
var doc = document.implementation.createHTMLDocument('');
931+
var div = doc.createElement('div');
932+
div.innerHTML = '<a></a><b></b>';
933+
var a = div.firstChild;
934+
var b = div.lastChild;
935+
936+
visual.removeAllChildNodes(div);
937+
938+
expectStructure(div, {
939+
firstChild: a,
940+
lastChild: b
941+
});
942+
943+
expectStructure(a, {
944+
parentNode: div,
945+
nextSibling: b
946+
});
947+
948+
expectStructure(b, {
949+
parentNode: div,
950+
previousSibling: a
951+
});
952+
953+
var c = document.createElement('c');
954+
div.insertBefore(c, b);
955+
956+
expectStructure(div, {
957+
firstChild: a,
958+
lastChild: b
959+
});
960+
961+
expectStructure(a, {
962+
parentNode: div,
963+
nextSibling: c
964+
});
965+
966+
expectStructure(b, {
967+
parentNode: div,
968+
previousSibling: c
969+
});
970+
971+
expectStructure(c, {
972+
parentNode: div,
973+
previousSibling: a,
974+
nextSibling: b,
975+
});
976+
977+
assert.equal(div.ownerDocument, doc);
978+
assert.equal(a.ownerDocument, div.ownerDocument);
979+
assert.equal(b.ownerDocument, div.ownerDocument);
980+
assert.equal(c.ownerDocument, div.ownerDocument);
981+
});
982+
929983
suite('replaceChild', function() {
930984
test('simple', function() {
931985
var div = document.createElement('div');

0 commit comments

Comments
 (0)