Skip to content

输入翻译在 contenteditable 替换后能撤销:普通 contenteditable 走原生撤销栈,受控编辑器走它自己的撤销栈,夹具与端到端都用真实按键验证(#657) - #699

Merged
Teeeeeeeerry merged 2 commits into
mainfrom
feat/657-contenteditable-undo
Oct 4, 2026
Merged

Teeeeeeeerry merged 2 commits into
mainfrom
feat/657-contenteditable-undo

Conversation

@Teeeeeeeerry

Copy link
Copy Markdown
Owner

问题

替换后 Ctrl / Cmd+Z 能把原文撤回来,是输入翻译的硬要求:扩展往用户自己写的文字上动手,原文只存在于用户的记忆里。多行文本框已经由 TC-E2E-115 钉住,contenteditable 还没有验证;受控编辑器的撤销栈由编辑器自己管,浏览器的原生撤销栈里根本没有它的改动,要单独验证。

根因

#656 之前 contenteditable 不写回,谈不上撤销。#656 的写回路径决定了撤销能不能成立:

  • 普通 contenteditable:替换是一次 execCommand('insertText'),进原生撤销栈
  • 受控编辑器:替换是一次被编辑器接管的 beforeinput,在编辑器的模型里是一步
    如果写回拆成先删后插,或者绕过编辑器改 DOM,撤销就会停在空框或者撤不回来。

修复

  • 产品代码不用改:输入翻译:contenteditable 的写回,编辑器状态与界面一致(#633) #656 的写回路径本身就是一步。本票补上验证
  • 夹具 rich-input.html 的受控编辑器加上自己的撤销栈(仿 slate-history):
    • 每次改模型记一步
    • Mod+Z / Mod+Shift+Z 在 keydown 里拦下,由编辑器自己撤销与重做
    • 浏览器的原生撤销栈里没有这些改动

验证

  • 端到端 TC-E2E-131,都用真实按键:
    • 普通 contenteditable:替换后 ControlOrMeta+z 一步回到原文,ControlOrMeta+Shift+z 回到译文
    • 受控编辑器:同样的按键,界面与编辑器模型都回到原文,再回到译文
  • 用例在当前代码上直接通过(写回本来就是一步)。临时把写回改成“先删后插”再跑:在受控编辑器那一段红(撤销后是空框),已改回
  • pnpm test 114 个文件 1407 条全绿;pnpm typecheck 通过;pnpm build 通过;pnpm test:e2e:core 88 过、2 跳过

Closes #657

Teeeeeeeerry and others added 2 commits October 5, 2026 10:40
…夹具与端到端都用真实按键验证(#657)

Co-Authored-By: zhexuancai-uts <261878103+zhexuancai-uts@users.noreply.github.com>
Co-Authored-By: zhexuancai-uts <261878103+zhexuancai-uts@users.noreply.github.com>
@Teeeeeeeerry
Teeeeeeeerry merged commit 95b2906 into main Oct 4, 2026
6 checks passed
@Teeeeeeeerry
Teeeeeeeerry deleted the feat/657-contenteditable-undo branch October 4, 2026 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

输入翻译:contenteditable 替换后原生撤销能撤回(#633)

1 participant