在线文档技术揭秘开篇 - 富文本编辑器
前言
本文旨在向大家介绍在线文档的核心模块富文本编辑器技术,并介绍业内主流商业文档产品如何进行富文本编辑器技术选型。
富文本编辑器
富文本编辑器,Rich Text Editor, 简称 RTE, 是一种可内嵌于浏览器,所见即所得的文本编辑器。
富文本编辑器 - 常见交互
- 内容输入区域
- 输入内容
- 选区 & 操作
- 操作栏
- 顶部工具栏
- 侧边栏
- 内嵌工具栏
- 右击菜单
富文本编辑器 - 分级
富文本编辑器通常会做3个分级:L0、L1 和 L2
L0
依赖浏览器特性,主要是使用到了 designMode、ContentEditable、webkit-user-modify、execCommand 等特性。早期的编辑器都采用这种方案,但可定制的空间有限。例如早期的技术产品 WYSIWYG Editor。
代码语言:javascript复制<div class="kuaishou" contentediable="true">请输入正文</div> <!-- 富文本输入框 -->
documennt.execCommand('bold'); //操作
复制代码
L1
L1 在 L0 的基础上继续使用浏览器的特性、DOM 的 API 来自主实现 Selection、Range、Element、TextNode 等,具备一定的可扩展性,但也会有很多难以解决的问题。主要商业产品包括石墨文档(Quill),腾讯文档(Etherpad ACE),飞书文档(Etherpad ACE), 语雀文档(slate, lake),印象笔记(PromiseMirror),Confluence WIKI以及SAAS 产品内集成的知识库(Teambition Thoughts、Pingcode 等等);技术产品包括CKEditor、TinyMCE、Draft.js、 Slate、Quil.js 、ACE 等等,通常我们对 L1 编辑器从布局实现方式还区分为【传统模式】和【MVC模式】
- 传统模式
DOM 树等于数据,使用 DOM API 直接操作(CKEditor 4、TineMCE、UEditor)
- MVC模式
数据和渲染分离,数据模型发生变更后,数据才发生变更(Slate、CKEditor 5、Quil.js)
L2
自定义输入和操作,包括光标、输入法、删除等基础动作,具备绘图布局等能力。主要商业产品包括Google Docs、 Office Word Online、WPS 以及轻雀文档。
富文本编辑器 - 对比
补充:Google Docs、WPS 以及 Office Online 之所以体验性能极致,产品体验丰富,也源于投入极大的研发成本。
富文本编辑器 - 技术选型
从团队规模角度
- 产品内容体验简单,并且缺乏编辑器开发者,推荐直接使用 Quill、 Slate.js、CKEditor、TIngMCE 进行二次开发。
- 产品内集成轻量级知识库,有5人以内的编辑器开发团队:推荐自研L1级别编辑器、
- 以协作编辑为产品核心,排版布局对标 Office,编辑器开发人员规模超过20 的编辑器研发团队: 推荐自研L2 编辑器。
从编辑器必备特性角度
- 健壮性 - 编辑器的稳定性是编辑器的生命线。
- 优秀的架构
- 能够定义一个文档模型,并且能够用一种简单的方式去区分两个文档模型是否在视觉上相等。
- 良好的MVC架构,创建一个在 DOM 与模型之间的映射,并且拥有完整的分层
- 在文档模型上能够定义表现良好的编辑操作(operation)。
- 可维护性 - 富文本编辑器代码量随着迭代会越来越大,所以能够用简单可依赖的方式去维护是很重要的
- 可扩展性 - 优秀的插件机制,优秀的扩展迭代能力。
userInput→ Action → Edit → Operation → Command → Mutation → Model → View(Layout,Redraw)→ DOM
block-style editor
类似 Notion 或者 Notion LIke 产品属于新的块级编辑体验笔记,拥有的页面和块无限层级,Back Link以及Database体验,与传统富文本编辑器在产品体验上有明显差异,本篇文章不着重描述,感兴趣可以先阅读 editorjs.io/
L2 富文本编辑器概览
分级
属于 L2 级
开发模式
- 编辑器核心输入区域是采用原生 JavaScript实现
- 顶部操作栏,侧边栏,内嵌栏,各种插件基于 React/Vue/原生JavaScript 皆可实现
核心模块
1.编辑引擎 & 计算引擎
独立的文档模型,管理文档 Model 与 View 之间的映射
2.布局引擎
重新实现渲染布局引擎,代替浏览器默认布局实现
3.协同引擎
多人协作操作OT,支撑多人同时在线协作编辑
4.插件引擎
支持编辑器block化的关键能力
关键设计
- command 的原子操作抽象和设计
- 大型前端软件的架构分层,面向扩展开放,面向修改封闭