`
yiminghe
  • 浏览: 1460382 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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)

 

 

  • 大小: 49.7 KB
  • 大小: 39.3 KB
  • 大小: 37.4 KB
  • 大小: 42.5 KB
  • 大小: 37.6 KB
  • 大小: 316.2 KB
分享到:
评论
10 楼 yiminghe 2011-02-18  
qzlake 写道
这些图片用PowerPoint画的吧?


截图工具 snagit
9 楼 qzlake 2011-02-18  


这些图片用PowerPoint画的吧?
8 楼 yiminghe 2010-07-28  
campaign 写道
比如在ie下,选区是跨td的,我要对里边的文字加粗strong,那不能简单的用extractContents,来做,因为根据dtd,td肯定不能放在strong里,那么就要对这个大的 range进行小的细分,小到每个小的range包含的内容都能放到strong,那么在用extractContent取出来,style.js就是干这个事情的
ff可以自动吧range分了,但是得到的range要shrink,才好在操作


多谢,我没看仔细,理解不全面!确实styles/plugin.js applyInlineStyle 里面有循环,内层循环根据 dtd 从原先的 range 中切出 小range(styleRange)再进行extractContents格式化
7 楼 campaign 2010-07-28  
比如在ie下,选区是跨td的,我要对里边的文字加粗strong,那不能简单的用extractContents,来做,因为根据dtd,td肯定不能放在strong里,那么就要对这个大的 range进行小的细分,小到每个小的range包含的内容都能放到strong,那么在用extractContent取出来,style.js就是干这个事情的
ff可以自动吧range分了,但是得到的range要shrink,才好在操作
6 楼 yiminghe 2010-07-27  
campaign 写道
将range按着操作切分成小的range,以满足操作的要求,我觉得这个是ck的很核心的东西,等于是做了原生命令的事情,对于后续的对于小的range进行extractContents,在按着自己的要求添加相应的元素,使其各个浏览器保持风格统一。我认为walker是为range服务的,但range是为style服务的

range切小range?ie下就一个range转换成标准兼容返回 [ range ],其他浏览器稍微转一下返回ranges,然后对每个range操作既可以了,这个不算很核心吧,核心还是树操作
遍历是很重要的组成部分,包括(逐渐抽象):
1.next/preSourceNode
2.walker
3.domiterator
5 楼 campaign 2010-07-27  
将range按着操作切分成小的range,以满足操作的要求,我觉得这个是ck的很核心的东西,等于是做了原生命令的事情,对于后续的对于小的range进行extractContents,在按着自己的要求添加相应的元素,使其各个浏览器保持风格统一。我认为walker是为range服务的,但range是为style服务的
4 楼 yiminghe 2010-07-26  
campaign 写道
既然你说到了style,我认为你应该先说style,在说extractContent,等
因为dom树上的选中的range很多都不能直接用extractContent,来切出来,尤其是ie,没有多range的概念
要先用style,切分割range成小块,再在小块的range中用extractContent,


呵呵,这个不难,就是style里循环一下,我觉得没有必要说吧
3 楼 campaign 2010-07-26  
既然你说到了style,我认为你应该先说style,在说extractContent,等
因为dom树上的选中的range很多都不能直接用extractContent,来切出来,尤其是ie,没有多range的概念
要先用style,切分割range成小块,再在小块的range中用extractContent,
2 楼 yiminghe 2010-07-22  
luolonghao 写道
:idea:,分析的不错,我觉得tinymce的架构也不错,也可以一起研究一下。

好啊,不过更希望你能听取yubo建议过来这边一起研究
1 楼 luolonghao 2010-07-22  
:idea:,分析的不错,我觉得tinymce的架构也不错,也可以一起研究一下。

相关推荐

    jsp中使用ckeditor

    配置项可以通过`config`对象传递给`CKEDITOR.replace()`函数。例如,设置编辑器高度和禁用图片上传: ```javascript CKEDITOR.replace('myEditor', { height: '300px', filebrowserBrowseUrl: null // 禁用图片...

    ckeditor5全屏按钮

    此外,还可以通过监听编辑器的事件来在全屏模式切换时执行特定的函数,比如保存当前编辑状态或者更新页面元数据。 为了集成CKEditor 5全屏按钮到自己的项目中,开发者需要引入CKEditor 5的库文件,并按照官方文档的...

    ckeditor配置(详细)

    1. **引入CKEditor核心文件**:要在页面中使用CKEditor,首先需要在`&lt;head&gt;`标签内引入CKEditor的核心文件`ckeditor.js`。此文件包含了CKEditor的所有功能和逻辑。 ```html &lt;script type="text/javascript" src="...

    CKEditor集成CKFinder配置完成插件(附图解)

    CKEditor和CKFinder是两个非常流行的开源富文本编辑器和文件管理工具,广泛应用于网站内容管理系统、论坛和其他需要用户编辑和上传文件的平台。CKEditor提供了丰富的文本编辑功能,而CKFinder则为CKEditor提供了方便...

    ckeditor4 行高插件

    为了实现这一功能,插件的核心代码会涉及到DOM操作、CSS属性设置以及CKEditor的事件监听。例如,当用户选择一个新的行高时,插件需要找到选中的文本元素,然后更新其CSS的`line-height`属性。此外,插件还需要处理...

    ckeditor的demo代码

    总的来说,这个"ckeditor的demo代码"主要展示了CKEditor的基本用法和核心概念,包括如何引入CKEditor库、创建编辑器实例、配置编辑器选项以及如何通过JavaScript与编辑器进行交互。对于初学者来说,这是一个很好的...

    ckeditor 行间距插件

    CKEditor 的行间距插件通常包含以下几个核心知识点: 1. **安装与集成**:首先,你需要将行间距插件下载并添加到CKEditor的配置中。这通常涉及到将`lineheight`文件夹放入CKEditor的plugins目录下,并在配置文件中...

    CKEditor3.0稳定版

    至于压缩包内的"ckeditor"文件,这通常是CKEditor的核心文件夹,包含编辑器的JavaScript文件、CSS样式表、语言包、插件和示例文件。安装或集成CKEditor时,通常需要将这个文件夹中的内容部署到服务器的相应位置,并...

    ckeditor 最新的安装包

    在这个压缩包中,你将找到CKEditor的核心文件,这些文件是构建和配置编辑器的基础。 CKEditor的主要特点包括: 1. **易用性**:它拥有直观的用户界面,无论是新手还是经验丰富的开发者都能快速上手。编辑器提供了...

    CKeditor控件.net版

    3. CK:同样,这可能是一个目录,包含CKeditor的核心文件或者.NET控件的实现代码。可能包括CKeditor的JavaScript库、CSS样式表,以及与.NET环境交互的C#类库等。 总结来说,这个压缩包为.NET开发者提供了完整的...

    让ckeditor只读 让ckeditor只读

    把ckeditor 3.4的ckeditor.js复盖就行

    ckeditor 完美精简版、优化版,附带调用方法页面

    - `plugins`目录是CKEditor的核心部分,包含了各种插件,如媒体嵌入、公式编辑、代码高亮等。 使用这个优化后的CKEditor,开发者不仅可以快速集成一个功能完善的富文本编辑器,还能通过调整配置和样式,使其更好地...

    CKEditor2.6.rar

    首先,我们来了解一下 CKEditor 的核心功能。CKEditor 提供了完整的文字编辑功能,包括字体、字号、颜色、对齐方式的调整,以及段落格式化等。此外,它还支持插入图片、链接、视频和各种媒体内容,使得用户能够创建...

    CKEditor(Standard Package)

    这个文件通常命名为`ckeditor.js`,它是CKEditor的核心,负责初始化编辑器实例、处理用户交互和提供各种编辑功能。此外,可能还会有其他相关的CSS和语言文件,如`contents.css`用于定义编辑器内的默认样式,以及不同...

    ckeditor4.2 自定义按钮和下拉框实现

    插件是CKEditor的核心组成部分,通过插件,我们可以添加新的功能或修改现有行为。要创建一个自定义按钮或下拉框,我们需要创建一个新的插件。 ### 创建自定义按钮 1. **创建插件文件**:在你的项目目录下,创建一...

    ckeditor及配置方法

    然后,为需要转换成编辑器的文本区域添加`id`,并调用CKEditor初始化函数: ```html &lt;textarea id="myEditor" name="myEditor"&gt;&lt;/textarea&gt; CKEDITOR.replace('myEditor'); ``` ### 4. 配置CKEditor CKEditor...

    ckeditor配置上传视频

    最近项目开发需要用到CKEditor在线编辑器,但发现他本身没有自带,所以需要自己手动配置插件。但网上很多配置都有问题,自己摸索了好久终于搞定。需要注意的细节有:flvPlayer文件夹的内容直接放在ckeditor文件夹...

    ckeditor5_v19完整版

    `index.html` 文件是网页的入口文件,包含了引入CKEditor5的核心代码,用户可以通过修改这个文件来集成编辑器到自己的网站中。`ckeditor.js` 和 `ckeditor.js.map` 分别是编辑器的主要脚本文件和源码映射文件,前者...

    ckeditor 自定义上传图片

    **ckeditor自定义上传图片** 在使用ckeditor作为富文本编辑器时,经常需要集成图片上传功能。ckeditor是一款强大的在线文本编辑器,它提供了丰富的文本格式化工具,使得在网页上编辑内容变得简单。然而,ckeditor...

    ckeditor4.0 最新版本

    CKEditor 4.0 的核心特点包括高度自定义、强大的功能集以及对多种浏览器和平台的良好兼容性。 1. **高度可定制性**:CKEditor 4.0 允许开发者根据需求定制编辑器的外观和功能。你可以选择启用或禁用各种工具栏按钮...

Global site tag (gtag.js) - Google Analytics