Composer(编写器)坐标与序列化
草稿存储负责 Markdown,Tiptap 负责编辑中的文档。富文本 设置会改变已安装的扩展,因此切换它时会根据 已存储的草稿重新挂载编辑器。纯文本模式必须让格式标记保持为字面文本。富文本模式会保留 空白和芯片来源,但会把受支持的定界符规范化(__ 改为 **, _ 改为 *),并把复选框的大小写规范化([X] 改为 [x])。
存储中的光标并不是 ProseMirror 位置:折叠坐标把一个芯片计为一个 字符,展开坐标计入它的源文本,而 ProseMirror 还会计入 块边界。转换逻辑请留在 文档模型 中。 空段落即使不含文本,也需要真实的插入符位置。显示在 带样式文本旁边的标记是装饰,因此落在它们内部的偏移会钳制到文本边缘。
只有受控文本发生变化时才替换编辑器内容。为移动光标而替换内容 会制造撤销条目,并重新生成引用标识。待处理的引用弹出层 必须等到所请求的草稿已经进入编辑器,再去定位它们的芯片。
富文本任务通过原生编辑器命令(command)来拆分,使标记和芯片得以保留。字面 列表使用 存储编辑。换行会变成 段落拆分:否则末尾的硬换行会显得需要按两次。 程序性移动必须显式地把插入符滚入视野。
剪贴板文本必须来自 Markdown 序列化器,而不是 DOM 文本:芯片标签省去了 来源,标记装饰也不是内容。可用时,结构化的上下文记录会随 这段文本一起提供。粘贴会补全尾部的芯片定界符,并在芯片紧接文本之后插入时加上前导 边界。
块节点(围栏、列表、引用、分隔线、标题)把精确的 Markdown 定界符保留为节点属性,因此往返后逐字节一致,而定界符 内部的偏移会像任务标记和样式标记一样钳制到该块的文本。 序列化器只写出语法所包含的内容:引用包含段落,列表 包含段落和列表。因此块只能在顶层段落上形成。 输入规则会检查这一点,而且 Tiptap 自带的块快捷键(Mod-Shift-8、Mod-Alt-c 等)已被移除,因为嵌套一个序列化器写不出来的块, 会让它的文本从已存储的草稿中丢失。列表语法就是 composer-list-continuation 中纯文本模式 续行所用的那一套; 请让二者保持同步。
按下回车即发送,因此 handleKeyDown 中的围栏处理必须在发送 处理程序之前运行:若放到后面才检查,围栏永远不会打开,围栏内的换行还会把 草稿发送出去。