From 3f1c5881287ce11217766d876cded7635e1bb2b6 Mon Sep 17 00:00:00 2001 From: Innei Date: Fri, 30 Aug 2024 16:32:19 +0800 Subject: [PATCH] fix: shadow dom style injected in prod build Signed-off-by: Innei --- .../src/components/common/ShadowDOM.tsx | 66 ++++++++++++++----- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/src/renderer/src/components/common/ShadowDOM.tsx b/src/renderer/src/components/common/ShadowDOM.tsx index 1351fc1d5..3fc07b62c 100644 --- a/src/renderer/src/components/common/ShadowDOM.tsx +++ b/src/renderer/src/components/common/ShadowDOM.tsx @@ -1,29 +1,65 @@ import { useIsDark } from "@renderer/hooks/common" import type { FC, PropsWithChildren, ReactNode } from "react" -import { createContext, createElement, useContext, useState } from "react" +import { + createContext, + createElement, + useContext, + useLayoutEffect, + useState, +} from "react" import root from "react-shadow" const ShadowDOMContext = createContext(false) + +const cloneStylesElement = () => { + const $styles = document.head.querySelectorAll("style").values() + const reactNodes = [] as ReactNode[] + let i = 0 + for (const style of $styles) { + const key = `style-${i++}` + reactNodes.push( + createElement("style", { + key, + dangerouslySetInnerHTML: { __html: style.innerHTML }, + }), + ) + } + + document.head.querySelectorAll("link[rel=stylesheet]").forEach((link) => { + const key = `link-${i++}` + reactNodes.push( + createElement("link", { + key, + rel: "stylesheet", + href: link.getAttribute("href"), + crossOrigin: link.getAttribute("crossorigin"), + }), + ) + }) + + return reactNodes +} export const ShadowDOM: FC>> & { useIsShadowDOM: () => boolean } = (props) => { const { ...rest } = props - const [stylesElements] = useState(() => { - const $styles = document.head.querySelectorAll("style").values() - const reactNodes = [] as ReactNode[] - let i = 0 - for (const style of $styles) { - const key = `style-${i++}` - reactNodes.push( - createElement("style", { - key, - dangerouslySetInnerHTML: { __html: style.innerHTML }, - }), - ) + const [stylesElements, setStylesElements] = + useState(cloneStylesElement) + + useLayoutEffect(() => { + const mutationObserver = new MutationObserver(() => { + setStylesElements(cloneStylesElement()) + }) + mutationObserver.observe(document.head, { + childList: true, + subtree: true, + }) + + return () => { + mutationObserver.disconnect() } - return reactNodes - }) + }, []) const dark = useIsDark() return (