前言
注意下,是框架,不是编辑器
这个系列,主要是参考的 react 开源社区的 Slate 编辑器框架来写的,其他例如draft.js等没研究过不好对比。不了解这个框架的,可以先看下这篇文章 Slate.js - 革命性的富文本编辑框架
目前有很多轻量级的编辑器,很多都是使用 document.execCommond(),这个方法不同浏览器厂商的实现都不一样,不靠谱,我是不喜欢这种方式的。2018年关注到 Slate的时候,我就被它的设计吸引了。它设计的model和 react 的配合,在我看来,确实是实现编辑器框架的一个可行方案。
这个系列,可能不会贴很多源码,主要是介绍概念,以及大体的结构,所以每一篇篇幅都不会长。对相关代码感兴趣可以去文末我的github上看,额外的资料我也会贴在文末。当然自己也可以研究分析 Slate 最新的源码。
目录
- 如何开发富文本编辑器框架(一) 了解Leaf、Text、Mark
- 如何开发富文本编辑器框架(二)——了解选区
- 如何开发富文本编辑器框架(三)——了解Decoration、Inline、Block、Document模型
- [如何开发富文本编辑器框架(四)——History实现redo、undo]
- [如何开发富文本编辑器框架(五)——借助Schema自动校验内容]
- [如何开发富文本编辑器框架(六)——高扩展性的插件系统]
- [如何开发富文本编辑器框架(七)——神奇的 Change ]
- ...
正文
废话不多说。今天我计划先介绍 Leaf、Text、Mark 模型。
Leaf 叶节点
字面意思,这个是叶节点,处于树形结构里最末梢的节点。Slate 里的Node 模型,是对照dom设计的,所以节点间的关系同样是嵌套的树形结构关系。因这个设计,在使用 React 渲染相应节点时也方便处理。
new Leaf({
text: 'hello world',
marks: ['bold', 'italics']
})
Mark 模型,在后面会介绍为什么会有这个。一个 Leaf 节点包含一个 text 属性,里面存放一段文本。
没了,Leaf 数据模型就是这样简洁:)。
Text 文本节点
显而易见,这个是文本节点。一个 Text 节点里可能包含多个 Leaf 节点。
new Text({
leaves: [
new Leaf({
text: 'hello world',
marks: ['bold', 'italics']
})
]
})
为什么一个 Text 内可能存在多个 Leaf ?
因为,一段文本可能有多种文本修饰。比如 markdown 里,有的文字加粗,有的斜体。
Text({
leaves: [
Leaf({
text: '有的文字',
marks: []
}),
Leaf({
text: '加粗',
marks: ['bold']
}),
Leaf({
text: ',有的',
marks: []
}),
Leaf({
text: '斜体',
marks: ['italics']
}),
]
})
这个就是 Mark 数据模型的作用,意味标记。加粗、斜体、上标、下标,诸如此类的都可以归为 mark。
如果相邻的 Leaf 节点拥有相同的 marks,我们会在合适的时机合并这两个 Leaf 节点。
说到合并 Leaf 节点,我们自然会想到怎么拆开一个 Leaf?
比如,如果我们上面的 文字也加粗,我们怎么知道从哪里开始截断 Leaf,产生一个新的Leaf,并和后面的加粗 Leaf合并?
这个我们就要开始引入 Point、Range、Selection 模型了。
今天就先讲这么多,Point、Range、Selection 留到如何从零开始开发富文本编辑器框架(二)讲。对这方面感兴趣的欢迎关注我的 Github,有几个 repository 都和这个相关,是我摸索时建的。