让我们继续探究富文本编辑器ProseMirror。

ProseMirror是通过Step来管理文档的改动呢。Step用来表示一个原子级的改动,既可以应用(apply)到现有文档之上,形成一个新的文档。又可以撤销(invert),把文档恢复到改动之前的状态。

在文档上应用Step不一定会成功,它会返回一个StepResult,包含一个failed属性,用来指示这个Step是否应用成功。

另外多个Step可以还可以合并(Merge)到一起,形成一个新的Step。

Mapping

同时,Step还支持getMap()方法,可以返回一个StepMap。这个StepMap记住了文档改动的位置信息,里面记载的是一系列信息,主要包括:

  • 改动的开始位置
  • 改动前的大小
  • 改动后的大小

有了上面这些信息,可以把文档之前的索引更新为文档改动之后的索引。

多个StepMap还可以组合起来,用一个Mapping类型来管理。

除此之外,Step还有一个map(Mappable)方法,可以通过其他的Mappable来更新自己的mapping。这个主要是用来支持Rebasing的。

Transform

ProseMirror提供了一个Transform类,专门用于管理文档的改动。Transform可以把多个Steps累计到一起,把它们逐个应用到文档中。另外,Transform还保留了一个文档列表。因为采用immutable数据结构的关系,每次应用一个Step,就会产生一个新的文档,但是也会留下一个旧的文档。Transform会把这些旧的文档聚拢在一起,形成一个数组。

另外直接使用Step来修改文档会显得有点繁琐,Transform提供了很多方法来方便文档操作:

  • insert,插入内容
  • delete,删除内容
  • addMark,给平铺内容添加标记
  • removeMark,删除标记
  • replace,替换内容
  • ……

更多可以参考ProseMirror Guide: Transforms

Editor State 和 Transaction

作为一个编辑器,ProseMirror的状态(State)除了文档本身之外,还有一些其他因素,比如当前的选取范围(Selection)、以及当前使用的标记集合等等。所以ProseMirror用一个新的类EditorState来表示状态。跟这个相搭配的,Transaction(Transform的扩展类)用来管理针对EditorState的改动。Transaction除了处理文档改动之外,还管理选取范围、当前使用标记集合、还有时间戳等等。Transaction可以直接从EditorState的tr属性来生成。

EditorState并不是通过new EditorState()这种方式创建,而是通过EditorState.create()静态方法创建的。EditorState使用一个叫Configuration的类来保存参数,这个Configuration类可以包含以下内容:

  • schema
  • doc
  • selection
  • storedMarks
  • plugins

(未完待续)