2017 年末,公司组织了 WPS 黑客马拉松比赛已正式开赛,比赛的主题是:利用 WPS 客户端、云,及其它第三方开放服务,针对文档的查看 、创作 ,以及工作、学习中的团队分享、合作等,来构想并实现 WPS 产品创新点。冲着主题宽泛,开发时间长,且一等奖 1 万的奖金 🤑,毫不犹豫的报名了。经过一个多月的开发,SharedPen 富文本实时协同编辑器基本功能开发完成,最终在评审中也如愿获得一等奖 👏
SharedPen 目前仍处于开发阶段,欢迎感兴趣的朋友与我联系一起交流,项目地址:GitHub: YingshanDeng/SharedPen。本文将对 SharedPen 整体架构进行介绍,下列文章对其中具体的技术方案进行了详细介绍:
SharedPen 之区间树优化
前文 SharedPen 之 AnnotationList 讲到:
为了管理,操作整个富文本文档流,我们引入 AnnotationList 单链表结构,把每一段富文本当成
Node
节点,由此形成链表结构。
单链表数据结构形象容易理解,但是执行操作(增删改查)的效率比较低,所有操作的算法复杂度都是 O(N)
(其中N为节点数);优化的方向是将链表数据结构改造成树形结构。本文将对优化思路进行分析。
SharedPen 之 Operational Transformation
当多用户协同编辑同一篇文档,由于没有锁的机制,便会出现内容冲突,这时就需要一定的算法来自动解决冲突,使所有对文档的修改同步后,每个协同编辑的用户看到的文档内容是完全一致的。而 Operational Transformation (简称 OT) 算法就是解决协同问题的通用算法,支持各类协同编辑引用,例如文档,表格,演示,代码编辑等。其最早发表于 1989 年,后因 Google 的在线协作产品 Google Wave,Google Docs 的应用而成熟流行。
关于 Google Wave: Google Wave,值得纪念的伟大失败
GitHub 上开源项目 ot.js 已经对 OT 算法进行 JavaScript 语言实现。本文将对 OT 算法进行介绍 👉
❗️注意: ot.js 库只是针对纯文本协同编辑的 OT 算法实现;SharedPen 使用了这个库,但是 SharedPen 支持富文本编辑,所以需要对 ot.js 库进行增强,使之支持富文本文档编辑的协同。
SharedPen 之 AnnotationList
CodeMirror 是一款优秀的开源文本编辑器,常用于代码编辑器。但并不支持富文本编辑功能。但是得益于 CodeMirror 的 API
markText: Can be used to mark a range of text with a specific CSS class name.
能够为指定 range 的文本设置一个 CSS class,这样我们就可以通过这个 class 来设置富文本样式。例如对于文本:ABCDEFGHF
,我们可以通过如下方式为其设置 class
markText
方法会返回一个 CodeMirror.TextMarker
对象,该对象中的 clear()
方法用于清除 class,这样就非常便于我们动态为文本设置富文本样式了。
为了管理,操作整个富文本文档流,我们引入 AnnotationList 单链表结构,把每一段富文本当成 Node
节点,由此形成链表结构。
本文将详解 AnnotationList 单链表结构 🤓
探究 Gulp:基于流的自动化构建工具
Gulp 是三个自动化构建工具(Grunt, Gulp, Webpack)之一,其通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理,仅提供几个 API 就能将构建任务很好完成,而且有着丰富的插件生态,本文将探究 Gulp 的原理及如何创建插件。
检测鼠标指针移动离开页面
本文将介绍一种方法用于检测鼠标指针在页面中移动时,判断是否离开页面 👉
学习正则表达式
对正则表达式,我们并不陌生。在很多地方都会用到,尤其是字符串处理,正则表达式更是一把利器。本文通过一个例子来学习总结一下正则表达式的一些知识内容 🤓
Node.js 中的 UnhandledPromiseRejectionWarning 问题
问题引入:今天在 Gulp 构建任务中出现一个 html 解析错误,但是并没有报错,也没有中断 gulp 构建任务的执行,而是出现 UnhandledPromiseRejectionWarning
的警告,所以会误以为构建成功,这篇文章将对此进行探究并解决该问题。
|
|
探究数据绑定(2)ES6 Proxy
在上一篇文章:探究数据绑定(1)脏检查和存取器方法 中,探究了 ES5 中实现数据绑定的两种方式;而在本文中,将会探究使用 ES6 Proxy 实现数据绑定。
探究数据绑定(1)脏检查和存取器方法
Data binding is a general technique that binds data sources from the provider and consumer together and synchronizes them.
在前端组件化框架中,基本都有数据绑定这一特性,数据绑定是将生产者的数据源绑定到消费者,并负责数据同步。本文将探究数据绑定的不同实现方式。🤓
目前主要有以下几种实现方案:
- 脏检查(dirty check)
- 存取器方法(accessor method):
Object.defineProperty
ES5 Proxy
: ES6 支持较差【Proxies are one of the few non polyfillable additions.(babel不支持转换)】Object.observe
: ES7,已经移出草案,不支持object.watch
: 目前只有基于gecko的浏览器如火狐支持,官方建议仅供调试用
其中前两种方式是主流,angular、Polymer 使用的就是脏检查,Vue 使用的就是存取器方法。