Files
mnote/bugs/05-editor-mainline/done/5-39-block-menu-delete-undo-regression-v1.md
T

58 lines
2.9 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.
# 5-39 Block menu 删除后 Ctrl+Z 不恢复目标块
> 创建时间:2026-05-25
> 状态:`done`
> Owner`05-editor-mainline`
## 现象
`node scripts/task489-block-menu-delete-undo-smoke.js` 连续两次失败。块菜单删除 `Beta block` 成功,但随后 `Control+Z` 未恢复目标块,最终等待 `Beta block` 重新出现超时。
失败证据:
- `tmp/task489-block-menu-delete-undo-smoke/result.json`
- `tmp/task489-block-menu-delete-undo-smoke/failure.png`
当前 result 摘要:
```json
{
"ok": false,
"states": [
{ "step": "opened", "text": "Block Undo\n\nAlpha block\n\nBeta block\n\nGamma block" },
{ "step": "deleted", "text": "Block Undo\n\nAlpha block\n\nGamma block" }
],
"error": "page.waitForFunction: Timeout 30000ms exceeded."
}
```
## 初步判断
失败点不是删除动作本身,而是删除后的 undo 历史不可恢复。当前代码已经调用 `editor_runtime::history_safe_commands::delete_top_level_block_with_history(&editor, block_index)`,需要继续核实:
- `delete_range(range)` 是否真的进入 Tiptap history。
- 删除后 `sync_persisted_editor_command(...)` 是否触发了会清空 undo history 或重建 editor state 的路径。
- 失败是否与焦点丢失有关;需要用最小浏览器复现确认点击 editor 后再 `Control+Z` 是否能恢复。
## 根因
块菜单按钮点击后,删除命令先通过 Tiptap history-safe `delete_range` 路径删除目标块,并在 helper 内调用了一次 `editor.focus()`。但随后 Leptos 继续关闭 block menu / anchor / hovered block 状态,点击目标按钮被卸载,最终浏览器焦点可能落回非 ProseMirror 元素。`Control+Z` 因此没有稳定送到 Tiptap editor,表现为删除成功但撤销不恢复。
## 修复
- 在块菜单删除成功、关闭菜单状态后,再补一次 `editor.focus()`,确保后续键盘撤销进入 ProseMirror。
- 同批拆出 `editor_runtime/block_menu_document.rs`,隔离 legacy 顶层块 JSON helper;当前运行路径仍优先使用 history-safe command,不回退到 HTML 整文替换删除。
## 验收
- `cargo fmt --manifest-path rust/Cargo.toml --all --check` 通过。
- `cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml` 通过。
- `cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release` 通过,并已执行 `wasm-bindgen` 更新 island wasm。
- `node scripts/task489-block-menu-delete-undo-smoke.js` 通过。
- `node scripts/task488-local-attachment-link-delete-undo-smoke.js` 通过。
- 不得回退到 HTML 整文替换删除路径。
## 未覆盖
- `cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml block_menu_document -- --test-threads=1` 当前被既有 `STYLE` 测试编译错误阻断,错误为 `cannot find value STYLE in this scope`,未进入本次新增 helper 测试。