Skip to content

Commit 6e16619

Browse files
author
Steven Orvell
committed
Fixes #3295. Only cache a false-y result for an element's owner shady root iff the element is currently in the document.
1 parent 44232bd commit 6e16619

3 files changed

Lines changed: 88 additions & 4 deletions

File tree

‎src/lib/dom-api-shady.html‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@
170170
if (!node) {
171171
return;
172172
}
173-
if (node._ownerShadyRoot === undefined) {
174-
var root;
173+
var root = node._ownerShadyRoot;
174+
if (root === undefined) {
175175
if (node._isShadyRoot) {
176176
root = node;
177177
} else {
@@ -183,9 +183,16 @@
183183
root = null;
184184
}
185185
}
186-
node._ownerShadyRoot = root;
186+
// memo-ize result for performance but only memo-ize a false-y
187+
// result if node is in the document. This avoids a problem where a root
188+
// can be cached while an element is inside a fragment.
189+
// If this happens and we cache the result, the value can become stale
190+
// because for perf we avoid processing the subtree of added fragments.
191+
if (root || document.contains(node)) {
192+
node._ownerShadyRoot = root;
193+
}
187194
}
188-
return node._ownerShadyRoot;
195+
return root;
189196
},
190197

191198
_maybeDistribute: function(node) {

‎test/smoke/owner-root.html‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
5+
<title>early owner-root</title>
6+
7+
<meta charset="utf-8">
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
10+
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
11+
<link rel="import" href="../../polymer.html">
12+
13+
</head>
14+
<body>
15+
16+
17+
<dom-module id="x-owner-root">
18+
<template>where am I?</template>
19+
<script>
20+
Polymer({
21+
is: 'x-owner-root',
22+
23+
properties: {
24+
nug: {type: String, observer: '_nugChanged'}
25+
},
26+
27+
_nugChanged: function() {
28+
console.log(this.localName, Polymer.dom(this).getOwnerRoot());
29+
}
30+
31+
32+
});
33+
</script>
34+
</dom-module>
35+
36+
<dom-module id="x-test">
37+
<template>
38+
<template is="dom-if" if="{{foo}}">
39+
<x-owner-root nug="foo"></x-owner-root>
40+
</template>
41+
</template>
42+
<script>
43+
Polymer({
44+
is: 'x-test',
45+
attached: function() {
46+
this.foo = true;
47+
Polymer.dom.flush();
48+
var e = Polymer.dom(this.root).querySelector('x-owner-root');
49+
var r = e && Polymer.dom(e).getOwnerRoot();
50+
console.log(e, r, r === this.root);
51+
}
52+
});
53+
</script>
54+
</dom-module>
55+
56+
<x-test></x-test>
57+
58+
</body>
59+
</html>

‎test/unit/polymer-dom.js‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,24 @@ suite('Polymer.dom non-distributed elements', function() {
12071207
assert.equal(Polymer.dom(test).getOwnerRoot(), c1.root, 'getOwnerRoot incorrect for child added to element in root');
12081208
});
12091209

1210+
test('getOwnerRoot when out of tree and adding subtree', function() {
1211+
var container = document.createDocumentFragment();
1212+
var test = document.createElement('div');
1213+
container.appendChild(test);
1214+
assert.notOk(Polymer.dom(test).getOwnerRoot(), 'getOwnerRoot incorrect when not in root');
1215+
var c1 = document.createElement('x-compose');
1216+
var project = c1.$.project;
1217+
Polymer.dom(project).appendChild(container);
1218+
Polymer.dom.flush();
1219+
assert.equal(Polymer.dom(test).getOwnerRoot(), c1.root, 'getOwnerRoot incorrect for child added to element in root');
1220+
Polymer.dom(project).removeChild(test);
1221+
Polymer.dom.flush();
1222+
assert.notOk(Polymer.dom(test).getOwnerRoot(), 'getOwnerRoot incorrect for child moved from a root to no root');
1223+
Polymer.dom(project).appendChild(test);
1224+
Polymer.dom.flush();
1225+
assert.equal(Polymer.dom(test).getOwnerRoot(), c1.root, 'getOwnerRoot incorrect for child added to element in root');
1226+
});
1227+
12101228
test('getOwnerRoot, subtree', function() {
12111229
var test = document.createElement('div');
12121230
var testChild = document.createElement('div');

0 commit comments

Comments
 (0)