[{"data":1,"prerenderedAt":236},["ShallowReactive",2],{"msfe-doc:\u002Fconcepts\u002Fsource-first":3},{"id":4,"title":5,"body":6,"description":219,"extension":220,"keywords":221,"locale":227,"meta":228,"navigation":229,"order":230,"path":231,"section":232,"seo":233,"stem":234,"__hash__":235},"docs\u002Fconcepts\u002Fsource-first.zh-CN.md","源码优先",{"type":7,"value":8,"toc":209},"minimark",[9,13,17,77,80,108,117,120,138,161,164,167,171,174,177,180,202],[10,11,12],"h2",{"id":12},"一份持久内容",[14,15,16],"p",{},"CodeMirror 文本是编辑器的内容权威。解析器和扩展从源码派生语法范围、字段及呈现；保存时读取当前 Markdown。",[18,19,20,33],"table",{},[21,22,23],"thead",{},[24,25,26,30],"tr",{},[27,28,29],"th",{},"层",[27,31,32],{},"负责什么",[34,35,36,45,53,61,69],"tbody",{},[24,37,38,42],{},[39,40,41],"td",{},"编辑器核心",[39,43,44],{},"文本、选区、事务、历史、模式与生命周期",[24,46,47,50],{},[39,48,49],{},"语法与字段",[39,51,52],{},"识别当前源码范围，读取字段，校验并编码精确修改",[24,54,55,58],{},[39,56,57],{},"命令",[39,59,60],{},"描述源码操作，在一次事务中提交",[24,62,63,66],{},[39,64,65],{},"组件与主题",[39,67,68],{},"显示内容、提供交互，通过受控动作请求修改",[24,70,71,74],{},[39,72,73],{},"宿主应用",[39,75,76],{},"文件、存储、权限来源、上传服务和业务界面",[10,78,79],{"id":79},"从组件操作回到源码",[14,81,82,83,87,88,91,92,95,96,99,100,103,104,107],{},"以 ",[84,85,86],"code",{},"[[todo]]"," 为例：语法确认 token 后，",[84,89,90],{},"read()"," 派生 ",[84,93,94],{},"{ value: 'todo' }","。组件请求 ",[84,97,98],{},"{ value: 'done' }","，",[84,101,102],{},"patch()"," 只替换括号内部的字段，最终源码成为 ",[84,105,106],{},"[[done]]","。",[14,109,110,111,116],{},"这种操作与键盘输入共用历史，因此用户可以撤销组件按钮造成的修改。见",[112,113,115],"a",{"href":114},"\u002Fextensions\u002Fcustom-node","自定义节点","的完整实现。",[10,118,119],{"id":119},"语义与界面分别扩展",[14,121,122,125,126,129,130,133,134,137],{},[84,123,124],{},"Node.create()","、",[84,127,128],{},"Mark.create()"," 和 ",[84,131,132],{},"Extension.create()"," 提供声明入口。可以先定义字段和命令，再由应用用 ",[84,135,136],{},".extend()"," 添加 Vue、React 或原生 DOM 呈现。",[14,139,140,141,125,144,125,147,150,151,155,156,160],{},"这些声明当前不是 ProseMirror schema。",[84,142,143],{},"parseHTML",[84,145,146],{},"renderHTML",[84,148,149],{},"NodeViewContent"," 等接口不能直接从 Tiptap 示例中搬入；请以 ",[112,152,154],{"href":153},"\u002Fapi\u002Feditor","API 参考","和",[112,157,159],{"href":158},"\u002Fsupport","支持范围","为准。",[10,162,163],{"id":163},"何时保留源码",[14,165,166],{},"未知、未闭合或暂时无法呈现的结构保留原文。自定义语法与资源加载也应明确回退行为，不能以隐藏原文代替解析成功。",[10,168,170],{"id":169},"与-ast-编辑器集成时的选择","与 AST 编辑器集成时的选择",[14,172,173],{},"解析树是可重新计算的索引，不能接替文本成为唯一存档。把 Markdown 转成 ProseMirror JSON、编辑后再序列化会改变可表示范围和原始拼写策略；这属于另一条内容管线，不是 MSFE 的透明内核。",[14,175,176],{},"若应用同时有富文本视图和源码优先视图，应明确转换边界、损失政策和每个编辑会话的权威来源，不让两份内容同时自动互相覆盖。当前文档只承诺本编辑器内的单一源码事务流。",[10,178,179],{"id":179},"复杂扩展的一次数据流",[181,182,183,187,190,193,196,199],"ol",{},[184,185,186],"li",{},"用户输入进入 CodeMirror 文本与历史。",[184,188,189],{},"增量解析确认语法范围；未确认部分仍显示源码。",[184,191,192],{},"codec 读取字段，投影描述视觉，组件只呈现收到的属性。",[184,194,195],{},"组件操作通过命令或字段 patch 请求精确修改。",[184,197,198],{},"编辑器校验当前意图、权限和范围，接受后通知宿主增量变化。",[184,200,201],{},"宿主按自己的持久化协议保存 Markdown。",[14,203,204,205,107],{},"这个分工同时适用于简单状态标记、嵌套容器和异步图表；不同之处在于选择了哪些 ",[112,206,208],{"href":207},"\u002Fconcepts\u002Fextensions","扩展入口",{"title":210,"searchDepth":211,"depth":211,"links":212},"",2,[213,214,215,216,217,218],{"id":12,"depth":211,"text":12},{"id":79,"depth":211,"text":79},{"id":119,"depth":211,"text":119},{"id":163,"depth":211,"text":163},{"id":169,"depth":211,"text":170},{"id":179,"depth":211,"text":179},"理解 Markdown、派生字段、组件视图和事务之间的关系。","md",[222,223,224,225,226],"架构","JSON","AST","文档模型","CodeMirror","zh-CN",{},true,0,"\u002Fconcepts\u002Fsource-first","核心概念",{"title":5,"description":219},"concepts\u002Fsource-first.zh-CN","8miW5dIJJVlFfq4ifR-hfHlX7_CdeFRWPzyI5mJC7is",1793046311419]