Custom Elements 中文规范

W3C Editor's Draft

当前版本
http://w3c.github.io/webcomponents/spec/custom/
最新版本
http://w3c.github.io/webcomponents/spec/custom/
前一个版本
http://www.w3.org/TR/custom-elements/
校订历史
https://github.com/w3c/webcomponents/commits/gh-pages/spec/custom/
参与
讨论 public-webapps@w3.org (Web Applications Working Group)
File bugs (w3.org's Bugzilla)
编辑
Dimitri Glazkov, Google, <>

摘要

该规范介绍了允许开发者在文档里定义和使用新的DOM元素类型的方法

文档状态

本节介绍此文档发布时的状态。其他文档可能取代此文档。在 W3C 技术报告索引 (http://www.w3.org/TR/) 可以找到此技术报告的当前W3C发布版本和最新修订版本列表。

此文档是由 Web应用工作组 发布的编辑草案。如果你想提交关于此文档的评论,请发送至 public-webapps@w3.org (订阅存档)。 欢迎任何反馈。

发布为编辑草案并不意味着 W3C 会员的认可。这是一个文档草案,可能在任何时候更新、覆盖或被其他文档替代。不宜在在产品中引用此文档。

此文档由 W3C 专利政策 (2004-02-05) 操作的一个小组出品。 W3C 维护一个关联此小组产出成果的 专利声明的公开名单,该页面还包含了专利公开说明书。根据 W3C 专利政策第6条,拥有专利实际知识,且相信包含基本权利的人必须公开相关信息。

目录

  1. 关于本文
  2. 依赖
  3. 动机
  4. 概念
  5. 自定义元素生命周期
    1. 入栈和调用回调函数
    2. 回调函数类型
  6. 创建和传递注册
  7. 注册自定义元素
    1. 扩展文档接口
    2. Unresolved伪类元素
  8. 实例化自定义元素
    1. 扩展文档接口
  9. 解析自定义元素
  10. 自定义元素和ECMAScript 6
  11. 附录A:在一个图中的所有算法
  12. 鸣谢

关于本文

所有图表,示例,备注,以及明确标记为非规范的部分都是非规范的。其他内容都是规范的。

在本文档的规范部分中的关键字 "必须", "禁止", "要求", "会", "不会", "应该", "不应该", "推荐", "可以", 和 "可选" 在 RFC2119 的描述中有解释。为了方便阅读,这些词语不会以全部大写字母出现在本规范。

任何时刻,一个符合UA必须对状态或概念模型状态的反应做决定。这被称为算法。这些算法根据等价处理定义。等价处理 是强加给算法实现者的约束。对于相同的输入,要求UA实现和指定算法的输出必须保持完全一致。

依赖

文档依赖以下规范:

动机

有两个动机,加剧了本规范的发展:

  1. 提供一种方法让Web开发人员建立自己的,功能齐全的DOM元素. 虽然长期以来可以用任何HTML标签去创建DOM元素,但是这些元素实用性不够。 通过给web开发者方法去告诉解析器如何正确构建元素,并且对元素生命周期的变化做出反应, 该规范省去了DOM作为一种渲染视图脚手架现已存在于大多数web框架或是库这个必要。
  2. 理顺平台。该规范确保其所有的新特性和功能在网络平台相关位协调运作,所以这些新特性可以用来解释现有网络平台的特性功能,例如HTML元素。

大部分花在寻找两个动机平衡的努力,由动机不是相互违背而且是互补的愿望驱使。例如,尽管该规范的范围目前仅限于由作者创建自定义的元素,它旨在缩短与一个更加宏伟目标的距离,这个目标是理顺所有的HTML,SVG和MathML元素到一个连贯的系统。

概念

自定义元素是一个 平台对象接口由开发者定义。自定元素接口接口原型对象被称为 自定义元素原型

自定义元素类型 标识一个自定义元素接口 必须NCName 产生方式相匹配的字符串,必须包含一个U+002D连字符号字符, 且不能包含任何ASCII大写字母. 自定义元素类型禁止是下面的任何一种:

上面的名称列表是所有来自适用规范中包含连字符元素的名称的总结, 即 SVGMathML.

元素定义描述了一个自定义元素,包括:

在创建时, 文档可以和一个注册表关联。注册表元素定义集合

元素注册是一个添加元素定义到一个注册表的过程。 一个元素定义只能被注册到一个注册表.

如果一个文档 有一个与之关联的 注册 , 那么这个 文档 和在这个 注册表特定的 元素定义 , 自定义元素接口 必须元素接口 ,分别为 自定义元素类型本地命名命名空间值,和元素定义命名空间

实际上,每当一个新的DOM元素被创建的时候注册表被查询,是否由解析器执行。每当一个匹配的元素定义在注册表中被找到,在这个定义中的信息用于创建一个自定义元素的新实例。

如果一个文档 没有一个 注册表与它关联, 所有元素注册 的尝试就会失败。

确切建立注册,与文档关联, 元素注册在这个规范被进一步定义 。

自定义元素生命周期

一个 自定义元素 可以在它的生命周期贯穿这些改变:

各种回调函数被调用当一个自定义元素 贯穿这些变化。这些回调函数在内部以建-值对的集合存储,被称为生命周期回调函数

把一个被称作 name 的回调函数从一个被称作property的对象属性转移到 生命周期回调,用户代理 必须 执行以下步骤:

输入
NAME, 回调函数的名字
PROPERTY, 属性的名字
OBJECT, PROPERTY被移交到的对象
LIFECYCLE, 生命周期回调函数
输出
None
  1. CALLBACK成为获取 一个被称作 OBJECT PROPERTY的属性的结果
  2. 如果 CALLBACK存在且是一个可调用的对象, 把 CALLBACK 添加到LIFECYCLE, 用键 NAME来关联。

入栈和调用回调函数

为了方便调用回调函数, 相关的类似浏览上下文的每个单元 有一个处理堆栈, 最初是空的。堆栈的每一项是一个元素队列,最初也是空的。元素队列的每一项是一个 自定义元素

每个 自定义元素有一个相关的回调队列和一个元素被创建成为 标志。标志最初设置为 false 以及 回调队列 最初是空的。在队列中的每项包含回调本身和零个或多个被用作回调参数的字符串值。

在一个 元素队列调用回调函数, 用户代理必须 执行这些步骤或类似:

输入
QUEUE, 一个元素队列
输出
None
  1. 队列每个元素自定义元素 :
    1. CALLBACKS 成为 元素回调队列
    2. 重复直到CALLBACKS是空的:
      1. CALLBACKS移除第一项,让 CALLBACK成为这一项
      2. ELEMENT作为回调函数的值 去调用 CALLBACK, 如果存在,在 CALLBACK中用字符串值作为参数

任何时候,一个脚本调用一个方法,读取或设置属性由用户代理执行,下面的操作必须出现:

如上所述,这些行为包含每个用户代理实现的方法或属性访问。预期的效果是任何生命周期回调, 排队运行这些方法或访问器的结果是把控制权返回给脚本调用。如果一个方法或访问被永不排队生命周期回调所知,用户代理可以选择不把它包装成一个性能优化。

除了一个元素队列, 也有一个排队的元素队列自定义元素被保存在增加 自定义元素顺序的顺序中。

自定义元素顺序文档自定义元素顺序输入树顺序的总和, 其中 输入树顺序 被控制以使它的最低值总是比文档自定义元素顺序的最高可能值要大。

文档自定义元素顺序是一个数值,与每一个自定义元素相关。 这个值是 自定义元素文档 保持一个递增的数值并分配到 自定义元素 作为它的 自定义元素顺序 每当发生以下情况的结果:

输入树的特定自定义元素输入树顺序 由被压入每个输入链路输入文档的内容来替换的输入树树顺序决定。

最稳定的顺序 是紧接着前面的一个元素在第一个入口的 自定义元素顺序的值,在树顺序, 其 准备好的标志 尚未设定。 如果不存在这样的元素, 最高的稳定顺序在扁平的输入树里 是最高的自定义元素。

由于输入异步加载, 我们需要将一个有序的元素放入已经稳定的队列里(所有的输入已经加载),以及一直还在加载的部分里,因此实际排序顺序尚未确定。 例如,假设您有以下文件结构:


index.html:
<link rel="import" href="import.html">
...
<me-second></me-second>
...

import.html:
<me-first></me-first>

自定义元素在扁平输入树的顺序是 me-first (1), me-second (2)。 然而, 解析器很可能找到me-second 快于me-first,因为后者需要加载 import.html。当网络堆栈在执行时,最高的稳定顺序停留在最初的位置。当 import.html 已经准备好了, 顺序会跳到me-second (2).

每一个 与浏览器上下文相关的单元有一个最初为空的存储元素队列, 被成为 基本元素队列.

作为microtask checkpoint的一部分, 用户代理 必须 处理基础元素队列与浏览器上下文相关的单元脚本浏览上下文

为了阻止重写,当 处理基础元素队列时,每一个 与浏览器上下文相关的单元有一个处理基础元素队列 标志, 必须 初始化为false.

目前,HTML规范已经在microtask checkpoint有步骤的处理顺序 。因为每一步都可以潜在地为过去的步骤产生额外microtasks, 这可能导致microtask checkpoint 目标不完全执行。本规范假定这一不足已得到解决 ,并添加了新的步骤到 microtask checkpoint ,确保用尽microtasks的各种类型步骤。

为了处理基本元素队列, 用户代理必须 执行以下步骤或 同等

输入
ENVIRONMENT, 与浏览器上下文相关的单元
输出
None
  1. PROCESSING 成为 处理解基本元素队列 标志
  2. 如果 PROCESSINGtrue, 停止.
  3. 设置 PROCESSINGtrue.
  4. 调用回调ENVIRONMENT基本元素队列上升为 最高稳定顺序(含)
  5. 设置 PROCESSINGfalse.

在属于脚本浏览上下文 与浏览器上下文相关的单元 , 当前元素队列处理堆栈 的顶部的元素队列,或是基本元素队列 如果 处理堆栈 为空。

排队一个生命周期回调, 用户代理必须运行以下步骤或等同:

输入
NAME,回调函数的名字
ELEMENT, 为回调函数排队的自定义元素
输出
None
  1. DEFINITION 成为 ELEMENT定义
  2. 如果DEFINITION 不存在, 让 CALLBACK 成为null 并且 停止
  3. CALLBACKS成为生命周期回调函数 通过 DEFINITION
  4. CALLBACK 成为回调函数, 在 CALLBACKS里与key NAME关联
  5. 如果没有这样的回调, 停止。
  6. 添加 CALLBACKELEMENT回到队列
  7. 如果 被创建的元素 标志为 false, 添加 ELEMENT当前元素队列

回调函数类型

下面的回调确认:

createdCallback
这个回调被调用在自定义元素 实例被创建之后,并且 定义注册。这个回调的确实时间在本规范中会进一步定义。
定义元素原型 必须设置 在调用回调函数之前。
回到函数调用期间,被创建的元素 标志 必须 设置为 true。 在所有情况下,标志 必须 被设为 false
如果被 创建 的回调存在于一个元素,所有回调 不能被排队直到 被创建 回调的调用开始。
attachedCallback
除非另有规定,回调 必须入队自定义元素插入一个文档 这个 文档有一个浏览上下文
detachedCallback
除非另有规定, 回调 必须入队自定义元素从文档移除 这个 文档 有一个 浏览上下文
attributeChangedCallback
除非另有规定, 回调 必须入队自定义元素属性添加, 修改 或是 移除。根据 属性 修改类型, 下列额外的字符串被添加到队列项中:
属性被设置
属性名, null, 新 属性值, 和 属性命名空间
属性被改变
属性名, 旧 属性值, 新 属性值, 和 属性命名空间
属性被移除
属性名, 旧 属性值, null, 和 属性命名空间

要在自定义元素设置自定义元素的原型, 用户代理 必须 执行以下步骤或 同等

输入
ELEMENT, 元素
输出
None
  1. PROTOTYPE 成为自定义元素原型ELEMENT定义
  2. 设置ELEMENT内部属性 [[Prototype]]的值到PROTOTYPE.
  3. 如果 ELEMENT 在一个文档里 且这个 文档浏览上下文
    1. 队列ELEMENT 绑定 回调

创建和传递注册

当一个 HTML Document加载 进一个 浏览上下文,一个新的 注册 必须 被创建且关联到这个document

一个新 document 实例 必须 被关联到一个现有 注册 在这些例子里:

在所有情况下, 新的 documents 不能 有一个 注册

注册自定义元素

因为 元素注册 可在任何时间发生, 一个自定义元素在它的 定义注册之前可能被创建。 这样的 自定义元素 实例被称为 unresolved elements。当一个unresolved element 被创建, 如果它的元素实例 没有被 HTML 或者 其他适用的规范定义。 unresolved element元素实例 必须 是:

声明的结果是任何拥有本地命名的HTML (或者SVG)元素是一个有效的自定义元素类型有HTMLElement (或者 SVGElement) 作为元素接口,而不是HTMLUnknownElement.

每个 注册 有一个相关联的给出一对自定义元素类型命名空间的所有unresolved elements 实例的。这些数据结构被称为 升级的候选表 且初始化是空 。在表里的每项值是一个存储元素队列

无论何时一个unresolved element被创建,必须 被添加到相应的 存储元素队列升级的候选表里。

注册 一个 元素定义元素配准算法的职责, 必须等于 执行这些步骤:

输入
DOCUMENT, 文档
TYPE, 被注册元素的自定义元素类型
PROTOTYPE, 自定义元素类型
NAME, 本地命名,可选
输出
ERROR, 持有下列值之一的变量: None, InvalidType, InvalidName, NoRegistry, 或者 DuplicateDefinition
  1. ERRORDEFINITION 成为用 DOCUMENT, TYPE, PROTOTYPE, 和 NAME作为参数执行 定义构造算法的结果
  2. 如果 ERROR 不是 None, 停止
  3. REGISTRY 成为 DOCUMENT注册
  4. 如果REGISTRY不存在,设置ERROR REGISTRY停止
  5. 添加 定义注册表
  6. 成为注册升级的候选表
  7. 执行 元素升级算法MAPDEFINITION 作为参数。

定义构造算法创建一个 元素定义必须 等同于 运行这些步骤:

输入
DOCUMENT, 文档
TYPE, 被创建的元素的自定义元素类型
PROTOTYPE, 定义元素类型
NAME, 本地命名,可选
输出
DEFINITION, 元素定义
ERROR, 持有下列值之一的变量: None, InvalidType, InvalidName, 或者 DuplicateDefinition
  1. ERRORNone
  2. 转换 TYPE 为 ASCII小写字母
  3. 如果DOCUMENTHTML document, 转换 NAME 为 ASCII 小写字母
  4. 如果TYPE 是无效的 自定义元素类型, 设置 ERROR无效类型停止
  5. NAMESPACEHTML 命名空间
  6. 如果PROTOTYPE接口SVGElement继承,设置NAMESPACESVG 命名空间
  7. 如果已经存在一个相同类型定义, 设置 ERROR重复定义停止
  8. 如果NAME 被提供且不是null
    1. BASE 成为 NAMENAMESPACE元素接口
    2. 如果BASE 不存在或是一个自定义元素接口, 设置 ERROR无效命名停止.
  9. 相反:
    1. 如果 NAMESPACESVG 命名空间, 设置 ERROR无效命名停止
    2. NAME 成为 TYPE
  10. LIFECYCLE 成为生命周期回调函数
  11. PROTOTYPE上称为createdCallback的属性传递回调函数被称为createdLIFECYCLE
  12. PROTOTYPE上称为attachedCallback的属性传递回调函数被称为attachedLIFECYCLE
  13. PROTOTYPE上称为detachedCallback的属性传递回调函数被称为detachedLIFECYCLE
  14. PROTOTYPE上称为attributeChangedCallback的属性传递回调函数被称为attributeChangedLIFECYCLE
  15. DEFINITION 成为一个元素定义自定义元素类型 设置到TYPE, 本地命名 设置到NAME, 命名空间 设置到 NAMESPACE, 自定义元素原型 设置到 PROTOTYPE, 且 生命周期回调函数 设置到 LIFECYCLE.

元素升级算法 升级 unresolved elements,它的定义现在被 注册必须 等同于 运行这些步骤:

输入
MAP, 成为一个 升级候选表
DEFINITION, 元素定义
输出
None
  1. TYPE 成为 自定义元素类型DEFINITION
  2. CANDIDATES 成为TYPENAMESPACE存储元素队列MAP
  3. 对于每一项 ELEMENTCANDIDATES里:
    1. 队列 created 回调给 ELEMENT
  4. 设置 CANDIDATES 到空的存储元素队列

扩展文档接口

文档 接口的 注册元素 方法提供了一种 注册 和 返回它的 自定义元素构造函数的方法。


partial interface Document {
    Function registerElement(DOMString type, optional ElementRegistrationOptions options);
};

dictionary ElementRegistrationOptions {
     object? prototype = null;
     DOMString? extends = null;
};

调用时, 注册元素 方法 必须 执行这些步骤:

输入
DOCUMENT,方法的内容对象, 一个 文档
TYPE, 被注册元素的自定义元素类型
PROTOTYPE, 自定义元素原型, 可选
EXTENDS, HTMLSVG 元素本地命名被扩展,可选
输出
CONSTRUCTOR, 自定义元素构造函数
  1. I如果PROTOTYPEnull, 让 PROTOTYPE 成为调用Object.createHTMLElement接口原型对象 作为唯一参数的结果。
  2. NAME 成为 EXTENDS
  3. ERROR 成为用 DOCUMENT, TYPE, PROTOTYPE, 和 NAME执行 元素注册算法 的结果。
  4. 如果ERROR无效类型抛出 语法错误停止
  5. 如果 ERROR不是 None, 抛出 不支持错误停止
  6. 返回用DOCUMENTPROTOTYPE 作为参数执行自定义元素构造函数生成算法的结果。
  7. ElementRegistrationOptions是允许使用函数对象和ES6类作为document.register方法的第二个参数的抽象。

元素注册选项 是一个允许使用函数对象和ES6类作为 document.register方法的第二个参数的概念。

为了用原型去注册 一个自定义元素 ,其他 HTMLElement 或是SVGElementdocument.registerElement的访问必须创建一个正确的从 HTMLElement继承的原型对象。这里有一个简单的例子:


document.registerElement('x-foo', {
    prototype: Object.create(HTMLParagraphElement.prototype, {
        firstMember: {
            get: function() { return "foo"; },
            enumerable: true,
            configurable: true
        },
        // specify more members for your prototype.
        // ...
    }),
    extends: 'p'
});

注意:使用 扩展 选项去指定该元素被注册成为一个类型扩展 -- 就是说, 这个元素没有引入一个新标签 (像 自定义标签 元素那样), 而是扩展HTMLParagraphElement现有类型元素。 这里怎样实例化这种元素:


<p is="x-foo">Paragraph of amazement</p>
或者用JavaScript命令:

var foo = document.createElement('p', 'x-foo');

SVGElement 原型的元素值得一提的是: 使用 自定义标签方法 的结果是在SVG忽略元素。 因此, 基于SVG的自定义元素可能几乎始终是 类型扩展名

Unresolved伪类元素

:unresolved 伪类 必须 匹配所有被创建的回调还没有被调用的 自定义元素

:unresolved 伪类 可以用来减轻 没有样式内容的Flash (FOUC) 问题 用 自定义元素

实例化自定义元素

自定义元素类型 被给到一个自定义元素在它的实例的两种方式中的一种:

  1. 由于自定义元素本地命名。这些自定义元素类型的类型被称为 自定义标签
  2. 由于 自定义元素attribute值。 自定义元素类型 被给定的方法叫做 类型扩展

自定义元素 被实例化之后,改变它的属性不能影响该元素的自定义元素类型

如果两种自定义元素类型在元素实例化的时候被提供, 自定义标签 必须 胜过 类型扩展

所有 自定义元素 必须 可用 函数对象构建,被称为 自定义元素构建函数。该构造函数 必须自定义元素构造函数生成算法生成, 可以 等于 执行这些步骤:

输入
PROTOTYPE, 自定义元素类型
DOCUMENT, 新的自定义元素的所有者 文档
输出
CONSTRUCTOR, 自定义元素构造函数
  1. 如果PROTOTYPE 是一个接口原型对象 对于任何 接口对象 或者 PROTOTYPE 有一个不可配置的 构造函数属性,抛出一个 不支持错误停止
  2. DEFINITION成为一个 元素定义PROTOTYPE 作为 自定义元素原型
  3. REGISTRY 成为 DOCUMENT注册
  4. CONSTRUCTOR 成为接口对象,它的 接口原型对象PROTOTYPE 且当被作为一个构造函数调用时,执行下列步骤:
    1. ELEMENT 成为 内容对象
    2. TYPE成为 自定义元素类型DEFINITION
    3. NAME 成为 本地命名DEFINITION
    4. NAMESPACE 成为 命名空间DEFINITION
    5. 设置 ELEMENT本地命名NAME, 命名空间 设置到 NAMESPACE, 和节点文档 设置到 DOCUMENT
    6. 如果 TYPE 是不一样的NAME, 设置 ELEMENT属性TYPE
    7. 排队 created 回调函数给 ELEMENT
    8. 返回 ELEMENT

扩展 文档 接口

要允许同时创建 自定义标签类型扩展自定义元素, 在createElementcreateElementNS 方法有 重载一个 typeExtension 参数:


partial interface Document {
    Element createElement(DOMString localName, DOMString typeExtension);
    Element createElementNS(DOMString? namespace, DOMString qualifiedName, DOMString typeExtension);
};

替代在createElement里的步骤3 和在 createElementNS 里的步骤9,即这些步骤确定 元素接口,两种方法 必须 执行以下步骤:

  1. TYPE 成为 类型扩展, 或者 本地命名 如果 类型扩展 不存在
  2. 如果一个元素定义 有匹配的 本地命名, 命名空间, 和 类型 没有令牌文档注册 with, 设置 TYPE本地命名
  3. 接口 成为 TYPE本地命名命名空间元素接口 (HTML命名空间 对于 创建元素)

此外, createElementcreateElementNS 方法 必须 执行下列步骤在结果返回 之前

  1. 如果 TYPE 是不一样的本地命名, 设置ELEMENT 属性 值为 TYPE
  2. 排队 created 回调函数给 ELEMENT

解析自定义元素

树构造函数期间启用实例化 自定义元素 , 一个符合标准的 UA 必须 执行 排队 created 回调函数无论何时 创建 一个自定义元素

对于 树构造函数的 修改有被创建的自定义元素解析HTML文档片段时的结果。

自定义元素和ECMAScript 6

一旦 ECMAScript标准版6被发布,这部分将纳入该规范的各个区域。 在此之前,这里是ECMAScript 6和自定义元素是如何整合的概述。

如果用户代理实现了@@create 方法, 本规范将会停止处理 ElementRegistrationOptions 选项registerElement作为一个词典的争议 ,相反把它看做是一个 自定义元素构造函数

用户代理将会用一个新的@@create方法创建一个新的元素对象改变这种争议,而不是用一个构造函数去创建。

由于registerElement的第二个参数现在是一个构造函数,该元素定义应改为持有的构造函数,而不是自定义元素的原型。

由于registerElement的第二个参数现在是一个构造函数, 该元素定义 应改为持有构造函数,而不是 自定义元素原型

为了适应这种变化, 元素注册算法为下面的两步:

输入
DOCUMENT, 文档
TYPE, 被注册元素的 自定义元素类型
FUNCTION, 自定义元素构造函数
NAME, 本地命名, 可选
输出
ERROR, 持有下列值之一的变量:None, InvalidType, InvalidName, NoRegistry, 或 DuplicateDefinition
  1. ERROR and DEFINITION 成为用DOCUMENT, TYPE, PROTOTYPE, 和 NAME 作为参数执行定义构造函数算法 的结果。
  2. 如果 ERROR 不是None, 停止
  3. REGISTRY 成为 DOCUMENT注册
  4. 如果 REGISTRY 不存在,设置ERRORNoRegistry停止
  5. 添加 DEFINITIONREGISTRY
  6. MAP 成为 REGISTRY升级候选表
  7. 执行 元素升级算法MAPDEFINITION作为参数

registerElement的步骤执行时会改变:

输入
DOCUMENT, 方法的 内容对象, 一个文档
TYPE, 被注册元素的自定义元素类型
FUNCTION, 自定义元素够着函数r, 可选
EXTENDS, HTML 或是 SVG 元素本地命名会被继承, 可选
输出
CONSTRUCTOR, 自定义元素构造函数
  1. 如果 FUNCTIONnull:
    1. FUNCTION成为调用 FunctionAllocateHTMLElement 作为functionPrototype 的结果,且结果是严格true
    2. PROTOTYPE 成为调用 ObjectCreateHTMLElement接口原型对象 作为唯一参数的结果
    3. 调用 DefinePropertyOrThrow(PROTOTYPE, "constructor", PropertyDescriptor{[[Value]]: FUNCTION, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})
    4. 调用 DefinePropertyOrThrow(FUNCTION, "prototype", PropertyDescriptor{[[Value]]: PROTOTYPE, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})
  2. 否则:
    1. PROTOTYPE 成为获取(FUNCTION, "prototype")的结果
  3. NAME 成为 EXTENDS
  4. ERROR 成为执行 元素注册算法DOCUMENT, TYPE, PROTOTYPE, 和 NAME作为参数的结果
  5. 如果 ERROR无效类型, 抛出 一个 SyntaxError停止
  6. 如果 ERROR 不为 None, 抛出 一个 NotSupportedError停止
  7. 返回用PROTOTYPE, FUNCTION, 和 DOCUMENT作为参数执行 自定义元素构造函数生成算法的结果。

同样,自定义元素的构造函数生成算法将发生如下改变:

输入
PROTOTYPE, 自定义元素类型
FUNCTION, 自定义元素构造函数
DOCUMENT,新的 自定义元素的所有者 文档
输出
FUNCTION,突变的自定义元素构造函数
  1. 如果 FUNCTION 已经是一个 接口对象 对于任何 接口, 抛出NotSupportedError停止
  2. DEFINITION 成为一个有 PROTOTYPE 作为 自定义元素原型元素定义
  3. CREATE 成为一个被调用的函数, 执行下列步骤:
    1. ELEMENT 成为 内容对象
    2. TYPE 成为在DEFINITION里的自定义元素类型
    3. NAME 成为在DEFINITION里的本地命名
    4. NAMESPACE 成为在DEFINITION里的命名空间
    5. 设置 ELEMENT本地命名NAME, 命名空间NAMESPACE, 和 节点文档DOCUMENT
    6. 如果 TYPE 是不一样的 NAME, 设置 ELEMENT属性 TYPE
    7. 排队 创建 回调函数给ELEMENT
    8. 返回 ELEMENT
  4. 调用 DefinePropertyOrThrow(FUNCTION, @@create, PropertyDescriptor{[[Value]]: CREATE, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})
  5. 返回 FUNCTION

附录A:在一个图中的所有算法

为了帮助导航规范及其相互作用的各个部分,这里有一个表试图放进在同一个空间出发的所有算法执行。点击每个框去相应的算法或执行。

图。所有算法在一个图里

鸣谢

David Hyatt 开发了 XBL 1.0Ian Hickson 参与了 XBL 2.0 的编写。这些文献在行为依附问题上提供了巨大而深刻的见解,并极大地影响了本说明书。

Alex Russell 和他的重要远见引发了新一波围绕行为依附课题的热潮和如何在网络上应用于实践。

Dominic CooneyRoland Steiner 不知疲倦的仔细研究网络平台范围内的问题,为此文档打下了坚实的基础。

编辑还要感谢 Alex KomoroskeAngelina FabbroAnne van KesterenBoris ZbarskyBrian KardellDaniel BuchnerEdward O'ConnorEric BidelmanErik ArvidssonElliott SprehnGabor KrizsanitsHayato ItoJames SimonsenJonas SickingKen ShirriffNeel GoyalOlli PettayRafael WeinsteinScott MilesSteve OrvellTab AtkinsWilliam Chan,和 William Chen,感谢他们对此说明书的评论和贡献。

这个列表太短了。还有很多工作要做。请通过评审和提交bugs来参与贡献 — 不要忘了要求编辑添加你的名字到此章节。