目前大部分开源的富文本的实现,都是基于contenteditable,execCommand,selection浏览器api的而实现的,查看mdn, execCommand这个api面临着废弃,至于为什么要废弃这个api,我猜测可能是这个api背后实现的标签,太老了,例如strong等标签, 而且也缺乏更多的灵活性,标签可能会嵌套太多等.
通常大家把编辑器技术分为三个阶段
Level 0(不知道为啥从零开始)是编辑器的起始阶段,代表旧一代的编辑器的实现.
Level 1 第二阶段,是在第一阶段发展过来的,有一定的先进性,也引入了主流的一些编程思想,对于富文本内容有一定的抽象.
Level 2 第三阶段,完全不依赖浏览器的编辑能力,独立的实现光标和排版.
废弃后, 该如何实现富文本编辑器呢?
一.slate.js
依赖浏览器原生的编辑能力(Level 1 Pro)
Shchema 定义数据的约束规则(ProseMirror)
Nest Data Model(ProseMirror)
React作为视图层(Draft.js)
插件作为一等公民,开发者对于交互拥有很大的控制权(Draft.js)
Immutable、统一的数据更改Commands(Draft.js)
二.有道云的实现方式
使用XML严格定义了数据
编辑时,数据层与视图层分离
不依赖浏览器原生的Range/Selection,自实现NoteRange/NoteSelection及其绘制
不依赖contenteditable特性,使用中间层对接输入法
不依赖document.execCommand, 自实现全部命令及命令的管理
细粒度的undo/redo,占用更少的内存
更加可控,扩展性更强,有利于实现协同编辑、类Word分页等功能.
三.google docs
早在2010年Google Doc就使用了全新的技术来实现富文本编辑器,就是大家通常说的第三阶段(Level 2),
可以实现文本的独立排版,不再依靠浏览器的任何编辑功能,自主实现选区光标和内容排版,
只不过目前还没有一款基于这套架构的开源技术。
主要趋势都是要自行实现document.execCommand()这个命令,根据我的设想, 需要将编辑数据层与视图层分离,不再使用传统的实现方式(主要是给当前选区增加标签的方式), 而是使用增加css的方式,例如加粗, 直接使用css的font-weight属性,目前我也想不到如何自主实现选区和光标,这应该涉及到更深层的知识, 就像开发一个浏览器的原生功能一样.
采用类似vue的MVVM设计理念, 将编辑器编辑显示部分设计为视图层,引入虚拟DOM, 编辑器用户操作之后, 先生成AST,再根据设计的规则, 转换为最终的html标签集合.添加一张图片,就是先修改生成的AST,然后再输出.那么, 主要问题就转移到如何设计富文本编辑器的AST.以标签处理各种文本,但是选区是可以跨标签的,修改一个跨标签的选区的样式, 可能会涉及到修改多个标签的css属性. 可能会随着选区的变化, 不断删除或者新增虚拟标签节点Node.以上只是一周以来参阅各种富文本相关的文章获得的一些新知识, 刷新了我编辑器的新认知.