Skip to content

用户界面系统 ​

本文引用的源码文件

本文引用的文件

更新摘要 ​

变更内容

  • 新增第三个统计桶 .subtask-stat-other 的样式定义和可访问性支持
  • 增强子任务统计系统的三态分类(成功/失败/其他)
  • 完善 WCAG AA 对比度合规性验证
  • 扩展国际化支持以包含第三个统计桶的翻译

目录 ​

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与可访问性
  8. 故障排查指南
  9. 结论
  10. 附录:开发示例

引言 ​

本文件面向 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

图表来源

章节来源

核心组件 ​

  • 主题 Token 与运行时:通过 data-theme 在 <html> 上切换亮/暗;所有颜色使用语义化 Token,避免硬编码色值。
  • 国际化运行时:提供 t(key, params)、setLanguage、initI18n、applyI18n,支持 DOM 属性驱动文案填充。
  • 子任务统计系统:三态分类(✓ 成功 / ✗ 失败 / ⊘ 其他),支持点击过滤和 WCAG AA 对比度合规。
  • 侧边栏与配置页:分别由 side_panel/index.js 与 options/index.js 初始化主题与语言,并订阅变更以刷新 UI。
  • 后台入口:注册翻译、处理快捷键与侧边栏可见性,同时作为扩展消息中枢。

更新 新增了子任务统计系统的第三态支持,用于处理已取消、终止时未完成等边缘情况,确保统计完整性。

章节来源

架构总览 ​

主题与语言是贯穿各界面的横切关注点。主题通过 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

图表来源

章节来源

主题审计与对比度门禁 ​

  • 动态审计(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() 刷新文案

图表来源

章节来源

响应式设计实现 ​

  • 侧边栏窄屏适配:在 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 合规"]

图表来源

章节来源

界面组件开发指南 ​

  • 样式定制方法:
    • 所有颜色必须引用 theme.css 中的 Token,禁止硬编码色值。
    • 浮层与菜单使用 --elev-pop / --elev-float / --elev-surface 组合,确保暗色下阴影与描边一致。
    • 表单控件统一继承文字色,避免暗色残留黑字。
  • 交互模式最佳实践:
    • 下拉菜单与子菜单使用 show 类切换显隐,配合 aria-expanded 控制可访问性。
    • 长列表采用虚拟滚动与键盘焦点同步,确保方向键与 Tab 导航体验。
    • Toast 与模态框使用语义化 Token 控制背景与前景,确保对比度达标。

更新 新增统计桶开发规范:

  • 新的统计桶应使用独立的 CSS 类名,避免与其他统计桶共用颜色 Token
  • 确保所有统计数字都具备可访问性属性(data-node-filter、title)
  • 遵循 WCAG AA 对比度标准,特别是在浅色背景下的可读性

章节来源

依赖关系分析 ​

  • 主题依赖链: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

图表来源

章节来源

性能与可访问性 ​

  • 性能:
    • 主题切换仅在 resolved 变化时通知订阅者,避免重复渲染。
    • 语言切换通过 subscribe 批量刷新,减少 DOM 操作次数。
    • 侧边栏长列表使用虚拟滚动,降低重排重绘开销。
  • 可访问性:
    • ARIA 属性与键盘导航确保屏幕阅读器与键盘用户可用。
    • 对比度审计确保暗色下文本与图形可读性符合 WCAG AA。
    • 第三个统计桶使用合适的颜色 Token,确保在所有主题下的可读性。

更新 第三个统计桶的可访问性已通过单元测试验证,确保在不同主题和背景下都能满足 WCAG AA 标准。

章节来源

故障排查指南 ​

  • 主题未切换:
    • 检查 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" 属性是否存在。

更新 新增了子任务统计相关的故障排查指南。

章节来源

结论 ​

本项目通过 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 确保合规。

章节来源

翻译维护示例 ​

  • 新增文案:在 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',

章节来源

新增统计桶开发示例 ​

新增章节 开发新的统计桶类型时,请遵循以下规范:

  1. CSS 样式定义:

    css
    .subtask-stat-newtype {
      color: var(--your-token);
    }
  2. HTML 渲染模板:

    javascript
    ${newTypeCount > 0 ? `<span class="subtask-stat-newtype${filter === 'newtype' ? ' subtask-stat-active' : ''}" data-node-filter="newtype" title="${t('chatMsg.newTypeHint')}">符号${newTypeCount}</span>` : ''}
  3. 国际化支持:

    javascript
    // 在 chat-manager.js 中注册翻译
    registerTranslations('zh', {
      chatMsg: {
        newTypeHint: '新类型节点的说明文案',
      }
    });
  4. 可访问性验证:

    • 确保颜色 Token 满足 WCAG AA 对比度要求
    • 添加适当的 data-node-filter 属性
    • 提供清晰的 title 文本说明

章节来源