Files
mnote/design/old/05-editor-mainline/done/rust-block-editor-interaction-samples-v1.md
T

7.2 KiB
Raw Blame History

[recycle] Rust Block Editor Interaction Samples v1

更新时间:2026-04-18

主要来源:

  • /mnt/Data1T/mnote-next/docs/architecture/p1-human-stable-interface.md
  • /mnt/Data1T/mnote-next/apps/web/app/components/editor/BlockEditor.tsx
  • /mnt/Data1T/mnote-next/apps/web/app/components/editor/*.test.mjs

定位说明:

  • 这些样例是内部回归样本
  • 用来冻结“人层已稳定语义”
  • 明确 不作为主 benchmark

1. 使用方式

本文件服务 task-049:把 mnote-next 里已经跑通过的一批人层交互沉淀成新 editor core 的回归样例。

固定原则:

  • 样例来自 mnote-next
  • 语义需要迁移到 Rust editor core
  • mnote-next 本身 不作为主 benchmark
  • 新实现应优先参考 reference-code 的命令、块模型、输入原语,而不是继续延长旧壳寿命

2. 样例总表

样例 旧来源 新 editor core 应冻结的语义 参考层依据
单块编辑 p1-human-stable-interface.md 第 27 行 更新单块 type/content/props,不要求整页重算 edita-core 命令容器、blocks 块更新
插入同级块 第 28 行 在当前块后插入新块;拆块时允许“先更新当前块,再插入下一块” edita-core command、blocks document insert
空块退格合并上一块 第 29 行 当前块为空时,把内容并回上一块并删除当前块 blocks merge / history、kode 光标与退格输入
单块删除 第 30 行 删除目标块,不提前扩成整棵树删除 edita-core delete command
上移下移 第 31 行 平面顺序调整,先不承诺跨父节点复杂移动 blocks reorder 胶水、edita-core command
有限缩进 第 32 行 Tab / Shift+Tab 只调整有限层级展示,不升级为正式树协议 kode 输入处理、edita-core set-indent command
行内页面引用 第 33 行 [[ 触发候选并把文本替换成稳定 token kode 输入规则、blocks token serialize
块引用占位插入 第 34 行 # 或 slash 触发,先插入占位块,不承诺完整搜索器 edita-core insert placeholder、blocks serialize

3. 回归样例明细

3.1 单块编辑

稳定语义:

  • 当前焦点块的文本可直接修改
  • 块类型转换仍保持单块粒度
  • 标题级别调整属于同一块 props 更新

新 editor core 的最小断言:

  • 输入文本只产生一次 update_block
  • 标题级别变化不应触发整页重排
  • advancedTodo 状态切换仍属于单块更新

参考层采用依据:

  • edita-core:采用 Command<State> 风格封装 update_block
  • blocks:采用块内容变更与序列化
  • kode:部分采用块内光标、输入和选择处理
  • leptos-tiptap:不作为主实现,仅保留 Leptos 事件桥接参考

3.2 插入同级块

稳定语义:

  • Enter 拆块
  • 左侧加号插入
  • 粘贴到下方
  • 复杂块占位插入后也仍是“在当前块后插入同级块”

新 editor core 的最小断言:

  • 目标位置明确是 after current block
  • 返回新块 id
  • 焦点应跳到新块

参考层采用依据:

  • edita-core:采用 insert_block_after 风格命令
  • blocks:采用文档插入和序列化
  • kode:部分采用 Enter 时的输入与光标迁移

3.3 空块退格合并上一块

稳定语义:

  • 当前块为空
  • Backspace
  • 若上一块允许合并,则把当前块内容并入上一块并删除当前块

新 editor core 的最小断言:

  • 合并后焦点回到上一块末尾
  • 不应残留空块
  • 若块类型不兼容,则明确返回 no-op

参考层采用依据:

  • blocks:采用 merge / history 的思路
  • kode:部分采用退格、选择、光标偏移处理
  • edita-core:采用“命令执行后改写状态”的方式,不把逻辑写死在 DOM 事件里

3.4 单块删除

稳定语义:

  • 菜单删除
  • 键盘删除分支
  • 明确只删除目标块

新 editor core 的最小断言:

  • 删除后返回新的块序列
  • 焦点落到前一块或后一块
  • 删除复杂块时只删除占位,不在 core 内处理宿主资源生命周期

参考层采用依据:

  • edita-core:采用 delete command
  • blocks:采用文档删除和回放能力

3.5 上移下移

稳定语义:

  • “上移下移”先冻结为平面重排
  • 不承诺跨父节点、批量树移动、保留折叠上下文

新 editor core 的最小断言:

  • 同一列表内块顺序可交换
  • heading、普通块、占位块都能复用同一 reorder 命令
  • 操作后序列化结果稳定

参考层采用依据:

  • edita-core:采用通用 reorder command
  • blocks:采用文档块顺序变更

3.6 有限缩进

稳定语义:

  • Tab / Shift+Tab
  • 只调整有限层级展示
  • 允许 clamp 到非负值

新 editor core 的最小断言:

  • indent >= 0
  • 存在最大层级上限
  • 缩进不等于真实树结构重挂接

参考层采用依据:

  • kode:部分采用键盘输入和选择移动
  • edita-core:采用 set_indent 命令
  • blocks:保留 indent 元数据序列化

3.7 行内页面引用

稳定语义:

  • 触发器是 [[
  • 选中候选页后在原光标位置替换成 token
  • 刷新回显和桥接读取应使用同一份 token 解析结果

新 editor core 的最小断言:

  • 能识别 [[
  • 能插入稳定 token
  • Markdown / JSON 导出结果一致

参考层采用依据:

  • kode:部分采用输入规则和候选触发
  • blocks:采用 token 文本与导出转换
  • edita-core:采用 insert_page_reference_token 命令

3.8 块引用占位插入

稳定语义:

  • 输入 # 或 slash
  • 先插入块引用占位块
  • 允许复制块引用后粘贴
  • 当前只保证占位插入、回显、复制粘贴,不承诺完整块搜索器

新 editor core 的最小断言:

  • 占位块有稳定 type=blockReference
  • 至少持有 sourceDocumentId / targetBlockId / label
  • 占位块可删除、可移动、可导出

参考层采用依据:

  • edita-core:采用 insert_block_reference_placeholder
  • blocks:采用自定义块型序列化
  • kode:部分采用触发字符、候选框和插入位置处理

4. 不进入 benchmark 的内容

下面这些内容仍可作为内部回归样本,但 不作为主 benchmark

  • 旧 BlockEditor 的 hover、slash 菜单显示状态
  • 旧桥接层的反链聚合细节
  • BlockNote / ProseMirror 兼容行为
  • 旧壳中的复杂 DOM 事件与 focus hack

新 editor core 只需要继承其“稳定人层语义”,不需要继承其所有实现细节。

5. 新 editor core 建议命令名

为保证 Phase 1 可测,建议直接冻结下面这组命令名:

  • update_block
  • insert_block_after
  • merge_block_with_previous
  • delete_block
  • move_block_up
  • move_block_down
  • set_block_indent
  • insert_page_reference_token
  • insert_block_reference_placeholder

6. 结论

task-049 的结论不是“继续复刻 mnote-next 编辑器”,而是:

  • 单块编辑
  • 插入同级块
  • 空块退格合并上一块
  • 单块删除
  • 上移下移
  • 有限缩进
  • 行内页面引用
  • 块引用占位插入

这 8 条稳定语义沉淀成 Rust editor core 的第一批回归样例。