主题
用户界面系统
本文引用的源码文件
本文引用的文件
- src/shared/theme.css
- src/shared/theme.js
- scripts/theme-dark-audit.mjs
- scripts/theme-contrast-check.py
- src/shared/i18n.js
- src/shared/locales/zh.js
- src/shared/locales/en.js
- _locales/en/messages.json
- _locales/zh_CN/messages.json
- src/side_panel/styles.css
- src/side_panel/index.js
- src/side_panel/chat-manager.js
- src/options/index.js
- src/background/index.js
- test/unit/subtask-node-stats.unit.test.js
更新摘要
变更内容
- 新增第三个统计桶
.subtask-stat-other的样式定义和可访问性支持 - 增强子任务统计系统的三态分类(成功/失败/其他)
- 完善 WCAG AA 对比度合规性验证
- 扩展国际化支持以包含第三个统计桶的翻译
目录
引言
本文件面向 UI 主题、国际化、响应式与可访问性,以及侧边栏与配置页的界面实现。文档围绕以下目标展开:
- 主题系统:CSS 变量 Token 体系、亮/暗/跟随系统三态切换、对比度审计与"白斑"检测。
- 国际化:扩展端 chrome 消息与运行时 i18n 双通道、多语言字典组织、运行时语言切换与跨环境同步。
- 响应式:移动端适配、屏幕尺寸断点与布局优化。
- 可访问性:ARIA 属性、键盘导航、屏幕阅读器兼容与色彩对比度合规。
- 组件开发指南:样式定制方法、交互模式最佳实践,并给出主题开发与翻译维护的具体示例。
更新 新增了第三个统计桶 .subtask-stat-other 的实现,用于处理已取消/未完成的子任务节点,确保完整的三态统计分类和 WCAG AA 可访问性合规。
项目结构
UI 相关代码主要分布在以下位置:
- 主题 Token 与运行时:
src/shared/theme.css、src/shared/theme.js - 国际化:
src/shared/i18n.js、src/shared/locales/*.js、_locales/*/messages.json - 侧边栏界面:
src/side_panel/styles.css、src/side_panel/index.js、src/side_panel/chat-manager.js - 选项(配置)页:
src/options/index.js - 后台 Service Worker:
src/background/index.js - 主题审计工具:
scripts/theme-dark-audit.mjs、scripts/theme-contrast-check.py
graph TB subgraph "共享层" T["theme.css<br/>Token 定义"] TJ["theme.js<br/>主题读写与同步"] I18N["i18n.js<br/>运行时翻译"] LO_ZH["locales/zh.js"] LO_EN["locales/en.js"] CHROME_EN["_locales/en/messages.json"] CHROME_ZH["_locales/zh_CN/messages.json"] end subgraph "界面层" SP_CSS["side_panel/styles.css"] SP_JS["side_panel/index.js"] CHAT_JS["side_panel/chat-manager.js<br/>子任务统计系统"] OPT_JS["options/index.js"] BG_JS["background/index.js"] end subgraph "质量门禁" AUDIT["theme-dark-audit.mjs"] CONTRAST["theme-contrast-check.py"] TEST["subtask-node-stats.unit.test.js<br/>WCAG 对比度测试"] end T --> SP_CSS TJ --> SP_JS TJ --> OPT_JS I18N --> SP_JS I18N --> OPT_JS CHAT_JS --> SP_CSS CHAT_JS --> I18N LO_ZH --> I18N LO_EN --> I18N CHROME_EN --> BG_JS CHROME_ZH --> BG_JS T --> AUDIT T --> CONTRAST SP_CSS --> TEST
图表来源
- src/shared/theme.css#L1-L289
- src/shared/theme.js#L1-L90
- src/shared/i18n.js#L1-L251
- src/side_panel/styles.css#L4290-L4320
- src/side_panel/chat-manager.js#L3620-L3650
- test/unit/subtask-node-stats.unit.test.js#L130-L190
章节来源
- src/shared/theme.css#L1-L289
- src/shared/theme.js#L1-L90
- src/shared/i18n.js#L1-L251
- src/side_panel/styles.css#L1-L800
- src/side_panel/chat-manager.js#L1-L800
- src/side_panel/index.js#L1-L800
- src/options/index.js#L1-L800
- src/background/index.js#L1-L800
- scripts/theme-dark-audit.mjs#L1-L257
- scripts/theme-contrast-check.py#L1-L114
核心组件
- 主题 Token 与运行时:通过
data-theme在<html>上切换亮/暗;所有颜色使用语义化 Token,避免硬编码色值。 - 国际化运行时:提供
t(key, params)、setLanguage、initI18n、applyI18n,支持 DOM 属性驱动文案填充。 - 子任务统计系统:三态分类(✓ 成功 / ✗ 失败 / ⊘ 其他),支持点击过滤和 WCAG AA 对比度合规。
- 侧边栏与配置页:分别由
side_panel/index.js与options/index.js初始化主题与语言,并订阅变更以刷新 UI。 - 后台入口:注册翻译、处理快捷键与侧边栏可见性,同时作为扩展消息中枢。
更新 新增了子任务统计系统的第三态支持,用于处理已取消、终止时未完成等边缘情况,确保统计完整性。
章节来源
- src/shared/theme.css#L1-L289
- src/shared/theme.js#L1-L90
- src/shared/i18n.js#L1-L251
- src/side_panel/chat-manager.js#L3620-L3650
- src/side_panel/index.js#L1-L800
- src/options/index.js#L1-L800
- src/background/index.js#L1-L800
架构总览
主题与语言是贯穿各界面的横切关注点。主题通过 theme.js 写入 data-theme,CSS 根据该属性切换 Token 值;语言通过 i18n.js 持久化到 chrome.storage.local,并在多个页面间通过 storage.onChanged 同步。
sequenceDiagram participant User as "用户" participant Options as "options/index.js" participant Theme as "shared/theme.js" participant CSS as "shared/theme.css" participant Storage as "chrome.storage.local" User->>Options : 选择主题偏好 Options->>Theme : setTheme(pref) Theme->>Storage : 写入 appTheme Theme->>CSS : 设置 <html data-theme> Note over Theme,CSS : 所有组件通过 var(--*) 自动生效
图表来源
章节来源
详细组件分析
主题系统与 Token 体系
- Token 分层:表面、文本、品牌、边框分隔、状态、Toast、蒙层阴影等,均使用语义命名。
- 亮/暗双主题:
:root定义亮色值,html[data-theme="dark"]覆盖暗色值,确保 WCAG AA 对比度。 - 固定不翻转 Token:如纸面语义、终端代码块背景在两主题下保持一致。
- 原生控件统一:checkbox/radio/range/color/progress 使用品牌强调色。
- Markdown 暗色覆盖:针对第三方库写死亮色的类进行暗色回退。
flowchart TD
Start(["应用启动"]) --> ReadPref["读取 appTheme 偏好"]
ReadPref --> Resolve{"是否为 system?"}
Resolve --> |是| DetectOS["matchMedia('prefers-color-scheme: dark')"]
Resolve --> |否| UsePref["直接使用 light/dark"]
DetectOS --> Apply["apply(resolved)"]
UsePref --> Apply
Apply --> SetAttr["documentElement.setAttribute('data-theme', resolved)"]
SetAttr --> Notify["通知订阅者刷新 UI"]
图表来源
章节来源
子任务统计系统 - 三态分类增强
新增功能 子任务统计系统现已支持三个独立的统计桶:
- 成功桶 (✓):
subtask-stat-done类,绿色主题,表示成功完成的子任务 - 失败桶 (✗):
subtask-stat-fail类,红色主题,表示失败的子任务 - 其他桶 (⊘):
subtask-stat-other类,灰色主题,表示已取消、终止时未完成等边缘情况
样式实现
第三个统计桶使用独立的 CSS 类和颜色主题:
css
.subtask-stat-other {
color: var(--text-secondary);
}该样式确保与其他两个统计桶有明确的视觉区分,同时保持 WCAG AA 对比度要求。
渲染逻辑
在聊天管理器中,第三个统计桶的渲染逻辑如下:
javascript
${otherNodes > 0 ? `<span class="subtask-stat-other${progressEl._nodeFilter === 'other' ? ' subtask-stat-active' : ''}" data-node-filter="other" title="${t('chatMsg.subtaskStatOtherHint')}">⊘${otherNodes}</span>` : ''}可访问性支持
- 每个统计数字都带有
data-node-filter属性,支持点击过滤 - 悬停和激活状态都有相应的视觉反馈
- 标题文本提供清晰的说明信息
flowchart TD SubtaskStats["子任务统计"] --> Success["✓ 成功节点"] SubtaskStats --> Failed["✗ 失败节点"] SubtaskStats --> Other["⊘ 其他节点"] Success --> Green["绿色主题<br/>--success-strong"] Failed --> Red["红色主题<br/>--danger-strong"] Other --> Gray["灰色主题<br/>--text-secondary"] Green --> Filterable["可点击过滤"] Red --> Filterable Gray --> Filterable
图表来源
章节来源
- src/side_panel/styles.css#L4290-L4320
- src/side_panel/chat-manager.js#L3620-L3650
- test/unit/subtask-node-stats.unit.test.js#L130-L190
主题审计与对比度门禁
- 动态审计(Playwright):加载 dist 构建产物,将侧边栏与配置页切换到暗色,遍历已渲染元素计算前景/背景对比度,检测"白斑"(近纯白大块背景),输出违规清单。
- 静态审计(Python):解析 theme.css 中暗色 Token,按文本 4.5:1、图形 3:1 阈值校验,装饰性分隔仅 INFO 提示。
flowchart TD
Build["npm run build:silent"] --> Launch["Playwright 启动浏览器加载 dist"]
Launch --> Dark["写入 appTheme=dark 并等待 data-theme='dark'"]
Dark --> Audit["注入审计函数遍历 DOM 计算对比度"]
Audit --> Report["汇总违规与白斑,非空则退出码 1"]
Contrast["theme-contrast-check.py 解析 theme.css 暗色 Token"] --> Check["按 WCAG 阈值计算对比度"]
Check --> Result{"是否达标"}
Result --> |否| Fail["[AA FAIL] 输出失败项"]
Result --> |是| Pass["通过"]
图表来源
章节来源
国际化支持与运行时切换
- 运行时 i18n:
i18n.js提供t(key, params)、setLanguage、subscribe、registerTranslations、initI18n、applyI18n。 - 语言包组织:
locales/zh.js、locales/en.js按模块分组,key 用点分访问;侧边栏与后台脚本可按需追加翻译。 - Chrome 扩展消息:
_locales/*/messages.json用于扩展名称、描述与命令文案,由chrome.i18n提供。 - 运行时语言切换:
options/index.js初始化语言选择器,调用setLanguage并触发applyI18n()刷新 DOM。
更新 新增了第三个统计桶的国际化支持,包括中文和英文的提示文案。
sequenceDiagram participant Opt as "options/index.js" participant I18N as "shared/i18n.js" participant DOM as "DOM" participant Store as "chrome.storage.local" Opt->>I18N : initI18n() I18N->>Store : 读取 language 偏好 I18N-->>Opt : 返回当前语言 Opt->>DOM : applyI18n() 填充 data-i18n* 元素 Opt->>I18N : setLanguage(code) I18N->>Store : 持久化 language I18N-->>Opt : 触发 subscribe 回调 Opt->>DOM : 再次 applyI18n() 刷新文案
图表来源
章节来源
- src/shared/i18n.js#L1-L251
- src/shared/locales/zh.js#L1-L800
- src/shared/locales/en.js#L1-L800
- _locales/en/messages.json#L1-L12
- _locales/zh_CN/messages.json#L1-L12
- src/options/index.js#L103-L153
响应式设计实现
- 侧边栏窄屏适配:在
max-width: 420px下隐藏标题文字与助手名,仅保留图标;输入框工具栏与模型设置按钮也做精简。 - 更窄断点:
max-width: 320px下隐藏更多元素,保证紧凑可用。 - 滚动条与浮层:自定义滚动条宽度与颜色,浮层使用 Token 控制阴影与边框。
flowchart TD
Viewport["视口宽度变化"] --> Breakpoint{"<= 420px?"}
Breakpoint --> |是| CompactHeader["隐藏标题文字/助手名"]
Breakpoint --> |否| NormalHeader["正常显示"]
CompactHeader --> Narrower{"<= 320px?"}
Narrower --> |是| HideMore["隐藏更多元素"]
Narrower --> |否| KeepCompact["保持紧凑布局"]
图表来源
章节来源
可访问性支持
- ARIA 属性:
applyI18n支持data-i18n-aria-label,将翻译文案写入aria-label,提升屏幕阅读器可读性。 - 键盘导航:侧边栏确认弹窗默认聚焦确认按钮,支持 Enter 确认、Esc 取消;工作区面板虚拟滚动时更新焦点视觉。
- 色彩对比度:暗色 Token 经过静态与动态双重审计,确保正文与状态文本达到 WCAG AA。
更新 第三个统计桶 .subtask-stat-other 专门选择了 --text-secondary 而非 --text-tertiary,以确保在浅色背景下满足 WCAG AA 对比度要求(4.5:1)。
flowchart TD
Init["初始化 i18n"] --> Scan["扫描 data-i18n-aria-label"]
Scan --> SetAria["setAttribute('aria-label', t(key))"]
Focus["键盘事件"] --> FocusBtn["自动聚焦确认按钮"]
FocusBtn --> Keys{"Enter/Esc"}
Keys --> |Enter| Confirm["执行确认"]
Keys --> |Esc| Cancel["执行取消"]
Accessibility["可访问性检查"] --> Contrast["对比度验证"]
Contrast --> WCAG["WCAG AA 合规"]
图表来源
- src/shared/i18n.js#L214-L238
- src/side_panel/index.js#L182-L223
- src/side_panel/workspace-panel.js#L1603-L1629
章节来源
- src/shared/i18n.js#L214-L238
- src/side_panel/index.js#L182-L223
- src/side_panel/workspace-panel.js#L1603-L1629
界面组件开发指南
- 样式定制方法:
- 所有颜色必须引用
theme.css中的 Token,禁止硬编码色值。 - 浮层与菜单使用
--elev-pop/--elev-float/--elev-surface组合,确保暗色下阴影与描边一致。 - 表单控件统一继承文字色,避免暗色残留黑字。
- 所有颜色必须引用
- 交互模式最佳实践:
- 下拉菜单与子菜单使用
show类切换显隐,配合aria-expanded控制可访问性。 - 长列表采用虚拟滚动与键盘焦点同步,确保方向键与 Tab 导航体验。
- Toast 与模态框使用语义化 Token 控制背景与前景,确保对比度达标。
- 下拉菜单与子菜单使用
更新 新增统计桶开发规范:
- 新的统计桶应使用独立的 CSS 类名,避免与其他统计桶共用颜色 Token
- 确保所有统计数字都具备可访问性属性(
data-node-filter、title) - 遵循 WCAG AA 对比度标准,特别是在浅色背景下的可读性
章节来源
- src/shared/theme.css#L106-L117
- src/side_panel/styles.css#L146-L233
- src/side_panel/workspace-panel.js#L1603-L1629
依赖关系分析
- 主题依赖链:
options/index.js→shared/theme.js→shared/theme.css - 语言依赖链:
options/index.js→shared/i18n.js→locales/*.js - 侧边栏依赖链:
side_panel/index.js→shared/theme.js、shared/i18n.js→side_panel/styles.css - 子任务统计依赖链:
chat-manager.js→styles.css、i18n.js - 后台入口:
background/index.js注册翻译、处理快捷键与侧边栏可见性,并与 storage 同步。
graph LR Options["options/index.js"] --> ThemeJS["shared/theme.js"] Options --> I18NJS["shared/i18n.js"] SidePanel["side_panel/index.js"] --> ThemeJS SidePanel --> I18NJS ChatManager["side_panel/chat-manager.js"] --> StylesCSS["side_panel/styles.css"] ChatManager --> I18NJS ThemeJS --> ThemeCSS["shared/theme.css"] I18NJS --> Locales["locales/*.js"] Background["background/index.js"] --> I18NJS
图表来源
- src/options/index.js#L1-L800
- src/side_panel/index.js#L1-L800
- src/side_panel/chat-manager.js#L1-L800
- src/background/index.js#L1-L800
- src/shared/theme.js#L1-L90
- src/shared/i18n.js#L1-L251
- src/shared/theme.css#L1-L289
章节来源
- src/options/index.js#L1-L800
- src/side_panel/index.js#L1-L800
- src/side_panel/chat-manager.js#L1-L800
- src/background/index.js#L1-L800
- src/shared/theme.js#L1-L90
- src/shared/i18n.js#L1-L251
- src/shared/theme.css#L1-L289
性能与可访问性
- 性能:
- 主题切换仅在
resolved变化时通知订阅者,避免重复渲染。 - 语言切换通过
subscribe批量刷新,减少 DOM 操作次数。 - 侧边栏长列表使用虚拟滚动,降低重排重绘开销。
- 主题切换仅在
- 可访问性:
- ARIA 属性与键盘导航确保屏幕阅读器与键盘用户可用。
- 对比度审计确保暗色下文本与图形可读性符合 WCAG AA。
- 第三个统计桶使用合适的颜色 Token,确保在所有主题下的可读性。
更新 第三个统计桶的可访问性已通过单元测试验证,确保在不同主题和背景下都能满足 WCAG AA 标准。
章节来源
- src/shared/theme.js#L18-L37
- src/shared/i18n.js#L111-L135
- src/side_panel/workspace-panel.js#L1603-L1629
- scripts/theme-dark-audit.mjs#L1-L257
- test/unit/subtask-node-stats.unit.test.js#L151-L190
故障排查指南
- 主题未切换:
- 检查
appTheme是否正确写入 storage,data-theme是否设置为light或dark。 - 确认
theme.js的apply函数是否被调用且无异常。
- 检查
- 语言未刷新:
- 确认
initI18n已调用,applyI18n是否在语言变更后重新执行。 - 检查
data-i18n*属性是否正确绑定。
- 确认
- 对比度不达标:
- 运行
scripts/theme-contrast-check.py检查 Token 对比度。 - 运行
scripts/theme-dark-audit.mjs检查实际渲染元素的对比度与"白斑"。
- 运行
- 子任务统计显示异常:
- 检查第三个统计桶
.subtask-stat-other是否正确渲染。 - 确认
subtaskStatOtherHint翻译是否已注册。 - 验证统计数字的
data-node-filter="other"属性是否存在。
- 检查第三个统计桶
更新 新增了子任务统计相关的故障排查指南。
章节来源
- src/shared/theme.js#L54-L89
- src/shared/i18n.js#L168-L207
- scripts/theme-contrast-check.py#L1-L114
- scripts/theme-dark-audit.mjs#L1-L257
结论
本项目通过 Token 化的主题系统与完善的对比度审计,确保了亮/暗主题的视觉一致性与可访问性;通过运行时 i18n 与 Chrome 扩展消息的双通道,实现了多语言支持与跨环境同步;通过响应式断点与键盘导航,提升了移动端与无障碍体验。新增的第三个统计桶 .subtask-stat-other 进一步完善了子任务统计系统,确保所有类型的子任务都能得到准确分类和展示,同时保持了 WCAG AA 可访问性标准。
建议在后续开发中继续遵循 Token 化与 ARIA 规范,并使用审计工具保障质量。
附录:开发示例
主题开发示例
- 新增 Token:在
theme.css的:root与html[data-theme="dark"]中成对定义,确保暗色对比度达标。 - 使用 Token:在组件样式中引用
var(--token-name),避免硬编码色值。 - 验证:运行
scripts/theme-contrast-check.py与scripts/theme-dark-audit.mjs确保合规。
章节来源
- src/shared/theme.css#L1-L289
- scripts/theme-contrast-check.py#L1-L114
- scripts/theme-dark-audit.mjs#L1-L257
翻译维护示例
- 新增文案:在
locales/zh.js与locales/en.js中添加对应 key,使用点分命名。 - 运行时使用:在组件中调用
t('module.key', { param }),并通过applyI18n()刷新 DOM。 - 扩展消息:在
_locales/*/messages.json中添加扩展名称、描述与命令文案。
更新 新增了第三个统计桶的翻译示例:
javascript
// 中文翻译
subtaskStatOtherHint: '已取消 / 未完成节点(用户拒绝确认、任务终止时仍在执行等),点击过滤',
// 英文翻译
subtaskStatOtherHint: 'Cancelled / unfinished nodes (denied confirmations, still running when the task ended). Click to filter',章节来源
- src/shared/locales/zh.js#L1-L800
- src/shared/locales/en.js#L1-L800
- _locales/en/messages.json#L1-L12
- _locales/zh_CN/messages.json#L1-L12
- src/shared/i18n.js#L214-L238
新增统计桶开发示例
新增章节 开发新的统计桶类型时,请遵循以下规范:
CSS 样式定义:
css.subtask-stat-newtype { color: var(--your-token); }HTML 渲染模板:
javascript${newTypeCount > 0 ? `<span class="subtask-stat-newtype${filter === 'newtype' ? ' subtask-stat-active' : ''}" data-node-filter="newtype" title="${t('chatMsg.newTypeHint')}">符号${newTypeCount}</span>` : ''}国际化支持:
javascript// 在 chat-manager.js 中注册翻译 registerTranslations('zh', { chatMsg: { newTypeHint: '新类型节点的说明文案', } });可访问性验证:
- 确保颜色 Token 满足 WCAG AA 对比度要求
- 添加适当的
data-node-filter属性 - 提供清晰的
title文本说明
章节来源