Skip to content

输入翻译在 contenteditable 里写回:先派发可取消的 beforeinput 让受控编辑器按自己的模型插入,没人接管再走原生插入;圆点跟着编辑宿主的 DOM 变动出现(#656) - #698

Merged
Teeeeeeeerry merged 2 commits into
mainfrom
feat/656-contenteditable-writeback
Oct 4, 2026
Merged

Teeeeeeeerry merged 2 commits into
mainfrom
feat/656-contenteditable-writeback

Conversation

@Teeeeeeeerry

Copy link
Copy Markdown
Owner

问题

#655 之后圆点能在 contenteditable 里出现,但点下去只把译文弹在提示条里,不写回。直接改 innerHTML 也不行:Slack、Discord 这类受控编辑器背后是自己的文档模型,绕过它改 DOM,轻则光标乱跳,重则发出去的是模型里的旧内容或空消息。另外,受控编辑器里打字时圆点不跟着出现。

根因

  • replaceInputText() 只会 select() 加 execCommand('insertText'),这是文本框的路径。实测 Chrome 的 execCommand 不派发 beforeinput,而 Slate、Lexical 一类编辑器正是靠 beforeinput 改模型;对它们执行 execCommand,DOM 被直接改掉,模型不知道
  • 受控编辑器拦下 beforeinput 后自己重新渲染,浏览器不再派发 input 事件,而圆点只听 input

修复

验证

  • 夹具 rich-input.html 新增一个受控编辑器 #editor,仿 Slate:
    • 模型是唯一的真相;beforeinput 一律拦下,改模型后自己重新渲染
    • 选区在 selectionchange 时同步进模型
    • 记录收到的输入事件,并统计绕过编辑器的 DOM 变动
  • 单元(生命周期注册表):input-dot.test.ts 新增 2 条(编辑宿主的 DOM 变动驱动圆点出现与消失;失焦后不再驱动),修复前红
  • 端到端 TC-E2E-129:
    • 受控编辑器(带选区)替换后,模型与界面都是译文
    • 编辑器收到 { inputType: 'insertText', data: 译文 },绕过编辑器的 DOM 变动为 0
    • 模型选区在末尾,焦点还在,接着打字落在末尾
    • 普通 contenteditable 走原生插入,页面收到一次 insertText 的 input
  • 端到端 TC-E2E-130(受控编辑器):
    • 进行中转圈,再点不发第二次请求
    • 送翻后又打了字就不覆盖,译文进提示条,模型与界面都是新打的字
  • 两条新用例修复前都红
  • pnpm test 114 个文件 1407 条全绿;pnpm typecheck 通过;pnpm build 通过
  • pnpm test:e2e:core 86 过、2 跳过、1 不稳定:TC-E2E-86 是设置页站点规则,与本票无关,重试通过,单独连跑 3 次都过

Closes #656

Teeeeeeeerry and others added 2 commits October 5, 2026 10:34
…插入;圆点跟着编辑宿主的 DOM 变动出现(#656)

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 430df3e into main Oct 4, 2026
6 checks passed
@Teeeeeeeerry
Teeeeeeeerry deleted the feat/656-contenteditable-writeback branch October 4, 2026 23:38
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