Files
halo-dark-mode-plugin/docs/暗色模式残留排查报告.md
T

158 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Halo 暗色模式残留排查报告
> 排查时间:2026-08-07
> 排查环境:腾讯云生产站 `blog.liuhangyv.top`Halo Pro 2.24.2
> 排查方式:Playwright 自动化全路由扫描,共 92 个后台路由
## 一、结论摘要
1. **部署版本没有问题**。服务端实际加载的 `bundle.css` 与本仓库 `ui/build/dist/style.css` 的 194 条暗色规则完全一致,不存在"部署了旧包"的情况。
2. **73 个后台路由存在深浅色残留**,19 个路由完全干净(主要是 Shop 插件全家桶、快照页、权限页)。
3. 残留可归纳为 **3 类根因**
- 插件 CSS 加载顺序在最前,同特异性规则被后加载的 Halo 核心样式覆盖;
- UnoCSS 哈希类前缀已从 `i-*` 变为 `uno-*`,现有兜底规则匹配不到;
- 第三方插件页面(AstraHub、RSS 订阅、私密文章、AI 评论等)基本没有覆盖。
## 二、扫描方法与产物
### 方法
1. Playwright 启动持久化 Edge 上下文,复用已登录会话;
2. 从 Vue Router 读取全部注册路由(92 个),逐页加载;
3. 每页强制 `data-halo-theme="dark"`,等待网络空闲后扫描;
4. 扫描规则:可见且尺寸大于 50×20 的元素,背景 RGB 均 >235 记为浅色背景残留,直接文本颜色 RGB 均 <70 记为深色文字残留;
5. 每页截图存档,结果按页面 + 元素分组去重。
### 产物(均在 `workplace/`
| 文件 | 说明 |
|------|------|
| `scan_dark.py` | 全路由扫描脚本 |
| `scan-results.json` | 原始扫描结果(92 页 × 元素级) |
| `aggregate.txt` | 按元素/类名/问题聚合后的明细 |
| `shots/*.png` | 92 页深色模式截图 |
| `deployed-bundle.css` | 服务端实际部署的 CSS 快照 |
| `probe_conflict.py` / `fetch_bundle.py` | 样式表加载顺序与版本对比脚本 |
## 三、总体数据
| 指标 | 数值 |
|------|------|
| 扫描路由数 | 92 |
| 存在残留的路由 | 73 |
| 完全干净的路由 | 19 |
| 去重后的残留组 | 134 |
| 页面 × 元素残留条目 | 256 |
| 影响页面最多的残留 | 侧边栏 `.menu-item-title.active` 高亮背景(68 页) |
| 次多 | `.empty-title` 深色文字(16 页) |
无残留的 19 个路由:`/console/403`、Shop 插件全部 11 个页面、`/console/app-store/privacy-policy``/console/posts/snapshots``/console/single-pages/snapshots``/console/users/auth-providers``/console/users/roles`
## 四、根因分析
### 根因 1(P0):插件 CSS 加载顺序在最前,同特异性规则被 Halo 核心样式覆盖
**证据**(来自 `probe_conflict.py`):
- 插件 `bundle.css``document.styleSheets` 的第 0 张表;
- Halo 核心样式 `process-bar-DsZ2lvXx.css` 是第 9 张表,加载更晚;
- 双方存在同特异性规则,CSS 级联规则让"后加载者"胜出:
| 规则 | 特异性 | 结果 |
|------|--------|------|
| Halo`.description-item-wrapper .description-item__label { color: rgb(17 24 39) }` | (0,2,0) | 胜出 |
| 插件:`[data-halo-theme="dark"] .description-item__label { color: var(--halo-text-secondary) }` | (0,2,0) | 被覆盖 |
**受影响页面**`/console/overview``/console/schedule-calendar``/console/theme` 的详情描述项(名称、Halo、站点地址等文字仍是深色)。
**修复建议**
- 对这类核心语义类统一加 `!important`
- 或把前缀从 `[data-halo-theme="dark"]` 提升为 `html[data-halo-theme="dark"]`,把特异性从 (0,2,0) 提高到 (0,2,1)。
推荐两者并用(提高特异性 + `!important` 双保险),因为 Halo 核心样式后续仍可能继续调整。
### 根因 2(P0):UnoCSS 哈希类前缀已变化,现有兜底规则失效
**证据**
- 大量残留元素的类名是 `uno-*` 前缀(如 `uno-ga61as``uno-529526``uno-b60d0h`);
- `plugin-pages.css` 中的兜底规则只覆盖 `[class*="i-"]`,这是旧版 UnoCSS 的哈希前缀;
- 部署 CSS 探针确认:`menu-item-title``empty-title``alert-wrapper` 三个关键字在暗色规则中完全不存在。
**受影响页面**AI Foundation 全家桶(每页 3–24 处)、数据迁移、装备/关注/照片/时间线/投票的卡片头部"新增"栏、SummaraidGPT 等。
**修复建议**
- 新增 `[class*="uno-"]` 的兜底覆盖(背景、文字、边框三件套),并加 `!important`
- 保留 `i-*` 规则,因为扫描中仍有少量 `i-*` 哈希(如 `.i-p4hnaq`)在真实页面出现,两个前缀并存。
### 根因 3(P0):核心语义类缺覆盖
以下类在部署 CSS 中**完全没有暗色规则**,属于新增覆盖而非覆盖失效:
| 类名 | 残留内容 | 影响页面 |
|------|----------|----------|
| `.menu-item-title.active` | 高亮背景 `rgb(243,244,246)` | 68 页 |
| `.empty-title` | 文字 `rgb(17,24,39)` | 16 页 |
| `.alert-wrapper` / `.alert-default` | 背景 `rgb(249,250,251)` | 3 页(概览、许可证、导入) |
| `.description-item__label/content` | 文字 `rgb(17,24,39)` | 3 页(同特异性失效,见根因 1) |
**修复建议**
- 侧边栏高亮:覆盖 `.menu-item-title.active`(含 `:hover`),用 `--halo-menu-item-active` 变量;
- 空状态:覆盖 `.empty-title`,用 `--halo-text-secondary`
- 提示条:覆盖 `.alert-wrapper` 及各变体的背景/边框/文字。
### 根因 4(P1):第三方插件页面几乎未覆盖
| 插件/页面 | 残留类名 | 说明 |
|-----------|----------|------|
| AstraHub + 心愿便签 | `.ah-card``.ah-topbar``.ah-float-nav``.ah-topbar-brand` | 两插件共用同一套 `ah-*` UI,覆盖一次可同时生效 |
| RSS 订阅 | `.subscription-panel``.feed-toolbar``.feed-status-tabs``.feed-stream``.feed-brief__title` | 整个页面几乎整片浅色 |
| 私密文章 | `.focus-card``.overview-card``.list-card``.empty-state` | 半透明白背景叠在深色上,文字也是深色 |
| AI 评论自动处理 | `.setting-panel``.form-row``.sidebar-card``.tabs-wrap``.list-col``.reply-card` | 设置页和日志页整片浅色 |
| 数据工坊 | `.modal-content``.uno-*` 卡片 | 弹窗与主内容区均残留 |
| 代码注入器 | `.uno-*` 侧栏/编辑区 | 整页浅色 |
| Meilisearch 概览 | `.uno-*` | 卡片与标题残留 |
| 日志查看器 | `.monaco-editor``.margin``.lines-content` | **Monaco Editor 自带独立主题系统**,仅靠 CSS 覆盖很难稳定 |
| 导入/存储工具 | `.uno-*` | 提示卡片、分页栏残留 |
**修复建议**
- `ah-*``feed-*``focus-card/overview-card/list-card``setting-panel/form-row/sidebar-card` 等语义类按插件页面补 `!important` 规则;
- Monaco 不要硬啃 CSS,优先在 JS 里监听主题切换并调用 `monaco.editor.setTheme('vs-dark')`,或加载官方 dark 主题 CSS;
- 每个插件补完后再跑一次 `scan_dark.py` 验证零残留。
### 根因 5(P2):历史遗留规则与自相矛盾的选择器
- `components.css` 中大量 `.v-*`Vuetify 类)在 Halo 2.25 的真实 DOM 中不存在,属无效规则(CLAUDE.md 已记录);
- `[class*="tag-"]``[class*="modal"]` 等宽泛匹配容易误伤,建议逐步收紧;
- `utilities.css``halo-core.css` 对链接色的规则互相覆盖,最终生效结果不明确;
- `halo-core.css``html, body` 编译后为 `[data-halo-theme="dark"] html`,该选择器**永远不匹配**(html 元素不会是其自身的后代),根背景兜底实际只靠 `body` 一条,页面在特殊滚动场景下仍有露白风险。
## 五、修复优先级清单
### P0(一次重构后全站收益最大)
1. 全局暗色规则前缀从 `[data-halo-theme="dark"]` 升级为 `html[data-halo-theme="dark"]`
2. 核心语义类(`.page-header``.card-wrapper``.description-item-*``.table` 等)加 `!important`
3. 新增 `.menu-item-title.active``.empty-title``.alert-wrapper` 覆盖;
4. 新增 `[class*="uno-"]` 兜底三件套;
5. 修正根背景规则,让 `html` 本身也参与暗色。
### P1(按插件逐个补齐并复扫)
6. `ah-*``feed-*`、私密文章、AI 评论插件语义类覆盖;
7. Monaco 主题切换接入;
8. 数据工坊、代码注入器、Meilisearch、导入/存储工具等 `uno-*` 页面复查。
### P2(清理)
9. 删除失效的 Vuetify 类规则,收敛宽泛匹配;
10. 统一链接色规则,消除重复/冲突。
## 六、完整残留明细
`workplace/aggregate.txt`(134 组,含影响页面列表),原始数据见 `workplace/scan-results.json`