From 6e048e59d7b6a60db63eaf83f0bdcffbb432376b Mon Sep 17 00:00:00 2001 From: Hakadao Date: Sat, 14 Sep 2024 12:08:03 +0800 Subject: [PATCH] refactor: `startShadowDOMStyleInjection()` --- src/contentScripts/index.ts | 107 ++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/src/contentScripts/index.ts b/src/contentScripts/index.ts index b768b978..84370e21 100644 --- a/src/contentScripts/index.ts +++ b/src/contentScripts/index.ts @@ -198,7 +198,7 @@ function injectApp() { }, 500) } - // startShadowDOMStyleInjection() + startShadowDOMStyleInjection() // inject svg icons const svgDiv = document.createElement('div') @@ -212,41 +212,76 @@ function injectApp() { app.mount(root) } -// function startShadowDOMStyleInjection() { -// if (isSupportedPages()) { -// setInterval(() => { -// injectStylesRecursively(document) -// }, 1000) -// } +function startShadowDOMStyleInjection() { + if (isHomePage() && !isSupportedPages()) + return -// function injectStylesRecursively(root: Document | ShadowRoot) { -// if (root instanceof ShadowRoot) { -// injectStyleToShadowDOM(root) -// } + // Create a MutationObserver to watch for Shadow DOM additions + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.type === 'childList') { + mutation.addedNodes.forEach((node) => { + if (node instanceof HTMLElement && node.shadowRoot) { + injectStyleToShadowDOM(node.shadowRoot) + // Observe nested Shadow DOMs recursively + observeShadowDOMRecursively(node.shadowRoot) + } + }) + } + }) + }) -// root.querySelectorAll('*').forEach((element) => { -// if (element.shadowRoot) { -// injectStylesRecursively(element.shadowRoot) -// } -// }) -// } + // Observe the entire document for new Shadow DOMs + observer.observe(document.body, { + childList: true, + subtree: true, + }) -// function injectStyleToShadowDOM(shadowRoot: ShadowRoot) { -// if (!shadowRoot.querySelector('style[data-bewly-style]')) { -// const styleEl = document.createElement('style') -// styleEl.setAttribute('data-bewly-style', 'true') -// styleEl.textContent = ` -// @import url(${browser.runtime.getURL('dist/contentScripts/style.css')}); -// ` -// if (settings.value.adaptToOtherPageStyles) { -// // Reset the theme color to ensure the theme color is updated -// styleEl.textContent += ` -// * { -// --bew-theme-color: ${settings.value.themeColor}; -// } -// ` -// } -// shadowRoot.appendChild(styleEl) -// } -// } -// } + // Inject styles into existing Shadow DOMs on initial load + injectStylesRecursively(document) + + function observeShadowDOMRecursively(shadowRoot: ShadowRoot) { + observer.observe(shadowRoot, { + childList: true, + subtree: true, + }) + + // Recursively observe nested Shadow DOMs within this Shadow DOM + shadowRoot.querySelectorAll('*').forEach((el) => { + if (el.shadowRoot) { + observeShadowDOMRecursively(el.shadowRoot) + } + }) + } + + function injectStylesRecursively(root: Document | ShadowRoot) { + if (root instanceof ShadowRoot) { + injectStyleToShadowDOM(root) + } + + root.querySelectorAll('*').forEach((element) => { + if (element.shadowRoot) { + injectStylesRecursively(element.shadowRoot) + } + }) + } + + function injectStyleToShadowDOM(shadowRoot: ShadowRoot) { + if (!shadowRoot.querySelector('style[data-bewly-style]')) { + const styleEl = document.createElement('style') + styleEl.setAttribute('data-bewly-style', 'true') + styleEl.textContent = ` + @import url(${browser.runtime.getURL('dist/contentScripts/style.css')}); + ` + if (settings.value.adaptToOtherPageStyles) { + // Reset the theme color to ensure the theme color is updated + styleEl.textContent += ` + * { + --bew-theme-color: ${settings.value.themeColor}; + } + ` + } + shadowRoot.appendChild(styleEl) + } + } +}