30 KiB
CORE-23 键盘、焦点与可访问名称
从 faaa3e8c 接续,开始时工作区干净。任务 doing,覆盖主要控件、设置树/范围输入、选择列表、模式退出及字幕可用性;本页随实现补充证据,不代表全任务已完成。
已核实的问题与边界
BASE-DOM-01 已记录主要控件没有 Tab 入口。进一步源码审查发现:播放/音量由两个互斥显示的图标处理点击,直接让图标可聚焦会在切换时隐藏焦点;控件自动隐藏仅检查鼠标/播放/输入状态;设置按钮/树和质量 selector 依赖点击及 hover,未实现键盘操作。已有 tooltip 提供 aria-label,应复用当前语言文本。
保留现有 DOM 节点和类名、指针点击事件及公开回调形状。新增内部按键归属记录,避免键盘激活同时触发全局 Space 快捷键;不把所有 defaultPrevented 事件一概排除,以免改变旧自定义热键行为。内部监听器随条目/实例 scope 释放,更新/移除/销毁后不得继续响应。
实现依据:WAI Button Pattern、Slider Pattern、Keyboard Interface。采用 Enter/Space 激活、可见焦点及范围键盘语义;角色和属性必须与真实交互一起验证。这些模式不等于整个产品已通过屏幕阅读器或 WCAG 认证。
分步实施与验收
- 固定实际 Tab 缺口,建立可清理的按钮按键处理,接入稳定的主控件节点与已有点击路径。
- 补齐进度/音量范围操作、选择列表与设置树的进入/返回/关闭和焦点恢复;保护输入和已有快捷键。
- 检查全屏/mini 等模式退出、动态更新/移除、跨实例、SSR、名称变化及字幕可用性。
- 严格类型、风险用例、安装包及三浏览器完整回归;更新架构、风险、任务状态后独立提交。
CORE-23 已完成。按钮、滑块、选择列表、设置树、动态控件、mini、信息面板、锁定层和默认菜单均已实现并取得阶段证据;模式退出、SSR/字幕及设置入口失效的补充检查通过,新安装包现代/legacy 全量验收通过,BASE-DOM-01 已关闭。下列各阶段记录保留当时的状态与证据,最终结论见末尾验收表。
按钮与焦点第一阶段
新增 accessibility/button、keyboard、focus 三个 TS 模块。按键标记保留原事件身份,Enter 按下/Space 松开复用旧 click 路径,阻止重复按键、失焦或销毁后的晚到操作;旧 Hotkey 的普通 keydown 观察和无关 defaultPrevented 策略保留。原生 button/summary/ARIA button/switch 的激活键及链接 Enter 不被播放器劫持,KeyK 等其他自定义快捷键仍工作。
已接入主要按钮和自定义 option.click 控件。播放使用稳定 wrapper;音量保留原图标/面板层级,在互斥图标切换时只移交原有焦点;设置按钮增加 aria-expanded。原有 tooltip/i18n 提供名称,没有新增英文专用翻译键。键盘焦点更新已有 isFocus/isInput,不增加指针 focus/blur 公开事件次数。新增焦点样式和 art-keyboard-focus 类。
首次真实 Chromium 运行固定 Tab 缺口:发布基线通过“控件被跳过”的已知行为断言,修改前候选在目标可达断言失败。首轮三浏览器有三个 Firefox 用例失败,精确探针确认原生 video 本身先接受 Tab;修正测试保留该原生入口,再验证控制按钮,未删除或跳过失败测试。随后新增鼠标用例复现本轮最初 :focus-within/任意焦点策略会让控制栏常驻;改为独立输入方式与资源归属,保留鼠标自动隐藏。该回归及修正证据保留在阶段记录中。
当前 accessibility/hotkey 三浏览器共 69 项通过(含 18 项按钮/焦点/指针用例),25 项按钮/焦点/Hotkey/组件资源单元通过。最终本阶段 CI 456 项(425 单元、6 工程、25 基线)、232 个生产 TS 文件严格检查通过。阶段证据 保存当前源/用例指纹、三组失败复现和最终通过结果。核心源已有改动,当前浏览器使用 Vite 源码构建,不能作为最新 npm/legacy 安装产物的验收;完整包构建和全量矩阵留最终任务收尾。
下一步继续进度/音量 slider、selector、设置树与 Escape/焦点恢复、动态更新/跨实例/SSR/字幕检查。CORE-23 和 BASE-DOM-01 仍开放,未创建任务完成 commit;上一完成任务仍为 faaa3e8c。无新依赖、版本调整、push/publish/tag/merge。
进度与音量滑块阶段
新增 accessibility/slider.ts 与 control/progress/keyboard.ts,分别负责通用范围键盘/ARIA 状态和播放器进度绑定。原 progress/interactions.ts 保持鼠标职责。方向键使用 SEEK_STEP 或 VOLUME_STEP;PageUp/PageDown 使用十倍步长,Home/End 到达端点,重复按键可连续调整。无有效时长/范围时禁用操作并认领按键,避免回落到播放器全局快捷键;ARIA 数值随实际媒体时间、时长、音量更新。
进度按键保持 setBar 在 seek 之前,第三个指针事件参数省略,不把 KeyboardEvent 混入旧 MouseEvent/TouchEvent 类型。回调切源、移除、销毁或触发更新的嵌套按键后,旧 seek 不得继续。音量键先取消静音再设置音量,muted 回调销毁或触发新操作会取消旧写入。音量范围位于原图标按钮之外,键盘聚焦静音图标时展开面板,Tab 继续进入滑块;鼠标拖动和原图标节点保留。
增加 Progress 可访问名称及十二个已有语言字典的翻译。public/i18n.ts 使用可选 Progress 字段,保持完整旧字典可赋值;通过 build:types/build:ts 同步生成包声明与 Monaco 声明,未手工修改生成文件。无新增依赖。
验证与实际修正:
- 新增七项单元用例,与原进度拖动测试合计 17 项通过:步长/重复/上下限、无效范围、修饰键/IME、scope 清理、事件顺序、切源与嵌套取消。
- 初次 Chromium 浏览器 9 通过、1 失败,复现 transition: all 将新 visibility 状态一起过渡,快速 Tab 跳过音量滑块。限制过渡为 opacity/transform 后,原用例通过,未通过等待或跳过来隐藏该问题。
- 首次三浏览器 122 通过、1 失败,WebKit 在请求 1 秒时实际落点约 1.003 秒;测试改为验证实际时间的步长和 ARIA 同步,并保留请求值/事件顺序的精确检查。
- 首次完整 CI 检出 Monaco 声明遗漏新翻译键;build:ts 生成修复后完整 CI 463 项通过(432 单元、6 工程、25 基线),234 个生产 TS 文件严格检查通过。此处计数包括核心与 chapter。
- 最终 accessibility、hotkey、progress-quality 三浏览器 123 项全部通过,无失败、重试或跳过;其中滑块专项 12 项。实际版本 Chromium 153.0.8010.12、Firefox 155.0、WebKit 26.6。
滑块阶段证据 保存源文件、声明、用例、日志及报告指纹、浏览器构建来源、失败复现与最终结果。此前按钮阶段快照保持原样。本阶段浏览器仍为 Vite 源码构建,最新安装包/legacy 全量验收尚未执行。
下一步处理 selector 与设置树的键盘进入、选择、返回/Escape,以及动态焦点恢复、模式退出、跨实例/SSR/字幕检查。CORE-23 仍 doing,BASE-DOM-01 保持开放,总体 57 done、1 doing、156 todo;完成整个任务后再独立 commit。
选择列表阶段
control/selector-keyboard.ts 独立管理打开/关闭、焦点与键盘导航,旧 selector.ts 继续负责条目绑定、check 和异步 onSelect 结果归属。Tab 可到达当前值,Enter/Space/上下键打开并聚焦当前项;方向键、Home/End 和连续字符前缀仅移动焦点,不提前切换清晰度。Enter/Space 通过原 item.click 提交,保持回调 this、item/node 身份、click 参数及已有 generation/trackSelection 检查。Escape 关闭并返回当前值,Tab 离开不提交;关闭后再次 Escape 交回播放器。
普通列表采用 listbox/option 和 aria-selected,参考 WAI Listbox Pattern。含原生交互 HTML 的选项采用 group,保留按钮/输入框语义与编辑按键;group 不声明不匹配的 aria-haspopup。原生按钮作为当前值时直接承担展开入口,外层不新增嵌套 button 角色。check/异步 HTML 返回会刷新该绑定,仅在替换已聚焦的当前值子节点导致焦点回到 body 时恢复新入口;回调主动移交外部焦点时不抢回。调用方自定义交互内容仍需自行提供其可访问名称。
列表的可见性过渡只涉及 opacity/transform,避免重现滑块阶段的快速 Tab 问题。hover 与键盘打开状态分别维护,Escape 可在鼠标仍悬停时关闭列表。disabled 空列表不会报告 expanded=true。原来的 DOM 类名、selector getter 描述符、鼠标 click 路径和异步失效检查保留;无新增依赖或公开类型字段。
新增十项浏览器场景,覆盖实际 Tab/Enter/Space、typeahead、Escape 与 web fullscreen 的先后归属、空列表、鼠标 hover、异步竞态/移除、回调移交焦点及原生按钮/输入框。截图检查确认当前项高亮与独立焦点框同时可见。补充用例先在 Chromium 复现“关闭后的第二次 Escape 仍被吞掉”和“空列表悬停报告展开”两个失败,再统一用实际 expanded 条件修复;失败与最终验证均保留在阶段证据中。
最终 CI 463 项通过(432 单元、6 工程、25 基线),235 个生产 TS 文件严格检查通过;accessibility/hotkey/progress-quality/components 匹配到的三浏览器回归共 282 项通过(包括 prompt-components),无失败、重试或跳过,其中选择列表专项 30 项。选择列表阶段证据 保存当前源文件/用例、完整 CI、浏览器构建来源、三引擎截图指纹和修复前两个失败。浏览器仍使用 Vite 源码构建,尚非新安装包/legacy 全量验收。
下一步是设置树、模式退出、动态控件移除/替换焦点恢复,以及跨实例/SSR/字幕检查。任务与发布门槛保持开放:CORE-23 doing,BASE-DOM-01 open;57 done、1 doing、156 todo,完成全部任务验收后再独立 commit。无 push/publish/tag/merge。
设置面板、DOM 移动焦点与原生跳转校正阶段
设置模块新增 keyboard.ts、keyboard-item.ts、keyboard-focus.ts,分别负责面板导航和关闭、条目按键/语义、可见焦点目标及恢复。设置按钮 Enter/Space/ArrowDown 进入当前项,ArrowUp 直接进入最后一项;方向键/Home/End 在可操作项间移动,Right 进入子面板,Left/返回行回到原项,Escape 关闭并返回设置按钮。Tab 离开后关闭,不把原生 input 的编辑键交给播放器。原生按钮保留浏览器 click 路径,不新增嵌套按钮角色;开关同步 aria-checked,选择项同步 aria-current,范围输入使用条目文字作为名称。
面板与条目监听器遵循已有 scope 暂停/恢复/释放。更新成功、失败回滚及移除后,仅在原焦点因替换或隐藏丢失时恢复可见目标;回调已移交外部焦点则保留外部焦点。focusout 使用可释放的零延迟任务读取浏览器完成 Tab 后的实际焦点:首次微任务版本会在焦点暂处 body 时误关闭,已由真实用例复现修正。暂停中的条目既不能激活,也不能让方向键落入全局 seek。
accessibility/moved-focus.ts 保存 DOM 移动前实际聚焦节点。网页全屏进入/退出和失败恢复后,只有该节点仍连接且移动导致焦点落到 body 才恢复;销毁清理不聚焦,恢复时回调销毁会阻止后续 fullscreenWeb/resize 通知。真实用例先复现 FULLSCREEN_WEB_IN_BODY 丢失设置按钮焦点,再验证恢复和销毁边界。新增 Back、Settings 的十二语言翻译,公开字段可选,包和 Monaco 声明均用生成脚本同步。无新增依赖。
扩大回归时复现 WebKit 的原生跳转竞态:End 后立即 PageDown 已正确发出 seek(3),焦点未丢失,但结束事件随后将实际时间写回约 8 秒。重复五次探针中四次失败,不能归为帧级舍入。进度键盘复用 source/restore-position.ts 的一次有限校正;初次仍经过原 seek setter,校正使用 currentTime,不重复公开 seek 事件。操作 scope 同时归控件与 source 管理;新键盘操作、公开 currentTime 写入、切源、移除或销毁会取消旧校正。新增单元检查一次上限、事件顺序、手动覆盖及监听器释放;修正后五次 WebKit 探针全部通过。
验证记录:
- 完整 CI 468 项(437 单元、6 工程、25 基线)和 239 个生产 TS 严格检查通过。严格检查期间修正 cleanup 的 undefined 返回约定和 proxy 媒体宿主的内部结构类型,没有放宽到 any。
- 扩大 accessibility/setting/display-web/hotkey/progress-quality/source 三浏览器回归 477 项通过。该运行在上述内部类型修正前启动;之后对最终源码重跑设置、滑块、切源专项 57 项,全部通过。分别保存构建指纹,不能把两次当作同一构建的全量通过。
- 最终专项中途出现 56 通过、1 失败:旧测试 once(setBar) 会被媒体加载的 loaded/零进度更新提前消费,控件提前移除后按键实际走全局 Hotkey。测试改为匹配本次非零 played 更新后再移除,仍精确验证取消 seek;未添加等待、重试或跳过。修改后的两个浏览器文件额外 lint 通过。
- 七项设置场景跨三引擎共 21 项通过,覆盖真实 Enter/Space/Tab、树导航、switch/range、更新回滚、暂停和原生按钮。截图目标改为全屏移动后的实际 .art-video-player,避免只截到旧容器的局部视频。
设置阶段证据 保存失败报告、源文件/类型/测试指纹、CI、两轮浏览器构建及截图。此前三个阶段快照不改写。当前均为 Vite 源码构建;新安装包/legacy 全量验收、剩余动态控件焦点/模式退出/跨实例/SSR/字幕检查及最终提交仍未完成。CORE-23 doing,57 done、1 doing、156 todo;无版本调整、push/publish/tag/merge。
动态控件替换与移除焦点阶段
修改前在真实 Chromium 固定六个场景,其中五项失败:聚焦控件更新、移除、失败替换、聚焦 selector 子项替换及最后控件移除均会失去焦点;回调主动聚焦外部的既有场景通过。新增 component/focus.ts,Component.remove/update 在 finally 中结束焦点操作,仅对 control 生效;同一 update 的内部 remove 不先把焦点移到相邻项,保持单次最终恢复和旧 add/update 返回约定。
优先聚焦同名替换条目的可用节点,否则按原 DOM 顺序选择后续或前一个仍存活的控件。原生按钮作为实际目标,隐藏/禁用字段集/aria-disabled/inert 内容不能承担恢复目标。beforeUnmount 拒绝移除时原节点仍聚焦;mounted 失败清理后恢复相邻控件。回调主动聚焦外部,或正在操作其他实例时不移交焦点;焦点恢复中的回调销毁播放器后,保留节点也不得再触发旧 click。
没有可用控件时使用 accessibility/player-focus.ts 聚焦仍连接的播放器。首版立即移除临时 tabindex 的实测会让 Chromium 再次失焦;现在保留自建 tabindex=-1 至实例清理,不增加顺序 Tab 停留点,既有调用方 tabindex 保留。该失败及修正记录保存在独立报告中。
最终增加到九项动态控件场景,包括原生替换按钮、禁用字段集、跨实例隔离及恢复时销毁,三引擎共 27 项通过。完整 CI 468 项通过(437 单元、6 工程、25 基线),241 个生产 TS 文件严格检查;accessibility/components/setting/hotkey/progress-quality 组合三浏览器 507 项通过,无失败、重试或跳过。12 项原组件资源和焦点单元专项也通过,未添加只镜像实现的模拟 DOM 测试。
动态控件阶段证据 保存两组先失败的报告、最终源/用例指纹、CI 和完整组合回归。架构说明同步至 packages/artplayer/ARCHITECTURE.md;此前阶段快照不改写。本阶段无新增依赖、公开类型或版本调整。
源码检查显示 mini-view.ts 的关闭与播放图标、info/poll.ts 的关闭图标及 plugins/lock.ts 的层按钮仍主要依赖点击,后续需先固定真实键盘缺口,再补模式内操作和退出焦点。跨实例动态控件已验证,但不能代表整个播放器的跨实例可用性已验收。SSR/字幕及安装包/legacy 全量检查继续保留;CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,无任务完成 commit,无 push/publish/tag/merge。
mini 播放器键盘与退出焦点阶段
修改前四项真实 Chromium 场景全部失败。自建 mini-view 的既有关闭节点和稳定播放 wrapper 现使用 keyboardButton,Enter/Space 通过原关闭或当前可见播放/暂停图标的 click 路径执行。播放状态变化保留 wrapper 焦点并更新名称;弹窗内 Escape 仅在 mini 活跃时认领。focus-within 显示原 hover 按钮,focus-visible 提供白色焦点框。使用 Close、Mini Player、Play、Pause 既有翻译键,无新增公开类型或字典字段。
新增 display/mini-focus.ts 管理会话来源:键盘从播放器进入时聚焦关闭按钮;指针/程序打开不会抢走外部焦点。关闭仅在焦点仍属于弹窗时恢复原入口,入口已删除、隐藏、禁用或 inert 时聚焦播放器;新会话清除陈旧来源。mini 原有 revision/closing 检查围绕焦点回调,恢复焦点时销毁或再次切换会取消旧 mini 通知。销毁清理不尝试恢复焦点。
保留首次/复用 DOM 顺序、拖动、播放器视频节点移动/恢复和失败重试。调用方提供的自有 mini 容器不追加本轮自建按钮绑定、角色或样式,其交互继续由调用方管理;退出 API 可恢复其当前弹窗焦点。新 UI 资源随已有 mini scope 释放。
最终六场景跨三引擎共 18 项通过,覆盖实际 Tab/Enter/Space/Escape、真实播放/暂停、指针打开、重复会话、外部/隐藏/删除来源、国际化、隐藏后的晚到按键,以及焦点回调销毁后的节点点击。此前 Chromium 组合 24 项通过;最终 accessibility/display-mini/display-web/hotkey 三浏览器组合 300 项全部通过,无失败、重试或跳过。完整 CI 468 项、242 个生产 TS 严格检查通过。
mini 阶段证据 保存修改前失败、最终源和测试指纹、CI、三引擎版本及构建来源;截图保存在本地缓存并检查焦点框和按钮可见性。包内架构文档已同步。当前仍为 Vite 源码构建;信息面板/锁定层、其他模式退出、跨实例/SSR/字幕和安装包/legacy 最终验收仍待完成。CORE-23 doing,57 done、1 doing、156 todo,无新依赖、版本调整、任务完成 commit 或 push/publish/tag/merge。
信息面板与锁定层阶段
信息面板新增 info/keyboard.ts,监听器随原 poll scope 初始化、替换和释放,保留 Info 自有字段、原型方法、轮询次数及 close click 路径。键盘打开聚焦关闭按钮,Enter/Space/Escape 关闭并返回当前会话的播放器入口,原入口不再可用时聚焦播放器。程序/指针操作保留外部焦点;重复 init 不丢失返回目标。名称复用 Close、Video Info。失败名称初始化释放新监听器和轮询,原错误仍可捕获并重试。
严格类型检查发现 $info 在历史模板边界中可空,不能为了通过检查直接断言为必需。保留这个 SSR 约定:缺少外层时跳过依赖该节点的键盘逻辑,轮询和原关闭事件保持;旧发布版和候选版都通过真实 SSR 节点保留与关闭用例。节点存在时才加 group 名称和按键行为。Node 单元宿主补齐实际新增的 EventTarget/属性契约,原轮询和错误用例仍完整执行。
锁定层新增 plugins/lock-keyboard.ts,使用原层节点作为稳定 toggle button,aria-pressed 跟随 lock 通知,Enter/Space 复用原 click,Escape 仅在锁定状态解锁。accessibility/suspend-focus.ts 在锁定期间为控制栏设置自有 inert/aria-hidden 并保存 tabindex,MutationObserver 处理新增与移出节点;解锁、移除或销毁恢复自有值,已被调用方改成不同值的属性不覆盖。实际移除原生 inert 后仍能通过 Tab 回退用例,原有 inert/aria-hidden 和正 tabindex 也能恢复。
键盘焦点样式不再覆盖锁定控制栏原来的隐藏位移;锁定按钮在控制栏隐藏时保留 Tab 可达性,仍按原逻辑视觉隐藏,聚焦后显示。新增可选 Lock 字典类型和十二语言翻译,通过 build:types/build:ts 生成包及 Monaco 声明,旧完整字典不被新增必需字段拒绝。无新依赖。
另外固定了已锁定状态重挂载层的旧缺陷:原 mounted 总把锁定图标隐藏,与实际 state 不符;现在按 getState 初始化图标,保留通常未锁定初始化的样式写入。重挂载恢复新的焦点 scope,Space 解锁仍仅发一次事件。
验证与纠正:
- 信息面板修改前四项 Chromium 场景中三项失败、程序/指针焦点场景通过;锁定层修改前三项全部失败。实现后首批信息面板/提示组件 Chromium 19 项和相关 Node 17 项通过。
- 首轮锁定组合有一项测试错误假设外部 Outside 按钮紧随播放器,真实测试页先有 Play/Pause;依据实际 Tab 结果改为验证 Play,再 Shift+Tab 返回锁定按钮。未增加等待或跳过。
- 重挂载先复现图标 display:none,修正后浏览器把 flex 子项的 inline-flex 计算为 flex,导致三个引擎的计算样式断言失败。测试改为实际可见性与 inline display 值分别检查,仍保留解锁次数及属性清理断言。失败和修正报告都保留。
- 最终完整 CI 468 项通过(437 单元、6 工程、25 基线),245 个生产 TS 文件严格检查;最后仅上述浏览器样式断言调整,额外 lint 通过。最终 accessibility/builtin-layers/prompt-components/hotkey 三浏览器组合 306 项全部通过,无失败、重试或跳过;信息面板共 21 项(含旧/新 SSR 对照),锁定层共 18 项。新专项没有未处理浏览器错误或 console error。
信息面板与锁定层证据 固定源文件、单元宿主、公开/编辑器声明、用例、CI、构建指纹及各次失败。移动条件使用 UA 选择加真实键盘测试,不能当作物理 Android/iOS 或屏幕阅读器验收。默认菜单入口、其他模式退出、跨实例/SSR/字幕和新安装包/legacy 完整矩阵继续交本任务剩余工作。CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,无任务完成 commit、版本调整或 push/publish/tag/merge。
默认菜单键盘与跨面板焦点阶段
修改前六项 Chromium 场景中四项失败。新增 contextmenu/keyboard.ts 管理 Shift+F10/ContextMenu、方向键/Home/End、文字导航、Escape/Tab 退出与焦点恢复;contextmenu/position.ts 原样提取鼠标定位计算,键盘使用当前元素边界作为入口坐标。容器用具名 group,动作项为 button,选择行保留 data-value span 并逐个增加按钮语义、aria-pressed;contextmenu/choices.ts 同步既有 art-current 状态。版本原生链接、自定义 button/input 保持原生角色与编辑/激活路径。
菜单 init 在成功添加条目后替换根 scope,重复添加失败不拆掉既有监听器。Component 焦点恢复从 control 扩展到 contextmenu,同名替换优先,否则选择 DOM 后续/前一个可用项。菜单关闭跳过已隐藏、删除、禁用或 inert 的原入口,必要时回到播放器;外部主动焦点、销毁中回调和双播放器相互独立。
accessibility/overlay-focus.ts 记录菜单来源,Info/mini 进入时解析到原始控件,避免退出后聚焦已经隐藏的菜单项。没有提前移动焦点或调整原 click/public 事件顺序;自定义菜单 callback 仍自行决定是否关闭,参数与 this 保持不变。输入/textarea/select/contenteditable 上的上下文菜单手势改为不拦截,这是修复用户编辑功能的行为差异(API-08),合成事件验证不等于操作过系统原生菜单。
Context Menu 是新增可选公开 i18n 键,十二语言及生成包/Monaco 声明一致。无依赖或版本调整。测试修正保留证据:首轮错误预期移除 Beta 后回到 Alpha,实际排序下下一项是 Info,截图确认恢复正确,现先断言 DOM 邻居再断言焦点;第二轮取消监听器错误假设 Emitter 默认 this 是 art,改为闭包引用已有实例,未修改 Emitter 契约。
最终完整 CI 468 项通过(437 单元、6 工程、25 基线),249 个生产 TS 文件严格检查;之后只有浏览器文件增加边界及修正上述假设,额外 lint 通过。最终 accessibility/components/prompt-components/display-mini/hotkey 三浏览器组合 444 项全部通过,无失败、重试或跳过;菜单十三场景共 39 项,无未处理错误或 console error。测试包含 Info/mini 交接、重复 init、失效来源、外部焦点/销毁、原生内容、取消打开、双实例及菜单边界,保留各引擎中文键盘焦点截图。
菜单阶段证据 固定当前源/声明/用例、构建、CI、截图与失败报告,不改写此前快照。剩余原生模式退出、SSR/字幕和最终新安装包/legacy 全量验收继续推进;CORE-23 doing、BASE-DOM-01 open,57 done、1 doing、156 todo,尚无任务完成 commit,无 push/publish/tag/merge。
模式、SSR/字幕与最终边界审查
新增 accessibility-integration 四项真实场景,三引擎 12 项通过:Enter/Space 原生全屏进入退出、浏览器 API 主动退出后保留当前控件焦点、原生 PiP 键盘切换或不支持时提示,以及 SSR 保留播放器/video/字幕节点、实际 WebVTT cue、键盘字幕开关和网页全屏焦点。Chromium 153 与 Firefox 155 本次具有标准 PiP API,实际进入/退出并验证原事件;Windows WebKit 26.6 无该能力,验证既有不支持提示且不误触发播放,不能把该分支当作成功 PiP 会话。字幕维持被动呈现,不追加 Tab 停留点或强制 aria-live 逐条播报;截图检查字幕与焦点框实际可见,物理辅助技术仍由发布复盘验证。
第一次新安装包全量运行期间,额外真实 Chromium 探针复现设置按钮被删除后 Escape 仍聚焦隐藏面板中的条目。增加四项回归,在旧安装包上全部失败:入口删除、visibility:hidden、aria-disabled,以及导航遇到隐藏行/inert 子树。setting/keyboard-focus.ts 统一可用目标过滤,增加只接管关闭面板内焦点的设置入口恢复;无可用入口时使用播放器 fallback,外部焦点或销毁状态不接管。没有改变公开 Setting 的属性/方法或回调形状。
已验证原全量进程树身份后主动停止旧产物测试;保留 interrupted 日志,不计入通过。修正后三浏览器设置/集成组合 45 项通过;随后将隐藏面板断言的错误单数选择器改为实际 .art-settings,先检查唯一节点再检查隐藏,核心焦点缺陷的前后证据仍来自明确 toBeFocused 断言。最终 CI 和新打包检查重新执行,源与声明不复用旧结果。refactor/.cache/core23-setting-exit-before.json 保存四项旧产物失败;原阶段快照保留不变。
最终验收与交接
| 验收项 | 实际证据 |
|---|---|
| 结构 | 按键认领/按钮/范围/焦点与 DOM 所有权分离;控件、设置、菜单、mini、信息/锁定层各自持有局部状态和清理范围;包内 ARCHITECTURE.md 提供文件地图、回归入口及限制 |
| 类型 | 最终 CI 468 项通过,249 个生产 TS 文件严格检查;37 个公共声明无漂移;五组历史消费与八组精确消费模式无诊断,新增五个翻译字段均可选 |
| 兼容 | 保留旧构造器、属性、快捷键、click 回调参数/this、DOM/CSS 钩子及分发入口;新增键盘路径不重复激活播放;34 项隔离安装运行时契约通过,原有新旧核心/chapter 组合在全量矩阵中继续通过 |
| 真实交互 | 控件 Tab、Enter/Space、slider、selector/设置树、菜单/模式退出、动态更新移除、失效入口、双实例、SSR/字幕有真实浏览器用例,缺陷先固定失败再修正 |
| 最终安装包 | run-4QYvJQ 经 Yarn pack、隔离安装和 frozen 重装;源/声明/资源 381 文件与快照一致,工作区构建的分发内容与安装包字节一致;没有把工作区链接当作 npm 安装 |
| 完整浏览器 | modern 1749 项、legacy 1749 项;每种格式 Chromium/Firefox/WebKit 各 583 项,无失败、重试或跳过;每个用例核对已安装核心和 chapter 产物哈希 |
| 分发与导入 | 按正式脚本重建核心三个 JS 格式与 i18n;ESM/i18n/SSR 三项导入检查通过,声明/Monaco 由生成器维护 |
| 交接与提交 | 任务状态、风险台账、阶段快照和最终证据一并更新;本任务独立本地 commit,后续任务必须在核实该提交后开始 |
最终证据 保存源/测试/工具指纹、包完整文件清单、运行时与类型结果、两个完整浏览器矩阵、构建/安装日志指纹、设置入口四项失败及中断旧产物运行的原因。此前八份阶段 JSON 不改写。新增 Progress/Back/Settings/Lock/Context Menu 可选翻译键,十二语言与两份声明同步;本任务没有新增依赖或改版本。
BASE-DOM-01 resolved,只关闭主要控件 Tab 不可达这一已复现问题。Windows 浏览器与受控 adapter 检查不代表物理 Apple/AirPlay/触摸/IME 或屏幕阅读器认证;相关 REL-03/REVIEW-02 与 BASE-ENV-01 门槛保留。CORE-22 仍待核心资源/性能及生态集成总验收,其前置 ENG-08 尚未完成,因此下一项先补覆盖率、资源清理与性能报告,再进入 CORE-22。多数生态包、CI/CD、各包下一大版本和三轮发布复盘仍待推进,没有公开发布结论。
总体为 214 项:58 done、156 todo。回退时以父提交 faaa3e8c 为基准整体 revert 本任务 commit,同步回退源、生成声明/编辑器、dist/docs 编译文件与测试,不只回退 helper 或复制旧 bundle。无 push/publish/tag/merge。