Fixes #3295. Only cache a false-y result for an element's owner shady root iff the element is currently in the document.

This commit is contained in:
Steven Orvell 2016-01-14 15:12:34 -08:00
parent 44232bdf03
commit 6e16619a4a
3 changed files with 88 additions and 4 deletions

View File

@ -170,8 +170,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
if (!node) {
return;
}
if (node._ownerShadyRoot === undefined) {
var root;
var root = node._ownerShadyRoot;
if (root === undefined) {
if (node._isShadyRoot) {
root = node;
} else {
@ -183,9 +183,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
root = null;
}
}
node._ownerShadyRoot = root;
// memo-ize result for performance but only memo-ize a false-y
// result if node is in the document. This avoids a problem where a root
// can be cached while an element is inside a fragment.
// If this happens and we cache the result, the value can become stale
// because for perf we avoid processing the subtree of added fragments.
if (root || document.contains(node)) {
node._ownerShadyRoot = root;
}
}
return node._ownerShadyRoot;
return root;
},
_maybeDistribute: function(node) {

View File

@ -0,0 +1,59 @@
<!doctype html>
<html>
<head>
<title>early owner-root</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../polymer.html">
</head>
<body>
<dom-module id="x-owner-root">
<template>where am I?</template>
<script>
Polymer({
is: 'x-owner-root',
properties: {
nug: {type: String, observer: '_nugChanged'}
},
_nugChanged: function() {
console.log(this.localName, Polymer.dom(this).getOwnerRoot());
}
});
</script>
</dom-module>
<dom-module id="x-test">
<template>
<template is="dom-if" if="{{foo}}">
<x-owner-root nug="foo"></x-owner-root>
</template>
</template>
<script>
Polymer({
is: 'x-test',
attached: function() {
this.foo = true;
Polymer.dom.flush();
var e = Polymer.dom(this.root).querySelector('x-owner-root');
var r = e && Polymer.dom(e).getOwnerRoot();
console.log(e, r, r === this.root);
}
});
</script>
</dom-module>
<x-test></x-test>
</body>
</html>

View File

@ -1207,6 +1207,24 @@ suite('Polymer.dom non-distributed elements', function() {
assert.equal(Polymer.dom(test).getOwnerRoot(), c1.root, 'getOwnerRoot incorrect for child added to element in root');
});
test('getOwnerRoot when out of tree and adding subtree', function() {
var container = document.createDocumentFragment();
var test = document.createElement('div');
container.appendChild(test);
assert.notOk(Polymer.dom(test).getOwnerRoot(), 'getOwnerRoot incorrect when not in root');
var c1 = document.createElement('x-compose');
var project = c1.$.project;
Polymer.dom(project).appendChild(container);
Polymer.dom.flush();
assert.equal(Polymer.dom(test).getOwnerRoot(), c1.root, 'getOwnerRoot incorrect for child added to element in root');
Polymer.dom(project).removeChild(test);
Polymer.dom.flush();
assert.notOk(Polymer.dom(test).getOwnerRoot(), 'getOwnerRoot incorrect for child moved from a root to no root');
Polymer.dom(project).appendChild(test);
Polymer.dom.flush();
assert.equal(Polymer.dom(test).getOwnerRoot(), c1.root, 'getOwnerRoot incorrect for child added to element in root');
});
test('getOwnerRoot, subtree', function() {
var test = document.createElement('div');
var testChild = document.createElement('div');