Marijn的博客
如果对多人协作、富文本编辑器、代码编辑器、代码解析器、JavaScript性能感兴趣,Marijn的博客不能错过。
Marijn是谁呢?下面这些库都是Marjin开发的。
- Acorn: 一个用JavaScript开发的Parser,Babel、Webpack等工具都使用Acorn做代码解析。
- CodeMirror: 世界上使用最广泛的基于浏览器的代码编辑器。比如Chrome Devtools、Github、Codepen等等,都用了CodeMirror。作者最近正在对它进行重写。
- ProseMirror: 富文本编辑器。Confluence、Jira、Substack等编辑器都是基于ProseMirror开发的。
关于富文本编辑器
作者2015年对ProseMirror的介绍。
我使用ProseMirror时就有一些疑问,作者为什么要单独设计Schema、为什么要拆很多小package等。这篇ProseMirror初版设计文章基本都解答了。
大部分富文本编辑器都基于contentEditable,但contentEditable不可靠。
ProseMirror的思想和React.js很像,即把文档抽象为一个状态,文档的所有修改都由代码改变状态而不是由contentEditable控制。状态修改后,产生一个新的状态。
把浏览器事件转成自定义的操作,就可以很容易兼容不同浏览器、处理剪贴板、回退、拖拽、输入法的预输入等等。
另一个是basecamp的trix的做法,把contentEditable想象成一个IO设备,而IO设备就是不稳定不可靠的。
ProseMirror自己设计Schema,而没有用类DOM结构。一个重要的原因是:最终输出的不一定是HTML、可能是Markdown、或者任意格式文档。
另外,一个段落里的文字是扁平结构,而不是像DOM是一棵树,处理文本样式比较方便。比如一个文字不允许被加粗两次,而DOM树是可以 <em><em>test</em></em>
的。
ProseMirror定义了 inputrules 模块,能够轻易地实现输入 1. 空格
自动转换为有序列表。
ProseMirror的种种设计思路,使得可以基于它几乎做出任何可协作的富文本编辑器(就像文本编辑器届的React.js)。比如SciFlow的学术协作、Confluence、Jira、Bitbucket的编辑器、纽约时报的CMS。
关于多人协作
- ProseMirror的设计 (2015年)
- ProseMirror的协作算法 (2015年)
- 重写CodeMirror后的协作算法 (2020年)
ProseMirror设计之初就考虑了多人协作,这影响了history等模块的设计:因为协作中的undo不是撤销一个共享的history,而是撤销本地的上一次修改。
关于协作算法,文献中的和现实中的实现方式,是十分割裂的。
大部分文献考虑的是:完全分布式的协作、同时有多个人编辑、同样的角色、直接交换变更、并且都在同一个文档上。
而一个典型的Web系统,是客户端和服务端通信,由服务端来协调变更。
这两者面临的问题是截然不同的。如果你实现的是后者(非完全分布式),那么文献中提到的95%的问题,都不会出现。
文章里介绍了OT、CRDT的基本原理、二者的优劣、以及ProseMirror、CodeMirror分别用了什么方式。他们的Trade-Off分别是什么,以及都有哪些坑。
关于扩展性和插件系统
CodeMirror和ProseMirror的可扩展性都是非常强的。把可扩展性作为第一优先级考虑。这篇文章作者介绍了在设计插件系统时需要考虑的问题、常见的解决办法以及可能会遇到的挑战。
另外figma的文章也值得一读,是不同的角度:https://www.figma.com/blog/how-we-built-the-figma-plugin-system/
关于Roam Research
最近几个月一直使用Roam Research记录所有事情。Roam设计得非常精妙,很难找出结构上的缺陷。Block、Page、References等概念的设计,缺一不可。
Deep Dive Into Roam's Data Structure - Why Roam is Much More Than a Note Taking App
这篇文章详细的分析了Roam使用的数据库,数据结构,以及查询语法。
Roam使用的数据库是:Datomic。查询语法是Datalog。Datalog是Prolog的子集,看Wiki上大概是1977年就出现了,但我之前完全没有听说过它。
Roam内置了一个计算器 calc
发现Roam有很多组件是我平时几乎用不到的,比如看板、流程图、手绘、番茄时间等等。
最近发现计算器组件在记录菜谱时非常实用。我修改份数,就能自动计算每个原材料的量。比Google Sheets要更加直观。