ckeditor 核心函数图解

序言:

 

    承接上文,ckeditor 既然不用 execCommand ,那么编辑器的格式化功能就只能通过自己手动添加格式化标签实现,一般格式化包括四步:

1.得到选择位置,

2.抽取选择节点集,

3.对节点集格式化,

4.格式化节点集加入文档,

    其中第1步在标准浏览器中可以通过w3c range 直接得到,而ie 则要费些周折,而2,3,4则是真正麻烦的地方,2要保证节点集的完整性,3要防止格式化代码的冗余,4则要判断最终插入的位置。其中第2步其实w3c range已经实现,但是ck为了最大程度地兼容各个浏览器,不依赖于浏览器,使用了 dom2-core 来自己实现对应功能,毕竟参照规范:The Range interface provides methods for accessing and manipulating the document tree at a higher level than similar methods in the Node interface. The expectation is that each of the methods provided by the Range interface for the insertion, deletion and copying of content can be directly mapped to a series of Node editing operations enabled by DOM Core. In this sense, the Range operations can be viewed as convenience methods that also enable the implementation to optimize common editing patterns.(在这一点上又同css选择器引擎构建 类似)

 

      本质上文档是DOM树,抽取插入格式化节点集都是对树进行操作,树(tree data structure) 作为计算机科学中一种重要的数据结构,在web信息抽取编译语法树 )以及自然语言处理领域 已经达到了广泛的应用,而在浏览器前端由于复杂度多由服务器承担而不受重视(近来也开始渐受关注,参见 high performance javascript ),基于浏览器的编辑器随着用户的持续修改,会对dom树产生巨大的变动,相应地树操作算法对于编辑的流畅性变得至关重要。

 

Demo :


ckeditor core

 

 

核心函数:

 

range.extractContents


对应于规范的同名函数 extractContents ,将用户选中的区域节点集完整抽取出来作为 DocumentFragment 返回:(注意连续文本节点需要 splitText 操作),并且将选择范围 collpase 到一点。


抽取前:


绿色表示文本节点,红色表示标签

 

 

 

 

抽取后得到的文档碎片:


包含了完整的选择区域节点集,需要注意 为了完整性: 起始节点所在树路径的节点必须复制下来:

 

 

 

 

抽取后的文档树:

 

注意从开始节点到结束节点,以DFS(深度优先)遍历遇到的节点如果不在起始节点的树路径上则直接删除:

 

 

dom.mergeSilblings :

 

随着用户的添加删除,必然剩下很多没有文字节点的空标签,如<span style="xx">1</span><span></span>...,ckeditor在下次添加格式标签后会进行标签合并工作:


合并前:

 


合并后:

 

 

 

 

style.applyInlineStyle

 

和规范中的 surroundContents 类似,简单的说就是调用了 extractContents 和 mergeSilblings ,生成对应的格式标签包裹抽取节点集,然后插入到原来的选择位置。不过这个函数也有一些处理:

 

1.range 切分

 

将 range 切分为一系列更小范围的 range,使得格式标签根据 xhtml dtd 嵌套规则得以能够包裹这个 range 的 html 内容,譬如选择了 p 标签以及其内的所有内容调整字体大小,但是格式标签<span style="font-size:xx"></span>并能直接包裹 p ,而只能包裹 p 内的行内元素,然后再由 p 来包裹 格式标签,遇到选择多个 p 时更需要逐一处理,即切与分。 


2.抽取节点集的格式清理 ,子节点重复的style属性删除


包裹后格式清理前:

 

<span style="xx">

<span style="xx">
zz
</span>

yy

</span>

 

包裹后格式清理后:

 

<span style="xx">

<span>
zz
</span>

yy

</span>

 

3.无属性,无样式的标签清理


清理前:

 

<span style="xx">

<span>
zz
</span>

yy

</span>
 

清理后:

 

<span style="xx">

zz

yy

</span>

 


总结:


上述只是大概说明了实现编辑操作的必要需求,但是性能则取决于具体算法实现,或许前端是时候看看图论 了。


 

PS:调试相关

 

建议 firefox(代表标准浏览器下)使用 firebug 调试,ie使用 ie8 自带调试工具,双屏对比调试就能对浏览器差异有更深刻的认识了:

 

 

 

(修订于:2010-08-08)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值