1. 2 公共基础设施
    1. 2.1 术语
      1. 2.1.1 Parallelism
      2. 2.1.2 资源
      3. 2.1.3 XML 兼容性
      4. 2.1.4 DOM 树
      5. 2.1.5 脚本
      6. 2.1.6 插件
      7. 2.1.7 字符编码
      8. 2.1.8 符合性类别
      9. 2.1.9 Dependencies
      10. 2.1.10 可扩展性
      11. 2.1.11 与 XPath 和 XSLT 交互
    2. 2.2 String comparison
    3. 2.3 Policy-controlled features
    4. 2.4 公共微语法
      1. 2.4.1 常见的解析器风格
      2. 2.4.2 布尔属性
      3. 2.4.3 关键字和枚举属性
      4. 2.4.4 数字
        1. 2.4.4.1 有符号整数
        2. 2.4.4.2 非负整数
        3. 2.4.4.3 浮点数
        4. 2.4.4.4 百分数和长度
        5. 2.4.4.5 非零百分数和长度
        6. 2.4.4.6 浮点数列表
        7. 2.4.4.7 维度值列表
      5. 2.4.5 日期和时间
        1. 2.4.5.1 月份
        2. 2.4.5.2 日期
        3. 2.4.5.3 无年的日期
        4. 2.4.5.4 时间
        5. 2.4.5.5 本地日期和时间
        6. 2.4.5.6 时区
        7. 2.4.5.7 全球日期和时间
        8. 2.4.5.8 星期
        9. 2.4.5.9 时间间隔
        10. 2.4.5.10 模糊的时间
      6. 2.4.6 颜色
      7. 2.4.7 空格分隔的令牌
      8. 2.4.8 逗号分隔的字符集
      9. 2.4.9 引用
      10. 2.4.10 媒体查询
    5. 2.5 URL
      1. 2.5.1 术语
      2. 2.5.2 解析 URL
      3. 2.5.3 基 URL 的动态变化
    6. 2.6 获取资源
      1. 2.6.1 术语
      2. 2.6.2 确定响应类型
      3. 2.6.3meta 元素提取字符编码
      4. 2.6.4 CORS 设置属性
      5. 2.6.5 引荐来源策略属性
      6. 2.6.6 Nonce attributes
      7. 2.6.7 Lazy loading attributes
    7. 2.7 通用 DOM 接口
      1. 2.7.1 在 IDL 属性中反映内容属性
      2. 2.7.2 集合
        1. 2.7.2.1 The HTMLAllCollection interface
          1. 2.7.2.1.1 [[Call]] ( thisArgument, argumentsList )
        2. 2.7.2.2 HTMLFormControlsCollection 接口
        3. 2.7.2.3 HTMLOptionsCollection 接口
      3. 2.7.3 DOMStringList 接口
    8. 2.8 安全地传递结构化数据
      1. 2.8.1 可序列化对象
      2. 2.8.2 可传输对象
      3. 2.8.3 StructuredSerializeInternal ( value, forStorage [ , memory ] )
      4. 2.8.4 StructuredSerialize ( value )
      5. 2.8.5 StructuredSerializeForStorage ( value )
      6. 2.8.6 StructuredDeserialize ( serialized, targetRealm [ , memory ] )
      7. 2.8.7 StructuredSerializeWithTransfer ( value, transferList )
      8. 2.8.8 StructuredDeserializeWithTransfer ( serializeWithTransferResult, targetRealm )
      9. 2.8.9 在其他规范中执行序列化和传输

2 公共基础设施

该标准依赖于 WHATWG Infra 标准。 [INFRA]

2.1 术语

该标准所说的属性,指的是 HTML,XML 和 IDL 属性,通常在同一个上下文中。当未具体提及所指时,HTML 和 XML 属性指的是 content attributes,而 IDL attributes指的是在 IDL 接口中定义的属性。同样,“属性”这个词也同时指 Javascript 对象属性和 CSS 属性。在可能产生混淆时, 该标准使用 object propertiesCSS properties 来区别。

一般而言,当该标准申明一个特性可以在 HTML 语法XML 语法 中应用,则在另一个中也可用。 当一个特性仅在两个语言之一中应用时,该标准将显式申明它不能在另一个语言中使用, 如:“可在 HTML 中使用,…… (该语法不可用于 XML)”。

该标准使用术语 文档指任何 HTML,从短小精悍的文档到长篇累牍的论文, 亦或是多媒体报告、完整的交互式应用程序。该术语同时指 Document 对象和他们的后裔 DOM 树。至于序列化的字节流, 则根据上下文使用 HTML 语法XML 语法 来表示。

在 DOM 结构的上下文中,使用的术语 HTML 文档XML 文档 定义在 DOM 标准中, 并且特指 Document 对象所处的两种不同模式。 [DOM] (这样的使用都会超链接到它们的定义)

在字节流的上下文中,术语 HTML 文档 指标记为 text/html 的资源, 术语 XML 文档 指标记为 XML MIME type 的资源。


简单起见,像 shown, displayed, 以及 visible 这样的术语可能会用来指明文档渲染给用户的方式, 这些术语并不是指应用于视觉媒介;必须考虑将它们以等价的方式应用于其他的媒介。

某个元素是visible的并不仅仅指该元素在视觉上可见,比如屏幕阅读器也应将该元素阅读给用户。

2.1.1 Parallelism

To run steps in parallel means those steps are to be run, one after another, at the same time as other logic in the standard (e.g., at the same time as the event loop). This standard does not define the precise mechanism by which this is achieved, be it time-sharing cooperative multitasking, fibers, threads, processes, using different hyperthreads, cores, CPUs, machines, etc. By contrast, an operation that is to run immediately must interrupt the currently running task, run itself, and then resume the previously running task.

For guidance on writing specifications that leverage parallelism, see Dealing with the event loop from other specifications.

To avoid race conditions between different in parallel algorithms that operate on the same data, a parallel queue can be used.

A parallel queue represents a queue of algorithm steps that must be run in series.

A parallel queue has an algorithm queue (a queue), initially empty.

To enqueue steps to a parallel queue, enqueue the algorithm steps to the parallel queue's algorithm queue.

To start a new parallel queue, run the following steps:

  1. Let parallelQueue be a new parallel queue.

  2. Run the following steps in parallel:

    1. While true:

      1. Let steps be the result of dequeueing from parallelQueue's algorithm queue.

      2. If steps is not nothing, then run steps.

      3. Assert: running steps did not throw an exception, as steps running in parallel are not allowed to throw.

      Implementations are not expected to implement this as a continuously running loop. Algorithms in standards are to be easy to understand and are not necessarily great for battery life or performance.

  3. Return parallelQueue.

Steps running in parallel can themselves run other steps in in parallel. E.g., inside a parallel queue it can be useful to run a series of steps in parallel with the queue.

Imagine a standard defined nameList (a list), along with a method to add a name to nameList, unless nameList already contains name, in which case it rejects.

The following solution suffers from race conditions:

  1. Let p be a new promise.

  2. Run the following steps in parallel:

    1. If nameList contains name, reject p with a TypeError and abort these steps.

    2. Do some potentially lengthy work.

    3. Append name to nameList.

    4. Resolve p with undefined.

  3. Return p.

Two invocations of the above could run simultaneously, meaning name isn't in nameList during step 2.1, but it might be added before step 2.3 runs, meaning name ends up in nameList twice.

Parallel queues solve this. The standard would let nameListQueue be the result of starting a new parallel queue, then:

  1. Let p be a new promise.

  2. Enqueue the following steps to nameListQueue:

    1. If nameList contains name, reject p with a TypeError and abort these steps.

    2. Do some potentially lengthy work.

    3. Append name to nameList.

    4. Resolve p with undefined.

  3. Return p.

The steps would now queue and the race is avoided.

2.1.2 资源

本标准中术语 支持 是指用户代理是否实现了对外部资源的语义的解码能力。 支持 某种格式或类型是指这一实现可以处理该格式或类型的外部资源,且处理过程不会忽略关键方面。 是否 支持 某种特定资源取决于该资源类型有哪些在用的特性。

例如,如果可以解码和渲染 PNG 图片的像素数据,就可以认为支持 PNG 图片格式。 即使这一实现不知道该图片还包含了动画数据。

如果不支持使用的压缩格式,即使实现可以从文件的元数据确定电影的尺寸,MPEG-4 视频文件也不会被视为支持的格式。

有些标准中(特别是 HTTP 标准)中称为 表示(representation) 的在本标准中称为 资源(resource)[HTTP]

资源的 关键子资源 是那些需要被正确处理的资源。 哪些资源被认为是关键的,由定义该资源格式的标准来定义。

2.1.3 XML 兼容性

为了方便从 HTML 迁移到 XML,遵循本标准的用户代理会把 HTML 中的元素放在 http://www.w3.org/1999/xhtml 命名空间, 至少是为了 DOM 和 CSS 的目的。 本标准中使用的术语 "HTML 元素",是指所有在那个命名空间中的元素, 包括 XML 文档中的。

除非另有声明,所有本标准中定义和提到的元素均位于 HTML ("http://www.w3.org/1999/xhtml"), 本标准中所有定义和提到的属性(Attribute)没有命名空间。

术语 元素类型 用于指代给定命名空间和局部名的那些元素。 例如,button 元素的元素类型为 button,意味着它们的局部名为 "button" 且(如上述定义地)命名空间为 HTML

如果属性名匹配 XML 中定义的 Name 生成式且不包含 U+003A COLON 字符(:),那么它就是 XML 兼容的 [XML]

2.1.4 DOM 树

当声明 忽略 某些元素或属性,或当作其他值处理,或当作其他东西处理时, 都是指节点在 DOM 中之后的处理。在这些情形下用户代理禁止改动 DOM。

只有内容属性的新值和原值不同时,才说内容属性的值发生了 改变; 将内容属性设置到它已有的值不会让它发生改变。

术语 用于属性值、文本 节点、或字符串时, 表示文本的长度是零(即不包含控制字符 或 U+0020 SPACE)。

插入节点 A 到节点 B 是指以 A 作为参数调用 插入步骤, 然后 A 新的父节点就是 B。类似地,从节点 B 移除节点 A 是指以 A 作为 removedNode 参数,以 B 作为 oldParent 参数调用 移除步骤

插入节点到文档 是指把它作为参数调用 插入步骤, 然后它就 在文档树中 了。类似地, 从文档中移除节点 是指把它作为参数调用 移除步骤, 然后它就不 在文档树中 了。

把节点作为参数调用 插入步骤 后, 节点就 变成已连接的。 类似地,把它作为参数调用 移除步骤 后, 节点就 变成了分离的

如果节点是 已连接的 且它的 包含 Shadow 的根浏览环境,那么它是 连接到浏览环境的。 把节点作为参数调用 插入步骤 后, 它就 连接到了浏览环境。 把节点作为参数调用移除步骤, 或者它的 包含 Shadow 的根 不再拥有 浏览环境 后, 它就 与浏览环境分离了

2.1.5 脚本

有时会用构造 "一个 Foo 对象" (其中 Foo 其实是一个接口), 来表示 "一个实现了 Foo 接口的对象"。

获取 IDL 属性的值称为 获取(例如在作者的脚本中), 将新的值赋值给 IDL 属性则称为 设置

如果 DOM 对象是 活的,该对象上的属性和方法 必须 在真正的底层数据(而不是数据快照)上进行操作。

2.1.6 插件

术语 插件 是指一些用户代理定义的内容处理程序,用户代理用它们 参与 Document 对象的渲染,但不会作为 Document子浏览环境,也不会给 Document 的 DOM 引入任何 Node 对象。

通常,这样的内容处理程序由第三方提供,尽管用户代理也可以将内置的内容处理程序指定为插件。

用户代理不得将 text/plainapplication/octet-stream 类型视为注册有 插件

插件的一个例子是当用户导航到PDF文件时在 浏览环境 中实例化的PDF查看器。 无论执行PDF查看器组件的一方是否与实现用户代理本身的方相同,这将被视为插件。 但是根据定义,与用户代理(而不是使用相同的接口)分开启动的PDF查看器应用程序不是插件。

该规范没有定义与插件交互的机制,因为插件预期就是用户代理和平台特定的。 UA 可以选择支持某种插件机制,比如 Netscape Plugin API; 也可以选择对某些类型使用远程内容转换器或提供内置支持。 实际上,本标准根本没有要求用户代理支持插件。[NPAPI]

安全 插件应该遵循 sandbox 属性的语义。

例如,在沙盒 iframe 中初始化的 安全插件应该阻止其中的内容创建弹出窗口。

在与 插件 的外部内容交互时,浏览器应该格外小心。 当第三方软件以与用户代理本身相同的权限运行时,第三方软件中的漏洞变得与用户代理中的漏洞同样危险。

因为不同的用户有不同的 插件,这提供了唯一识别用户的指纹向量, 推荐用户代理对每个用户都支持同样的 plugins

2.1.7 字符编码

字符编码 或着没有歧义时说的 编码,是一种字节流与 Unicode 字符串的转换, 定义在 Encoding 中。编码 包括一个 编码名称 和一个或更多的 编码标签,编码的 名称标签 定义在 Encoding 标准中。 [ENCODING]

2.1.8 符合性类别

本标准描述了 用户代理(实现者相关)和 文档 (作者和编写工具的实现者相关) 的符合性标准。

符合规范的文档 是符合所有符合性要求的文档。 为了提高可读性,有些符合性要求是对作者提出的;这些是对文档的隐性要求: 按照定义所有文档都有对应的作者。(有些情况下,作者本身可能是一个用户代理 — 这些用户代理受其他规则的约束,见下文。)

例如,如果一项要求声明 "作者 禁止使用 foobar 元素",意味着文档不允许包含名为 foobar 的元素。

文档的符合性要求与实现的符合性要求没有隐含的关系。 用户代理不能随意处理不合规范的文档;不论输入的文档是否合规,本标准中描述的处理模型都适用。

按照不同的符合性要求,用户代理分为(有重合的)几类。

Web 浏览器和其他交互式用户代理

支持 XML 语法 的 Web 浏览器必须按照本标准的描述 处理 XML 文档中 HTML 命名空间 的元素和属性, 以便用户与之交互,除非那些元素的语义已经被其他标准覆盖。

在 XML 文档中查找 script 元素时,符合规范的 Web 浏览器会执行该元素包含的脚本。然而,如果该元素处于 XSLT 变换中(假设用户代理也支持 XSLT), 那么处理器会将 script 元素作为组成这一变换的不透明元素处理。

支持 HTML 语法 的 Web 浏览器必须按照本标准的描述 处理标记为 HTML MIME 类型 的文档,以便用户与它们交互。

支持脚本的用户代理也必须一致地实现本标准中的 IDL 片段,IDL 片段定义在 Web IDL 标准中。 [WEBIDL]

除非明确声明,覆盖 HTML 元素语义的标准不覆盖对(表示这些元素的) DOM 对象的要求。 例如,上面例子中的 script 元素仍然实现 HTMLScriptElement 接口。

表示性的非交互式用户代理

处理 HTML 和 XML 文档并纯粹地渲染它们的非交互式版本的用户代理必须遵循与 Web 浏览器同样的符合性规范,除了它们可以免除用户交互的要求。

非交互式用户代理的典型例子就是打印机(静态 UA)和投影仪(动态 UA)。 多数静态的非交互式用户代理 不支持脚本

非交互式的动态 UA 仍然会执行脚本,以便动态提交表单。 但是因为没有获得焦点的概念,这些 UA 可能不需要实现焦点相关的 DOM API。

支持建议默认渲染的可视化用户代理

无论是交互式还是非交互式用户代理,都可以被指定(比如通过作为用户选项)本标准定义的建议默认渲染。

这并非强制要求,特别是即使用户代理实现了建议默认渲染,也建议为此提供设置来提升用户体验, 例如改变色彩对比度,使用不同的焦点样式,或者其他提升可访问性和可用性的方式。

如果指定了建议默认渲染,支持建议默认渲染的用户代理必须根据 渲染部分 定义的规则实现 用户代理 期望 实现的行为。

不支持脚本的用户代理

不支持脚本的实现(或者完全禁用了其脚本特性的用户代理)可以不支持本标准中提到的事件和 DOM 接口。 但对于本标准中定义的事件模型和 DOM,这些用户代理仍然必须表现地像支持事件和 DOM 一样。

脚本可能是构成应用的一部分。不支持脚本或禁用了脚本的 Web 浏览器可能无法完全表达作者的意图。

符合性检查器

符合性检查器必须验证文档是否符合 符合性检查程序必须验证文档是否符合本规范中描述的适用的一致性标准。 自动化的符合检查程序可以不必检测需要解释作者意图的错误(例如, blockquote 的内容不是引用文档就不符合标准,如果符合性检查程序在运行时没有人为判断的输入, 就不必检查 blockquote 元素是否只包含引用的内容)。

符合性检查器必须检查没有 浏览环境 (意味着没有脚本运行,并且禁用了解析器的 脚本标志 )时解析输入文档符合规范, 还应检查在会执行脚本的 浏览环境 下解析输入文档符合规范,并且脚本的执行永远不会导致不符合规范的状态(脚本执行过程中除外)出现。 (这只是一个“应该”而不是“必须”的要求,因为这已被证明是不可能的。[COMPUTABLE]

"HTML 校验器" 可以指代遵循本标准中的适用要求的符合性检查器。

XML DTD 无法表达本标准的所有符合性要求。因此 XML 校验器加 DTD 不能代替符合性检查器。 此外本标准中定义的这两种写作格式都不属于 SGML,因此 SGML 系统也不能代替符合性检查器。

换句话说,有三种符合性规则:

  1. DTD 可表达的规则。
  2. DTD 不可表达但仍然可以由机器检查的规则。
  3. 只能由人工检查的规则。

符合性检查器可以检查前面两种。简单的基于 DTD 的校验器只能检查第一类错误, 因此根据本标准,它不是一种遵循标准的符合性检查器。

数据挖掘工具

不是出于渲染文档或检查文档是否符合规范目的的,处理 HTML 和 XML 文档的应用程序和工具, 其行为应当与其处理的文档的语义保持一致。

只增加每个段落(paragraph)的嵌套层级但不增加每个章节(section)的嵌套层级的 文档大纲 生成工具是不合规范的。

只增加 <p> 的层级而不增加 <section> 的层级会破坏 DOM 原有的语义,比如让段落变成了子段落。

编写工具和标记生成器

编写工具和标记生成器必须生成 符合规范的文档。 在适当的地方,适用于作者的符合性规则也适用于编写工具。

如果编写工具还不能决定作者的意图,可以免除“只能按规定的用途使用元素”的严格要求。 但是编写工具禁止自动地错误使用元素或鼓励它们的用户这样做。

例如,将 address 元素用于任意的联系信息是不合规范的; 该元素只能用于标记文档或章节作者的联系信息。因为编写工具不能区分此意图,所以可以免除这项要求。 但这不意味着(比如)编写工具可以为了斜体字而任意地使用 address 元素; 只意味着编写工具可以在用户给章节插入联系信息时不验证它, 也不需保证用户没用它做别的事或插入别的东西。

在符合性检查方面,文本编辑器必须像符合性检查器一样输出符合规范的文档。

当使用编写工具编辑不符合规范的文档时,可以保持未编辑部分的符合性错误。 (即允许错误的内容经过编辑工具而不发生改变)。 但如果保持了错误,禁止编写工具声明其输出是符合规范的。

编写工具大致分为两类:在结构化或语义数据上进行编辑, 或者在所见即所得的(WYSIWYG)特定媒体上进行编辑。

前者是编写 HTML 工具的理想机制,因为源码信息中的结构可用于更好地选择 HTML 元素和属性。

但是 WYSIWYG 工具也是合理的。WYSIWYG 工具应该使用它们认为合适的元素, 不应该使用它们不确定是否合适的元素。这可能在特定极端情况下意味着对能够使用的流式元素做出限制, 比如 divbi,以及 span,以及使用大量的 style 属性。

不论是不是 WYSIWYG,所有编写工具都应该尽量让用户创建良构的、语义丰富的、媒体无关的内容。

为了防范诸如 DoS 攻击、内存耗尽,或解决平台相关的限制, 用户代理可能会对本来不受约束的输入强加实现相关的限制。

为了兼容既有内容与标准,本标准描述了两种写作格式: 一种基于 XML, 另一种基于 SGML 启发的 自定义格式 (称为 HTML 语法)。 本标准鼓励实现同时支持以上两种格式,但至少支持其中一种。

一些符合性要求称为元素、属性、方法或对象的要求。 这些要求分为两类:描述内容模型限制的,和描述实现行为的。   前者是对文档和编写工具的要求,后者是对用户代理的要求。   类似地,另一些符合性要求称为对作者的要求;这些要求应解释为对作者产出的文档的符合性要求。 (换句话说,本标准不区分对作者和对文档的符合性要求)

2.1.9 Dependencies

This specification relies on several other underlying specifications.

Infra

The following terms are defined in Infra: [INFRA]

Unicode and Encoding

The Unicode character set is used to represent textual data, and Encoding defines requirements around character encodings. [UNICODE]

This specification introduces terminology based on the terms defined in those specifications, as described earlier.

The following terms are used as defined in Encoding: [ENCODING]

  • Getting an encoding
  • Get an output encoding
  • The generic decode algorithm which takes a byte stream and an encoding and returns a character stream
  • The UTF-8 decode algorithm which takes a byte stream and returns a character stream, additionally stripping one leading UTF-8 Byte Order Mark (BOM), if any
  • The UTF-8 decode without BOM algorithm which is identical to UTF-8 decode except that it does not strip one leading UTF-8 Byte Order Mark (BOM)
  • The encode algorithm which takes a character stream and an encoding and returns a byte stream
  • The UTF-8 encode algorithm which takes a character stream and returns a byte stream
  • The BOM sniff algorithm which takes a byte stream and returns an encoding or null.
XML and related specifications

Implementations that support the XML syntax for HTML must support some version of XML, as well as its corresponding namespaces specification, because that syntax uses an XML serialization with namespaces. [XML] [XMLNS]

Data mining tools and other user agents that perform operations on content without running scripts, evaluating CSS or XPath expressions, or otherwise exposing the resulting DOM to arbitrary content, may "support namespaces" by just asserting that their DOM node analogues are in certain namespaces, without actually exposing the namespace strings.

In the HTML syntax, namespace prefixes and namespace declarations do not have the same effect as in XML. For instance, the colon has no special meaning in HTML element names.


The attribute with the name space in the XML namespace is defined by Extensible Markup Language (XML). [XML]

The Name production is defined in XML. [XML]

This specification also references the <?xml-stylesheet?> processing instruction, defined in Associating Style Sheets with XML documents. [XMLSSPI]

This specification also non-normatively mentions the XSLTProcessor interface and its transformToFragment() and transformToDocument() methods. [XSLTP]

URLs

The following terms are defined in URL: [URL]

A number of schemes and protocols are referenced by this specification also:

Media fragment syntax is defined in Media Fragments URI. [MEDIAFRAG]

HTTP and related specifications

The following terms are defined in the HTTP specifications: [HTTP]

The following terms are defined in HTTP State Management Mechanism: [COOKIES]

  • cookie-string
  • receives a set-cookie-string
  • `Cookie` header

The following term is defined in Web Linking: [WEBLINK]

The following terms are defined in Structured Field Values for HTTP: [STRUCTURED-FIELDS]

The following terms are defined in MIME Sniffing: [MIMESNIFF]

Fetch

The following terms are defined in Fetch: [FETCH]

The following terms are defined in Referrer Policy: [REFERRERPOLICY]

The following terms are defined in Mixed Content: [MIX]

Paint Timing

The following terms are defined in Paint Timing: [PAINTTIMING]

Long Tasks

The following terms are defined in Long Tasks: [LONGTASKS]

Web IDL

The IDL fragments in this specification must be interpreted as required for conforming IDL fragments, as described in Web IDL. [WEBIDL]

The following terms are defined in Web IDL:

The Web IDL also defines the following types that are used in Web IDL fragments in this specification:

The term throw in this specification is used as defined in Web IDL. The DOMException type and the following exception names are defined by Web IDL and used by this specification:

When this specification requires a user agent to create a Date object representing a particular time (which could be the special value Not-a-Number), the milliseconds component of that time, if any, must be truncated to an integer, and the time value of the newly created Date object must represent the resulting truncated time.

For instance, given the time 23045 millionths of a second after 01:00 UTC on January 1st 2000, i.e. the time 2000-01-01T00:00:00.023045Z, then the Date object created representing that time would represent the same time as that created representing the time 2000-01-01T00:00:00.023Z, 45 millionths earlier. If the given time is NaN, then the result is a Date object that represents a time value NaN (indicating that the object does not represent a specific instant of time).

JavaScript

Some parts of the language described by this specification only support JavaScript as the underlying scripting language. [JAVASCRIPT]

The term "JavaScript" is used to refer to ECMA-262, rather than the official term ECMAScript, since the term JavaScript is more widely known. Similarly, the MIME type used to refer to JavaScript in this specification is text/javascript, since that is the most commonly used type, despite it being an officially obsoleted type according to RFC 4329. [RFC4329]

The following terms are defined in the JavaScript specification and used in this specification:

Users agents that support JavaScript must also implement ECMAScript Internationalization API. [JSINTL]

WebAssembly

The following term is defined in WebAssembly JavaScript Interface: [WASMJS]

DOM

The Document Object Model (DOM) is a representation — a model — of a document and its content. The DOM is not just an API; the conformance criteria of HTML implementations are defined, in this specification, in terms of operations on the DOM. [DOM]

Implementations must support DOM and the events defined in UI Events, because this specification is defined in terms of the DOM, and some of the features are defined as extensions to the DOM interfaces. [DOM] [UIEVENTS]

In particular, the following features are defined in DOM: [DOM]

The following features are defined in UI Events: [UIEVENTS]

The following features are defined in Touch Events: [TOUCH]

The following features are defined in Pointer Events: [POINTEREVENTS]

This specification sometimes uses the term name to refer to the event's type; as in, "an event named click" or "if the event name is keypress". The terms "name" and "type" for events are synonymous.

The following features are defined in DOM Parsing and Serialization: [DOMPARSING]

The following features are defined in Selection API: [SELECTION]

User agents are encouraged to implement the features described in execCommand. [EXECCOMMAND]

The following parts of Fullscreen API are referenced from this specification, in part to define the rendering of dialog elements, and also to define how the Fullscreen API interacts with HTML: [FULLSCREEN]

High Resolution Time provides the current high resolution time and the DOMHighResTimeStamp typedef. [HRT]

File API

This specification uses the following features defined in File API: [FILEAPI]

Indexed Database API

This specification uses cleanup Indexed Database transactions defined by Indexed Database API. [INDEXEDDB]

Media Source Extensions

The following terms are defined in Media Source Extensions: [MEDIASOURCE]

Media Capture and Streams

The following terms are defined in Media Capture and Streams: [MEDIASTREAM]

Reporting

The following terms are defined in Reporting: [REPORTING]

XMLHttpRequest

The following features and terms are defined in XMLHttpRequest: [XHR]

Battery Status

The following features are defined in Battery Status API: [BATTERY]

Media Queries

Implementations must support Media Queries. The <media-condition> feature is defined therein. [MQ]

CSS modules

While support for CSS as a whole is not required of implementations of this specification (though it is encouraged, at least for web browsers), some features are defined in terms of specific CSS requirements.

When this specification requires that something be parsed according to a particular CSS grammar, the relevant algorithm in CSS Syntax must be followed, including error handling rules. [CSSSYNTAX]

For example, user agents are required to close all open constructs upon finding the end of a style sheet unexpectedly. Thus, when parsing the string "rgb(0,0,0" (with a missing close-parenthesis) for a color value, the close parenthesis is implied by this error handling rule, and a value is obtained (the color 'black'). However, the similar construct "rgb(0,0," (with both a missing parenthesis and a missing "blue" value) cannot be parsed, as closing the open construct does not result in a viable value.

To parse a CSS <color> value, given a string input with an optional element element, run these steps:

  1. Let color be the result of parsing input as a CSS <color>. [CSSCOLOR]

  2. If color is failure, then return failure.

  3. If color is 'currentcolor', then:

    1. If element is not given, then set color to opaque black.

    2. Otherwise, set color to the computed value of the 'color' property of element.

  4. Return color.

The following terms and features are defined in Cascading Style Sheets (CSS): [CSS]

CSS also defines the following border properties: [CSS]

Border properties
Top Bottom Left Right
Width 'border-top-width' 'border-bottom-width' 'border-left-width' 'border-right-width'
Style 'border-top-style' 'border-bottom-style' 'border-left-style' 'border-right-style'
Color 'border-top-color' 'border-bottom-color' 'border-left-color' 'border-right-color'

The basic version of the 'display' property is defined in CSS, and the property is extended by other CSS modules. [CSS] [CSSRUBY] [CSSTABLE]

The following terms and features are defined in CSS Logical Properties: [CSSLOGICAL]

The following terms and features are defined in CSS Color: [CSSCOLOR]

The following terms are defined in CSS Images: [CSSIMAGES]

The term paint source is used as defined in CSS Images Level 4 to define the interaction of certain HTML elements with the CSS 'element()' function. [CSSIMAGES4]

The following features are defined in CSS Backgrounds and Borders: [CSSBG]

The following features are defined in CSS Box Alignment: [CSSALIGN]

The following terms and features are defined in CSS Display: [CSSDISPLAY]

The following features are defined in CSS Flexible Box Layout: [CSSFLEXBOX]

The following terms and features are defined in CSS Fonts: [CSSFONTS]

The following features are defined in CSS Grid Layout: [CSSGRID]

The following terms are defined in CSS Inline Layout: [CSSINLINE]

The following terms and features are defined in CSS Intrinsic & Extrinsic Sizing: [CSSSIZING]

The 'list-style-type' property is defined in CSS Lists and Counters. [CSSLISTS]

The following features are defined in CSS Overflow. [CSSOVERFLOW]

The following features are defined in CSS Positioned Layout: [CSSPOSITION]

The following features are defined in CSS Multi-column Layout. [CSSMULTICOL]

The 'ruby-base' value of the 'display' property is defined in CSS Ruby Layout. [CSSRUBY]

The following features are defined in CSS Table: [CSSTABLE]

The following features are defined in CSS Text: [CSSTEXT]

The following features are defined in CSS Writing Modes: [CSSWM]

The following features are defined in CSS Basic User Interface: [CSSUI]

The algorithm to update animations and send events is defined in Web Animations. [WEBANIMATIONS].

Implementations that support scripting must support the CSS Object Model. The following features and terms are defined in the CSSOM specifications: [CSSOM] [CSSOMVIEW]

The following features and terms are defined in CSS Syntax: [CSSSYNTAX]

The following terms are defined in Selectors: [SELECTORS]

The following features are defined in CSS Values and Units: [CSSVALUES]

The term style attribute is defined in CSS Style Attributes. [CSSATTR]

The following terms are defined in the CSS Cascading and Inheritance: [CSSCASCADE]

The CanvasRenderingContext2D object's use of fonts depends on the features described in the CSS Fonts and Font Loading specifications, including in particular FontFace objects and the font source concept. [CSSFONTS] [CSSFONTLOAD]

The following interfaces and terms are defined in Geometry Interfaces: [GEOMETRY]

The following terms are defined in the CSS Scoping: [CSSSCOPING]

The following terms and features are defined in CSS Color Adjustment: [CSSCOLORADJUST]

Intersection Observer

The following term is defined in Intersection Observer: [INTERSECTIONOBSERVER]

WebGL

The following interfaces are defined in the WebGL specifications: [WEBGL]

WebVTT

Implementations may support WebVTT as a text track format for subtitles, captions, metadata, etc., for media resources. [WEBVTT]

The following terms, used in this specification, are defined in WebVTT:

The WebSocket protocol

The following terms are defined in Fetch: [FETCH]

The following terms are defined in The WebSocket protocol: [WSP]

  • the WebSocket connection is established
  • extensions in use
  • subprotocol in use
  • a WebSocket message has been received
  • send a WebSocket Message
  • fail the WebSocket connection
  • close the WebSocket connection
  • start the WebSocket closing handshake
  • the WebSocket closing handshake is started
  • the WebSocket connection is closed (possibly cleanly)
  • the WebSocket connection close code
  • the WebSocket connection close reason
  • Sec-WebSocket-Protocol field
ARIA

The role attribute is defined in Accessible Rich Internet Applications (ARIA), as are the following roles: [ARIA]

In addition, the following aria-* content attributes are defined in ARIA: [ARIA]

Finally, the following terms are defined ARIA: [ARIA]

Content Security Policy

The following terms are defined in Content Security Policy: [CSP]

Service Workers

The following terms are defined in Service Workers: [SW]

Secure Contexts

The following algorithms are defined in Secure Contexts: [SECURE-CONTEXTS]

Permissions Policy

The following terms are defined in Permissions Policy: [PERMISSIONSPOLICY]

Payment Request API

The following feature is defined in Payment Request API: [PAYMENTREQUEST]

MathML

While support for MathML as a whole is not required by this specification (though it is encouraged, at least for web browsers), certain features depend upon small parts of MathML being implemented. [MATHML]

The following features are defined in Mathematical Markup Language (MathML):

SVG

While support for SVG as a whole is not required by this specification (though it is encouraged, at least for web browsers), certain features depend upon parts of SVG being implemented.

User agents that implement SVG must implement the SVG 2 specification, and not any earlier revisions.

The following features are defined in the SVG 2 specification: [SVG]

Filter Effects

The following feature is defined in Filter Effects: [FILTERS]

Cooperative Scheduling of Background Tasks

The following features are defined in Cooperative Scheduling of Background Tasks: [REQUESTIDLECALLBACK]

Storage

The following terms are defined in Storage: [STORAGE]

Web App Manifest

The following features are defined in Web App Manifest: [MANIFEST]


This specification does not require support of any particular network protocol, style sheet language, scripting language, or any of the DOM specifications beyond those required in the list above. However, the language described by this specification is biased towards CSS as the styling language, JavaScript as the scripting language, and HTTP as the network protocol, and several features assume that those languages and protocols are in use.

A user agent that implements the HTTP protocol must implement HTTP State Management Mechanism (Cookies) as well. [HTTP] [COOKIES]

This specification might have certain additional requirements on character encodings, image formats, audio formats, and video formats in the respective sections.

2.1.10 可扩展性

强烈不鼓励本规范的厂商专有的用户代理扩展。 文档不能使用这样的扩展,因为这样做减少了互操作性并且分割了用户群,只允许特定用户代理的用户访问相关内容。

所有扩展的定义必须使得,扩展的使用既不会违反本标准,也不会导致本标准定义的功能的不一致。

例如(强烈不鼓励这样做)实现上可以为控件添加一个新的 IDL 属性 "typeTime" 返回(比如)用户选择控件的当前值所花费的时间。 另一方面,在表单的 elements 数组中定义一个新的控件也会违反上述要求, 因为它将违反本标准给出的 elements 定义。


当本标准需要厂商中立的扩展时,或者相应地更新本标准,或者编写一个扩展标准并重写本标准中的要求。 如果有人在他的活动中使用了本标准,并决定识别该扩展标准的要求,这一标准就变成了本标准中符合性要求的 适用规范

有人可能会编写一个规范来定义任意的字节流为合规的,然后声明他的随机产生的垃圾为符合规范的。 但是这并不意味着他的随机垃圾符合所有人的目的:如果有人认为该标准不适用于他的工作, 他就可以很合理地说上述随机垃圾就是垃圾,根本不符合规范。 就符合性而言,(某一特定)社区内 同意 适用才是最重要的。


用户代理必须将它们不理解的原始和属性当作语义中立的来处理; (DOM 处理器)把它们留在 DOM 中,(CSS 处理器)根据 CSS 设置它们的样式, 但不要推测它们的语义。

当功能的支持被禁用时(例如作为减轻安全问题的紧急措施或协助开发或出于性能原因), 用户代理的表现必须像不支持该功能一样,像本标准没提到该功能一样。 例如,如果某个特性是通过 Web IDL 接口的属性来访问的,实现该接口的对象将会忽略掉这个属性 — 把属性留在对象上,让它返回 null 或抛出异常是不够的。

2.1.11 与 XPath 和 XSLT 交互

操作以本标准的方式解析或创建的 HTML 文档 (例如作为 document.evaluate() API 的一部分) 的 XPath 1.0 的实现必须在 XPath 1.0 标准的基础上遵循以下改动。

首先,移除这一段话:

节点测试中的 QName 使用表达式上下文的命名空间声明展开为 expanded-name, 展开的方式与开始和结束标签的元素类型名称一样,但是不使用以 xmlns 声明的默认命名空间:如果 QName 没有前缀,那么命名空间 URI 就是 null (这与属性名的展开方式相同)。 如果 QName 的命名空间前缀 在表达式上下文中没有声明将会引发错误。

然后,在同样的位置插入下面一段:

节点测试中的 QName 使用表达式上下文的命名空间声明展开为 expanded-name。 如果 QName 有前缀,则该前缀必须在表达式上下文中有一个 URI 与之关联的命名空间声明, 且相应的。 如果 QName 的命名空间前缀 在表达式上下文中没有声明将会引发错误。

如果 QName 没有前缀且轴的主节点类型为元素,那么使用默认的元素命名空间。 否则,如果 QName 没有前缀,命名空间 URI 就是 null。 默认的元素命名空间是 XPath 表达式的上下文中的成员。 按照 DOM3 XPath API 执行 XPath 表达式时,默认的元素命名空间的值由以下方式决定:

  1. 如果上下文节点来自 HTML DOM,默认元素命名空间是 "http://www.w3.org/1999/xhtml"。
  2. 否则,默认元素命名空间 URI is null。

这相当于将 XPath 2.0 的默认元素命名空间特性添加到 XPath 1.0, 并将 HTML 命名空间用作 HTML 文档的默认元素命名空间。这样做是希望实现兼容于遗留的 HTML 内容的同时, 支持本标准在 HTML 元素命名空间方面引入的变更,以及希望使用 XPath 1.0 而不是 XPath 2.0。

这一变更的 有意的违反 XPath 1.0 标准, 这样做是希望实现兼容于遗留内容的同时支持本标准在 HTML 元素命名空间方面引入的变更。 [XPATH10]


当输出方法为 "html" 时(显式地设置或采用了 XSLT 1.0 的默认规则), XSLT 1.0 处理器的 DOM 输出受一下规则的影响:

如果转换程序输出没有命名空间的元素, 处理器必须在构造相应的 DOM 元素节点之前将元素的命名空间更改为 HTML 命名空间, 将局部名称 改为 ASCII 小写, 并且把元素上无命名空间的属性名 改为 ASCII 小写

本要求是 XSLT 1.0 标准的 故意违反, 本标准为了兼容基于 DOM 的 XSLT 转换,而改变了 HTML 的命名空间和大小写敏感性规则。 (不影响序列化该输出的处理器) [XSLT10]


本标准不指定 XSLT 处理具体如何与 HTML 解析器 基础设施交互 (例如,XSLT 处理器是否将所有元素放到 打开元素栈 中)。 但是当成功地完成后,XSLT 处理器必须 停止解析, 也必须首先将 当前文档就绪状态 设置为 "interactive",在退出后再设置为 "complete"。


本标准不指定 XSLT 如何与 导航 算法进行交互, 如何与 事件循环 相匹配, 也不指定错误页面如何处理(例如 XSLT 错误是替代 XSLT 增量输出,还是内联呈现等等)。

script 元素部分,有一些关于 XSLT 与 HTML 之间交互的非规范性注释, template 元素部分 有一些关于 XSLT,XPath,和 HTML 之间交互的非规范性注释。

2.2 String comparison

A string pattern is a prefix match for a string s when pattern is not longer than s and truncating s to pattern's length leaves the two strings as matches of each other.

2.3 Policy-controlled features

This document defines the following policy-controlled features:

Headers/Feature-Policy/autoplay

Firefox🔰 65+SafariNoChrome64+
Opera51+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox Android🔰 65+Safari iOSNoChrome Android64+WebView Android64+Samsung Internet9.0+Opera Android47+

Headers/Feature-Policy/document-domain

Firefox🔰 65+SafariNoChrome77+
Opera64+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox Android🔰 65+Safari iOSNoChrome AndroidNoWebView AndroidNoSamsung InternetNoOpera AndroidNo

2.4 公共微语法

HTML 中有很多地方接受特定的数据类型,比如日期和数字。 这一部分描述了那些类型的内容应符合的标准,以及如何解析它们。

强烈要求实现者仔细地检查考虑用来实现如下语法解析的第三方库。 例如,日期库实现的错误处理行为可能与本标准所要求的不同。 因为在描述类似本标准使用的日期语法的其他标准中,通常没有给出错误处理行为, 所以实现的错误处理可能很不一样。

2.4.1 常见的解析器风格

空格字符 是 在 Unicode PropList.txt 数据文件中 Unicode 属性为 "White_Space" 的字符。[UNICODE]

不要与 Unicode.txt 数据文件中 "Bidi_Class" 属性的 "White_Space" 值(缩写为 "WS")相混淆。

有些下面描述的微解析器遵循这样的模式:维护一个 input 变量保存待解析字符串,以及一个 position 变量指向 input 中下一个要解析的字符。

2.4.2 布尔属性

有些属性是 布尔属性。 布尔属性出现在元素上表示值为 true,不出现表示表示值为 false。

如果该属性出现,它的值必须为空字符串或者匹配属性的标准名称的 ASCII 大小写不敏感 字符串, 并且前后没有空格。

布尔属性上不允许 "true" 和 "false" 值。 为了表示 false 值,应该一并忽略该属性。

这里有一个例子,表示复选框被选中和禁用。 checkeddisabled 属性就是布尔属性。

<label><input type=checkbox checked name=cheese disabled> Cheese</label>

这可以等价地写成:

<label><input type=checkbox checked=checked name=cheese disabled=disabled> Cheese</label>

你也可以混合两种风格;下面的写法仍然是等价的:

<label><input type='checkbox' checked name=cheese disabled=""> Cheese</label>

2.4.3 关键字和枚举属性

有些属性定义为取值只能是有限的关键字集合中的一个。 这样的属性称为 枚举属性。 这些关键字都定义为映射到特定的状态 state (可能多个关键字映射到同一个状态, 此时这些关键字互为同义词;此外有些关键字其实是不合规范的,它们在还在这里完全是历史原因)。 除此之外可以给出两个默认状态:第一个是 非法值的默认状态, 第二个是 缺失值的默认状态

如果指定了枚举属性,属性值必须是一个匹配其中一个关键字(不包括不合规范)的 ASCII 大小写不敏感 字符串,并且前后没有空格。

指定属性时,如果它的值是匹配其中一个关键字的 ASCII 大小写不敏感 字符串 那么该属性表示的状态就是该关键字的状态。如果属性值不匹配任何给定的关键字,但该属性有一个 非法值的默认状态,那么该属性表示那个状态。 否则如果该属性的值不匹配任何关键字但定义有一个 缺失值的默认状态, 那么该属性表示的状态就是 那个状态。否则,没有默认状态的情况, 非法值不表示任何状态。

没有 指定属性时,如果定义有 缺失值的默认状态, 那么这个(缺失)属性表示的状态就是这个状态。否则, 缺失的属性不表示任何状态。

空字符串可以是一个合法的关键字。

2.4.4 数字

2.4.4.1 有符号整数

由一个或更多 ASCII 数字 组成的字符串就是 合法的整数。 可以有一个 U+002D HYPHEN-MINUS 字符 (-) 作为前缀。

没有 U+002D HYPHEN-MINUS 字符 (-) 作为前缀的 合法整数 表示 该数字字符串以 10 为基所表示的数字。 有着 U+002D HYPHEN-MINUS 字符 (-) 作为前缀的 合法的整数 表示零减去该字符串以 10 为基所表示的数字。

解析整数的规则 由下列算法给出。 被调用时,必须以给定的步骤执行,在第一个有返回值的步骤中止。该算法会返回一个整数或者一个错误。

  1. input 为被解析的字符串。

  2. positioninput 里面的指针,初始指向字符串的开始。

  3. sign 拥有值 "positive"。

  4. 跳过 input 中的 ASCII 空格,得到 position

  5. 如果 position 越过了 input 的末尾,返回一个错误。

  6. 如果 position 处的(第一个)字符是一个 U+002D HYPHEN-MINUS 字符 (-):

    1. sign 为 "negative"。
    2. position 前进到下一个字符。
    3. 如果 position 越过了 input 的末尾,返回一个错误。

    否则,如果 position 处的(第一个)字符是一个 U+002B PLUS SIGN 字符 (+):

    1. position 前进到下一个字符。 (虽然 "+" 会被忽略但并不符合规范。)
    2. 如果 position 越过了 input 的末尾,返回一个错误。
  7. 如果 position 处的字符不是 ASCII 数字,则返回一个错误。

  8. input 的给定 position 收集ASCII 数字 的代码点序列,将得到的序列解释为以10为基的整数。 令 value 为该整数。

  9. 如果 sign 为 "positive",返回 value,否则返回0减去 value 的结果。

2.4.4.2 非负整数

由一个或更多 ASCII 数字 组成的字符串就是 合法的非负整数

合法的非负整数 表示该数字字符串以10为基所表示的数字。

解析非负整数的规则 由以下算法给出,被调用时该算法必须按顺序执行以下步骤,在第一个有返回值的步骤中止。 该算法将返回 0,正整数或者错误。

  1. input 为被解析的字符串。

  2. value 为使用 解析整数的规则 解析 input 的结果。

  3. 如果 value 是一个错误, 返回一个错误。

  4. 如果 value 小于零, 返回一个错误。

  5. 返回 value

2.4.4.3 浮点数

合法的浮点数 这样构成:

  1. 一个可选的 U+002D HYPHEN-MINUS 字符(-)。
  2. 下面的其中一个或者依次的两个:
    1. 一个或更多 ASCII 数字 组成的序列。
    2. 依次出现:
      1. 单个 U+002E FULL STOP 字符(.)。
      2. 一个或更多 ASCII 数字 组成的序列。
  3. 可选地:
    1. 一个 U+0065 LATIN SMALL LETTER E 字符(e)或 U+0045 LATIN CAPITAL LETTER E 字符(E)。
    2. 可选地,一个 U+002D HYPHEN-MINUS 字符(-) 或 U+002B PLUS SIGN 字符 (+)。
    3. 一个或更多 ASCII 数字 组成的序列。

合法的浮点数 表示将有效数乘以10的指数。 其中有效数是第一个数字,按十进制解析(包括小数点和小数点后的数字,如果后面有的话) 如果整个字符串以 U+002D HYPHEN-MINUS character (-)字符开始且该数字不为零的话, 将有效数解析为负数。 其中指数是 E 后面的数字(如果有的话),如果在 E 和该数字之间有一个 U+002D HYPHEN-MINUS 字符(-) 且该数字不为零的话,解析为负数,如果在 E 和该数字之间有一个 U+002B PLUS SIGN 字符(+)的话忽略该字符。 如果没有 E,指数当做零来处理。

Infinity 和 Not-a-Number (NaN)值不是 合法的浮点数

典型地, 合法的浮点数 的概念只用于限制作者,对用户代理的要求采用下面的 解析浮点数值的规则 (例如,progress 元素的 max 属性)。 然而,在某些情况下要求用户代理检查字符串是否是 合法的浮点数(例如, Number 状态的 input 元素的 值清理算法,或者 解析 srcset 属性 算法)。

浮点数的最佳表示 n 是 运行 ToStringn)得到的字符串。 ToString 抽象方法不是唯一确定的。如果在特定的值上运行 ToString 可能得到多个字符串,用户代理必须对那个值总是返回同样的字符串 (虽然它可能和其他用户代理使用的值不同)。

解析浮点数值的规则 由以下算法给出。 该算法必须在第一个有返回值的步骤中止。 该算法将会返回一个数字或者错误。

  1. input 为被解析的字符串。

  2. positioninput 内的指针,初始指向字符串的开始。

  3. value 的值为 1。

  4. divisor 的值为 1。

  5. exponent 的值为 1。

  6. 跳过 input 中的 ASCII 空格,得到 position

  7. 如果 position 越过了 input 的末尾,返回一个错误。

  8. 如果 position 处的(第一个)字符是一个 U+002D HYPHEN-MINUS 字符 (-):

    1. valuedivisor 改为 −1。
    2. position 前进到下一个字符。
    3. 如果 position 越过了 input 的末尾,返回一个错误。

    否则,如果 position 处的(第一个)字符是一个 U+002B PLUS SIGN 字符 (+):

    1. position 前进到下一个字符。 (虽然 "+" 会被忽略但并不符合规范。)
    2. 如果 position 越过了 input 的末尾,返回一个错误。
  9. 如果 position 处的字符是 U+002E FULL STOP (.),且不是 input 的最后一个字符, 而且 position 表示的字符的后一个字符是 ASCII 数字, 则将 value 设置为零并跳到 fraction 标记的步骤。

  10. 如果 position 处的数字不是 ASCII 数字, 则返回一个错误。

  11. input 的给定 position 收集ASCII 数字 的代码点序列,将得到的序列解释为以10为基的整数。 将 value 乘以该整数。

  12. 如果 position 越过了 input 的末尾,跳到标记为 conversion 的步骤。
  13. Fraction:如果 position 处的数字是 U+002E FULL STOP (.),运行以下子步骤:

    1. position 前进到下一个字符。

    2. 如果 position 越过了 input 的末尾或者不是 ASCII 数字、 U+0065 LATIN SMALL LETTER E (e),或 U+0045 LATIN CAPITAL LETTER E (E), 跳到 conversion 标记的步骤。

    3. 如果 position 处的字符是 U+0065 LATIN SMALL LETTER E character (e)或 U+0045 LATIN CAPITAL LETTER E 字符(E),跳过下面的子步骤。

    4. Fraction loop: 将 divisor 乘以 10。

    5. 按照十进制(0..9)解释 position 处的字符,除以 divisor, 加到 value 上。
    6. position 前进到下一个字符。

    7. 如果 position 越过了 input 的末尾, 跳到 conversion 标记的步骤。

    8. 如果 position 处的字符是 ASCII 数字, 跳回到 fraction loop 标记的子步骤。

  14. 如果 position 处的字符是 U+0065 (e)或 U+0045 (E),则:

    1. position 前进到下一个字符。

    2. 如果 position 越过了 input 的末尾,跳到标记为 conversion 的步骤。

    3. 如果 position 处的字符是 U+002D HYPHEN-MINUS 字符(-):

      1. exponent 设置为 −1。
      2. position 前进到下一个字符。
      3. 如果 position 越过了 input 的末尾,跳到标记为 conversion 的步骤。

      否则,如果 position 处的字符是 U+002B PLUS SIGN 字符(+):

      1. position 前进到下一个字符。
      2. 如果 position 越过了 input 的末尾,跳到标记为 conversion 的步骤。

    4. 如果 position 处的字符不是 ASCII 数字,则跳到标记为 conversion 的步骤。

    5. input 的给定 position 收集ASCII 数字 的代码点序列,将得到的序列解释为以 10 为基的整数。 将 exponent 乘以该整数。

    6. value 乘以 10 的 exponent 指数。

  15. Conversion: 令S 为 IEEE 754 双精度浮点数值的有限集, −0 除外,但新增 21024 和 −21024 两个值。

  16. rounded-valueS 最接近 value 的数字, 如果有两个同样接近的数值,则选择有效数为奇数的数字。 (在这个处理中,21024 和 −21024 这两个特殊值应视为有奇数的有效数。)

  17. 如果 rounded-value 是 21024 或 −21024,返回错误。

  18. 返回 rounded-value

2.4.4.4 百分数和长度

解析维度值的规则 由下面算法给出。被调用时必须按给定顺序执行这些步骤,并在第一个有返回值的步骤中止。 本算法将会返回一个大于等于 0.0 的数字,或者一个错误;如果返回了数字, 那么它可能是百分数或者长度。

  1. input 为被解析的字符串。

  2. positioninput 中的指针,初始指向字符串的开始。

  3. 跳过 input 中的 ASCII 空格,得到 position

  4. 如果 position 越过了 input 的末尾,返回一个错误。

  5. 如果 position 处的字符是一个 U+002B PLUS SIGN 字符 (+), 将 position 前进到下一个字符

  6. 如果 position 越过了 input 的末尾,返回一个错误。

  7. 如果 position 处的字符不是 ASCII 数字,则返回一个错误。

  8. input 的给定 position 收集ASCII 数字 的代码点序列,将得到的序列解释为以 10 为基的整数。 令 value 为该整数。

  9. 如果 position 越过了 input 的末尾,将 value 作为长度返回。

  10. 如果 position 处的字符是 U+002E FULL STOP character (.):

    1. position 前进到下一个字符。

    2. 如果 position 越过了 input 的末尾,或者 position 处的字符不是 ASCII 数字,则将 value 作为长度返回。

    3. divisor 值为 1。

    4. Fraction loop:将 divisor 乘以 10。

    5. 按照十进制(0..9)解释 position 处的字符,除以 divisor, 加到 value 上。
    6. position 前进到下一个字符。

    7. 如果 position 越过了 input 的末尾,则将 value 作为长度返回。

    8. 如果 position 处的字符是一个 ASCII 数字, 返回到标记为 fraction loop 的子步骤。

  11. 如果 position 越过了 input 的末尾,则将 value 作为长度返回。

  12. 如果 position 处的字符是 U+0025 PERCENT SIGN character(%), 将 value 作为百分数返回。

  13. value 作为长度返回。

2.4.4.5 非零百分数和长度

解析非零维度值的规则 由下列算法给出。被调用时必须按给定顺序执行这些步骤,并在第一个有返回值的步骤中止。 本算法将会返回一个大于 0.0 的数字或者一个错误;如果返回了数字, 那么它可能是百分数或者长度。

  1. input 为被解析的字符串。

  2. value 为使用 解析维度值的规则 解析 input 的结果。

  3. 如果 value 是一个错误,返回一个错误。

  4. 如果 value 为 0,返回一个错误。

  5. 如果 value 为百分数,将 value 作为百分数返回。

  6. value 作为长度返回。

2.4.4.6 浮点数列表

合法的浮点数列表 是以 U+002C COMMA 字符分隔的 合法浮点数 , 且没有其他字符(比如 ASCII 空格)。 此外,可能会有浮点数个数限制,或者取值范围限制。

解析浮点数列表的规则 如下:

  1. input 为被解析的字符串。

  2. positioninput 中的指针,初始指向字符串的开始。

  3. numbers 为空的浮点数列表。该列表将会是本算法的结果。

  4. input 的给定 position 收集ASCII 空格, U+002C COMMA,或者 U+003B SEMICOLON 字符的代码点序列。 本步骤跳过了所有前导分隔符。

  5. position 没有越过 input 的末尾时:

    1. input 的给定 position 收集 不是 ASCII 空格, U+002C COMMA,U+003B SEMICOLON, ASCII 数字, U+002E FULL STOP, 或 U+002D HYPHEN-MINUS 字符的代码点序列。 本步骤跳过了前导的无用字符。

    2. input 的给定 position 收集 不是 ASCII 空格, U+002C COMMA,或者 U+003B SEMICOLON 字符的代码点序列,令 unparsed number 为收集的结果。

    3. number 为使用 解析浮点数值的规则 解析 unparsed number 的结果。

    4. 如果 number 是一个错误,将 number 设置为 0。

    5. number 添加到 numbers

    6. input 的给定 position 收集ASCII 空格, U+002C COMMA,或者 U+003B SEMICOLON 字符的代码点序列。 本步骤跳过了分隔符。

  6. 返回 numbers

2.4.4.7 维度值列表

解析维度值列表的规则 如下。 这些规则返回一个由数字或单位组成的偶对列表,包含0个或更多偶对。 其中的单位是 percentage, relative,和 absolute 之一。

  1. raw input 为被解析的字符串。

  2. 如果 raw input 的最后一个字符是 U+002C COMMA character(,), 则从 raw input 中移除该字符。

  3. 用逗号分割 raw input 字符串。 令raw tokens 为得到的标记列表。

  4. result 为 number/unit 偶对的空列表。

  5. raw tokens 中的每一个标记,运行以下子步骤:

    1. input 为该标记。

    2. positioninput 中的指针,初始指向字符串的开始。

    3. value 为数字 0。

    4. unitabsolute

    5. 如果 position 越过了 input 的末尾,将 unit 设为 relative 并跳到最后一个子步骤。

    6. 如果 position 处的字符是 ASCII 数字, 从 input 的给定 position 收集ASCII 数字 的代码点序列,将得到的序列解释为以10为基的整数, 将 value 递增这个整数。

    7. 如果在 position 处的字符是 U+002E(.),则:

      1. input 的给定 position 收集ASCII 空格ASCII 数字 的代码点序列, 令 s 为得到的结果序列。

      2. 移除 s 中所有的 ASCII 空格

      3. 如果 s 不是空字符串,则:

        1. lengths 中(移除空格后的)字符数。

        2. fraction 为将 s 解释为以10为基的整数后的结果, 将这个数字除以 10length

        3. value 递增 fraction

    8. 从给定的 position 跳过 input 中的 ASCII 空白字符

    9. 如果 position 处的字符是 U+0025 PERCENT SIGN 字符(%), 将 unit 设为 percentage

      否则,如果 position 处的字符是 U+002A ASTERISK 字符(*), 则将 unit 设为 relative

    10. result 中增加一项,包含由 value 给定的数字, 以及由 unit 给定的单位。

  6. 返回 result 列表。

2.4.5 日期和时间

在下面的算法中, yearmonth 月的天数 是: 这考虑了格里历(现行公历)的闰年。[GREGORIAN]

当本部分定义的日期与时间语法中使用了 ASCII 数字 时, 这些数字表示10进制数。

虽然这里描述的格式旨在成为相应的 ISO8601 格式的子集,但是本规范比 ISO8601 更详细地定义了解析规则。因此,在使用实现者之前,请仔细检查任何日期解析库,然后再使用它们来实现下面描述的解析规则; ISO8601 库可能不会以完全相同的方式解析日期和时间。[ISO8601]

本标准中的 外推格里历 是指现代格里历向前外推到第 1 年。 外推格里历 中的日期 (有时直接称 外推格里历日期), 的指用外推格里历描述的日期,即使当时还没有颁布格里历。 [GREGORIAN]

格里历在本标准中作为连线协议使用并非出于决策者的文化偏好。参考: 对表单中的 date,time,和 number 格式 的讨论 (对作者而言), 关于表单控件本地化的实现说明,, 以及 time 元素。

2.4.5.1 月份

月份 由特定的 外推格里历日期 组成, 不包含时区信息,也不包含年和月以上的日的信息。[GREGORIAN]

表示 yearmonth 月的 合法的月字符串 包含下列部分(有序):

  1. 表示 year 年的 4 个或更多 ASCII 数字, 其中 year > 0
  2. 一个 U+002D HYPHEN-MINUS 字符(-)
  3. 表示 month 月的两个 ASCII 数字,在范围 1 ≤ month ≤ 12 之内

解析月字符串 的规则如下。将返回年和月,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析月的部分 来获得 yearmonth。 如果它没有返回,则失败。

  4. 如果 position 没有 超出 input 的结尾,则失败。

  5. 返回 yearmonth

给定 input 字符串和位置 position解析月的部分 的规则如下。 将返回年和月,或者什么都不返回。 如果算法的任何一个步说它 "失败了",这意味着它在那一步退出并什么都不返回。

  1. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不够 4 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 year

  2. 如果 year 不是大于0的数字则失败。。

  3. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+002D HYPHEN-MINUS 字符,则失败。 否则将 position 前进一个字符。

  4. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 month

  5. 如果 month 不是 1 ≤ month ≤ 12 范围内的数字就失败。

  6. 返回 yearmonth

2.4.5.2 日期

日期 由特定的 外推格里历日期 组成, 不包含时区信息,由年、月、日组成。[GREGORIAN]

表示 year 年,month 月,day 日的 合法的日期字符串 由下列几个有序的组成部分:

  1. 表示 yearmonth合法的月字符串
  2. 一个 U+002D HYPHEN-MINUS 字符(-)
  3. 表示 day 的两个 ASCII 数字, 处于范围 1 ≤ day ≤ maxday 内,其中 maxdayyearmonth 月的天数

解析日期字符串 的规则如下。将会返回一个日期或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析日期部分 来获得 yearmonthday。 如果它没有返回,则失败。

  4. 如果 position 没有 超出 input 的结尾,则失败。

  5. date 的年月日分别为 yearmonthday

  6. 返回 date

给定 input 字符串和位置 position解析日期部分 的规则如下。 将返回年、月、日,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. 解析月的部分 来获得 yearmonth 如果它没有返回,则失败。

  2. maxdayyearmonth 月的天数

  3. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+002D HYPHEN-MINUS 字符,则失败。 否则将 position 前进一个字符。

  4. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 day

  5. 如果 day 不是 1 ≤ day ≤ maxday 范围内的数字就失败。

  6. 返回 yearmonthday

2.4.5.3 无年的日期

一个 无年的日期 由一个格里历月和该月内的一天组成,但没有关联的年份。[GREGORIAN]

表示 monthday 日的 合法的无年日期 包含如下有序的部分:

  1. 可选地,两个 U+002D HYPHEN-MINUS 字符 (-)
  2. 表示 month 月的两个 ASCII 数字,在范围 1 ≤ month ≤ 12 之内
  3. 一个 U+002D HYPHEN-MINUS 字符 (-)
  4. 表示 day 的两个 ASCII 数字, 处于范围 1 ≤ day ≤ maxday 内,其中 maxday 任意闰年(例如 4 或 2000)的 month 月的天数

换句话说,如果 month 为 "02"(二月), 那么可以是 29 日,把这一年当做闰年。

解析无年的日期字符串 的规则如下。 将会返回月和日,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析无年的日期部分 来获得 monthday。 如果它没有返回,则失败。

  4. 如果 position 没有 超出 input 的结尾,则失败。

  5. 返回 monthday

给定 input 字符串和位置 position解析无年的日期部分 的规则如下。 将返回月和日,或者什么都不返回。 如果算法的任何一个步说它 "失败了",这意味着它在那一步退出并什么都不返回。

  1. input 中给定的位置 position 收集 U+002D HYPHEN-MINUS 字符 (-)组成的代码点序列。 如果收集到的序列长度不是 0 或 2,就失败。

  2. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列长度不是 2 就失败。 否则将结果序列解释为 10 进制整数。令那个数为 month

  3. 如果 month 不是 1 ≤ month ≤ 12 范围内的数字就失败。

  4. maxday 任意闰年(例如 4 或 2000)的 month 月的天数

  5. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+002D HYPHEN-MINUS 字符,则失败。 否则将 position 前进一个字符。

  6. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 day

  7. 如果 day 不是 1 ≤ day ≤ maxday 范围内的数字就失败。

  8. 返回 monthday

2.4.5.4 时间

时间 由一个没有时区信息的特定时间组成。 包含小时、分钟、秒,以及秒的小数。

hourminutesecond 秒的 合法的时间字符串 由以下有序的几部分组成:

  1. 表示 hour 的两个 ASCII 数字, 在 0 ≤ hour ≤ 23 范围内
  2. 一个 U+003A COLON 字符 (:)
  3. 表示 minute 的两个 ASCII 数字, 在 0 ≤ minute ≤ 59 范围内
  4. 如果 second 不是零(是零也合法):
    1. 一个 U+003A COLON 字符(:)
    2. 表示 second 的两个 ASCII 数字, 在 0 ≤ second ≤ 59 范围内
    3. 如果 second 不是整数(是整数也合法):
      1. 一个 U+002E FULL STOP 字符(.)
      2. 表示 second 的一到三个 ASCII 数字

second 部分不可以是 60 或 61;闰秒无法表示。

解析时间字符串 的规则如下。将会返回一个时间或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析时间部分 来获得 hourminutesecond。 如果它没有返回,则失败。

  4. 如果 position 没有 超出 input 的结尾,则失败。

  5. time 的时分秒分别为 hourminutesecond

  6. 返回 time

给定 input 字符串和位置 position解析时间部分 的规则如下。 将返回时、分、秒,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 hour

  2. 如果 hour 不是 0 ≤ hour ≤ 23 范围内的数字就失败。

  3. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+003A COLON 字符,则失败。 否则将 position 前进一个字符。

  4. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 minute

  5. 如果 minute 不是 0 ≤ minute ≤ 59 范围内的数字就失败。

  6. second 为 0。

  7. 如果 position 没有超出 input 的末尾并且 position 处的字符是 U+003A(:),则:

    1. position 前进一个字符。

    2. 如果 position 恰好位于或者超出了 input 的末尾, 或者 input 中从 position 开始的 两个 字符不都是 ASCII 数字,则失败。

    3. input 中给定的位置 position 收集 ASCII 数字 或 U+002E FULL STOP 字符 组成的代码点序列。 如果收集到的序列长度为 3, 或者长度大于 3 且第 3 个字符不是 U+002E FULL STOP 字符, 或者有多于一个的 U+002E FULL STOP 字符,则失败。 否则将结果序列解释为 10 进制数(可能有小数部分)。 将 second 设置为那个数字。

    4. 如果 second 不是 0 ≤ second < 60 范围内的数字就失败。

  8. 返回 hourminutesecond

2.4.5.5 本地日期和时间

本地日期和时间 由一个特定的 外推格里历日期(包含年、月、日) 和时间(包含时、分、秒,以及秒的小数),但没有时区。[GREGORIAN]

表示日期和时间的 合法的本地日期和时间字符串 由以下有序的部分组成:

  1. 表示日期的 合法的日期字符串
  2. 一个 U+0054 LATIN CAPITAL LETTER T 字符(T)或者 U+0020 SPACE 字符
  3. 表示时间的 合法的时间字符串

表示日期和时间的 合法的正则化的本地日期和时间字符串 由以下有序的几部分组成:

  1. 表示日期的 合法的日期字符串
  2. 一个 U+0054 LATIN CAPITAL LETTER T 字符 (T)
  3. 表示时间的 合法的时间字符串, 按给定时间的最短可能的字符串表示。(例如如果秒是 0 的话忽略秒的部分)

解析本地日期和时间字符串 的规则如下。 将会返回一个日期或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析日期部分 来获得 yearmonthday。 如果它没有返回,则失败。

  4. 如果 position 超出了 input 的末尾或者 position 处的字符是 U+0054 LATIN CAPITAL LETTER T 字符(T) 或 U+0020 SPACE 字符,则失败。否则将 position 前进一个字符。

  5. 解析时间部分 来获得 hourminutesecond。 如果它没有返回,则失败。

  6. 如果 position 没有 超出 input 的结尾,则失败。

  7. date 的年月日分别为 yearmonthday

  8. time 的时分秒分别为 hourminutesecond

  9. 返回 datetime

2.4.5.6 时区

时区 由一个小时和分钟的有符号数字组成。

表示时区的 合法的时区字符串 包含下列之一:

此格式允许从-23:59到+23:59的时区偏移。 现在,实际时区的偏移范围是-12:00到+14:00,分钟分量始终是 00,30 或 45。 但不能保证情况永远是这样的,因为时区被用作政治足球,受到异想天开的政策的支配。

另请参阅下面的 全球日期和时间 部分的使用说明和示例,具体了解如何在正式的时区形成之前的历史时间上使用时区偏移。

解析时区偏移字符串 的规则如下。 将会返回一个时区偏移或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析时区偏移部分 来获得 timezonehourstimezoneminutes。 如果它没有返回,则失败。

  4. 如果 position 没有 超出 input 的结尾,则失败。

  5. 返回距离 UTC timezonehours 小时 timezoneminutes 分钟的时区偏移。

给定 input 字符串和位置 position解析时区偏移部分 的规则如下。 将会返回一个时区偏移的小时和分钟,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. 如果 position 处的字符是一个 U+005A LATIN CAPITAL LETTER Z 字符(Z),则:

    1. timezonehours 为 0。

    2. timezoneminutes 为 0。

    3. position 前进到 input 的下一个字符。

    否则,如果 position 是 U+002B PLUS SIGN (+)或 U+002D HYPHEN-MINUS (-),则:

    1. 如果 position 处的字符是一个 U+002B PLUS SIGN (+),令 sign 为 "正"。 如果它是一个 U+002D HYPHEN-MINUS (-),则令 sign 为 "负"。

    2. position 前进到 input 的下一个字符。

    3. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。令 s 为收集到的序列。

    4. 如果 s 恰好是两个字符长度,则:

      1. s 解释为10进制整数,并赋值给 timezonehours

      2. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+003A COLON 则失败。 否则将 position 前进一个字符。

      3. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符则失败。 否则将结果序列解释为 10 进制整数。令那个数为 timezoneminutes

      如果 s 恰好是 4 个字符长度,则:

      1. s 的前两个字解释为 10 进制整数,并赋值给 timezonehours

      2. s 的后两个字解释为 10 进制整数,并赋值给 timezoneminutes

      其他情况失败。

    5. 如果 timezonehours 不在 0 ≤ timezonehours ≤ 23 范围内则失败。
    6. 如果 sign 为 "负",则对 timezonehours 求反。
    7. 如果 timezoneminutes 不在 0 ≤ timezoneminutes ≤ 59 范围内则失败。
    8. 如果 sign 为 "负",则对 timezoneminutes 求反。

    其他情况失败。

  2. 返回 timezonehourstimezoneminutes

2.4.5.7 全球日期和时间

全球日期和时间 由一个特定的 外推格里历日期(包含年、月、日) 和时间(包含时、分、秒,以及秒的小数),以及附加的时区信息,一个包括小时和分钟的有符号数。[GREGORIAN]

表示日期、时间和时区的的 合法的全球日期和时间字符串 由以下有序的部分组成:

  1. 表示日期的 合法的日期字符串
  2. 一个 U+0054 LATIN CAPITAL LETTER T 字符(T)或者 U+0020 SPACE 字符
  3. 表示时间的 合法的时间字符串
  4. 表示时区的 合法的时区偏移字符串

在 20 世纪中叶 UTC 形成之前的时间必须按照 UT1(0° 经度处的太阳时)而不是 UTC( UT1 的近似,按照 SI 制秒增长)表示和解析。时区形成前的时间必须按照 UT1 时间表示和解析, 且带有明确的时区信息,以此来近似适当的本地时间和伦敦格林尼治观测到的时间差。

下面是按照 合法的全球日期和时间字符串 编写的日期示例。

"0037-12-13 00:00Z"
使用伦敦时间的地区的午夜,罗马皇帝 Nero 的生日。关于实际对应的日期见下文的进一步讨论。
"1979-10-14T12:00:00.001-04:00"
美国东海岸夏令时的 1979 年 10 月 14 日正午之后的一毫秒。
"8592-01-01T02:09+02:09"
UTC 时间 8592 年 1 月 1 日午夜。其时区是快于 UTC 的 2 小时 9 分钟, 目前还没有这个时区,尽管如此,它是允许的。

关于这些日期,值得一提的是:

解析全球日期和时间字符串 的规则如下。 将会返回一个带有时区信息(为了能够往返转换或显示等用途)的 UTC 时间,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. 解析日期部分 来获得 yearmonthday。 如果它没有返回,则失败。

  4. 如果 position 超出了 input 的末尾或者 position 处的字符是 U+0054 LATIN CAPITAL LETTER T 字符(T) 或 U+0020 SPACE 字符,则失败。否则将 position 前进一个字符。

  5. 解析时间部分 来获得 hourminutesecond。 如果它没有返回,则失败。

  6. 如果 position 超出了 input 的结尾,则失败。

  7. 解析时区偏移部分 来获得 timezonehourstimezoneminutes。 如果它没有返回,则失败。

  8. 如果 position 没有 越过 input 的结尾,则失败。

  9. 令时刻 time 的年月日时分秒分别为 yearmonthdayhourminutesecond,减去 timezonehours 小时 timezoneminutes 分钟。 该时刻的时区为 UTC 时区。

  10. timezone 为距 UTC timezonehours 小时 timezoneminutes 分钟的时区偏移。

  11. 返回 timetimezone

2.4.5.8 星期

星期 由一个表示年的数字(星期年)和一个表示星期的数字(周号)组成,表示从周一开始的 7 天时间段。 在这个日历系统中,每个星期年有 52 或 53 个这样的 7 天,定义如下。这样的 7 天周期从格里历 1969 年 12 月 29 日(1969-12-29)开始, 这一周被定义为 1970 年的第 1 周。后续的星期都依次进行编号。一个星期年的第一周之前是上一个星期年的最后一周,反之亦反。 [GREGORIAN]

如果编号为 year 的星期年对应的 外推格里历year 第一天(1月1日)是周二,或者这一天是周三且 year 可被 400 整除或可被 4 整除但不可被 100 整除, 那么这一星期年有 53 周。其他所有星期年都有 52 周。

有 53 周的星期年的 最后一天的周号 是 53; 有 52 周的星期年的最后一天的周号是 52。

特定日期的星期年的编号可能与包含这一天的 外推格里历 年不同。 星期年 y 的第一周为包含第一个周二的格里历年 y

为了现代目的,这里定义的 星期 等价于定义在 ISO 8601 中的 ISO 星期。 [ISO8601]

表示星期年 year 和周号 week合法的星期字符串 有下列几个有序的组成部分:

  1. 表示 year 的 4 个或更多 ASCII 数字,其中 year > 0
  2. 一个 U+002D HYPHEN-MINUS 字符 (-)
  3. 一个 U+0057 LATIN CAPITAL LETTER W 字符 (W)
  4. 表示周号 week 的两个 ASCII 数字,其中 1 ≤ week ≤ maxweekmaxweek 为星期年 year 最后一天的周号

解析星期字符串 的规则如下。将会返回星期年和周号两个数字,或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列长度小于 4 个字符长度则失败。 否则将结果序列解释为 10 进制整数。令那个数为 year

  4. 如果 year 小于等于零则失败。

  5. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+002D HYPHEN-MINUS 字符则失败。 否则将 position 前进一个字符。

  6. 如果 position 超出了 input 的末尾或者 position 处的字符不是 U+0057 LATIN CAPITAL LETTER W 字符(W)则失败。 否则将 position 前进一个字符。

  7. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。 如果收集到的序列不是恰好 2 个字符长度则失败。 否则将结果序列解释为 10 进制整数。令那个数为 week

  8. maxweekyear最后一天的周号

  9. 如果 week 不是在 1 ≤ week ≤ maxweek 范围内的数字就失败。

  10. 如果 position 没有 超出 input 末尾,则失败。

  11. 返回星期年 year 和周号 week

2.4.5.9 时间间隔

时间间隔 由 秒数构成。

由于月和秒是不可比较的(一月没有精确的秒数, 它的长度取决于究竟从哪天算起),本标准中定义的 时间间隔 不允许包含 月(或者年,它等于12个月)。 时间间隔只能描述秒数。

表示 时间间隔 t合法的时间间隔字符串 的组成方式可以是下列任何一种:

解析时间间隔字符串 的规则如下。将会返回一个 时间间隔 或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. monthsseconds,和 component count 均为零。

  4. M-disambiguatorminutes

    该标志的另一个值是 months。它用来消除 ISO8601 时间间隔中 "M" 单位的歧义, 在 ISO8601 中月和分钟都使用这个单位。虽然月是不允许的,但为了向前兼容, 以及避免误解 ISO8601 时间间隔(在其他上下文中仍然是合法的), 仍然对月进行了解析。

  5. position 开始 跳过 input 中的 ASCII 空格。

  6. 如果 position 越过了 input 的结尾,则失败。

  7. 如果 position 处的字符是一个 U+0050 LATIN CAPITAL LETTER P 字符, 则将 position 前进一个字符。将 M-disambiguator 设置为 months, 并从 position 开始 跳过 input 中的 ASCII 空格。

  8. while true:

    1. units 为 undefined。它的值可能是: yearsmonthsweeksdayshoursminutes,或 seconds

    2. next character 为 undefined。用来从 input 中处理字符。

    3. 如果 position 越过了 input 的结尾,则 break。

    4. 如果 position 处的字符是一个 U+0050 LATIN CAPITAL LETTER T 字符, 则将 position 前进一个字符。将 M-disambiguator 设置为 minutes, 并从 position 开始 跳过 input 中的 ASCII 空格。

    5. next character 设置为 inputposition 处的字符。

    6. 如果 next character 为一个 U+002E FULL STOP 字符 (.),则令 N 等于 0。 (不要前进 position。下面会处理它。)

      否则,如果 next character 是一个 ASCII 数字,则从 input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。将结果序列解释为 10 进制整数。令 N 为那个数字。

      否则如果 next character 不是数字,则失败。

    7. 如果 position 越过了 input 的结尾,则 break。

    8. next character 设置为 inputposition 处的字符, 这次将 position 前进到下一字符。 (如果 next character 刚才是一个 U+002E FULL STOP 字符(.),它将仍然是那个字符。)

    9. 如果 next character 是 U+002E (.),则:

      1. input 中给定的位置 position 收集 ASCII 数字 组成的代码点序列。令 day 为结果序列。

      2. 如果 s 是空字符串则失败。

      3. lengths 中的字符数。

      4. fraction 为将 s 解释为10进制数的结果, 把这个数除以 10length

      5. N 增加 fraction

      6. position 开始 跳过 input 中的 ASCII 空格。

      7. 如果 position 越过了 input 的结尾,则失败。

      8. next character 设为 inputposition 指向的字符, 并将 position 前进到下一字符。

      9. 如果 next character 既不是 U+0053 LATIN CAPITAL LETTER S 字符也不是 U+0073 LATIN SMALL LETTER S 字符,则失败。

      10. units 设为 seconds

      否则:

      1. 如果 next characterASCII 空格, 那么从 position 开始 跳过 input 中的 ASCII 空格。 将 next character 设为 inputposition 指向的字符, 并将 position 前进到下一字符。

      2. 如果 next character 是一个 U+0059 LATIN CAPITAL LETTER Y 字符或 U+0079 LATIN SMALL LETTER Y 字符,将 units 设置为 years 并将 M-disambiguator 设置为 months

        如果 next character 是一个 U+004D LATIN CAPITAL LETTER M 字符或 U+006D LATIN SMALL LETTER M 字符,且 M-disambiguatormonths,则将 units 设置为 months

        如果 next character 是一个 U+0057 LATIN CAPITAL LETTER W 或 U+0077 LATIN SMALL LETTER W 字符,将 units 设置为 weeks 并将 M-disambiguator 设置为 minutes

        如果 next character 是一个 U+0044 LATIN CAPITAL LETTER D 或 U+0064 LATIN SMALL LETTER D 字符,将 units 设置为 days 并将 M-disambiguator 设置为 minutes

        如果 next character 是一个 U+0048 LATIN CAPITAL LETTER H 或 U+0068 LATIN SMALL LETTER H 字符,将 units 设置为 hours 并将 M-disambiguator 设置为 minutes

        如果 next character 是一个 U+004D LATIN CAPITAL LETTER M 字符或 U+006D LATIN SMALL LETTER M 字符,且 M-disambiguatorminutes,则将 units 设置为 minutes

        如果 next character 是一个 U+0053 LATIN CAPITAL LETTER S 或 U+0073 LATIN SMALL LETTER S 字符,将 units 设置为 seconds 并将 M-disambiguator 设置为 minutes

        否则如果 next character 不是上述任何字符,则失败。

    10. 递增 component count

    11. multiplier 为 1。

    12. 如果 unitsyears,将 multiplier 乘以 12 并设置 unitsmonths

    13. 如果 unitsmonths,把 Nmultiplier 的乘积加到 months 上。

      否则:

      1. 如果 unitsweeks,将 multiplier 乘以 7 并设置 unitsdays

      2. 如果 unitsdays,将 multiplier 乘以 24 并设置 unitshours

      3. 如果 unitshours,将 multiplier 乘以 60 并设置 unitsminutes

      4. 如果 unitsminutes,将 multiplier 乘以 60 并设置 unitsseconds

      5. 否则 units 只能是 seconds 了。 将 Nmultiplier 的乘积加到 seconds 上。

    14. position 开始 跳过 input 中的 ASCII 空格。

  9. 如果 component count 为零,则失败。

  10. 如果 months 不为零,则失败。

  11. 返回包含 seconds 秒的 时间间隔

2.4.5.10 模糊的时间

合法的可选时间的日期字符串 是下列中的一种:


解析日期或时间字符串 的规则如下。 该算法将会返回一个 datetime,或 全球日期和时间 或者什么都不返回。 如果算法的任何一个点说它 "失败了",这意味着它在那一点退出并什么都不返回。

  1. input 为待解析字符串。

  2. positioninput 内的指针初始指向字符串开始。

  3. start position 设置为 position

  4. date presenttime present 标志设置为 true。

  5. 解析日期部分 来获得 yearmonthday。 如果它没有返回,设置 date present 为 false。

  6. 如果 date present 为 true,且 position 没有越过 input 的末尾, 且 position 处的字符是 U+0054 LATIN CAPITAL LETTER T 字符 (T)或 U+0020 SPACE 字符, 将 position 前进到 input 的下一个字符。

    否则,如果 date present 为 true,并且 position 越过了 input 的末尾或 position 处的字符既不是 U+0054 LATIN CAPITAL LETTER T 字符 (T)也不是 U+0020 SPACE 字符, 则设置 time present 为 false。

    否则,如果 date present 为 false,将 position 设置回 start position

  7. 如果 time present 为 true,则 解析时间部分 来获得 hourminutesecond。 如果它没有返回,则失败。

  8. 如果 date presenttime present 标志都是 true, 但 position 越过了 input 的末尾,则失败。

  9. 如果 date presenttime present 标志都是 true, 解析时区偏移部分 来获得 timezonehourstimezoneminutes。如果它没有返回则失败。

  10. 如果 position 没有 越过 input 的结尾,则失败。

  11. 如果 date present 标志为 true 且 time present 标志为 false, 则令 date 为年与日分别为 yearmonthday 的日期并返回 date

    否则,如果 time present 标志为 true 且 date present 标志为 false, 则令 time 为时分秒分别为 hourminutesecond 的时间并返回 time

    否则,令 timeyearmonthdayhour 时mminutesecond 秒, 减去 timezonehours 小时 timezoneminutes分钟,这一时刻是 UTC 时区的时间; 令 timezone 距离 UTC timezonehours 小时 timezoneminutes 分钟; 返回 timetimezone

2.4.6 颜色

简单颜色 由三个在 0..255 范围的 8 位数字组成。 分别表示 sRGB 色彩空间的颜色的红、绿、蓝分量。 [SRGB]

合法的简单颜色 字符串应恰好包含 7 个字符长度, 第一个字符是 U+0023 NUMBER SIGN 字符(#),剩下的 6 个都是 ASCII 十六进制数, 其中前两个表示红色分量,中间两个表示绿色分量,最后两个表示蓝色分量,均为 16 进制。

合法的小写简单颜色 字符串是 不使用任何 U+0041 LATIN CAPITAL LETTER A 到 U+0046 LATIN CAPITAL LETTER F 字符的 合法的简单颜色

解析简单色值的规则 由下列算法给出。 被调用时必须依次执行这些步骤,在第一个有返回值的步骤中止。该算法将会返回一个 简单颜色 或者错误。

  1. input 为待解析字符串。

  2. 如果 input 不是恰好 7 个字符则返回一个错误。

  3. 如果 input 的首字符不是 U+0023 NUMBER SIGN 字符(#),则返回一个错误。

  4. 如果 input 的后面 6 个字符不都是 ASCII 十六进制数字,则返回一个错误。

  5. result 为一个 简单颜色

  6. 将第2、3个字符解释为 16 进制数,令该结果为 result 的红色分量。

  7. 将第4、5个字符解释为 16 进制数,令该结果为 result 的绿色分量。

  8. 将第6、7个字符解释为 16 进制数,令该结果为 result 的蓝色分量。

  9. 返回 result

给定 简单颜色 序列化简单色值的规则 在下列算法中给出:

  1. result 为包含一个 U+0023 NUMBER SIGN 字符(#)的字符串。

  2. 将红、绿、蓝分量依次转换为两位 16 进制数字,并使用 ASCII 小写十六进制数字, 需要的话填充零。将这些数字按照红绿蓝的顺序追加到 result

  3. 返回 result,它将是一个 合法的小写简单颜色


有些废弃的遗留属性以更复杂的方式解析颜色,它们使用 解析遗留色值的规则,由以下算法给出。 被调用时必须依次执行这些步骤,在第一个有返回值的步骤中止。该算法将会返回一个 简单颜色 或者错误。

  1. input 为待解析字符串。

  2. 如果 input 位空字符串则返回一个错误。

  3. input移除前后的 ASCII 空白

  4. 如果 input ASCII 大小写不敏感地 匹配 字符串 "transparent",则返回一个错误。

  5. 如果 input ASCII 大小写不敏感地 匹配 命名颜色,则返回该关键字对应的 简单颜色[CSSCOLOR]

    没有识别 CSS2 System Colors

  6. 如果 input 是 4 个字符长度,且 input 的第一个字符是 U+0023(#), 且 input 后面的 3 个字符都是 ASCII 十六进制数字,则:

    1. result 为一个 简单颜色

    2. input 第二个字符解释为十六进制数字;令 result 的红色分量为得到的数字乘以 17。

    3. input 第三个字符解释为十六进制数字;令 result 的绿色分量为得到的数字乘以 17。

    4. input 第四个字符解释为十六进制数字;令 result 的蓝色分量为得到的数字乘以 17。

    5. 返回 result

  7. input 中任何代码点大于 U+FFFF 的字符(即任何不在基本多文种平面的字符)替换为两个字符的字符串 "00"。

  8. 如果 input 字符长度大于 128,把 input 截断到只有 128 个字符。

  9. 如果 input 中第一个字符是 U+0023 NUMBER SIGN 字符(#),移除它。

  10. input 中任何非 ASCII 十六进制数字 的字符替换为 U+0030 DIGIT ZERO(0)。

  11. While input 长度为零或者不是 3 的倍数,添加一个 U+0030 DIGIT ZERO (0)字符到 input

  12. input 分割成三个等长字符来获得三个分量。 令length 为这三个分量的长度(input 长度的三分之一)。

  13. 如果 length 大于 8,移除每个分量中前面的 length-8 个字符,并且令 length 为 8。

  14. While length 大于 2 并且每个分量的第一个字符是 U+0030 DIGIT ZERO (0)字符,移除该字符并将 length 减一。

  15. 如果 length 仍然 大于 2,截断每个分量,分别只保留前两个字符。

  16. result 为一个 简单颜色

  17. 将第一个分量解释为十六进制数字;令 result 的红色分量为得到的数字。

  18. 将第二个分量解释为十六进制数字;令 result 的绿色分量为得到的数字。

  19. 将第三个分量解释为十六进制数字;令 result 的蓝色分量为得到的数字。

  20. 返回 result


2D 图形上下文 有单独的颜色语法,还处理了不透明度。

2.4.7 空格分隔的令牌

空格分隔的令牌集合 是包含零个或更多词(称为令牌)的字符串,它们以一个或更多 ASCII 空白 分隔, 其中的词是由一个或更多的除 ASCII 空白 之外的字符组成的任何字符串。

包含 空格分隔的令牌集合 的字符串前后都可能有 ASCII 空白

空格分隔的无序不重复令牌集合 是一个没有令牌重复的 空格分隔的令牌集合

空格分隔的有序不重复令牌集合 是一个没有令牌重复但令牌顺序有意义的 空格分隔的令牌集合

空格分隔的令牌集合 有时定义有允许值的集合。 当定义了允许值的集合时,集合中的令牌必须都从那个允许的列表中来;其他值是不合规范的。 如果没有提供允许值的集合,那么所有值都是符合规范的。

set of space-separated tokens 中的令牌如何进行比较 (例如是否大小写敏感) 由各自集合定义。

2.4.8 逗号分隔的字符集

逗号分隔的字符集 is a string containing zero or more tokens each separated from the next by a single U+002C COMMA character (,), where tokens consist of any string of zero or more characters, neither beginning nor ending with ASCII whitespace, nor containing any U+002C COMMA characters (,), and optionally surrounded by ASCII whitespace.

是包含零个或多个字符的字符串,它们以一个 U+002C COMMA 字符(,)分隔,其中的字符是由一个或更多的字符组成的任意字符串,首尾不包括 ASCII 空白也不能包含 U+002C COMMA 字符(,),但前后可以有 ASCII 空白

例如字符串" a ,b,,d d "由四个字符组成:"a", "b", 空字符串和 "d d"。每个字符的前后空白不计入字符,空字符串可以是一个字符。

有时逗号分隔的字符集对合法字符的构成还有额外限制。如果定义了那些限制,字符就必须完全遵守;其他值都是不符合规范的。如果没定义其他限制,所有值都是符合规范的。

2.4.9 引用

type 类型的元素的 合法的哈希名引用 字符串由一个 U+0023 NUMBER SIGN 字符(#)和完全匹配 同一个 中的 type 元素的 name 属性的字符串构成。

给定上下文节点 scope解析对 type 类型的元素的哈希名引用的规则 如下:

  1. 如果被解析字符串不包含 U+0023 NUMBER SIGN 字符,或者第一个这样的字符是字符串的最后一个字符, 则返回 null 并中止这些步骤。

  2. s 为从紧接着第一个 U+0023 NUMBER SIGN 字符之后的字符开始,直到待解析字符串结尾的字符串。

  3. 返回 scope 中,按照 树序 的第一个 idname 属性的值是 s 的类型为 type 的元素。如果没有这样的元素就返回 null。

    虽然解析时用到了 id 属性, 但它不用于决定一个值是否是 合法的 哈希名引用。 也就是说,一个基于 id 引用元素的哈希名引用是符合性错误。 (除非那个元素也有一个具有相同值的 name 属性)。

2.4.10 媒体查询

合法的媒体查询列表 是一个匹配 Media Queries 标准中的 <media-query-list> 生成式的字符串。[MQ]

匹配用户环境 的字符串可以是空字符串、只包含 ASCII 空白 的字符串, 或者根据 Media Queries 标准给出的定义匹配用户环境的媒体查询列表。[MQ]

2.5 URL

2.5.1 术语

一个字符串如果是合法 URL 字符串,同时是非空字符串, 那么它就是 合法的非空 URL

如果 去掉前后 ASCII 空白 后是一个 合法 URL 字符串, 那么它就是一个 可能由空格包裹的合法 URL

如果 去掉前后 ASCII 空白 后是一个 合法的非空 URL, 那么它就是一个 可能由空格包裹的合法的非空 URL

本标准将 about:legacy-compat 定义为保留 URL。 因为 about: URL 不可解析,当需要兼容 XML 工具时, 用在 HTML 文档DOCTYPE 中。[ABOUT]

本标准将 about:html-kind 定义为保留 URL。 因为 about: URL 不可解析,可用于媒体轨道的类型标识。[ABOUT]

本标准将 about:srcdoc 定义为保留 URL。 因为 about: URL 不可解析, 被用于 iframe srcdoc 文档URL [ABOUT]

Document 对象 document后备基 URL 是通过执行这些步骤获得的 URL 记录

  1. 如果 document iframe srcdoc 文档, 则返回 document浏览环境容器文档文档基 URL

  2. 如果 documentURLabout:blank, 且 document浏览环境创建者的 base URL 是非空,那么返回该 创建者的 base URL

  3. 返回 documentURL

Document 对象的 文档基 URL 是通过执行这些步骤获得的 绝对 URL

  1. 如果 Document 中不存在拥有 href 属性的 base 元素,那么 文档基 URLDocument后备基 URL;中止这些步骤。

  2. 否则,文档基 URLDocument 中按照 树序 的 第一个有 href 属性的 base 元素的 冻结的基 URL

2.5.2 解析 URL

解析 URL 是从字符串中获取它表示的 URL 记录 的过程。 虽然这一过程定义在 WHATWG URL 标准中,但方便起见 HTML 标准也定义了一个包装过的版本。 [URL]

这一包装只用于出于历史原因当 URL 解析器的字符编码必须匹配文档或环境设置对象时。 除此之外可以直接使用 URL 解析器

相对于一个 documentenvironment settings object 解析 URL url, 用户代理必须使用下列步骤。 解析 URL 的结果可能是失败,也可能是 结果 URL 字符串结果 URL 记录

  1. 如果指定了 document, 令 encodingdocument字符编码, 否则令它为 environment settings objectAPI URL 字符编码

  2. 如果指定了 document, 令 baseURLdocument基 URL, 否则令它为 environment settings objectAPI 基 URL

  3. urlRecord 为 使用 baseURLencoding,在 url 上应用 URL 解析器 的结果。

  4. 如果 urlRecord 解析失败,中止这些步骤并产生一个错误。

  5. urlString 为在 urlRecord 上应用 URL 序列化 的结果。

  6. urlString 作为 结果 URL 字符串urlRecord 作为 结果 URL 记录 返回。

2.5.3 基 URL 的动态变化

当一个文档的 文档基 URL 变化时,该文档中所有元素多 受基 URL 变化的影响

当一个元素 受基 URL 变化影响 时执行下面的 基 URL 变化步骤(定义在 DOM 标准中):

如果该元素创建了 超链接

如果该超链接标识的 URL 正在展现给用户, 或任何从该 URL 来的数据正在影响显示,那么应该相对于该元素的 节点文档 重新解析 href 属性并适当地更新 UI。

例如 CSS :link/:visited 伪类 可能不受影响。

如果该超链接有 ping 属性 且它的 URL 正在展现给用户,那么应该相对于该元素的 节点文档 重新解析 ping 属性的令牌并适当地更新 UI。

如果该属性是有 cite 属性的 qblockquoteins,或 del 元素

如果 cite 属性标识的 URL 正在展现给用户, 或任何从该 URL 来的数据正在影响显示,那么应该相对于该元素的 节点文档 重新解析 href 属性并适当地更新 UI。

否则

该元素不直接受影响。

例如更改基 URL 不影响 img 元素显示的图片, 尽管脚本中后续对 src IDL 属性的访问将返回新的 绝对 URL,可能不再对应于正在显示的图片。

2.6 获取资源

2.6.1 术语

类型 为 "basic", "cors",或 "default" 的 响应 称为 CORS-same-origin[FETCH]

类型 为 "opaque" 或 "opaqueredirect" 的 响应 称为 CORS-cross-origin

响应不安全响应 是它的 内部响应(如果有的话),否则就是 响应 自己。

给定 urldestinationcorsAttributeState,以及可能有的 same-origin fallback 标志创建一个可能 CORS 的请求 应该执行以下步骤:

  1. 如果 corsAttributeStateNo CORS, 令 mode 为 "no-cors" ,否则令 mode 为 "cors"。

  2. 如果设置了 same-origin fallback 标志mode 为 "no-cors",则将 mode 设置为 "same-origin"。

  3. credentialsMode 为 "include"。

  4. 如果 corsAttributeStateAnonymous, 将 credentialsMode 设为 "same-origin"。

  5. request 为一个新的 request, 其 urlurl目标地址destination模式modecredentials 模式credentialsMode, 且设置了 use-URL-credentials 标志

2.6.2 确定响应类型

必须获取响应的 Content-Type 元数据 并按照 WHATWG MIME Sniffing 标准的要求解释。[MIMESNIFF]

必须按照 WHATWG MIME Sniffing 标准的要求找到资源的 计算后的 MIME 类型[MIMESNIFF]

嗅探图片 Content-Type 的规则 区分资源是文本还是二进制的规则,以及 嗅探音频和视频的规则 也定义在 WHATWG MIME Sniffing 标准中。 这些规则返回的结果是一个 MIME 类型[MIMESNIFF]

WHATWG MIME Sniffing 标准中的规则必须严格遵守。 当用户代理使用与服务器所期望的内容类型检测不同的启发式方法时,可能会发生安全问题。 有关更多详细信息,请参阅 WHATWG MIME Sniffing 标准。 [MIMESNIFF]

2.6.3meta 元素提取字符编码

给定字符串 s 从一个 meta 元素提起字符编码的算法 如下。 它或者返回一个字符编码,或者什么都不返回。

  1. positions 中的指针初始指向字符串开始。

  2. Loop:在 s 中找到 position 后面 ASCII 大小写不敏感地 匹配 "charset" 的前 7 个字符。 如果没有找到这样的匹配,什么都不返回并中止这些步骤。

  3. 跳过所有紧接着 "charset" 后面的 ASCII 空白(也可能没有)。

  4. 如果下一个字符不是 U+003D EQUALS SIGN (=),让 position 指向下一个字符之前, 跳回到标记为 loop 的步骤。

  5. 跳过所有紧接着等号后面的 ASCII 空白(也可能没有)。

  6. 处理下一个字符:

    如果它是一个 U+0022 QUOTATION MARK 字符(")且 s 中后面还有一个 U+0022 QUOTATION MARK 字符 (")
    如果它是一个 U+0027 APOSTROPHE 字符 (')且 s 中后面还有一个 U+0027 APOSTROPHE 字符 (')
    返回从当前字符到当前字符的下一次出现的子字符串 获取编码 的结果。
    如果它是一个没有闭合的 U+0022 QUOTATION MARK 字符 (")
    如果它是一个没有闭合的 U+0027 APOSTROPHE 字符 (')
    如果没有下一个字符
    什么都不返回。
    否则
    返回从当前字符到(不包含)第一个 ASCII 空白 或 U+003B SEMICOLON 字符(;) 或 s 的末尾(取决于哪一个先出现) 构成的子字符串中 获取编码 的结果。

该算法与 HTTP 规范中的算法不同 (例如,HTTP 不允许使用单引号,并且需要支持该算法不支持的反斜线转义机制)。 虽然在历史上本算法用于 HTTP 相关的上下文,但不同的实现支持的语法前段时间就不一样了。[HTTP]

2.6.4 CORS 设置属性

CORS 设置属性 是一个 枚举属性。下表列出了关键字以及属性状态 — 每行中第一列给出了那一行的关键字映射到的状态。

状态 关键字 简要介绍
Anonymous anonymous Requests for the element will have their mode set to "cors" and their credentials mode set to "same-origin"。
(the empty string)
使用 Credentials use-credentials 该元素的 请求 会把 模式 设置为 "cors" 把 credentials 模式 设置为 "include"。

属性的 非法值默认Anonymous 状态,它的 缺失值默认No CORS 状态。 用于 反射 时, Anonymous 状态的 标准关键字anonymous

CORS 设置属性 控制的多数请求都是通过 创建一个可能 CORS 的请求 算法来完成的。

对于更先进的特行,比如请求的 mode 总是 "cors", 某些 CORS 设置属性 用于其他语义, 不过还是只对 请求credentials 模式 起作用。 为了执行这个转换,定义了 CORS 设置属性 credentials 模式 来通过属性状态确定 CORS 设置属性

No CORS
Anonymous
"same-origin"
Use Credentials
"include"

2.6.5 引荐来源策略属性

引荐来源策略属性 是一个 枚举属性。 每个 引荐来源策略包括空字符串都是该属性的关键字, 都映射到一个同名的状态。

该属性的 非法值的默认缺失值的默认 都是空字符串状态。

这些状态对各种 获取 处理模型的影响详细地定义在 本标准中,WHATWG Fetch 标准中,以及 Referrer Policy 中。 [FETCH] [REFERRERPOLICY]

对给定的 获取 使用哪个处理模型取决于多个信号; 引荐来源策略属性只是其中之一。一般来说,这些信号的处理顺序是:

  1. 首先,是否出现一个 noreferrer 超链接类型;

  2. 然后,引荐来源策略属性 的值;

  3. 然后,是否出现任何 name 属性设为 referrermeta 元素。

  4. 最后,`Referrer-Policy` HTTP 头。

2.6.6 Nonce attributes

Global_attributes/nonce

Support in all current engines.

Firefox31+SafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)YesInternet ExplorerNo
Firefox Android31+Safari iOSYesChrome AndroidYesWebView AndroidYesSamsung InternetYesOpera AndroidYes

A nonce content attribute represents a cryptographic nonce ("number used once") which can be used by Content Security Policy to determine whether or not a given fetch will be allowed to proceed. The value is text. [CSP]

Elements that have a nonce content attribute ensure that the crytographic nonce is only exposed to script (and not to side-channels like CSS attribute selectors) by taking the value from the content attribute, moving it into an internal slot named [[CryptographicNonce]], exposing it to script via the HTMLOrSVGElement interface mixin, and setting the content attribute to the empty string. Unless otherwise specified, the slot's value is the empty string.

element . nonce

Returns the value of the element's [[CryptographicNonce]] internal slot.

Can be set, to update that slot's value.

HTMLElement/nonce

Firefox75+Safari🔰 10+Chrome61+
Opera48+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox Android79+Safari iOS🔰 10+Chrome Android61+WebView Android61+Samsung Internet8.0+Opera Android45+

The nonce IDL attribute must, on getting, return the value of this element's [[CryptographicNonce]]; and on setting, set this element's [[CryptographicNonce]] to the given value.

Note how the setter for the nonce IDL attribute does not update the corresponding content attribute. This, as well as the below setting of the nonce content attribute to the empty string when an element becomes browsing-context connected, is meant to prevent exfiltration of the nonce value through mechanisms that can easily read content attributes, such as selectors. Learn more in issue #2369, where this behavior was introduced.

The following attribute change steps are used for the nonce content attribute:

  1. If element does not include HTMLOrSVGElement, then return.

  2. If localName is not nonce or namespace is not null, then return.

  3. If value is null, then set element's [[CryptographicNonce]] to the empty string.

  4. Otherwise, set element's [[CryptographicNonce]] to value.

Whenever an element including HTMLOrSVGElement becomes browsing-context connected, the user agent must execute the following steps on the element:

  1. Let CSP list be element's shadow-including root's CSP list.

  2. If CSP list contains a header-delivered Content Security Policy, and element has a nonce content attribute attr whose value is not the empty string, then:

    1. Let nonce be element's [[CryptographicNonce]].

    2. Set an attribute value for element using "nonce" and the empty string.

    3. Set element's [[CryptographicNonce]] to nonce.

    If element's [[CryptographicNonce]] were not restored it would be the empty string at this point.

As each Document's CSP list is append-only, user agents can optimize away the contains a header-delivered Content Security Policy check by, for example, holding a flag on the Document, set during Document creation and initialization.

The cloning steps for elements that include HTMLOrSVGElement must set the [[CryptographicNonce]] slot on the copy to the value of the slot on the element being cloned.

2.6.7 Lazy loading attributes

Lazy_loading

Support in all current engines.

Firefox75+Safari15.4+Chrome77+
Opera64+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox Android79+Safari iOS15.4+Chrome Android77+WebView Android77+Samsung Internet12.0+Opera Android55+

A lazy loading attribute is an enumerated attribute. The following table lists the keywords and states for the attribute — the keywords in the left column map to the states in the cell in the second column on the same row as the keyword.

The attribute directs the user agent to fetch a resource immediately or to defer fetching until some conditions associated with the element are met, according to the attribute's current state.

Keyword State Description
lazy Lazy Used to defer fetching a resource until some conditions are met.
eager Eager Used to fetch a resource immediately; the default state.

The attribute's missing value default and invalid value default are both the Eager state.


The will lazy load element steps, given an element element, are as follows:

  1. If scripting is disabled for element, then return false.

    This is an anti-tracking measure, because if a user agent supported lazy loading when scripting is disabled, it would still be possible for a site to track a user's approximate scroll position throughout a session, by strategically placing images in a page's markup such that a server can track how many images are requested and when.

  2. If element's lazy loading attribute is in the Lazy state, then return true.

  3. Return false.

Each img and iframe element has associated lazy load resumption steps, initially null.

For img and iframe elements that will lazy load, these steps are run from the lazy load intersection observer's callback or when their lazy loading attribute is set to the Eager state. This causes the element to continue loading.

Each Document has a lazy load intersection observer, initially set to null but can be set to an IntersectionObserver instance.

To start intersection-observing a lazy loading element element, run these steps:

  1. Let doc be element's node document.

  2. If doc's lazy load intersection observer is null, set it to a new IntersectionObserver instance, initialized as follows:

    The intention is to use the original value of the IntersectionObserver constructor. However, we're forced to use the JavaScript-exposed constructor in this specification, until Intersection Observer exposes low-level hooks for use in specifications. See bug w3c/IntersectionObserver#427 which tracks this. [INTERSECTIONOBSERVER]

  3. Call doc's lazy load intersection observer's observe method with element as the argument.

    The intention is to use the original value of the observe method. See w3c/IntersectionObserver#427. [INTERSECTIONOBSERVER]

To stop intersection-observing a lazy loading element element, run these steps:

  1. Let doc be element's node document.

  2. Assert: doc's lazy load intersection observer is not null.

  3. Call doc's lazy load intersection observer unobserve method with element as the argument.

    The intention is to use the original value of the unobserve method. See w3c/IntersectionObserver#427. [INTERSECTIONOBSERVER]

(This is a tracking vector.) The lazy load root margin is an implementation-defined value, but with the following suggestions to consider:

It is important for privacy that the lazy load root margin not leak additional information. For example, the typical scrolling speed on the current device could be imprecise so as to not introduce a new fingerprinting vector.

2.7 通用 DOM 接口

2.7.1 在 IDL 属性中反映内容属性

定义有些 IDL 属性是为了 反映 特定的内容属性。 这意味着在获取 IDL 属性时返回的是内容属性的当前值, 在设置 IDL 属性时将内容属性更改为给定的值。

通常,当获取 IDL 属性时如果内容属性不存在,IDL 属性必须表现为该内容属性的值为空字符串; 当设置时,如果内容属性的值不存在,则必须首先添加它。

如果反映内容属性的 IDL 属性是USVString属性, 且它的内容属性定义为包含一个 URL。那么在获取时如果内容属性不存在,那么 IDL 属性必须返回空字符串。 否则,IDL 属性必须相对于元素的节点文档 解析内容属性的值,如果解析成功则返回 结果 URL 字符串。 如果解析失败,则必须将内容属性的值转换USVString 并返回。 在设置时,必须设置内容属性的值为新值。

如果反映内容属性的 IDL 属性是 DOMString属性, 且它的内容属性是 枚举属性, 且该 IDL 属性 只限于已知的一些值, 那么当获取时必须返回与属性所处状态关联的关键字值(如果有的话),或者空字符串 (如果没有关联的关键字值,或属性不在任何已定义的状态。比如属性缺失且没有 缺失默认值)。 该状态有如果有多个关键字值,则返回匹配的那个。 如果有多个匹配的关键字值,则指定一个作为 标准关键字 并选择它。 在设置时,内容属性必须设置为指定的新值。

如果反映内容属性的 IDL 属性是可为空的 DOMString 属性, 且它的内容属性是一个 枚举属性,那么当获取时, 如果对应的内容属性在 缺失默认值 状态,则 IDL 属性必须返回 null; 否则 IDL 属性必须返回属性所属状态对应的关键字值。如果有多个关键字值,返回匹配的那个。 如果有多个匹配的 If there are multiple conforming keyword values, then one will be 如果有多个匹配的关键字值,则指定一个作为 标准关键字 并选择它。 在设置时,如果新值为 null 则内容属性必须被移除;否则内容属性必须设置为指定的新值。

如果反映内容属性的 IDL 属性是 DOMStringUSVString 属性但不归于上述类别中, 那么获取和设置必须透明地,保持大小写地进行。

如果反映内容属性的 IDL 属性是 布尔 属性, 当获取该 IDL 属性时,如果设置了该内容属性则必须返回 true, 如果不存在则返回 false。当设置时,如果该 IDL 属性被设为 false 则必须移除该内容属性。 如果该 IDL 属性被设为 true 则必须将内容属性设为空字符串。 (这与布尔内容属性的规则对应。)

如果反映内容属性的 IDL 属性是有符号整数类型 (long), 那么当获取时,必须根据解析有符号整数的规则 解析内容属性,如果解析成功且值在该 IDL 属性的类型的取值范围内,则必须返回结果值。 如果解析失败或返回了范围外的值,或者该属性不存在,则必须返回默认值,如果没有默认值则返回0。 当设置时,必须将给定的值转换为可以将该数字表示为合法整数 的可能的最短字符串,然后该字符串必须被用作新的内容属性值。

如果反映内容属性的 IDL 属性是有符号整数类型 (long) 且 仅限为非负数字,那么当获取时, 该内容属性必须根据解析非负整数的规则 解析,如果解析成功且值在该 IDL 属性类型的取值范围内,必须返回结果值。 如果解析失败或返回了范围外的值,或者该属性不存在,则必须返回默认值, 如果没有默认值则返回 −1。 当设置时,如果值为负用户代理必须抛出 "IndexSizeError" DOMException。 否则必须将给定的值转换为可以将该数字表示为 合法非负整数 的可能的最短字符串, 然后该字符串必须被用作新的内容属性值。

如果反映内容属性的 IDL 属性是 无符号 整数类型 (unsigned long) ,那么当获取时,必须根据 解析非负整数的规则 解析内容属性,如果解析成功且值在 0 到 2147483647 范围内(含), 必须返回结果值。 如果解析失败或返回了范围外的值,或者该属性不存在,必须返回默认值, 如果没有默认值则返回 0。当设置时,如果新值处于 0 到 2147483647 范围内, 则令 n 为这个新值,否则令n 为默认值(如果没有默认值则为0); 然后必须将 n 转换为可将该数字表示为 合法非负整数 的可能的最短字符串,然后该字符串必须被用作新的内容属性值。

如果反映内容属性的 IDL 属性是无符号整数类型(unsigned long) 且 仅限于大于零的非负整数 ,那么行为与上一种情形类似,但零是不允许的。 当获取时,首先必须根据 解析非负整数的规则 解析内容属性, 如果解析成功且值在 1 到 2147483647 范围内(含),则必须返回结果值。 如果解析失败或返回了范围外的值,或者该属性不存在, 则必须返回默认值(没有默认值则为1)。 当设置时,如果值为0,用户代理必须抛出 "IndexSizeError" DOMException。否则, 如果新值在 1 到 2147483647 范围内,那么令 n 为这个新值。 否则令 n 为默认值( 如果没有默认值则为 1); 然后必须将n 转换为可将该数字表示为 合法非负整数 的可能的最短字符串,然后该字符串必须被用作新的内容属性值。

如果反映内容属性的 IDL 属性是无符号整数类型(unsigned long) 且 仅限于有fallback 的大于0的非负整数,则行为与前一种情形类似,但不允许的值将被转换为默认值。 当获取时, 首先必须根据解析非负整数的规则 解析内容属性,如果解析成功且值在 1 到 2147483647 范围内(含),则必须返回结果值。 如果解析失败或返回了范围外的值,或者该属性不存在,则必须返回默认值。 当设置时,如果新值在 1 到 2147483647 范围内,则令 n 为这个新值, 否则令 n 为默认值;然后必须将 n 转换为可将该数字表示为 合法非负整数 的可能的最短字符串,然后该字符串必须被用作新的内容属性值。

如果反映内容属性的 IDL 属性是固定范围 到 [min, max] 的无符号整数类型(unsigned long), 当获取时,必须先根据 解析非负整数的规则 解析内容属性,如果解析成功且值在 minmax 之间(包含), 必须返回该结果值。如果失败,必须返回默认值。如果解析成功但值小于 min,必须返回 min。 如果解析成功但值大于 max,必须返回 max。当设置时,其行为与设置普通无符号整数一样。

如果反映内容属性的 IDL 属性是浮点数类型(doubleunrestricted double),那么当获取时, 必须根据 解析浮点数值的规则 解析内容属性,如果解析成功则必须返回结果值。 如果解析失败或该属性不存在,则必须返回默认值(如果没有默认值则为0)。 当设置时, 必须将给定的值转换为 浮点数的最佳表示,然后该字符串必须被用作新的内容属性值。

如果反映内容属性的 IDL 属性是浮点数类型(doubleunrestricted double)且 仅限于大于零的数字,那么行为与上一种情形类似但不允许零和负值。当获取时,必须根据 解析浮点数值的规则解析内容属性,如果解析成功且值大于 0.0,则必须返回结果值。 否则如果解析失败或返回了范围外的值,或者该属性不存在,则必须返回默认值(如果没有默认值则为0)。 当设置时,如果新值小于等于0,那么必须忽略该值。 否则,必须将给定的值转换为 浮点数的最佳表示,然后该字符串必须被用作新的内容属性值。

当设置 Infinity 和 Not-a-Number (NaN)这些值时会抛出异常。 定义在 Web IDL 中。 [WEBIDL]

如果反映内容属性的 IDL 属性的类型为 DOMTokenList,那么当获取时, 必须返回 DOMTokenList 对象,与它关联的元素为被查询的元素, 与它关联的属性的本地名称为被查询的属性名。

如果反映内容属性的 IDL 属性为 HTMLElement 类型, 或者依赖于 HTMLElement 的接口,那么当获取时, 它必须运行下列算法(在第一个返回值的地方停机):

  1. 如果对应的内容属性不存在,那么 IDL 属性必须返回 null。
  2. candidate 为:以对应的内容属性的当前值为参数, 在内容属性的元素的 节点文档 上调用 document.getElementById() 方法将会找到的元素。
  3. 如果 candidate 是 null,或者它与 IDL 属性类型不兼容, 那么该 IDL 属性必须返回 null。
  4. 否则,它必须返回 candidate

当设置时,如果给定的元素有 id 属性, 且与被设置属性的元素有同样的 , 且给定的元素是该 ID 为该 id 属性值的第一个元素,则必须将内容属性设置为 该 id 属性的值。否则,必须设置该内容属性为空字符串。

2.7.2 集合

HTMLFormControlsCollectionHTMLOptionsCollection 接口是 从 HTMLCollection 接口派生出来的 集合HTMLAllCollection 接口是 集合, 但它不派生自 HTMLCollection

2.7.2.1 The HTMLAllCollection interface

The HTMLAllCollection interface is used for the legacy document.all attribute. It operates similarly to HTMLCollection; the main differences are that it allows a staggering variety of different (ab)uses of its methods to all end up returning something, and that it can be called as a function as an alternative to property access.

All HTMLAllCollection objects are rooted at a Document and have a filter that matches all elements, so the elements represented by the collection of an HTMLAllCollection object consist of all the descendant elements of the root Document.

Objects that implement the HTMLAllCollection interface are legacy platform objects with an additonal [[Call]] internal method described in the section below. They also have an [[IsHTMLDDA]] internal slot.

Objects that implement the HTMLAllCollection interface have several unusual behaviors, due of the fact that they have an [[IsHTMLDDA]] internal slot:

These special behaviors are motivated by a desire for compatibility with two classes of legacy content: one that uses the presence of document.all as a way to detect legacy user agents, and one that only supports those legacy user agents and uses the document.all object without testing for its presence first. [JAVASCRIPT]

[Exposed=Window,
 LegacyUnenumerableNamedProperties]
interface HTMLAllCollection {
  readonly attribute unsigned long length;
  getter Element (unsigned long index);
  getter (HTMLCollection or Element)? namedItem(DOMString name);
  (HTMLCollection or Element)? item(optional DOMString nameOrIndex);

  // Note: HTMLAllCollection objects have a custom [[Call]] internal method and an [[IsHTMLDDA]] internal slot.
};
collection . length

Returns the number of elements in the collection.

element = collection . item(index)
element = collection(index)
element = collection[index]

Returns the item with index index from the collection (determined by tree order).

element = collection . item(name)
collection = collection . item(name)
element = collection . namedItem(name)
collection = collection . namedItem(name)
element = collection(name)
collection = collection(name)
element = collection[name]
collection = collection[name]

Returns the item with ID or name name from the collection.

If there are multiple matching items, then an HTMLCollection object containing all those elements is returned.

Only button, form, iframe, input, map, meta, object, select, and textarea elements can have a name for the purpose of this method; their name is given by the value of their name attribute.

The object's supported property indices are as defined for HTMLCollection objects.

The supported property names consist of the non-empty values of all the id attributes of all the elements represented by the collection, and the non-empty values of all the name attributes of all the "all"-named elements represented by the collection, in tree order, ignoring later duplicates, with the id of an element preceding its name if it contributes both, they differ from each other, and neither is the duplicate of an earlier entry.

On getting, the length attribute must return the number of nodes represented by the collection.

The indexed property getter must return the result of getting the "all"-indexed element from this HTMLAllCollection given the passed index.

The namedItem(name) method must return the result of getting the "all"-named element(s) from this HTMLAllCollection given name.

The item(nameOrIndex) method must perform the following steps:

  1. If nameOrIndex was not provided, return null.

  2. Return the result of getting the "all"-indexed or named element(s) from this HTMLAllCollection, given nameOrIndex.


The following elements are "all"-named elements: a, button, embed, form, frame, frameset, iframe, img, input, map, meta, object, select, and textarea

To get the "all"-indexed element from an HTMLAllCollection collection given an index index, return the indexth element in collection, or null if there is no such indexth element.

To get the "all"-named element(s) from an HTMLAllCollection collection given a name name, perform the following steps:

  1. If name is the empty string, return null.

  2. Let subCollection be an HTMLCollection object rooted at the same Document as collection, whose filter matches only elements that are either:

  3. If there is exactly one element in subCollection, then return that element.

  4. Otherwise, if subCollection is empty, return null.

  5. Otherwise, return subCollection.

To get the "all"-indexed or named element(s) from an HTMLAllCollection collection given nameOrIndex:

  1. If nameOrIndex, converted to a JavaScript String value, is an array index property name, return the result of getting the "all"-indexed element from this HTMLAllCollection given the number represented by nameOrIndex.

  2. Return the result of getting the "all"-named element(s) from this HTMLAllCollection given nameOrIndex.

2.7.2.1.1 [[Call]] ( thisArgument, argumentsList )
  1. If argumentsList's size is zero, or if argumentsList[0] is undefined, return null.

  2. Let nameOrIndex be the result of converting argumentsList[0] to a DOMString.

  3. Let result be the result of getting the "all"-indexed or named element(s) from this HTMLAllCollection given nameOrIndex.

  4. Return the result of converting result to an ECMAScript value.

The thisArgument is ignored, and thus code such as Function.prototype.call.call(document.all, null, "x") will still search for elements. (document.all.call does not exist, since document.all does not inherit from Function.prototype.)

2.7.2.2 HTMLFormControlsCollection 接口

HTMLFormControlsCollection 接口用于 form 元素中 列出的元素集合

HTMLFormControlsCollection

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

RadioNodeList

Support in all current engines.

Firefox33+Safari7+Chrome21+
Opera15+Edge79+
Edge (Legacy)12+Internet Explorer9+
Firefox Android33+Safari iOS7+Chrome Android25+WebView Android4.4+Samsung Internet1.5+Opera Android14+
interface HTMLFormControlsCollection : HTMLCollection {
  // inherits length and item()
  getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem()
};

interface RadioNodeList : NodeList {
  attribute DOMString value;
};
collection . length

返回集合中元素的数目。

element = collection . item(index)
element = collection[index]

从集合中返回下标为 index 的项目。 这些项目以 树序 排序。

element = collection . namedItem(name)

HTMLFormControlsCollection/namedItem

Support in all current engines.

Firefox33+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android33+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+
radioNodeList = collection . namedItem(name)
element = collection[name]
radioNodeList = collection[name]

从集合中返回 IDnamename 的项目。

如果有多个匹配的项目,则返回一个包含所有那些元素的 RadioNodeList 对象。

radioNodeList . value [ = value ]

返回该对象表示的首个选中的单选按钮的值。

可以被设置,此时选中第一个值为该对象表示的值的单选按钮。

该对象 支持的属性下标HTMLCollection 中定义的相同。

支持的属性名该集合表示的 所有元素的所有 idname 属性的非空值组成。 这些值以 树序 排列, 忽略后面的重复项,元素的 idname 之前 (如果都存在的话),它们是互不相同的也互不为重复项。

namedItem(name) 方法必须根据下列算法操作:

  1. 如果 name 为空字符串,返回 null 并停止算法。
  2. 该方法被调用时,如果该集合中只有一个节点的 id 属性或 name 属性等于 name,则返回该节点并停止算法。
  3. 否则,如果集合中没有一个节点的 id 属性或 name 属性等于 name,则返回 null 并停止该算法。
  4. 否则,创建一个新的 RadioNodeList 对象, 表示该 HTMLFormControlsCollection 对象的一个 实时 视图, 且 RadioNodeList 对象中只包含 id 属性或 name 属性等于 name 的节点。RadioNodeList 对象中的节点必须以 树序 排序。
  5. 返回该 RadioNodeList 对象。

继承自 NodeList 接口的 RadioNodeList 接口的成员 必须与 NodeList 对象上的表现一致。

RadioNodeList/value

Support in all current engines.

Firefox33+Safari7+Chrome21+
Opera15+Edge79+
Edge (Legacy)12+Internet Explorer9+
Firefox Android33+Safari iOS7+Chrome Android25+WebView Android4.4+Samsung Internet1.5+Opera Android14+

在获取RadioNodeList 对象上的 value IDL 属性时, 必须返回运行下列步骤的返回值:

  1. elementRadioNodeList 对象表示的第一个 (树序type 属性处于 单选按钮 状态且 选中状态 为真的 input 元素。 如果这样的元素不存在,令它为 null。

  2. 如果 element 为 null,返回空字符串。

  3. 如果 element 为没有 value 属性的元素, 返回“on” 字符串。

  4. 否则返回该 元素value 属性的值。

当设置时,value IDL 属性必须执行下列步骤:

  1. 如果新的值是字符串“on”:令 elementRadioNodeList 对象表示的第一个(树序type 属性处于 单选按钮 状态且 value 内容属性缺失, 或存在且等于新的值(如果有新值的话)的 input 元素。 如果这样的元素不存在,令 element 为 null。

    除此之外:令 elementRadioNodeList 对象表示的第一个(树序type 属性处于 单选按钮 状态且 value 内容属性存在且等于新值(如果有的话) 的 input 元素。 如果这样的元素不存在,令 element 为 null。

  2. 如果 element 不是 null, 则设置它的 选中状态 为真。

2.7.2.3 HTMLOptionsCollection 接口

HTMLOptionsCollection 接口用于 option 元素的 集合。它经常以 select 元素为根, 且拥有操作其后代属性和方法。

interface HTMLOptionsCollection : HTMLCollection {
  // inherits item(), namedItem()
  [CEReactions] attribute unsigned long length; // shadows inherited length
  [CEReactions] setter void (unsigned long index, HTMLOptionElement? option);
  [CEReactions] void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
  [CEReactions] void remove(long index);
  attribute long selectedIndex;
};
collection . length [ = value ]

返回集合中元素的数目。

当设置为较小的数字时,截断相应容器中 option 元素的数目。

当设置为较大的数字时,在容器中新增空白的 option 元素。

element = collection . item(index)
element = collection[index]

返回集合中下标为 index 的项目。项目以 树序 排序。

collection[index] = element

index 比集合中项目的数目大时,在相应容器中新增空白 option 元素。

当设为 null 时,从集合中移除在下标 index 处的项目。

当设为一个 option 元素时,在下标 index 处新增或替换为该元素。

element = collection . namedItem(name)
element = collection[name]

从集合中返回 IDnamename 的元素。

如果有多个匹配项则返回第一个。

collection . add(element [, before ] )

before 节点前插入 element

before 参数是数字时,在该数字处的项前插入 element; 是集合中的元素时,在该元素前插入 element

如果 before 被省略或者为 null, 或者是一个溢出的数字, 就在列表尾部插入 element

如果 element 是被插入元素的祖先, 该方法将会抛出 "HierarchyRequestError" DOMException

collection . remove(index)

从集合中移除下标为 index 的元素。

collection . selectedIndex [ = value ]

返回第一个项的下标(如果有的话),否则,如果没有选中项则返回 −1。

可以被设置,来改变选中项。

该对象 支持的属性下标HTMLCollection 对象中定义的相同。

当获取时,length 属性必须返回 集合表示的 节点的数目。

当设置时,其行为取决于新的值等于、大于或小于 当时 集合表示的 节点的数目。 如果等于,则设置该属性不应做任何事情。如果大于,则必须将 n 个新的、 没有属性和子节点的 option 元素追加到 HTMLOptionsCollection 的根 select 元素上。其中 n 为这两个数字之差(新的值减去旧的值)。 同时必须触发 Mutation 事件,如同插入了包含这些 option 元素的 DocumentFragment 一样。如果新的值更小,则必须从父节点中移除集合中最后的 n 个节点,其中 n 为这两个数之差(旧的值减去新的值)。

设置 length 不会移除或增加任何 optgroup 元素,也不会给既有的 optgroup 元素增加子节点。 (虽然可以从中移除子节点)。

支持的属性名 由 所有 集合表示的 元素的 所有idname属性的非空值构成。 这些值以 树序 排列, 忽略后面的重复项,元素的 idname 之前(如果都存在的话),它们互不相同也互不为重复项。

当用户代理 设置一个新的索引属性的值设置已存在的索引属性的值 时, 设属性下标为 index,新的值为 value,它必须运行下列算法:

  1. 如果 value 为 null,以 index 为参数运行 remove 方法的步骤,并终止本步骤。

  2. length集合表示的 节点的数目。

  3. nindexlength

  4. 如果 n 大于0,则 追加 一个由 n-1 个新的、 没有属性和子元素的 option 元素组成的 DocumentFragmentHTMLOptionsCollection 所在的根 select 元素。

  5. 如果 n 大于等于0,追加 valueselect 元素。否则,以 value 替换 集合中第 index 个元素。

add(element, before) 方法必须按照下列算法执行:

  1. 如果 elementHTMLOptionsCollection 所在的根 select 元素的祖先节点,则抛出一个 "HierarchyRequestError" DOMException 并终止这些步骤。

  2. 如果 before 为一个元素,但它并非 HTMLOptionsCollection 所在的根 select 元素的后代,则抛出一个 "NotFoundError" DOMException 并终止这些步骤。

  3. 如果 elementbefore 为同一元素,则返回并终止这些步骤。

  4. 如果 before 为一个节点,那么令 reference 为该节点。 否则如果 before 为整数且集合中存在第 before 个节点,令 reference 为该节点。否则令 reference 为 null。

  5. 如果 reference 不为 null,令 parentreference 的父节点。否则令 parentHTMLOptionsCollection 所在的根 select 元素。

  6. reference之前插入 elementparent 节点中。

remove(index) 方法 必须按照下列算法执行:

  1. 如果 集合表示的 元素数目为0, 终止这些步骤。

  2. 如果 index 小于零,或小于 集合表示的 节点数目,终止这些步骤。

  3. element 为集合中第 index 个元素。

  4. element 从它的父节点移除。

selectedIndex IDL 属性必须像 HTMLOptionsCollection 所在的根 select 元素上的同名属性一样操作。

2.7.3 DOMStringList 接口

DOMStringList 接口是表示字符串列表的一种毫不时髦的复古的方式。

[Exposed=(Window,Worker)]
interface DOMStringList {
  readonly attribute unsigned long length;
  getter DOMString? item(unsigned long index);
  boolean contains(DOMString string);
};

新 API 必须使用 sequence<DOMString> 或 其他等价的接口,而不是 DOMStringList

strings . length

返回 strings 中字符串的个数。

strings[index]
strings . item(index)

返回 strings 中下标为 index 的字符串。

strings . contains(string)

如果 strings 包含 string 则返回 true,否则返回 false。

每个 DOMStringList 对象有一个与之关联的 列表

DOMStringList 对象 支持的属性下标 为 0 到关联列表的 大小 减 1。如果与它关联的列表 为空,它就没有 支持的属性下标

length 属性的读取方法必须返回 与该 DOMStringList 对象关联的列表的 大小

item(index) 方法被调用时, 必须返回该 DOMStringList 对象的关联列表中第 index 个项目, 如果 index 加一大于该 DOMStringList 对象的关联列表的 大小

contains(string) 方法被调用时,如果该 DOMStringList 对象的关联列表 包含 string,则必须返回 true, 否则必须返回 false。

2.8 安全地传递结构化数据

本节使用 JavaScript 标准的术语和排版惯例。 [JAVASCRIPT]

2.8.1 可序列化对象

可序列化对象 支持被序列化以及之后反序列化, 且这一过程与给定的 JavaScript 领域 无关。 这允许它们存储在磁盘中用于后续恢复,或者在文档和 worker 的边界上克隆 (包括不同 的文档之间, 或者不同的 事件循环 之间)。

并非所有对象都是 可序列化对象,也并不是 可克隆的对象 的所有方面都需要在序列化时保留。

平台对象 可以是 可序列化对象 只要它们实现了用 [Serializable] IDL 扩展属性 标注的接口。 这样的接口必须定义下面的算法:

序列化步骤, 接受一个 平台对象 value, 一个 记录 serialized, 和一个布尔值 forStorage

value 中的数据序列化为 serialized 字段的一系列步骤。 序列化到 serialized 中的结果数据必须独立于任何 JavaScript 领域

如果不可能序列化,这些步骤会抛出异常。

这些步骤可能会执行一个 子序列化 来序列化嵌套的数据结构。 它们不应直接调用 StructuredSerialize,因为这样做会忽略 一个重要的 memory 参数。

引入这些步骤,如果与该算法无关,则不应该提及 forStorage 参数。

反序列化步骤, 接受一个 记录 serialized 和一个 平台对象 value

serialized 中的数据反序列化的一系列步骤,用它适当地建立 valuevalue 将会是一个新创建的相应 平台对象 类型的实例, 它的内部数据还未建立;这一工作交给这些步骤:

如果不可能反序列化这些步骤会抛出一个异常。

这些步骤可能会执行一个 子反序列化 来反序列化嵌套的数据结构。 它们不能直接调用 StructuredDeserialize,一文这样做会忽略 重要的 targetRealmmemory 参数。

由平台对象的定义决定哪些数据被这些步骤序列化和反序列化。通常这些步骤是非常对称的。

[Serializable] 扩展属性不允许有任何参数, 并且不能出现任何不是接口的地方。在一个接口上它必须只出现一次。它不能用在回调接口上。 如果它出现在部分接口(partial interface)上,或者一个混入接口(mixin)上, 那么它必须也出现在原始(original)或被混入(mixed-in-to)接口上, 并且部分接口或混入提供任何的 序列化步骤反序列化步骤 应该理解为 增加到原始或被混入接口的对应步骤上。

加入我们在定义一个平台对象 Person,它与两部分数据相关联:

接着,我们使用 [Serializable] 扩展属性 标注 Person 接口,可以把 Person 实例定义为 可序列化对象,同时定义下列算法:

序列化步骤
  1. 设置 serialized.[[Name]] 为 value 关联的名字值。

  2. serializedBestFriendvalue 关联的最好朋友的值的 子序列化

  3. 设置 serialized.[[BestFriend]] 为 serializedBestFriend

反序列化步骤
  1. 设置 value 关联的名字值为 serialized.[[Name]]。

  2. deserializedBestFriendserialized.[[BestFriend]] 的 子反序列化

  3. 设置 value 关联的最好朋友值为 deserializedBestFriend

在 JavaScript 规范中定义的对象直接由 StructuredSerialize 抽象操作处理。

最初,本规范定义了“克隆对象”的概念, 可以从一个 JavaScript 领域 克隆到另一个。 但为了更好地指定某些更复杂的情况的行为,更新了模型来显示地进行序列化和反序列化。

2.8.2 可传输对象

可传输对象 支持在 事件循环 之间传输。传输其实就是有效地重新创建对象并共享对底层数据的引用,然后将被传输的对象分离。 在转让昂贵资源的所有权时很有用。并非所有对象都是 可传输对象, 也并非 可传输对象 的所有方面都会在传输时被保留。

传输是不可逆转的、不幂等的操作。对象一旦被传输就不可再次传输或使用。

平台对象 可以是 可传输对象, 只要它们实现了以 [Transferable] IDL 扩展属性 注解的接口。 这样的接口必须定义下列算法:

传输步骤, 接受一个 平台对象 value 和一个 记录 dataHolder

value 中的数据传输到 dataHolder 字段的一系列步骤。 dataHolder 中的结果数据必须独立于任何 JavaScript 领域

如果不可能传输,这些步骤会抛出异常。

接收步骤, 接收一个 记录 dataHolder 和一个 平台对象 value

接收 dataHolder 中的数据并用它适当地建立 value 的一系列步骤。 value 将会是一个新创建的相应 平台对象 类型的实例, 它的内部数据还未建立;这一工作交给这些步骤:

如果不可能接收这次传输,这些步骤会抛出异常。

由平台对象的定义决定哪些数据被这些步骤传输。通常这些步骤是非常对称的。

[Transferable] 扩展属性不允许有任何参数, 并且不能出现任何不是接口的地方。在一个接口上它必须只出现一次。它不能用在回调接口上。 如果它出现在部分接口(partial interface)上,或者一个混入接口(mixin)上, 那么它必须也出现在原始(original)或被混入(mixed-in-to)接口上, 并且部分接口或混入提供任何的 传输步骤接收步骤 应该理解为 增加到原始或被混入接口的对应步骤上。

可传输对象平台对象 有一个 [[Detached]] 内部槽。 用于确保一旦平台对象已经被传输,它不能被再次传输。

JavaScript 标准中定义的对象直接交由 StructuredSerializeWithTransfer 抽象操作处理。

2.8.3 StructuredSerializeInternal ( value, forStorage [ , memory ] )

StructuredSerializeInternal 抽象操作接受一个 JavaScript 值 value 作为输入, 把它序列化为一个 领域 无关的形式,在这里表示为一个 记录。这一序列化的形式有着后续反序列化到不同领域的新 JavaScript 值需要的所有必要信息。

这一过程可能会抛出一个异常,例如当尝试序列化不可序列化对象时。

  1. 如果没有提供 memory,令 memory 为一个空的 映射

    memory 映射是为了避免把对象序列化两次。 最终会用于保持环状结构以及标识图中的重复对象。

  2. 如果 memory[value] 存在,则 返回 memory[value]。

  3. deep 为 false。

  4. 如果 Type(value) 为 Undefined,Null,Boolean, Number,BigInt 或 String,则返回 { [[Type]]: "primitive",[[Value]]: value }。

  5. 如果 Type(value) 为 Symbol,则抛出一个 "DataCloneError" DOMException

  6. serialized 为一个未初始化的值。

  7. 如果 value 有一个 [[BooleanData]] 内部槽,则把 serialized 设置为 { [[Type]]: "Boolean",[[BooleanData]]: value.[[BooleanData]] }。

  8. 否则,如果 value 有一个 [[NumberData]] 内部槽,则把 serialized 设置为 { [[Type]]: "Number",[[NumberData]]: value.[[NumberData]] }。

  9. 否则,如果 value 有一个 [[BigIntData]] 内部槽,则把 serialized 设置为 { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }。

  10. 否则,如果 value 有一个 [[StringData]] 内部槽,则把 serialized 设置为 { [[Type]]: "String",[[StringData]]: value.[[StringData]] }。

  11. 否则,如果 value 有一个 [[DateValue]] 内部槽,则把 serialized 设置为 { [[Type]]: "Date",[[DateValue]]: value.[[DateValue]] }。

  12. 否则,如果 value 有一个 [[RegExpMatcher]] 内部槽,则把 serialized 设置为 { [[Type]]: "RegExp",[[RegExpMatcher]]: value.[[RegExpMatcher]],[[OriginalSource]]: value.[[OriginalSource]], [[OriginalFlags]]: value.[[OriginalFlags]] }。

  13. 否则,如果 value 有一个 [[ArrayBufferData]] 内部槽,则:

    1. sizevalue.[[ArrayBufferByteLength]]。

    2. 如果 ! IsSharedArrayBuffer(value) 为 true,则:

      1. agentClustersurrounding agentagent cluster

      2. 如果 agentCluster跨域隔离 为 false,则抛出一个 "DataCloneError" DOMException

        该检查只在序列化时需要(反序列化时不需要)。因为 跨域隔离 不会随着时间改变,而且 SharedArrayBuffer 不能离开 agent cluster

      3. 如果 forStorage 为 true,则抛出一个 "DataCloneError" DOMException

      4. serialized 设置为 { [[Type]]: "SharedArrayBuffer",[[ArrayBufferData]]: value.[[ArrayBufferData]],[[ArrayBufferByteLength]]: size, [[AgentCluster]]: agentCluster }。

    3. 否则:

      1. 如果 ! IsDetachedBuffer(value) 为 true,则抛出一个 "DataCloneError" DOMException

      2. dataCopy 为 ? CreateByteDataBlock(size)。

        在分配地址失败时可能会抛出一个 RangeError 异常。

      3. 执行 ! CopyDataBlockBytes(dataCopy,0,value.[[ArrayBufferData]],0,size)。

      4. serialized 设置为 { [[Type]]: "ArrayBuffer",[[ArrayBufferData]]: dataCopy,[[ArrayBufferByteLength]]: size }。

  14. 否则,如果 value 有一个 [[ViewedArrayBuffer]] 内部槽,则:

    1. buffervalue 的 [[ViewedArrayBuffer]] 内部槽的值。

    2. bufferSerialized 为 ? StructuredSerializeInternal(buffer,forStorage, memory)。

    3. 断言: bufferSerialized.[[Type]] 是 "ArrayBuffer"。

    4. 如果 value 有一个 [[DataView]] 内部槽,则把 serialized 设置为 { [[Type]]: "ArrayBufferView",[[Constructor]]: "DataView",[[ArrayBufferSerialized]]: bufferSerialized,[[ByteLength]]: value.[[ByteLength]],[[ByteOffset]]: value.[[ByteOffset]] }。

    5. 否则:

      1. 断言: value 有一个 [[TypedArrayName]] 内部槽。

      2. serialized 设置为 { [[Type]]: "ArrayBufferView",[[Constructor]]: value.[[TypedArrayName]],[[ArrayBufferSerialized]]: bufferSerialized, [[ByteLength]]: value.[[ByteLength]],[[ByteOffset]]: value.[[ByteOffset]],[[ArrayLength]]: value.[[ArrayLength]] }。

  15. 否则,如果 value 有 [[MapData]] 内部槽,则:

    1. 设置serialized 为 { [[Type]]: "Map",[[MapData]]: 一个新的空 列表 }。

    2. 设置deep 为 true。

  16. 否则,if value 有 [[SetData]] 内部槽,则:

    1. 设置 serialized 为 { [[Type]]: "Set",[[SetData]]: 一个新的空 列表 }。

    2. 设置 deep 为 true。

  17. 否则,如果 value 有 [[ErrorData]] 内部槽且 value 不是 平台对象,那么:

    1. name 为 ? Get(value, "name")。

    2. 如果 name 不是 "Error", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError" 或 "URIError",则设置 name 为 "Error"。

    3. valueMessageDesc 为 ? value.[[GetOwnProperty]]("message")。

    4. 如果 IsDataDescriptor(valueMessageDesc) 为 false, 令 message 为 undefined,否则为 ? ToString(valueMessageDesc.[[Value]])。

    5. 设置 serialized 为 { [[Type]]: "Error", [[Name]]: name, [[Message]]: message }。

    6. 用户代理应该把任何有用的还没标准化的附加数据都加到序列化表示 serialized 里,尤其是 stack 属性。

      该数据正在标准化,见 Error Stacks 提案。[JSERRORSTACKS]

  18. 否则,如果 value 是一个外来 Array 对象,那么:

    1. valueLenDescriptor 为 ? OrdinaryGetOwnProperty(value,"length")。

    2. valueLenvalueLenDescriptor.[[Value]]。

    3. 设置serialized 为 { [[Type]]: "Array",[[Length]]: valueLen, [[Properties]]: 一个新的空 列表 }。

    4. 设置deep 为 true。

  19. 否则,如果 value 是一个 可序列化的 平台对象

    1. 如果 value 有一个 [[Detached]] 内部槽且值为 true, 则抛出一个 "DataCloneError" DOMException

    2. typeStringvalue主接口 标识。

    3. 设置serialized 为 { [[Type]]: typeString }。

    4. 设置deep 为 true。

  20. 否则,如果 value 是一个 平台对象,则抛出一个 "DataCloneError" DOMException

  21. 否则,如果 IsCallable(value) 为 true,则抛出一个 "DataCloneError" DOMException

  22. 否则,如果 value 有除了 [[Prototype]] 和 [[Extensible]] 之外的任何内部槽, 则抛出一个 "DataCloneError" DOMException

    例如 [[PromiseState]] 或 [[WeakMapData]] 内部槽。

  23. 否则,如果 value 是一个外来对象且 value 不是 关联到任何 JavaScript realm%Object.prototype% intrinsic 对象, 则抛出一个 "DataCloneError" DOMException

    例如代理对象。

  24. 否则:

    1. 设置serialized 为 { [[Type]]: "Object",[[Properties]]: 一个新的空 列表 }。

    2. 设置deep 为 true。

    %Object.prototype% 最终会被本步骤或后续步骤处理。 最终结果是它的外来属性被忽略,反序列化后结果将是一个空对象(而不是 prototype 外部对象不变量)。

  25. 设置 memory[value] 为 serialized

  26. 如果 deep 为 true,则:

    1. 如果 value 有一个 [[MapData]] 内部槽,则:

      1. copiedList 为一个新的空 列表

      2. value.[[MapData]] 中的 每一个 记录 { [[Key]],[[Value]] } entry

        1. copiedEntry 为一个新的 记录 { [[Key]]: entry.[[Key]],[[Value]]: entry.[[Value]] }。

        2. 如果 copiedEntry.[[Key]] 不是特殊值 empty追加 copiedEntrycopiedList

      3. copiedList 中的 每一个 记录 { [[Key]],[[Value]] } entry

        1. serializedKey 为 ? StructuredSerializeInternal(entry.[[Key]],forStorage, memory)。

        2. serializedValue 为 ? StructuredSerializeInternal(entry.[[Value]],forStorage, memory)。

        3. 追加 { [[Key]]: serializedKey, [[Value]]: serializedValue } 到 serialized.[[MapData]]。

    2. 否则,如果 value 有一个 [[SetData]] 内部槽,则:

      1. copiedList 为一个新的空 列表

      2. value.[[SetData]] 中 每一个 entry

        1. 如果 entry 不是特殊值 empty追加 entrycopiedList

      3. copiedList每一个 entry

        1. serializedEntry 为 ? StructuredSerializeInternal(entry,forStorage, memory)。

        2. 追加 serializedEntryserialized.[[SetData]]。

    3. 否则,如果 value 是一个 可序列化的 平台对象,则给定 valueserialized,和 forStorage, 为 valueprimary interface 执行 序列化步骤

      序列化步骤 可能需要执行一个 字序列化。 该操作接受 subValue 值作为输入,返回 StructuredSerializeInternal (subValue, forStorage,memory)。 (换句话说,子序列化StructuredSerializeInternal 的与该调用一致的特化。)

    4. 否则,对 ! EnumerableOwnPropertyNames(value, key) 里的每个 key

      1. 如果 ! HasOwnProperty(value, key) 为 true,则:

        1. inputValue 为 ? value.[[Get]](key, value)。

        2. outputValue 为 ? StructuredSerializeInternal(inputValue, forStorage, memory)。

        3. 把 { [[Key]]: key, [[Value]]: outputValue } 加到 serialized.[[Properties]]。

  27. 返回 serialized

注意 StructuredSerializeInternal 产生的 记录 可能包含其他记录的 "指针",这产生了环装引用。例如当我们传递下面的 JavaScript 对象到 StructuredSerializeInternal 中时:

const o = {};
o.myself = o;

它产生了下面的结果:

{
  [[Type]]: "Object",
  [[Properties]]: «
    {
      [[Key]]: "myself",
      [[Value]]: <a pointer to this whole structure>
    }
  »
}

2.8.4 StructuredSerialize ( value )

  1. 返回 ? StructuredSerializeInternal(value, false).

2.8.5 StructuredSerializeForStorage ( value )

  1. 返回 ? StructuredSerializeInternal(value, true).

2.8.6 StructuredDeserialize ( serialized, targetRealm [ , memory ] )

StructuredDeserialize 抽象操作接受一个 记录 serialized 作为输入,它由之前的 StructuredSerializeStructuredSerializeForStorage 产生,把它反序列化到一个新的 targetRealm 中创建的 JavaScript 值。

该过程可能抛出一个异常,例如为新的对象尝试分配内存时(尤其是 ArrayBuffer 对象)。

  1. 如果没有提供 memory,令 memory 为一个空的 映射

    memory 映射是为了避免把对象反序列化两次。 最终会用于保持环状结构以及标识图中的重复对象。

  2. 如果 memory[sirialized] 存在,则 返回 memory[serialized]。

  3. deep 为 false。

  4. value 为一个未初始化的值。

  5. 否则,如果 serialized.[[Type]] 是 "primitive",则设置 valueserialized.[[Value]]。

  6. 否则,如果 serialized.[[Type]] 是 "Boolean",则设置 value 为一个 targetRealm 中的新的 Boolean 对象,其 [[BooleanData]] 内部槽值为 serialized.[[BooleanData]]。

  7. 否则,如果 serialized.[[Type]] 是 "Number",则设置 value 为一个 targetRealm 中的新的 Number 对象,其 [[NumberData]] 内部槽值为 serialized.[[NumberData]]。

  8. 否则,如果 serialized.[[Type]] 是 "BigInt",则设置 value 为一个 targetRealm 中的新的 BigInt 对象,其 [[BigIntData]] 内部槽的值为 serialized.[[BigIntData]]。

  9. 否则,如果 serialized.[[Type]] 是 "String",则设置 value 为一个 targetRealm 中的新的 String 对象,其 [[StringData]] 内部槽值为 serialized.[[StringData]]。

  10. 否则,如果 serialized.[[Type]] 是 "Date",则设置 value 为一个 targetRealm 中的新的 Date 对象,其 [[DateValue]] 内部槽值为 serialized.[[DateValue]]。

  11. 否则,如果 serialized.[[Type]] 是 "RegExp",则设置 value 为一个 targetRealm 中的新的 RegExp 对象,其 [[RegExpMatcher]] 内部槽值为 serialized.[[RegExpMatcher]],其 [[OriginalSource]] 内部槽值为 serialized.[[OriginalSource]],其 [[OriginalFlags]] 内部槽值为 serialized.[[OriginalFlags]]。

  12. 否则,如果 serialized.[[Type]] 是 "SharedArrayBuffer",则:

    1. 如果 targetRealm 对应的 agent cluster 不是 serialized.[[AgentCluster]],则抛出一个 "DataCloneError" DOMException

    2. 否则,设置 value 到一个 targetRealm 中的新的 SharedArrayBuffer 对象, 其 [[ArrayBufferData]] 内部槽值为 serialized.[[ArrayBufferData]], 其 [[ArrayBufferByteLength]] 内部槽值是 serialized.[[ArrayBufferByteLength]]。

  13. 否则,如果 serialized.[[Type]] 是 "ArrayBuffer",则设置 value 为一个 targetRealm 中新的 ArrayBuffer 对象,其 [[ArrayBufferData]] 内部槽值为 serialized.[[ArrayBufferData]],其 [[ArrayBufferByteLength]] 内部槽值为 serialized.[[ArrayBufferByteLength]]。

    如果这抛出了一个异常,则抛出一个 "DataCloneError" DOMException

    如果没有足够的内存来创建这样一个 ArrayBuffer 对象,该步骤可能会抛出异常。

  14. 否则,如果 serialized.[[Type]] 是 "ArrayBufferView",则:

    1. deserializedArrayBuffer 为 ? StructuredDeserialize(serialized.[[ArrayBufferSerialized]], targetRealm,memory)。

    2. 如果 serialized.[[Constructor]] 是 "DataView",则设置 valuetargetRealm 中的一个新的 DataView 对象,其 [[ViewedArrayBuffer]] 内部槽值为 deserializedArrayBuffer,其 [[ByteLength]] 内部槽值为 serialized.[[ByteLength]],其 [[ByteOffset]] 内部槽值为 serialized.[[ByteOffset]]。

    3. 否则,设置 value 为一个 targetRealm 中新的有类型数组对象, 使用 serialized.[[Constructor]] 给出的构造器,其 [[ViewedArrayBuffer]] 内部槽值为 deserializedArrayBuffer,其 [[TypedArrayName]] 内部槽值为 serialized.[[Constructor]],其 [[ByteLength]] 内部槽值为 serialized.[[ByteLength]],其 [[ByteOffset]] 内部槽值为 serialized.[[ByteOffset]],其 [[ArrayLength]] 内部槽值为 serialized.[[ArrayLength]]。

  15. 否则,如果 serialized.[[Type]] 是 "Map",则:

    1. 设置valuetargetRealm 中一个新的 Map 对象,其 [[MapData]] 内部槽值为一个新的空 列表

    2. 设置deep to true。

  16. 否则,如果 serialized.[[Type]] 是 "Set",则:

    1. 设置value 为一个 targetRealm 中新的设置对象,其 [[SetData]] 内部槽值为一个新的空 列表

    2. 设置deep 为 true。

  17. 否则,如果 serialized.[[Type]] 是 "Array",则:

    1. outputPrototargetRealm.[[Intrinsics]].[[%Array.prototype%]]。

    2. 设置 value 为 ! ArrayCreate(serialized.[[Length]], outputProto)。

    3. 设置deep 为 true。

  18. 否则,如果 serialized.[[Type]] 是 "Object",则:

    1. 设置valuetargetRealm 中一个新的 Object。

    2. 设置deep 为 true。

  19. 否则,如果 serialized.[[Type]] 是 "Error",则:

    1. prototype%Error.prototype%

    2. 如果 serialized.[[Name]] 是 "EvalError",则设置 prototype%EvalError.prototype%

    3. 如果 serialized.[[Name]] 是 "RangeError",则设置 prototype%RangeError.prototype%

    4. 如果 serialized.[[Name]] 是 "ReferenceError",则设置 prototype%ReferenceError.prototype%

    5. 如果 serialized.[[Name]] 是 "SyntaxError",则设置 prototype%SyntaxError.prototype%

    6. 如果 serialized.[[Name]] 是 "TypeError",则设置 prototype%TypeError.prototype%

    7. 如果 serialized.[[Name]] 是 "URIError",则设置 prototype%URIError.prototype%

    8. messageserialized.[[Message]]。

    9. 设置 value 为 ! ObjectCreate(prototype, « [[ErrorData]] »)。

    10. messageDescPropertyDescriptor{ [[Value]]: message, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }。

    11. 如果 message 不是 undefined,则执行 ! OrdinaryDefineOwnProperty(value, "message", messageDesc)。

    12. serialized 上面任何有用的附加数据都应该反序列化后再附加到value 上。

  20. 否则:

    1. interfaceNameserialized.[[Type]]。

    2. 如果 interfaceName 标识的接口没有 暴露targetRealm 中,则抛出一个 "DataCloneError" DOMException

    3. 设置value 为在 targetRealm 中创建的、 以 interfaceName 标识的接口的一个新的实例。

    4. 设置deep 为 true。

  21. 设置 memory[serialized] 为 value

  22. 如果 deep 为 true,则:

    1. 如果 serialized.[[Type]] 是 "Map",则:

      1. serialized.[[MapData]] 中的 每一个 记录 { [[Key]],[[Value]] } entry

        1. deserializedKey 为 ? StructuredDeserialize(entry.[[Key]],targetRealm, memory)。

        2. deserializedValue 为 ? StructuredDeserialize(entry.[[Value]],targetRealm, memory)。

        3. 追加 { [[Key]]: deserializedKey, [[Value]]: deserializedValue } 到 value.[[MapData]]。

    2. 否则,如果 serialized.[[Type]] 是 "Set",则:

      1. serialized.[[SetData]] 中 每一个 entry

        1. deserializedEntry 为 ? StructuredDeserialize(entry,targetRealm, memory)。

        2. 追加 deserializedEntryvalue.[[SetData]]。

    3. 否则,如果 serialized.[[Type]] 是 "Array" 或 "Object",则:

      1. serialized.[[Properties]] 中的 每一个 记录 { [[Key]],[[Value]] } entry

        1. deserializedValue 为 ? StructuredDeserialize(entry.[[Value]],targetRealm, memory)。

        2. result 为 ! CreateDataProperty(value, entry.[[Key]],deserializedValue)。

        3. 断言: result 为 true。

    4. 否则:

      1. 给定 serializedvalue,为 serialized.[[Type]] 标识的接口 执行适当的 反序列化步骤

        反序列化步骤 可能会执行一个 子反序列化。该操作接受 先前序列化后的 Record subSerialized 作为输入,返回 StructuredDeserialize(subSerialized,targetRealm, memory)。(换句话说,子反序列化 是 是 StructuredDeserialize 的与该调用一致的特化。)

  23. 返回 value

2.8.7 StructuredSerializeWithTransfer ( value, transferList )

  1. memory 为一个空的 映射

    除了它在 StructuredSerializeInternal 中的正常使用外, 在本算法中 memory 还用来确保 StructuredSerializeInternal 忽略了 transferList 中的项目,来让我们做自己的处理。

  2. transferList 中的 每一个 transferable

    1. 如果 transferable 既没有 [[ArrayBufferData]] 内部槽 又没有 [[Detached]] 内部槽,则抛出一个 "DataCloneError" DOMException

    2. 如果 transferable 有一个 [[ArrayBufferData]] 内部槽且 ! IsSharedArrayBuffer(transferable) 为 true 或 ! IsDetachedBuffer(transferable) 为 true,则抛出一个 "DataCloneError" DOMException

    3. 如果 transferable 有一个 [[Detached]] 内部槽且 transferable.[[Detached]] 为 true,则抛出一个 "DataCloneError" DOMException

    4. placeholder 为一个用户代理定义的占位对象。

    5. 设置 memory[transferable] 为 placeholder

  3. serialized 为 ? StructuredSerializeInternal(value, false,memory)。

  4. transferDataHolders 为一个新的空 列表

  5. transferList 中的 每一个 transferable

    1. placeholdermemory[transferable]。

    2. dataHolder 为一个未初始化的值。

    3. 如果 transferable 有一个 [[ArrayBufferData]] 内部槽,则:

      1. 设置dataHolder 为 { [[TransferConsumed]]: false,[[Type]]: "ArrayBuffer", [[ArrayBufferData]]: transferable.[[ArrayBufferData]],[[ArrayBufferByteLength]]: transferable.[[ArrayBufferByteLength]] }。

      2. 执行 ! DetachArrayBuffer(transferable)。

    4. 否则:

      1. 断言: transferable 是一个 可传输的 平台对象

      2. interfaceNametransferable主接口 的标识符。

      3. 设置dataHolder 为 { [[TransferConsumed]]: false,[[Type]]: interfaceName }。

      4. 指定 transferabledataHolder, 为 interfaceName 标识的接口执行适当的 传输步骤

      5. 设置transferable.[[Detached]] 为 true。

    5. serialized 中,用 dataHolder 替换所有的 placeholder 实例。

    6. 追加 dataHoldertransferDataHolders

  6. 返回 { [[Serialized]]: serialized,[[TransferDataHolders]]: transferDataHolders }。

2.8.8 StructuredDeserializeWithTransfer ( serializeWithTransferResult, targetRealm )

  1. memory 为一个空的 映射

    除了它在 StructuredDeserialize 中的正常使用外, 在本算法中 memory 还用来帮助我们确定传输值的列表。

  2. deserialized 为 ? StructuredDeserialize(serializeWithTransferResult.[[Serialized]], targetRealm,memory)。

  3. transferredValues 为一个新的空 列表

  4. serializeWithTransferResult.[[TransferDataHolders]] 中的 每一个 transferDataHolder

    1. 追加 memory[transferDataHolder] 到 transferredValues

  5. 返回 { [[Deserialized]]: deserialized,[[TransferredValues]]: transferredValues }。

2.8.9 在其他规范中执行序列化和传输

其他规范可以使用这里定义的抽象操作。下面为每个抽象操作何时比较有用提供了指导以及例子。

StructuredSerializeWithTransfer
StructuredDeserializeWithTransfer

把一个值克隆到另一个 JavaScript Realm, 带着传输列表但提前不知道目标领域。 这一情况下序列化步骤可以立即执行,反序列化步骤延迟到目标 Realm 已知的时候执行。

messagePort.postMessage() 使用这一对抽象操作,因为目标 Realm 直到 MessagePort 发出 时才知道。

StructuredSerialize
StructuredSerializeForStorage
StructuredDeserialize

为给定的值创建一个 JavaScript Realm 无关的可以保存无限时间的快照, 然后(可能很多次)具象化回 JavaScript 值。

StructuredSerializeForStorage 可以在序列化被用于持久保存值的时候 (而不是在 Realm 之间传递)使用。当尝试序列化 SharedArrayBuffer 对象时会抛出异常, 因为保存共享内存没有意义。类似地,当指定有着定制的 序列化步骤平台对象forStorage 参数为 true 时,也可能抛出异常或者有不同的行为。

history.pushState()history.replaceState() 在作者提供的状态对象上使用 StructuredSerializeForStorage,把它们存储为 会话历史入口序列化状态。 然后 history.state 属性用了 StructuredDeserialize 来返回最初提供的状态对象的一份克隆。

broadcastChannel.postMessage() 对它的输入使用了 StructuredSerialize,然后对结果多次使用了 StructuredDeserialize 来对每一个广播目标产生新的拷贝。注意在多目标情况下传输没有意义。

持久化 JavaScript 值到文件系统的 API 可能还会对它的输入使用 StructuredSerializeForStorage 并对它的输出使用 StructuredDeserialize

一般来说,调用点可能会传递 Web IDL 值而不是 JavaScript 值; 这将被理解为在调用这些算法之前执行到 JavaScript 值的隐式 转换

本规范曾经定义了“结构化克隆”算法和一个 StructuredClone 抽象操作。 然而在实践中,它的所有已知用途可以更好地通过单独的序列化和反序列化步骤来实现,所以把它删除了。


如果在任意对象上进行操作,对于非用户代码同步调用到用户代理方法的调用点必须在调用 StructuredSerializeStructuredSerializeForStorage, 或 StructuredSerializeWithTransfer 等抽象操作之前小心地 准备执行脚本 以及 准备运行 fallback。 这是必要的,因为序列化过程可能会调用作者定义的访问器作为最终的深度序列化步骤, 这些访问器调用的操作可能会依赖于 entryincumbent 的概念已经建立好。

window.postMessage() 对它的参数执行 StructuredSerializeWithTransfer 操作,但是在算法中的同步部分立即执行这一操作则需要小心。 因为可能无需 准备执行脚本准备执行 fallback 就能使用该算法。

作为对比,假设有个 API 直接通过 事件循环任务 来定期地使用 StructuredSerialize 序列化一些作者提供的对象, 可能需要事先确保它执行了适当的准备工作。现在我们还没见过平台上有这样的 API; 通常,作为作者代码的同步结果来事先执行序列化更加容易。