From 719cb36e9147a5e214b91117300df03ff0175559 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Sun, 3 Sep 2023 14:03:26 -0700 Subject: [PATCH] Updates Declarative Shadow DOM polyfill to apply recursively. Without this, only top-level DSD nodes would get applied. This allows us to nest one DSD node under another. --- .../declarative_shadow_dom_polyfill.mts | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/declarative_shadow_dom/declarative_shadow_dom_polyfill.mts b/packages/declarative_shadow_dom/declarative_shadow_dom_polyfill.mts index e0d5d6db..f6763cd2 100644 --- a/packages/declarative_shadow_dom/declarative_shadow_dom_polyfill.mts +++ b/packages/declarative_shadow_dom/declarative_shadow_dom_polyfill.mts @@ -1,23 +1,28 @@ /** * @fileoverview Polyfills declarative shadow DOM by searching for templates * which match its attributes and attaching them as real shadow roots. - * + * * Shamelessly stolen from: https://web.dev/declarative-shadow-dom/#polyfill and * adapted for TypeScript. */ -const templates = document.querySelectorAll('template[shadowrootmode]') as - NodeListOf; -for (const template of Array.from(templates)) { - const mode = template.getAttribute('shadowrootmode'); - if (mode !== 'open' && mode !== 'closed') { - console.error( - `Found declarative shadow root with invalid mode: ${mode}.`); - continue; - } +function applyDsdNodes(root: Element | ShadowRoot): void { + const templates = root.querySelectorAll('template[shadowrootmode]') as + NodeListOf; + for (const template of Array.from(templates)) { + const mode = template.getAttribute('shadowrootmode'); + if (mode !== 'open' && mode !== 'closed') { + console.error( + `Found declarative shadow root with invalid mode: ${mode}.`); + continue; + } - const parent = template.parentNode as Element; - const shadowRoot = parent.attachShadow({ mode }); - shadowRoot.appendChild(template.content); - template.remove(); + const parent = template.parentNode as Element; + const shadowRoot = parent.attachShadow({ mode }); + shadowRoot.appendChild(template.content); + template.remove(); + applyDsdNodes(shadowRoot); + } } + +applyDsdNodes(document.documentElement);