协同文档工作机制简介
如果无法正常显示,请先停止浏览器的去广告插件。
1. 第 十 六 届 D 2 前 端 技 术 论 坛
协同文档工作机制简介
钉钉文档前端架构师 - 本杰
2. 钉钉文档
钉钉文档是阿里巴巴钉钉推出与钉钉深度结合的在线文档产品
富文本编辑
批注
协同编辑
3. 钉钉文档 - 插入万物
支持嵌入脑图、甘特图等,且嵌入区块可协同编辑
区块可协同编辑
超过 20 种区块
4. 钉钉文档 - 专业排版
支持分页、分栏、图文混排等
页头、页脚
分页
5. 所见即所得
6. 专业排版
流式视图
分页视图
7. 专业排版 - 分行
如何分行是排版中最简单,也是最基础的一个问题
这是一段很长很长很长的文本,以至于触发了
换行。
8. 专业排版 - 测量与拆分
用户输入不带布局信息,经过排版引擎处理后增加分行等布局信息
9. 专业排版 - 字符测量与分行点
对字符逐一进行宽度测量并加总,再结合当前容器的宽度,可以得知分行点
分行点
这是一段很长很长很长的文本,以至于触发了
换行。
10. 专业排版 - 编辑数据流
用户在排版后的视图模型上交互,实际修改的是排版前的文档模型
11. 专业排版 - 编辑数据流
用户在排版后的视图模型上交互,实际修改的是排版前的文档模型
12. 专业排版 - 拆分与映射
通过约定数据节点唯一标识,及其映射关系,建立起视图模型到文档模型的链接
文档模型
视图模型
段落 1 段落 1-0
这是一段很长很长很长的文本,以至于触发了
换行。 这是一段很长很长很长的文本,以至于触发了
• 段落1-1.split(‘-’)[0] => 段落1
• 段落1-0.text.length + 2 => 22
段落 1-1
换行。
13. 不依赖 contentEditable 的编辑器
14. contentEditable
• W3C 标准
• 提供作用于 DOM 的编辑能力
专业排版
• 文档模型与视图模型异构
15. 不依赖 contentEditable,
编辑器如何响应用户的点击行为并绘制光标?
16. 视图 - 选区计算与绘制
以下图为例,当用户点击文档中空白部分,最符合用户直觉的行为是选中 Good 与 ! 之间
17. 视图 – 事件响应
使用鼠标、触摸事件计算选择行为
18. 视图 – 选区数据描述
该数据结构除了被视图层消费以绘制光标外,也用于协同场景中协同光标的同步及绘制
19. 不依赖 contentEditable,
编辑器如何响应用户的输入行为并呈现字符?
20. 视图 - 输入上屏
当用户输入文本时,需要实时看到所输入的内容上屏,并能选中所需的字符
21. 视图 - 幕后的 textarea
钉钉文档使用一个不可见 textarea 监听用户输入,并定位输入法浮层
22. 视图 – Composing 状态描述
Composing 指中文输入开始到选词结束间的中间状态
23. 视图 – 内容数据描述
用户选词后,文本将会被插入到当前的文档模型
24. 视图 – 渲染为 DOM
用户选区、文档内容,经过排版后,使用 React 渲染并输出为 DOM
25. 协同编辑
26. 协同编辑 – 冲突处理
自动处理用户协同编辑所产生的冲突,保证最终数据一致
27. 协同编辑 - Operational Transformation (OT)
对文档模型的修改映射为差量数据 operation,在接收到他人 operation 时,使用 transform 处理潜在冲突:
28. 编辑器如何支持 OT 算法?
29. 协同编辑 - 编辑数据流
用户的一切编辑行为,都转换为 9 种原子 operation 组合,并使用 operation 驱动文档模型更新,而非直接修改文档模型
30. 协同编辑 - 编辑器接入协同能力
协同引擎接收本地及远程 operations 后,使用 OT 算法处理冲突
31. 协同编辑 - Conflict-free Replicated Data Type(CRDT)
主流协同算法,除了 OT,还有 CRDT,钉钉文档在一些小功能中也开始试点
32. 开源计划
钉钉文档富文本编辑器已经沉淀为 SDK 并赋能内部 30+ 产品
• 专业排版能力
• 不依赖 contentEditable
• 协同编辑能力
33. Thanks
钉钉文档知乎专栏