Commit 17465b85 by olwater Committed by GitHub

fix(html): 修复 Shadow DOM 隔离渲染下深浅色模式无法自动切换的问题 (#5890)

Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被
Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver
监听 document.documentElement 的 class 变化,将 dark class 同步到
Shadow DOM 内的包装容器上,使深色模式样式正常生效。
parent 2f91d8cc
...@@ -134,6 +134,11 @@ function sanitizeHtmlContent( ...@@ -134,6 +134,11 @@ function sanitizeHtmlContent(
return DOMPurify.sanitize(content) return DOMPurify.sanitize(content)
} }
function syncDarkClass(wrapper: HTMLElement): void {
const isDark = document.documentElement.classList.contains('dark')
wrapper.classList.toggle('dark', isDark)
}
function IsolatedHtmlContent(props: { function IsolatedHtmlContent(props: {
className?: string className?: string
html: string html: string
...@@ -153,13 +158,27 @@ function IsolatedHtmlContent(props: { ...@@ -153,13 +158,27 @@ function IsolatedHtmlContent(props: {
'style, link[rel="stylesheet"]' 'style, link[rel="stylesheet"]'
), ),
].map((node) => node.cloneNode(true)) ].map((node) => node.cloneNode(true))
const wrapper = document.createElement('div')
syncDarkClass(wrapper)
wrapper.innerHTML = props.html
const contentTemplate = document.createElement('template') const contentTemplate = document.createElement('template')
contentTemplate.innerHTML = `${isolatedContentBaseStyles}${props.html}` contentTemplate.innerHTML = isolatedContentBaseStyles
shadowRoot.replaceChildren( shadowRoot.replaceChildren(
...applicationStyleNodes, ...applicationStyleNodes,
contentTemplate.content contentTemplate.content,
wrapper
) )
const observer = new MutationObserver(() => syncDarkClass(wrapper))
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class'],
})
return () => observer.disconnect()
}, [props.html]) }, [props.html])
return ( return (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment