From b05f0a237b9a56c45c15f8ed592648c04399cedf Mon Sep 17 00:00:00 2001 From: Pavel Pomerantsev Date: Sun, 30 Nov 2025 22:04:45 -0500 Subject: [PATCH 1/3] [WIP] Add shadow host instead of ignoring the shadow root Resolves #4941 --- lib/core/base/context/parse-selector-array.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/base/context/parse-selector-array.js b/lib/core/base/context/parse-selector-array.js index 4435664f41..08388e2a65 100644 --- a/lib/core/base/context/parse-selector-array.js +++ b/lib/core/base/context/parse-selector-array.js @@ -16,6 +16,8 @@ export function parseSelectorArray(context, type) { if (item instanceof window.Node) { if (item.documentElement instanceof window.Node) { result.push(context.flatTree[0]); + } else if (item.host instanceof window.Node) { + result.push(getNodeFromTree(item.host)); } else { result.push(getNodeFromTree(item)); } From d2f48cf1dee4dc361aa16899a4fff6406988659e Mon Sep 17 00:00:00 2001 From: Pavel Pomerantsev Date: Tue, 2 Dec 2025 21:46:57 -0500 Subject: [PATCH 2/3] Push children instead of the host --- lib/core/base/context/parse-selector-array.js | 8 +++++++- test/core/base/context.js | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/core/base/context/parse-selector-array.js b/lib/core/base/context/parse-selector-array.js index 08388e2a65..d237508fb5 100644 --- a/lib/core/base/context/parse-selector-array.js +++ b/lib/core/base/context/parse-selector-array.js @@ -17,7 +17,13 @@ export function parseSelectorArray(context, type) { if (item.documentElement instanceof window.Node) { result.push(context.flatTree[0]); } else if (item.host instanceof window.Node) { - result.push(getNodeFromTree(item.host)); + // Item is a shadow root. We only cache instances of `Element`, + // not `DocumentFragment`, so instead of the shadow root itself, + // we'll push all of its children to context. + const children = Array.from(item.children).map(child => + getNodeFromTree(child) + ); + result.push(...children); } else { result.push(getNodeFromTree(item)); } diff --git a/test/core/base/context.js b/test/core/base/context.js index 3a28ad0baa..d0ee8b5e00 100644 --- a/test/core/base/context.js +++ b/test/core/base/context.js @@ -16,7 +16,7 @@ describe('Context', () => { it('should not mutate exclude in input', () => { fixture.innerHTML = '
'; const context = { exclude: [['iframe', '#foo']] }; - // eslint-disable-next-line no-new + new Context(context); assert.deepEqual(context, { exclude: [['iframe', '#foo']] }); }); @@ -24,7 +24,7 @@ describe('Context', () => { it('should not mutate its include input', () => { fixture.innerHTML = '
'; const context = { include: [['#foo']] }; - // eslint-disable-next-line no-new + new Context(context); assert.deepEqual(context, { include: [['#foo']] }); }); @@ -109,6 +109,19 @@ describe('Context', () => { assert.equal(result.include[0].props.id, 'target'); }); + it('accepts a reference to a ShadowRoot', () => { + createNestedShadowDom( + fixture, + '
', + `

Heading

+

Content

` + ); + const shadowHost = fixture.querySelector('#shadowHost'); + const shadowRoot = shadowHost.shadowRoot; + const result = new Context(shadowRoot); + assert.deepEqual(selectors(result.include), ['#h1', '#p']); + }); + it('accepts a node reference consisting of nested divs', () => { const div1 = document.createElement('div'); const div2 = document.createElement('div'); From 2a272c1df283e52969896503cfaeba3576c2ac18 Mon Sep 17 00:00:00 2001 From: Pavel Pomerantsev Date: Wed, 3 Dec 2025 19:22:03 -0500 Subject: [PATCH 3/3] Format --- test/core/base/context.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/base/context.js b/test/core/base/context.js index d0ee8b5e00..410bfe09ab 100644 --- a/test/core/base/context.js +++ b/test/core/base/context.js @@ -16,7 +16,7 @@ describe('Context', () => { it('should not mutate exclude in input', () => { fixture.innerHTML = '
'; const context = { exclude: [['iframe', '#foo']] }; - + new Context(context); assert.deepEqual(context, { exclude: [['iframe', '#foo']] }); }); @@ -24,7 +24,7 @@ describe('Context', () => { it('should not mutate its include input', () => { fixture.innerHTML = '
'; const context = { include: [['#foo']] }; - + new Context(context); assert.deepEqual(context, { include: [['#foo']] }); });