# 5-25 Editor Tab Keyboard and MRU Checklist v1

> 状态：done
>
> 归档说明（2026-05-21）：editor tab keyboard 与 MRU 行为已完成。
>
> 日期：2026-05-21
>
> Owner：main editor tab keyboard / MRU behavior

## 1. 目标

参考 Sidex / VSCode `MultiEditorTabsControl`，补 MNote main tab 的基础键盘和 MRU 行为。当前只做轻量交互，不照搬完整 tab control。

## 2. 允许修改范围

- `rust/crates/mnote-web/src/routes/web_shell.rs`
- `rust/crates/mnote-web/src/ssr/styles.rs`
- 可新增聚焦 smoke

## 3. 禁止事项

- 不新增全局快捷键与浏览器默认冲突。
- 不实现完整 tab overflow 复杂布局。
- 不改变 resource tab identity。

## 4. Checklist

- [x] tab strip 支持左右箭头 roving focus。
- [x] `Enter` / `Space` 激活当前 focused tab。
- [x] 关闭 active resource tab 后回到 MRU 或 page tab，行为稳定。
- [x] tab 上保留可测试 DOM 状态。
- [x] 补测试或 smoke。

## 5. 验收

- `cargo test -p mnote-web web_shell -- --test-threads=1`
- 如新增 smoke：`node scripts/task47*-editor-tab-keyboard-*.js`

## 6. 执行记录

> 引用 proposal：`.codex/reasonix-proposals/2026-05-21-tab-keyboard-mru-proposal.md`

### 已确认

- `resourceTabMru` 数组 + `touchResourceTabMru` / `lastActiveResourceTabKey` / `removeFromResourceTabMru` 逻辑完整，MRU 核心逻辑无需改动。
- `activateMainEditorTab` 已正确维护 roving tabindex（active → `tabindex="0"`, others → `tabindex="-1"`）。
- `createResourceTabDom` 中 resource tab 初始 `tabindex="-1"` 符合预期。

### 已实现

- [x] 新增 `bindMainEditorTabStrip()` 函数（keydown 事件委托 + collectTabs + 箭头/Home/End/Enter/Space）。
- [x] 修改 `closeResourceTab()` 末尾，关闭后 focus 迁移到新激活的 tab。
- [x] 在 `styles.rs` 补充 `:focus-visible` 样式。
- [x] 更新 Rust contract test 断言。
- [x] `cargo test -p mnote-web web_shell -- --test-threads=1` 通过。

### 后续可选

- [ ] 如后续需要浏览器级回归，可新增 `scripts/task475-editor-tab-keyboard-mru-smoke.js`，覆盖多 tab 键盘切换与关闭后 focus。

### 非预期发现

- `closeResourceTab` 在 activate 后未显式调用 `focus()`，导致 keyboard focus 丢失。需修复。
- tab strip 无 `:focus-visible` 样式，键盘用户在箭头导航后看不到 focus 环。

### Codex 实施记录

- 2026-05-21：Reasonix Worker B 按要求只输出 proposal，未直接改源码。
- 2026-05-21：Codex 按 proposal 的最小安全集实现键盘 roving focus、Enter/Space 激活、关闭后 MRU/page tab focus 迁移。
- 2026-05-21：未新增全局快捷键；事件只绑定在 `[data-mnote-main-tab-strip]` 内。

## 7. 非目标

- 不做拖拽 tab 排序。
- 不做 close others / close saved 复杂菜单。
