diff --git a/lib/utils/scope-subtree.js b/lib/utils/scope-subtree.js
index 7932d27f81..f99a7fb724 100644
--- a/lib/utils/scope-subtree.js
+++ b/lib/utils/scope-subtree.js
@@ -9,10 +9,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
*/
import './boot.js';
+import {wrap} from './wrap.js';
const ShadyDOM = window.ShadyDOM;
const ShadyCSS = window.ShadyCSS;
+/**
+ * Return true if node scope is correct.
+ *
+ * @param {!Element} node Node to check scope
+ * @param {!Node} scope Scope reference
+ * @return {boolean} True if node is in scope
+ */
+function sameScope(node, scope) {
+ return wrap(node).getRootNode() === scope;
+}
+
/**
* Ensure that elements in a ShadowDOM container are scoped correctly.
* This function is only needed when ShadyDOM is used and unpatched DOM APIs are used in third party code.
@@ -38,13 +50,20 @@ export function scopeSubtree(container, shouldObserve = false) {
}
// capture correct scope for container
const containerScope = ScopingShim['scopeForNode'](container);
+ const root = wrap(container).getRootNode();
const scopify = (node) => {
+ if (!sameScope(node, root)) {
+ return;
+ }
// NOTE: native qSA does not honor scoped DOM, but it is faster, and the same behavior as Polymer v1
const elements = Array.from(ShadyDOM['nativeMethods']['querySelectorAll'].call(node, '*'));
elements.push(node);
for (let i = 0; i < elements.length; i++) {
const el = elements[i];
+ if (!sameScope(el, root)) {
+ continue;
+ }
const currentScope = ScopingShim['currentScopeForNode'](el);
if (currentScope !== containerScope) {
if (currentScope !== '') {
diff --git a/test/unit/styling-scoped-nopatch.html b/test/unit/styling-scoped-nopatch.html
index b1f82b1fea..2d9426c995 100644
--- a/test/unit/styling-scoped-nopatch.html
+++ b/test/unit/styling-scoped-nopatch.html
@@ -50,6 +50,24 @@
customElements.define('scope-subtree-element', ScopeSubtreeElement);
+
+
@@ -62,6 +80,12 @@
+
+
+
+
+
+