设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

为什么ContentEditable很恐怖

2014-11-19 10:27| 发布者: joejoe0332| 查看: 2857| 评论: 0|原作者: junker,LeoXu,Ley,无若|来自: oschina

摘要: ContentEditable 是一种在web浏览器上进行富文本编辑的本地原生组件. 它是那样让人…伤感.我会用一些顺手拈来的数学方法来想你证明,目前的ContentEditable的方法是不好的. 这并不是因为我觉得数学是解释这个论点的 ...



一个好的所见即所得编辑器框架


  一个最基本的 ContentEditable 元素是一个非常差的编辑器, 因为它打破了前面提到的所有定理.。那么我们怎样构建一个好的所见即所得的编辑器呢?


  对一个编辑器来说,有4个关键点。

  1. 创建一个文档模型,并且能够用一种简单的方式去区分两个模型是否在视觉上相等

  2. 创建一个在DOM与我们的模型之间的映射

  3. 在这种模型上能够定义表现良好的编辑操作

  4. 能够把所有的按键操作和鼠标点击转换成相应操作的序列


  我会简要的介绍每个关键点以及我们怎样对他们做出改变。最后,我会讨论浏览器工程师怎样才能把ContentEditable 做的更好,并且去掉这些组件中不好的部分


编辑器模型


  编辑器模型有两个领域:一连串的段落以及一连串的区域。


  每一个段落包括下面这些内容

  • 文本,一个普通文本的字符串

  • 标记,一连串格式化好的文本范围,比如“对位置1到5的字符进行加粗”

  • 图像或嵌入的元数据

  • 布局,一种我们怎样放置段落的描述


  一个区域描述一个子列表段落的背景。


  在编辑器中的任何选择操作都会被表述成两个点。每个点代表的是一个段落的索引和那么段落的文本偏移,以及一个类别。大多数选择操作都是文本类型的选择。我们也有媒介类型的选择(当提示信息显示在图片上时)和区域类型的选择(当提示信息显示在区域背景上面)。


  这种模型的优点是如果仅当这两种模型相等时他们会有同样的可视化渲染效果。对模型的任何改变都能转换到一个定义很好的可视化改变上来。


编辑器映射

  下面我会定义DOM空间到这种模型空间的映射。我们把这种映射分成两种:“室内”映射和“室外”映射。


  室内映射是指我们从编辑器中取出内容并且来回的在DOM空间和这种模型空间进行映射。我们希望室内映射是一对一的。


  室外映射是指我们从编辑器外获取HTML,就像用户从Word中拷贝HTML到一篇帖子中一样。我们需要把它转换到我们的段落和区域模型中。我们希望室外映射是有损的。我们优先处理普通文本,然后加粗/倾斜/超链接标签,然后图片以及其他各种各样的格式。


  我们的模型映射到DOM树后,看起来像下面这样:

1
2
3
4
5
6
<div<!-- root -->
  <section<!-- section -->
    <!-- section-inner -->
    <div class="section-inner layout-column">
      <p>  <!-- paragraph -->
        <strong><em>Baggins</em></strong<!-- text -->


  这个区域(section)节点是从区域模型中产生的,并且会将背景图片和颜色应用到一连串的段落中。


  这个区域内(section-inner)节点是根据段落排版属性而产生的,并且决定了主列的宽度。对于大部分段落来说,它是狭窄并且居中的。对于全宽的图片段落来说,它是100%宽的。对于上面的网格来说,它是原始的一般。


  下一个节点是段落的语义类别: P, H2, H3, PRE, FIGURE, BLOCKQUOTE, OL-LI (有序列表项), 和 UL-LI (无序列表项).


  当我们把标签类别转换到DOM节点的时候,我们会按照类别排序它们:A,然后 STRONG,再然后 EM。我们永远不会打印一个包含锚定的STRONG标签。我们会拆散它而让锚定包含STRONG标签。


编辑操作

  编辑器主要包括6个编辑操作:插入段落,移除段落,更新段落,插入区域,移除区域,以及更新区域。


  这些操作表现的会和描述的那样。段落操作会接受一个段落模型和一个索引。区域操作会接受一个区域模型和一个索引。


  所有可能的编辑器内容都能够被一系列的这些操作所表述,并且构造这样一个序列通常是比较简单的。


  显而易见,内容在这些编辑操作下能够表现的很好。这些操作是直接应用于我们的模型上面的,而不是DOM上面,并且这个模型能够更容易地区分两件东西在视觉上是否是相等的。


捕获编辑操作

  当你和编辑器交互的时候,我们必须将你的按键操作和鼠标点击操作转换成那6个操作的一个序列。


  这是最复杂的部分。我们不会对那么多的每种可能按键的序列履行职责。这对于一个以英语为语言的用户来说是一个非常巨大的列表,永远不考虑非拉丁字符和键盘。


  通过观察,我们能够用常规的ContentEditable键盘操作枚举所有对段落插入和移除的操作方式。他们是:回车(enter,ctrl-m,等。),删除(delete,backspace,等。),悬浮输入(type-over)(在一段选择的文本上输入),以及拷贝。所以我们能够捕获,取消,以及手动将这些键盘事件转换到我们的编辑器内部操作上来。


  对于所有其他键盘事件,我们让原有的ContentEditable 行为生效。在键盘事件结束之后,我们把段落的DOM映射回到段落的模型中来,并且和我们之前的模型进行比较。如果DOM改变了,我们会创建一个新的更新段落操作并且通过编辑器管线应用它,保持DOM和模型同步。


快速捕获编辑操作

  如果我们有无限计算的能力,那么直接应用这些编辑操作就可以了。我们应用这些操作到模型上,重新渲染的整个页面,最后结束操作。


  但是在现实生活中,对每个按键操作都重新渲染整个页面是非常慢的。并且你会看到许多丑陋的闪烁现象,因为内嵌框架(iframes)和图片会一直处于加载中。相反,我们会对模型的改变事件进行监听,并且尽最大可能减少对DOM的改变。


  当我在写篇文章时,我可以看到Chrome拼写检查程序在“keypress”单词下面所加的红色下划线在闪烁。这是因为编辑器正在同时对整个段落进行改变,而不是仅仅改变这个段落的一小块。如果我们仅仅对DOM进行相对很小的改变,那么闪烁就会消失,但是这样的代码会相对的更复杂。


期待将来有一个更智能的文本编辑操作

  最近有一些来自Chromium贡献者 (Levi Weintraub, Julie Parent, and Jelte Liebrand) 的流言说这些贡献者想去基于聚合元素(Polymer Elements)和Shadow DOM特性重做ContentEditable。这个方案也会像编辑器一样去尝试解决许多同样高级架构方面的问题。


  1. 创建一个由自定义 聚合元素(Polymer elements)构成的编辑器模型

  2. 定义编辑器模型与真实的具有 Shadow DOM特性的DOM之间的映射

  3. 所有在ContentEditable中的按键操作和鼠标点击操作都会被转换成一种抽象的编辑含义,被表示成像{editIntent: ‘delete’}这样的JSON对象。

  4. 聚合元素(Polymer Elements)对这样的编辑含义操作定义相应的处理方法


  如果编辑器能够获取某种编辑含义的API,那么我们就能够抛弃许多转换按键操作到抽象编辑操作的自定义代码了。将我们的段落模型当作聚合(Polymer)/ ShadowDOM元素是一件很有趣的尝试。


ContentEditable是什么

  不管我什么时候向那些从事于文本编辑器工作的人解释的时候,他们都认为我在玩花招。


  “当然编辑器要比ContentEditable更棒一些。你错了。ContentEditable努力的去成为一个通用的所见即所得HTML编辑器。而一般的编辑器放弃了'通用目的'的需求,所以你能够挑选你想去处理的任何HTML结构。”


  这是事实。但是确是误导的。


  一个好的所见即所得编辑器和一个好的具有通用目的HTML编辑器在理论上是不一致的。不可能把ContentEditable 构建成那样的,因为它们在需求上是冲突的。


  Steve Yegge的那篇“The Nonesuch Beast”文章影响了我的想法。 设计和UX(用户体验)问题与big-O算法问题一样地棘手。一个好的WYSIWYG任意HTML编辑器与halting问题一样不可能。


  ContentEditable可以挽救。 但它的使命必须改变。 丰富的DOM API像Shadow DOM一样,ContentEditable可能成为一个平台用来构建新一代的网络编辑器。但我们必须把它作为一个编辑平台和API,相对于独立的组件总比什么都自己做要好。


脚注:

  1. 如果你学过本科的高等数学, 一个良态的映射是一个态射。 那个单词感觉是费解的, 还带来了额外的包袱,在这里它不能帮助我们。 所以这次我们使用了良态。

  2. CSS复杂化这个讨论,和复杂的编辑算法,它的浏览器算法已经被实现。但是它不是一个彻底的证据证明,可以用来证明为什么ContentEditable是可怕的。 一般来说,我们忽视CSS, 也会限制我们对简单HTML的分析。


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部