Skip to content

Commit b2fcaaa

Browse files
Steven OrvellMartin MOIZARD-LANVIN
Steven Orvell
authored and
Martin MOIZARD-LANVIN
committed
Fixes Polymer#2334: when composing nodes in shady dom, check if a node is where we expect it to be before removing it from its distributed position. We do this because the node may have been moved by Polymer.dom in a way that triggered distribution of its previous location. The node is already where it needs to be so removing it from its parent when it's no longer distributed is destructive.
1 parent 83cc343 commit b2fcaaa

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

src/mini/shady.html

+7-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,13 @@
300300
// process removals
301301
for (var i=0, d=0, s; (i<splices.length) && (s=splices[i]); i++) {
302302
for (var j=0, n; (j < s.removed.length) && (n=s.removed[j]); j++) {
303-
remove(n);
303+
// check if the node is still where we expect it is before trying
304+
// to remove it; this can happen if Polymer.dom moves a node and
305+
// then schedules its previous host for distribution resulting in
306+
// the node being removed here.
307+
if (getComposedParent(n) === container) {
308+
remove(n);
309+
}
304310
composed.splice(s.index + d, 1);
305311
}
306312
d -= s.addedCount;

test/unit/polymer-dom-content.html

+78
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@
2929
</script>
3030
</dom-module>
3131

32+
<dom-module id="x-dist-simple">
33+
<template>
34+
<content id="content"></content>
35+
</template>
36+
<script>
37+
HTMLImports.whenReady(function() {
38+
Polymer({is: 'x-dist-simple'});
39+
});
40+
</script>
41+
</dom-module>
42+
3243
<dom-module id="x-dist-inside-deep-tree">
3344
<template>
3445
x-dist-inside-deep-tree
@@ -1171,6 +1182,73 @@
11711182
document.body.removeChild(h1);
11721183
});
11731184

1185+
test('moving children between distributing host with shallow insertion and fragment', function() {
1186+
var h1 = document.createElement('x-dist-simple');
1187+
var h2 = document.createDocumentFragment();;
1188+
document.body.appendChild(h1);
1189+
Polymer.dom.flush();
1190+
var d = document.createElement('div');
1191+
Polymer.dom(h1).appendChild(d);
1192+
Polymer.dom.flush();
1193+
assert.equal(Polymer.dom(h1).childNodes.length, 1);
1194+
assert.equal(Polymer.dom(h1).firstElementChild, d);
1195+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
1196+
assert.equal(Polymer.dom(h2).childNodes.length, 0);
1197+
Polymer.dom(h2).appendChild(d);
1198+
Polymer.dom.flush();
1199+
assert.equal(Polymer.dom(h2).childNodes.length, 1);
1200+
assert.equal(Polymer.dom(h2).firstElementChild, d);
1201+
assert.equal(Polymer.dom(h1).childNodes.length, 0);
1202+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
1203+
Polymer.dom(h1).appendChild(d);
1204+
Polymer.dom.flush();
1205+
assert.equal(Polymer.dom(h1).childNodes.length, 1);
1206+
assert.equal(Polymer.dom(h1).firstElementChild, d);
1207+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
1208+
assert.equal(Polymer.dom(h2).childNodes.length, 0);
1209+
Polymer.dom(h2).appendChild(d);
1210+
Polymer.dom.flush();
1211+
assert.equal(Polymer.dom(h2).childNodes.length, 1);
1212+
assert.equal(Polymer.dom(h2).firstElementChild, d);
1213+
assert.equal(Polymer.dom(h1).childNodes.length, 0);
1214+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
1215+
document.body.removeChild(h1);
1216+
});
1217+
1218+
test('moving children between distributing host with shallow insertion and fragment (parsed child)', function() {
1219+
var div = document.createElement('div');
1220+
div.innerHTML = '<x-dist-simple><div></div></x-dist-simple>';
1221+
var h1 = div.firstChild;
1222+
var h2 = document.createDocumentFragment();;
1223+
document.body.appendChild(h1);
1224+
Polymer.dom.flush();
1225+
var d = Polymer.dom(h1).firstElementChild;
1226+
assert.equal(d.localName, 'div');
1227+
assert.equal(Polymer.dom(h1).childNodes.length, 1);
1228+
assert.equal(Polymer.dom(h1).firstElementChild, d);
1229+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
1230+
assert.equal(Polymer.dom(h2).childNodes.length, 0);
1231+
Polymer.dom(h2).appendChild(d);
1232+
Polymer.dom.flush();
1233+
assert.equal(Polymer.dom(h2).childNodes.length, 1);
1234+
assert.equal(Polymer.dom(h2).firstElementChild, d);
1235+
assert.equal(Polymer.dom(h1).childNodes.length, 0);
1236+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
1237+
Polymer.dom(h1).appendChild(d);
1238+
Polymer.dom.flush();
1239+
assert.equal(Polymer.dom(h1).childNodes.length, 1);
1240+
assert.equal(Polymer.dom(h1).firstElementChild, d);
1241+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
1242+
assert.equal(Polymer.dom(h2).childNodes.length, 0);
1243+
Polymer.dom(h2).appendChild(d);
1244+
Polymer.dom.flush();
1245+
assert.equal(Polymer.dom(h2).childNodes.length, 1);
1246+
assert.equal(Polymer.dom(h2).firstElementChild, d);
1247+
assert.equal(Polymer.dom(h1).childNodes.length, 0);
1248+
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
1249+
document.body.removeChild(h1);
1250+
});
1251+
11741252
test('moving an element containing a dom-repeat that distributes items', function() {
11751253
var x1 = document.createElement('x-repeat');
11761254
var div = document.createElement('div');

0 commit comments

Comments
 (0)