fix(web): 修复 Shadow DOM 隔离渲染下自定义 HTML 深浅色失效的问题 - #5890
Conversation
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds dark-mode class synchronization to isolated HTML rendering. A new ChangesDark-mode Sync for Isolated HTML Content
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant DocumentElement
participant MutationObserver
participant IsolatedHtmlContent
participant Wrapper
IsolatedHtmlContent->>Wrapper: create wrapper div
IsolatedHtmlContent->>Wrapper: syncDarkClass(wrapper)
IsolatedHtmlContent->>Wrapper: set innerHTML to props.html
IsolatedHtmlContent->>MutationObserver: observe DocumentElement class attribute
DocumentElement-->>MutationObserver: class attribute changed
MutationObserver->>Wrapper: syncDarkClass(wrapper)
IsolatedHtmlContent->>MutationObserver: disconnect on cleanup
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…codes * origin/main: (180 commits) fix(billing): extend quantity validation and saturating conversions to remaining paths fix(billing): validate quantity parameters and harden quota calculations Fix/build date dns error (QuantumNous#5945) fix: avoid stale stream writes after client disconnect (QuantumNous#5710) feat(group): enhance group ratio editor with improved visibility rules and JSON parsing feat: optimize legacy top-up warning banner copy (QuantumNous#5851) (QuantumNous#5855) fix(web): redirect authenticated users away from sign-up page (QuantumNous#5910) feat(ssrf): implement SSRF protection in HTTP clients and validation functions feat(user): better messages for redeem failures fix(html): 修复 Shadow DOM 隔离渲染下深浅色模式无法自动切换的问题 (QuantumNous#5890) fix(web): sync home iframe theme and language (QuantumNous#5917) fix: 任务差额结算后 quota 和阿里视频时长优化 (QuantumNous#5923) fix(web): refine mobile user cards test(user): cover self-service password update guard feat(session): support opt-in Secure session cookies fix(auth): allow read-only access for non-disabled tokens fix(user): harden account email and password handling fix: align dynamic pricing style with log details dialog sections fix(channels): show field passthrough controls for Codex (QuantumNous#5902) fix(user): trim whitespace from username and validate input ... # Conflicts: # controller/redemption.go # controller/user.go # model/option.go # model/redemption.go # model/user.go # web/default/src/features/auth/api.ts # web/default/src/features/redemption-codes/api.ts # web/default/src/features/redemption-codes/components/redemptions-provider.tsx # web/default/src/features/redemption-codes/components/redemptions-table.tsx # web/default/src/features/redemption-codes/constants.ts # web/default/src/hooks/use-sidebar-data.ts # web/default/src/i18n/static-keys.ts # web/default/src/routes/__root.tsx
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。 (cherry picked from commit 17465b8)
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Shadow DOM 的样式隔离特性导致外部 html 元素上的 dark class 无法被 Shadow DOM 内部的 Tailwind dark: 选择器匹配到。通过 MutationObserver 监听 document.documentElement 的 class 变化,将 dark class 同步到 Shadow DOM 内的包装容器上,使深色模式样式正常生效。
Important
请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。
📝 变更描述 / Description
核心修复:深浅色模式适配
修复了自定义 HTML 页面在 Shadow DOM 隔离渲染模式下,无法随系统自动切换深浅色主题的问题。
在 Shadow DOM 内部增加了一层包装容器(
wrapper),并通过MutationObserver实时监听外部主文档(document.documentElement)的class变化,将dark类名动态同步至该包装容器上。这使得被克隆进 Shadow DOM 的 Tailwind 深色模式 CSS 规则能够重新匹配生效。🔍 问题背景与根因排查
关于自定义页面的渲染逻辑,最近经历了数次变更,导致了样式连环失效。经过在本地的详细排查与测试,还原了完整的原因:
1bff599): 出于防止恶意代码影响全局的考虑,核心团队将渲染方案重写为了 Shadow DOM 隔离渲染 并严格限制了DOMPurify规则。虽然杜绝了外部污染,但 Shadow DOM 的“绝对隔离”特性使得系统原本的 Tailwind 样式彻底进不去自定义内容中,导致了“样式白板”现象。<style>标签克隆进 Shadow DOM 来恢复排版。但遗漏了 Tailwind 深浅色生效的核心机制(依赖祖先元素上的.dark类名)。由于 Shadow DOM 内部无法感知外部标签的 class,这些深色 CSS 永远无法命中触发,导致深浅色切换失效。本 PR 补齐了这“最后一块拼图”。
🤔 关于技术路线的架构探讨
虽然本 PR 已彻底修复当前 Shadow DOM 下的深浅色问题,但借此想向核心团队提出一个产品层面的抉择探讨:
采用目前的 Shadow DOM + 强过滤 机制,意味着管理员在后台添加的任何包含
<script>的代码都必定无法执行。这将导致以下常见场景永远无法在自定义页面中实现:如果团队认为安全性高于一切,本 PR 提供了完善的深浅色修复,可直接合并(预期内隔离)。
如果团队认为应将选择权交还给管理员(毕竟是最高权限后台配置),建议后续考虑退回到 #5795 最初的逻辑,允许管理员自行对其配置的外部代码安全负责。抛砖引玉,供各位定夺。
🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
✅ 提交前检查项 / Checklist
📸 运行证明 / Proof of Work
bun run typecheck与bunx oxlint均通过无异常。Summary by CodeRabbit