@@ -2804,6 +2804,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
2804
2804
<li><dfn data-x="concept-request-destination" data-x-href="https://fetch.spec.whatwg.org/#concept-request-destination">destination</dfn></li>
2805
2805
<li><dfn data-x="concept-potential-destination" data-x-href="https://fetch.spec.whatwg.org/#concept-potential-destination">potential destination</dfn></li>
2806
2806
<li><dfn data-x="concept-potential-destination-translate" data-x-href="https://fetch.spec.whatwg.org/#concept-potential-destination-translate">translating</dfn> a <span data-x="concept-potential-destination">potential destination</span></li>
2807
+ <li><dfn data-x="concept-script-like-destination" data-x-href="https://fetch.spec.whatwg.org/#request-destination-script-like">script-like</dfn> <span data-x="concept-request-destination">destinations</span></li>
2807
2808
<li><dfn data-x="concept-request-priority" data-x-href="https://fetch.spec.whatwg.org/#concept-request-priority">priority</dfn></li>
2808
2809
<li><dfn data-dfn-for="request" data-x="concept-request-origin" data-x-href="https://fetch.spec.whatwg.org/#concept-request-origin">origin</dfn></li>
2809
2810
<li><dfn data-x="concept-request-referrer" data-x-href="https://fetch.spec.whatwg.org/#concept-request-referrer">referrer</dfn></li>
@@ -6960,6 +6961,28 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
6960
6961
data-x="attr-crossorigin-anonymous-keyword">anonymous</code> keyword. The <i data-x="missing value default">missing value default</i>, used when the attribute is omitted, is the <dfn data-x="attr-crossorigin-none">No
6961
6962
CORS</dfn> state.</p>
6962
6963
6964
+ <p>The majority of fetches governed by <span data-x="CORS settings attribute">CORS settings
6965
+ attributes</span> will be done via the <span>create a potential-CORS request</span> algorithm.</p>
6966
+
6967
+ <p>For <span data-x="module script">module scripts</span>, certain <span data-x="CORS settings
6968
+ attribute">CORS settings attributes</span> have been repurposed to have a slightly different
6969
+ meaning, wherein they only impact the <span data-x="concept-request">request</span>'s <span
6970
+ data-x="concept-request-credentials-mode">credentials mode</span> (since the <span
6971
+ data-x="concept-request-mode">mode</span> is always "<code data-x="">cors</code>"). To perform
6972
+ this translation, we define the <dfn>module script credentials mode</dfn> for a given <span>CORS
6973
+ settings attribute</span> to be determined by switching on the attribute's state:</p>
6974
+
6975
+ <dl class="switch">
6976
+ <dt><span data-x="attr-crossorigin-none">No CORS</span></dt>
6977
+ <dd>"<code data-x="">omit</code>"</dd>
6978
+
6979
+ <dt><span data-x="attr-crossorigin-anonymous">Anonymous</span></dt>
6980
+ <dd>"<code data-x="">same-origin</code>"</dd>
6981
+
6982
+ <dt><span data-x="attr-crossorigin-none">Use Credentials</span></dt>
6983
+ <dd>"<code data-x="">include</code>"</dd>
6984
+ </dl>
6985
+
6963
6986
6964
6987
<h4>Referrer policy attributes</h4>
6965
6988
@@ -13120,6 +13143,7 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> {
13120
13143
<code data-x="rel-alternate">alternate</code>,
13121
13144
<code data-x="rel-dns-prefetch">dns-prefetch</code>,
13122
13145
<code data-x="rel-icon">icon</code>,
13146
+ <code data-x="rel-modulepreload">modulepreload</code>,
13123
13147
<code data-x="rel-next">next</code>,
13124
13148
<code data-x="rel-pingback">pingback</code>,
13125
13149
<code data-x="rel-preconnect">preconnect</code>,
@@ -13273,15 +13297,24 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> {
13273
13297
destination</span> is a keyword for this attribute, mapping to a state of the same name. The
13274
13298
attribute must be specified on <code>link</code> elements that have a <code
13275
13299
data-x="attr-link-rel">rel</code> attribute that contains the <code
13276
- data-x="rel-preload">preload</code> keyword, but must not be specified on <code>link</code>
13277
- elements which do not. <span w-nodev>The processing model for how the <code
13278
- data-x="attr-link-as">as</code> attribute is used is given in the <span
13279
- data-x="concept-link-obtain">steps to obtain the resource</span>.</span></p>
13300
+ data-x="rel-preload">preload</code> keyword. It may be specified on <code>link</code> elements
13301
+ that have a <code data-x="attr-link-rel">rel</code> attribute that contains the <code
13302
+ data-x="rel-modulepreload">modulepreload</code> keyword; in such cases it must have a value which
13303
+ is a <span data-x="concept-script-like-destination">script-like destination</span>. For other
13304
+ <code>link</code> elements, it must not be specified.</p>
13305
+
13306
+ <p w-nodev>The processing model for how the <code data-x="attr-link-as">as</code> attribute is
13307
+ used is given in the steps to obtain the resource, for <span data-x="concept-link-obtain">for
13308
+ <code data-x="rel-preload">preload</code> links</span> and <a
13309
+ href="#modulepreload-obtain-steps">for <code data-x="rel-modulepreload">modulepreload</code>
13310
+ links</a>, respectively.</p>
13280
13311
13281
13312
<p class="note">The attribute does not have a <i data-x="missing value default">missing value
13282
13313
default</i> or <i data-x="invalid value default">invalid value default</i>, meaning that invalid
13283
13314
or missing values for the attribute map to no state. This is accounted for in the processing
13284
- model.</p>
13315
+ model. For <code data-x="rel-preload">preload</code> links, both conditions are an error; for
13316
+ <code data-x="rel-modulepreload">modulepreload</code> links, a missing value will be treated as
13317
+ "<code data-x="">script</code>".</p>
13285
13318
13286
13319
<hr>
13287
13320
@@ -23426,6 +23459,7 @@ interface <dfn>HTMLHyperlinkElementUtils</dfn> {
23426
23459
<span>allowed in the body</span>. The <span>body-ok</span> keywords defined by this specification
23427
23460
are
23428
23461
<code data-x="rel-dns-prefetch">dns-prefetch</code>,
23462
+ <code data-x="rel-modulepreload">modulepreload</code>,
23429
23463
<code data-x="rel-pingback">pingback</code>,
23430
23464
<code data-x="rel-preconnect">preconnect</code>,
23431
23465
<code data-x="rel-prefetch">prefetch</code>,
@@ -23516,6 +23550,16 @@ interface <dfn>HTMLHyperlinkElementUtils</dfn> {
23516
23550
<td>Imports an icon to represent the current document.</td>
23517
23551
</tr>
23518
23552
23553
+ <tr>
23554
+ <td><code data-x="rel-modulepreload">modulepreload</code></td>
23555
+ <td><span data-x="external resource link">External Resource</span></td>
23556
+ <td><em>not allowed</em></td>
23557
+ <td class="yes"> Yes </td>
23558
+ <td>Specifies that the user agent must preemptively <span data-x="fetch a single module script">fetch the module
23559
+ script</span> and store it in the document's <span data-x="concept-document-module-map">module map</span> for later
23560
+ evaluation. Optionally, the module's dependencies can be fetched as well.</td>
23561
+ </tr>
23562
+
23519
23563
<tr>
23520
23564
<td><code data-x="rel-license">license</code></td> <!-- seventh most used <a rel> value -->
23521
23565
<td><span>Hyperlink</span></td>
@@ -24117,6 +24161,176 @@ interface <dfn>HTMLHyperlinkElementUtils</dfn> {
24117
24161
</div>
24118
24162
24119
24163
24164
+ <h5>Link type "<dfn><code data-x="rel-modulepreload">modulepreload</code></dfn>"</h5>
24165
+
24166
+ <p>The <code data-x="rel-modulepreload">modulepreload</code> keyword may be used with
24167
+ <code>link</code> elements. This keyword creates an <span>external resource link</span>. This
24168
+ keyword is <span>body-ok</span>.</p>
24169
+
24170
+ <p>The <code data-x="rel-modulepreload">modulepreload</code> keyword is a specialized alternative
24171
+ to the <code data-x="rel-preload">preload</code> keyword, with a processing model geared toward
24172
+ preloading <span data-x="module script">module scripts</span>. In particular, it uses the specific
24173
+ fetch behavior for module scripts (including, e.g., a different interpretation of the <code
24174
+ data-x="attr-link-crossorigin">crossorigin</code> attribute), and places the result into the
24175
+ appropriate <span data-x="concept-document-module-map">module map</span> for later evaluation. In
24176
+ contrast, a similar <span>external resource link</span> using the <code
24177
+ data-x="rel-preload">preload</code> keyword would place the result in the preload cache, without
24178
+ affecting the document's <span data-x="concept-document-module-map">module map</span>.</p>
24179
+
24180
+ <p>Additionally, implementations can take advantage of the fact that <span data-x="module
24181
+ script">module scripts</span> declare their dependencies in order to fetch the specified module's
24182
+ dependency as well. This is intended as an optimization opportunity, since the user agent knows
24183
+ that, in all likelihood, those dependencies will also be needed later. It will not generally be
24184
+ observable without using technology such as service workers, or monitoring on the server side.
24185
+ Notably, the appropriate <code data-x="event-load">load</code> or <code
24186
+ data-x="event-error">error</code> events will occur after the specified module is fetched, and
24187
+ will not wait for any dependencies.</p>
24188
+
24189
+ <div w-nodev>
24190
+
24191
+ <p>The appropriate times to fetch the resource for such a link are:</p>
24192
+
24193
+ <ul>
24194
+ <li><p>When the <span>external resource link</span> is created on a <code>link</code> element
24195
+ that is already <span>browsing-context connected</span>.</p></li>
24196
+
24197
+ <li><p>When the <span>external resource link</span>'s <code>link</code> element <span>becomes
24198
+ browsing-context connected</span>.</p></li>
24199
+
24200
+ <li><p>When the <code data-x="attr-link-href">href</code> attribute of the <code>link</code>
24201
+ element of an <span>external resource link</span> that is already <span>browsing-context
24202
+ connected</span> is changed.</p></li>
24203
+ </ul>
24204
+
24205
+ </div>
24206
+
24207
+ <p class="note">Unlike some other link relations, changing the relevant attributes (such as <code
24208
+ data-x="attr-link-as">as</code>, <code data-x="attr-link-crossorigin">crossorigin</code>, and
24209
+ <code data-x="attr-link-referrerpolicy">referrerpolicy</code>) of such a <code>link</code>
24210
+ attribute does not trigger a new fetch. This is because the document's <span
24211
+ data-x="concept-document-module-map">module map</span> has already been populated by a previous
24212
+ fetch, and so re-fetching would be pointless.</p>
24213
+
24214
+ <div w-nodev>
24215
+
24216
+ <p id="modulepreload-obtain-steps">To obtain the resource for such a link:</p>
24217
+
24218
+ <ol>
24219
+ <li><p>If the <code data-x="attr-link-href">href</code> attribute's value is the empty string,
24220
+ then return.</p></li>
24221
+
24222
+ <li><p>Let <var>destination</var> be the current state of the <code
24223
+ data-x="attr-link-as">as</code> attribute (a <span
24224
+ data-x="concept-request-destination">destination</span>), or "<code data-x="">script</code>" if
24225
+ it is in no state.</p></li>
24226
+
24227
+ <li><p>If <var>destination</var> is not <span
24228
+ data-x="concept-script-like-destination">script-like</span>, then <span>queue a task</span> on
24229
+ the <span>networking task source</span> to <span data-x="concept-event-fire">fire an event</span>
24230
+ named <code data-x="event-error">error</code> at the <code>link</code> element, and
24231
+ return.</p></li>
24232
+
24233
+ <li><p><span data-x="parse a url">Parse</span> the <span>URL</span> given by the <code
24234
+ data-x="attr-link-href">href</code> attribute, relative to the element's <span>node
24235
+ document</span>. If that fails, then return. Otherwise, let <var>url</var> be the <span>resulting
24236
+ URL record</span>.</p></li>
24237
+
24238
+ <li><p>Let <var>settings object</var> be the <code>link</code> element's <span>node
24239
+ document</span>'s <span>relevant settings object</span>.</p></li>
24240
+
24241
+ <li><p>Let <var>credentials mode</var> be the <span>module script credentials mode</span> for the
24242
+ <code data-x="attr-link-crossorigin">crossorigin</code> attribute.</p></li>
24243
+
24244
+ <li><p>Let <var>cryptographic nonce</var> be the value of the <code
24245
+ data-x="attr-link-nonce">nonce</code> attribute, if it is specified, or the empty string
24246
+ otherwise.</p></li>
24247
+
24248
+ <li><p>Let <var>integrity metadata</var> be the value of the <code
24249
+ data-x="attr-link-integrity">integrity</code> attribute, if it is specified, or the empty string
24250
+ otherwise.</p></li>
24251
+
24252
+ <li><p>Let <var>options</var> be a <span>script fetch options</span> whose <span
24253
+ data-x="concept-script-fetch-options-nonce">cryptographic nonce</span> is <var>cryptographic
24254
+ nonce</var>, <span data-x="concept-script-fetch-options-integrity">integrity metadata</span> is
24255
+ <var>integrity metadata</var>, <span data-x="concept-script-fetch-options-parser">parser
24256
+ metadata</span> is "<code data-x="">not-parser-inserted</code>", and <span
24257
+ data-x="concept-script-fetch-options-credentials">credentials mode</span> is <var>credentials
24258
+ mode</var>.</p></li>
24259
+
24260
+ <li><p><span>Fetch a single module script</span> given <var>url</var>, <var>settings
24261
+ object</var>, <var>destination</var>, <var>options</var>, <var>settings object</var>, "<code
24262
+ data-x="">client</code>", and with the <var>top-level module fetch</var> flag set. Wait until
24263
+ algorithm asynchronously completes with <var>result</var>.</p></li>
24264
+
24265
+ <li><p>If <var>result</var> is null, <span data-x="concept-event-fire">fire an event</span>
24266
+ named <code data-x="event-error">error</code> at the <code>link</code> element, and
24267
+ return.</p></li>
24268
+
24269
+ <li><p><span data-x="concept-event-fire">Fire an event</span> named <code
24270
+ data-x="event-load">load</code> at the <code>link</code> element.</p></li>
24271
+
24272
+ <li>
24273
+ <p>Optionally, perform the following steps:</p>
24274
+
24275
+ <ol>
24276
+ <li><p>Let <var>visited set</var> be « <var>url</var> ».</p></li>
24277
+
24278
+ <li><p><span data-x="fetch the descendants of and instantiate a module script">Fetch the
24279
+ descendants of and instantiate</span> <var>result</var> given <var>destination</var> and
24280
+ <var>visited set</var>.</p></li>
24281
+ </ol>
24282
+
24283
+ <p class="note">Generally, performing these steps will be beneficial for performance, as it
24284
+ allows pre-loading the modules that will invariably be requested later, when <span>fetch a
24285
+ module script graph</span> is called. However, user agents might wish to skip them in
24286
+ bandwidth-constrained situations, or situations where the relevant fetches are already in
24287
+ flight.</p>
24288
+ </li>
24289
+ </ol>
24290
+
24291
+ </div>
24292
+
24293
+ <div class="example" id="example-modulepreload-manifest">
24294
+ <p>The following snippet shows the top part of an application with several modules preloaded:</p>
24295
+
24296
+ <pre><!DOCTYPE html>
24297
+ <html lang="en">
24298
+ <title>IRCFog</title>
24299
+
24300
+ <link rel="modulepreload" href="app.mjs">
24301
+ <link rel="modulepreload" href="helpers.mjs">
24302
+ <link rel="modulepreload" href="irc.mjs">
24303
+ <link rel="modulepreload" href="fog-machine.mjs">
24304
+
24305
+ <script type="module" src="app.mjs">
24306
+ ...</pre>
24307
+
24308
+ <p>Assume that the module graph for the application is as follows:</p>
24309
+
24310
+ <img src="images/ircfog-modules.svg" width="301" height="151" alt="The module graph is rooted at app.mjs, which depends on irc.mjs and fog-machine.mjs. In turn, irc.mjs depends on helpers.mjs.">
24311
+
24312
+ <p>Here we see the application developer has used <code
24313
+ data-x="rel-modulepreload">modulepreload</code> all of the modules in their module graph,
24314
+ ensuring that the user agent initiates fetches for them all. Without such preloading, the user
24315
+ agent might need to go through multiple network roundtrips before discovering <code
24316
+ data-x="">helpers.mjs</code>, if technologies such as HTTP/2 Server Push are not in play. In
24317
+ this way, <code data-x="rel-modulepreload">modulepreload</code> <code>link</code> elements can be
24318
+ used as a sort of "manifest" of the application's modules.</p>
24319
+ </div>
24320
+
24321
+ <div class="example" id="example-modulepreload-dynamic-import">
24322
+ <p>The following code shows how <code data-x="rel-modulepreload">modulepreload</code> links can
24323
+ be used in conjunction with <code>import()</code> to ensure network fetching is done ahead of
24324
+ time, so that when <code>import()</code> is called, the module is already ready (but not
24325
+ evaluated) in the <span>module map</span>:</p>
24326
+
24327
+ <pre><link rel="modulepreload" href="awesome-viewer.js">
24328
+
24329
+ <button onclick="import('./awesome-viewer.js').then(m => m.view())">
24330
+ View awesome thing
24331
+ </button></pre>
24332
+ </div>
24333
+
24120
24334
<h5>Link type "<dfn><code data-x="rel-nofollow">nofollow</code></dfn>"</h5>
24121
24335
24122
24336
<p>The <code data-x="rel-nofollow">nofollow</code> keyword may be used with <code>a</code> and
@@ -57839,24 +58053,12 @@ o............A....e
57839
58053
57840
58054
</li>
57841
58055
57842
- <li><p>Let <var>CORS setting</var> be the current state of the element's <code
58056
+ <li><p>Let <var>classic script CORS setting</var> be the current state of the element's <code
57843
58057
data-x="attr-script-crossorigin">crossorigin</code> content attribute.</p></li>
57844
58058
57845
- <li>
57846
- <p>Let <var>module script credentials mode</var> be determined by switching on <var>CORS
57847
- setting</var>:</p>
57848
-
57849
- <dl class="switch">
57850
- <dt><span data-x="attr-crossorigin-none">No CORS</span></dt>
57851
- <dd>"<code data-x="">omit</code>"</dd>
57852
-
57853
- <dt><span data-x="attr-crossorigin-anonymous">Anonymous</span></dt>
57854
- <dd>"<code data-x="">same-origin</code>"</dd>
57855
-
57856
- <dt><span data-x="attr-crossorigin-none">Use Credentials</span></dt>
57857
- <dd>"<code data-x="">include</code>"</dd>
57858
- </dl>
57859
- </li>
58059
+ <li><p>Let <var>module script credentials mode</var> be the <span>module script credentials
58060
+ mode</span> for the element's <code data-x="attr-script-crossorigin">crossorigin</code> content
58061
+ attribute.</p>
57860
58062
57861
58063
<li>
57862
58064
@@ -57923,7 +58125,7 @@ o............A....e
57923
58125
<dt>"<code data-x="">classic</code>"</dt>
57924
58126
<dd>
57925
58127
<p><span>Fetch a classic script</span> given <var>url</var>, <var>settings object</var>,
57926
- <var>options</var>, <var>CORS setting</var>, and <var>encoding</var>.</p>
58128
+ <var>options</var>, <var>classic script CORS setting</var>, and <var>encoding</var>.</p>
57927
58129
</dd>
57928
58130
57929
58131
<dt>"<code data-x="">module</code>"</dt>
@@ -117348,8 +117550,8 @@ interface <dfn>External</dfn> {
117348
117550
<tr>
117349
117551
<th> <code data-x="">as</code>
117350
117552
<td> <code data-x="attr-link-as">link</code>
117351
- <td> <span data-x="concept-potential-destination">Potential destination</span> for a preload request (for <code data-x="attr-link-rel">rel</code>="<code data-x="rel-preload">preload</code>")
117352
- <td> <span data-x="concept-potential-destination">Potential destination</span>
117553
+ <td> <span data-x="concept-potential-destination">Potential destination</span> for a preload request (for <code data-x="attr-link-rel">rel</code>="<code data-x="rel-preload">preload</code>" and <code data-x="attr-link-rel">rel</code>="<code data-x="rel-modulepreload">modulepreload</code>" )
117554
+ <td> <span data-x="concept-potential-destination">Potential destination</span>, for <code data-x="attr-link-rel">rel</code>="<code data-x="rel-preload">preload</code>"; <span data-x="concept-script-like-destination">script-like destination</span>, for <code data-x="attr-link-rel">rel</code>="<code data-x="rel-modulepreload">modulepreload</code>"
117353
117555
<tr>
117354
117556
<th> <code data-x="">async</code>
117355
117557
<td> <code data-x="attr-script-async">script</code>
0 commit comments