From df8f7397b2d6ae7c569bb6f9076b437181985384 Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 7 Jul 2026 11:59:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(editor):=20=E6=96=9C=E6=9D=A0=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=96=87=E6=9C=AC=E6=AE=8B=E7=95=99=E8=BF=9B=E6=96=B0?= =?UTF-8?q?=E8=8A=82=E7=82=B9(/code=20=E5=B8=A6=E5=85=A5=20codeBlock)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggestion 传给 command 的 range 在某些输入路径下过时——停在首次 输入 '/' 的位置 {from:1,to:2},不随后续字符更新。deleteRange 只删 '/', 命令文本(如 'code')残留,被 toggleCodeBlock 包进新节点。 该 bug 同时导致衍生症状:残留文本让 codeBlock 非空,Backspace 的 clearNodes 条件(!textContent.length)不成立,空块退格看似无效。 修复:command 转发处防御性重算 range——基于当前 selection 在同一段落 内往前找触发字符 '/',删到光标位置。对所有命令统一生效。 经 Playwright 真实浏览器复现验证(happy-dom 无法复现此 bug): - /code 回车:codeBlock 现为空(原残留 'code' 文本) - 空 codeBlock 退格:正常删除变段落(原无反应) --- libs/tiptap-editor/src/slash-command.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/tiptap-editor/src/slash-command.ts b/libs/tiptap-editor/src/slash-command.ts index a14f7c1..f0db2d9 100644 --- a/libs/tiptap-editor/src/slash-command.ts +++ b/libs/tiptap-editor/src/slash-command.ts @@ -277,7 +277,17 @@ export const SlashCommand = Extension.create({ }; }, command: ({ editor, range, props: item }) => { - item.command({ editor, range }); + // 防御性重算 range:Suggestion 的 range 在某些输入路径下会过时 + //(停在首次输入 '/' 的位置,不随后续字符更新),导致 deleteRange 只删 '/', + // 命令文本(如 'code')残留进新节点。基于当前 selection 重算: + // 从光标往前在同一段落内找触发字符 '/',删到光标。 + const { from } = editor.state.selection; + const $from = editor.state.doc.resolve(from); + const text = $from.parent.textBetween(0, $from.parentOffset, '', ''); + const slashIdx = text.lastIndexOf('/'); + const effectiveRange = + slashIdx >= 0 ? { from: $from.start() + slashIdx, to: from } : range; + item.command({ editor, range: effectiveRange }); }, }), ];