fix: shadow dom style injected in prod build

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-08-30 16:32:19 +08:00
parent 66035fea72
commit 3f1c588128
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
1 changed files with 51 additions and 15 deletions

View File

@ -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<PropsWithChildren<React.HTMLProps<HTMLElement>>> & {
useIsShadowDOM: () => boolean
} = (props) => {
const { ...rest } = props
const [stylesElements] = useState<ReactNode[]>(() => {
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<ReactNode[]>(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 (