HTML 导入

W3C 已停止草案

关于此文档的更多细节
此版本
https://w3org.cn/TR/2023/DISC-html-imports-20230615/
最新发布版本
https://w3org.cn/TR/html-imports/
最新编辑草案
https://wicg.github.io/webcomponents/spec/imports/
历史
https://w3org.cn/standards/history/html-imports
提交历史
编辑
(谷歌公司)
(谷歌公司)
反馈
GitHub w3c/webcomponents (拉取请求, 新议题, 打开的议题)

摘要

HTML 导入是一种在其他 HTML 文档中包含和复用 HTML 文档的方式 [HTML].

本文档状态

本节描述本文档在发布时的状态。当前的 W3C 出版物列表以及本技术报告的最新修订版可在 https://w3org.cn/TR/ 的 W3C 技术报告索引 中找到。

本文件由 Web Applications Working Group 以 已停止草案 形式发布,使用 推荐轨道

以已停用草案形式发布并不意味着得到 W3C 及其成员的认可。

以停止草案的形式发布意味着该文档不再计划推进或维护。引用此文档时应视为已废弃的工作。

本文件由遵循 W3C 专利政策 的小组制作。W3C 维护一份 公开的专利披露列表,列出与小组交付物相关的专利披露;该页面还包括披露专利的指南。任何实际了解其认为包含 必要权利要求 的专利的个人,必须依据 W3C 专利政策第 6 节进行披露。

本文档受 2021 年 11 月 2 日的 W3C 流程文档管辖。

1. 一致性

除了标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性内容。本规范中的其他所有内容均为规范性内容。

本文档中的关键词 MAYMUST 应按照 BCP 14 [RFC2119] [RFC8174] 的说明进行解释,仅当它们全大写出现时(如本文所示)。

任何点,当符合规范的 UA 必须对概念模型的状态或对状态的反应作出决定时,都被捕获为 算法。这些算法以 处理等价性 为定义依据。处理等价性 是对算法实现者施加的约束,要求 UA 实现的算法与规范中规定的算法在所有输入下的输出完全相同。

2. 术语

HTML 导入(或下文简称 imports)是 HTML 文档 [HTML],它们被 链接外部资源,来源于另一个 HTML 文档。链接到 import 的文档称为 import referrer。对于任意给定的 import,其 import referrer ancestor 要么是它的 import referrer,要么是该 import referrer 的任何 import referrer ancestor。由于同一 import 可以从多个 import referrer 被引用,因此每个 import 都拥有一个或多个 import referrersimport referrer ancestors

一个 import referrer 并非 import,即它不关联任何 import referrer,此类文档称为 主文档。每个 import 与唯一的 主文档 关联:如果该 referrer 本身是 主文档,则它就是该 import主文档。否则,该 import referrer主文档 即为该 import主文档

一个 URL 被称为 import location

在每个 import referrer 中,importDocument [WHATWG-DOM] 的形式表现,称为 imported document

问题 197: [imports]:导入与浏览上下文之间的关系应更清楚地说明 (bugzilla: 26682) html-importsneeds-clarification

导入的文档并不存在 浏览上下文

主文档 关联的所有 import 组成该 主文档import map。该映射以 import location 为键,import 为值进行存储。映射在开始时为空;在 import fetching algorithm 指定时会向映射添加新项。

2.1 导入依赖者

为了跟踪 已请求 的 import,每个文档都有一个 import link list。每个条目由 link(即 link 元素)以及 location(URL)组成。条目还可以 标记为分支。列表起始为空,条目按 import request 算法的规定加入。

每个 imported document 都有一个 import parent:如果文档 Aimport link list 包含一个标记为 分支 的条目,其 location 指向文档 B,则 ABimport parent

每个 imported document 还拥有一个或多个 import ancestor:若文档 A 是文档 Bimport parent,则 ABimport ancestorimport ancestor 关系具传递性:如果 ABimport parent,且 BCimport parent,则 A 也同时是 Cimport parent

每个 imported document 还有一个或多个 import predecessor。若文档 A 的 URL 在文档 Bimport parentimport link list 中位于文档 B 的 URL 之前,并且其对应的 link 被标记为 分支,则 ABimport predecessor

文档 Aimport ancestor predecessors 定义如下:若文档 B 为文档 Cimport predecessor,且 CAimport ancestor,则 BAimport ancestor predecessor

处于 import ancestor predecessorsimport predecessors 中的 Document,或从文档 Aimport link list 中标记为 分支 的条目链接而来,称为 Aimport dependent

import link listimport dependent 共同约束了导入中脚本的执行顺序。其目的是提供一个由每个 import 中的 link 元素顺序决定的确定性脚本执行顺序。每个节点的边按 import link list 的顺序排列。import predecessor 的选择也会考虑此顺序。

import link lists 的链接结构形成一个有向图。图中的每个节点对应一个文档,边对应一个 link。标记为 分支 的节点旨在形成该图的生成树。此树为脚本执行提供确定的顺序。

1 导入链接列表示例

1 中,

import referrer 与 import parent 的区别在于:import referrer 反映 节点树 的状态,而 import parent 则由本文件所述算法构建。

4. HTMLLinkElement 接口的扩展

WebIDLpartial interface HTMLLinkElement {
    readonly attribute Document? import;
};

在获取时,import 属性 必须返回 null,如果

否则,属性 必须返回对应 imported document,该文档由 import,并由该 link 元素表示。

每次都应返回同一对象。

Document(HTML 解析器或 XML 解析器)的上下文中出现的 import,如果满足以下条件,则被视为 阻塞脚本的 import:该 元素 由该 Document 的解析器创建,且该 元素 为类型为 importlink,且该 link 未被标记为 async,且 import 尚未 完全加载,并且在事件循环最近一次到达步骤 1 时,该 元素 正在该 Document 中,且用户代理尚未放弃该 import。用户代理 可以 在任何时候放弃一个 import

在 import 加载完毕之前放弃它,即使之后它仍会加载,这意味着脚本可能会在信息不完整的情况下运行。例如,如果一个 import 注册了自定义元素,而脚本依赖该元素的可用性,则当用户代理过早放弃时,脚本会发现该元素不可用。实现者必须在脚本使用错误信息的可能性与因等待慢速网络请求而产生的性能影响之间取得平衡。

如果 Document 中存在 阻塞脚本的 import,则该文档 拥有阻塞脚本的 import。如果文档的 import dependent 中不存在此类 import,则该文档 没有阻塞脚本的 import

拥有阻塞脚本的 import” 状态会在每次已有 import 完全加载或新的 import 加载启动时改变。HTML 解析器会在这些时机相应地解除阻塞。

5. Document 接口的扩展

5.1 document.open() 方法的补充

将以下步骤作为定义的第一步

  1. 如果 Documentimport,则抛出 InvalidStateError 异常。

5.2 document.write() 方法的补充

将以下步骤作为定义的第一步

  1. 如果 Documentimport,则抛出 InvalidStateError 异常。

5.3 document.close() 方法的补充

将以下步骤作为定义的第一步

  1. 如果 Documentimport,则抛出 InvalidStateError 异常。

6. 加载导入

6.1 更新分支

在向 import link list 添加 link 后,需对 master document 运行 update marking 算法,等价于执行以下步骤。

输入:
DOCUMENT,即 Document
  1. 如果 DOCUMENTmaster document,则取消标记 branch 状态的所有 links,以及与 DOCUMENT 关联的每个 imported document
  2. LISTDOCUMENTimport link list
  3. LIST 中的每个 ITEM ……
    1. LOCATIONITEMlocation
    2. IMPORT 为 URL 与 LOCATION 相同的 import
    3. 如果不存在另一个 link,其 locationLOCATION 相同且被标记为 branch,则将 ITEM 标记为 branch
    4. 如果 ITEM 已标记为 branchIMPORT 不为 null,则调用 update marking 算法并传入 IMPORT

6.2 请求导入

当用户代理尝试 获取 已链接的 import 时,必须同时运行 import request 算法,等价于执行以下步骤。

输入:
LINK,创建指向 import 的 link 元素。
LOCATION,所链接资源的 URL
  1. 如果 LINKasync 属性为 true,则将 LINK 标记为 async
  2. DOCUMENTLINK 所在的文档。
  3. LISTDOCUMENTimport link list
  4. ITEMLINKLOCATION 的组合。
    1. ITEM 添加到 LIST 的末尾。
    2. 使用 master document 调用 update marking 算法。

6.3 获取导入

所有从 master document 或其 import map 中的 import必须使用下面描述的 import fetching algorithm 进行获取,而非 HTML 所规定的 获取已链接资源 方法。

import fetching 算法 必须 等价于执行以下步骤。

输入:
LINK,一个创建指向 import 的 link 元素。
LOCATIONimport location
输出:
IMPORT,对应的 imported document
  1. 如果 LOCATION 已存在于 import map
    1. IMPORT 为对应的 imported document,并 停止
  2. 获取资源 [Fetch] 从 LOCATION,请求的来源设置为主文档主文档来源模式设为 CORS凭据模式设为 same-origin
    1. 如果获取的响应类型error 或响应包含名称为 Content-Disposition头部
    2. IMPORT 为一个新的Document,其文档地址LOCATION
    3. PARSER 为一个新的HTML 解析器,并与 IMPORT 关联
    4. LOCATIONIMPORT 加入导入映射
    5. 对于在获取期间由网络任务源放置到任务队列的每个任务
      1. 用获取的字节填充 PARSER输入字节流
      2. PARSERutf-8 [WHATWG-ENCODING] 作为已知确定编码处理输入字节流
    6. 当不再有可用字节时
      1. 将任务排入队列,来源为网络任务源,使 PARSER 处理隐含的 EOF 字符

所有已加载的导入以及正在加载的导入均位于导入链接列表中,因此列表中任何导入所链接的导入也将使用导入获取算法进行加载,LOCATION 为该导入的导入位置

如果算法完成时 IMPORT 不为 null,则该加载尝试 MUST 被视为成功;否则视为失败。

每个未被标记为 async延迟文档的 load 事件的导入。

link 元素在加载成功时触发一个名为load的简单事件。若加载失败,则触发一个名为error的简单事件

由于导入会延迟 load 事件,Document 在其所有已链接导入的加载尝试完成之前并非完全加载

6.4 导入与内容安全策略

内容安全策略 [CSP3] MUST 通过script-src指令限制导入加载。

每个导入 MUST 受其主文档的内容安全策略约束。例如,如果向导入发送了内容安全头字段,用户代理 MUST 强制执行 主文档的策略于被导入的文档。

7. 解析导入

导入的解析行为被定义为对HTML 解析的一组更改。

7.1 对 Prepare A Script 算法的补充

准备脚本算法的第 15 步中,修改以 如果元素没有 src 属性 开头的条件的最后部分,使其读取

...以及创建 DocumentHTML 解析器XML 解析器script 元素有阻止脚本执行的样式表有阻止脚本执行的导入

7.2 对树构建算法的补充

12.2.5.4.1 “initial” 插入模式章节的 DOCTYPE 部分,修改文本 if the document is not an iframe srcdoc document...

if the document is not an iframe src document nor an import...

“text” 插入模式中,条件 An end tag whose name is "script" 的子条件 Otherwise 中,将第 3 步修改为

  1. 如果解析器的Document 有阻止脚本的样式表有阻止脚本的导入该脚本“ready to be parser‑executed” 标志未被设置:旋转事件循环,直至解析器的Document 没有阻止脚本的样式表没有阻止脚本的导入且该脚本的“ready to be parser‑executed” 标志被设置。

7.3 对解析 XHTML 文档的补充

修改在准备 script 元素后运行的步骤第 3 步,使其读取

  1. 旋转事件循环,直至解析器的Document 没有阻止脚本的样式表没有阻止脚本的导入pending parsing‑blocking script“ready to be parser‑executed” 标志被设置。

8. 导入中的脚本

8.1 对脚本启用条件的补充

将以下条件加入启用与禁用脚本准则列表

8.2 document.currentScript 的补充

修改document.currentScript 的定义如下

在获取 currentScript 属性时,MUST 返回文档或该文档的导入映射中最近一次初始化的值。文档创建时,currentScript MUST 被初始化为 null。若文档是被导入的文档,其 currentScript 始终为 null。

9. 使用导入的样式处理

style 元素的内容以及link 元素的外部资源在导入MUST 被视为样式处理模型 [CSS2] 的输入来源,适用于主文档

9.2 出现顺序与导入

来自不同文档的声明的出现顺序 [CSS-CASCADE-3] 由导入链接树决定。若两条声明所属的节点文档不同,则比较它们在导入链接树中的树序,后者获胜。

10. 导入中的事件

导入中的事件被定义为对HTML 事件的一组更改。

10.1 对事件处理程序的补充

通过扩展首段来修改事件处理程序内容属性的脚本创建准则。

当设置事件处理程序内容属性时,若该元素所属的Document 位于浏览上下文中或位于导入映射中,……

11. 自定义元素处理

本规范将custom element order(自定义元素顺序)重新定义为[CUSTOM-ELEMENTS]的自定义元素顺序导入树顺序之和,其中导入树顺序会被缩放,使其最低值始终大于[CUSTOM-ELEMENTS]的自定义元素顺序可能的最高值。

给定自定义元素导入链接树中的导入树顺序树序决定,前提是该导入链接树已通过将每个导入link 替换为其被导入文档的内容后进行扁平化。

最高稳定顺序是指在第一次遇到的导入中,自定义元素顺序之前的那个值(依据树序),且该导入尚未完全加载。如果不存在这样的元素,则最高稳定顺序为扁平化导入链接树中最高的自定义元素顺序。在处理基元素队列时,用户代理应只调用至最高稳定顺序(含)之前的回调。

由于导入是异步加载的,我们需要把已排序的元素队列拆分为两部分:一部分是所有导入已经加载完毕、状态已稳定的部分,另一部分是仍在加载、实际排序尚未确定的部分。例如,假设你有如下文档结构

index.html

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

import.html

<me-first></me-first>

在扁平化的导入链接树中,自定义元素的顺序为 me-first(1),me-second(2)。然而,解析器很可能会先发现 me-second,因为后者不需要加载 import.html。当网络栈完成工作时,最高稳定顺序仍停留在起始位置。一旦 import.html 准备就绪,顺序会直接跳到 me-second(2)。

A. 致谢

David Hyatt 开发了 XBL 1.0,而 Ian Hickson 与其共同编写了 XBL 2.0。这些文档为行为附件问题提供了大量洞见,并深刻影响了本规范。

Alex Russell 及其深谋远虑的构想在行为附件以及其在 Web 上的实际应用方面掀起了新一轮热潮。

Dominic CooneyRoland Steiner 不懈努力,在 Web 平台范围内界定了问题的边界,为本文件奠定了坚实的基础。

编辑者还想感谢 Alex KomoroskeAngelina FabbroAnne van KesterenBoris ZbarskyBrian KardellDaniel BuchnerEdward O'ConnorEric BidelmanErik ArvidssonElliott SprehnGabor KrizsanitsHayato ItoJames SimonsenJonas SickingKen ShirriffNeel GoyalOlli PettayRafael WeinsteinScott MilesSteve OrvellTab AtkinsWilliam ChanWilliam Chen 对本规范的评论与贡献。

此名单过于简短,仍有大量工作待完成。请通过审阅并提交错误报告来贡献力量——并别忘了请编辑者把你的名字加入本节。

B. 参考资料

B.1 规范性参考资料

[CSP3]
Content Security Policy Level 3. Mike West; Antonio Sartori. W3C. 2023 年 5 月 3 日. W3C Working Draft. URL: https://w3org.cn/TR/CSP3/
[CSS-CASCADE-3]
CSS Cascading and Inheritance Level 3. Elika Etemad; Tab Atkins Jr.. W3C. 2021 年 2 月 11 日. W3C Recommendation. URL: https://w3org.cn/TR/css-cascade-3/
[CSS2]
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. Bert Bos; Tantek Çelik; Ian Hickson; Håkon Wium Lie. W3C. 7 June 2011. W3C Recommendation. URL: https://w3org.cn/TR/CSS21/
[CUSTOM-ELEMENTS]
Custom Elements. Domenic Denicola. W3C. 2018 年 5 月 3 日. W3C Working Group Note. URL: https://w3org.cn/TR/custom-elements/
[Fetch]
获取 (Fetch) 标准. Anne van Kesteren. WHATWG. 活标准. URL: https://fetch.spec.whatwg.org/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.whatwg.cn/multipage/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 关键词中大小写的歧义. B. Leiba. IETF. 2017年5月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[WHATWG-DOM]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[WHATWG-ENCODING]
编码标准. Anne van Kesteren. WHATWG. 活标准. URL: https://encoding.spec.whatwg.org/