Skip to content

Commit

Permalink
Improve clarity in link and style sheet resource fetching
Browse files Browse the repository at this point in the history
* Defines the critical subresources for CSS as @imported style sheets, including
  indirectly imported ones. This was previously defined nowhere; probably it
  should live in CSS, but for now it lives here.
* Makes it clearer that the steps to obtain the resource are the default steps,
  which some link types override.
* Adds explicit steps for fetching critical subresources, and ties those to the
  load/error events.
* Uses fetch primitives like network error and ok status instead of vague
  language.
* Makes it clearer how incorrect Content-Types for CSS generate error events, by
  defining the new "resource-specific fetch error" concept.
* Makes it clearer that resources apply if and only if their main fetch
  succeeds. (Critical subresource fetches generate error events, but do not
  impact the "obtained successfully" or "apply" concepts.)

Fixes #3532.
  • Loading branch information
domenic committed Mar 7, 2018
1 parent 185190c commit a4ccf1c
Showing 1 changed file with 96 additions and 49 deletions.
145 changes: 96 additions & 49 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2025,8 +2025,14 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<ref spec=HTTP></p>

<p>A resource's <dfn>critical subresources</dfn> are those that the resource needs to have
available to be correctly processed. Which resources are considered critical or not is defined by
the specification that defines the resource's format.</p>
available to be correctly processed. Which resources are considered critical or not generally
defined by the specification that defines the resource's format. For CSS style sheets, we define
here that their critical subresources are other style sheets imported via <code
data-x="">@import</code> rules, including those indirectly imported by other imported
stylesheets.</p>

<p class="&#x0058;&#x0058;&#x0058;">This definition should be moved to CSS, alongside more detail
around how they are fetched.</p>


<h4 id="xml">XML compatibility</h4>
Expand Down Expand Up @@ -2768,6 +2774,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#concept-network-error">network error</dfn></li>
<li>`<dfn data-dfn-type="http-header" data-x="http-origin" data-x-href="https://fetch.spec.whatwg.org/#http-origin"><code>Origin</code></dfn>` header</li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#process-response">process response</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#process-response-done">process response done</dfn></li>
<li><dfn data-x="concept-header-list-set" data-x-href="https://fetch.spec.whatwg.org/#concept-header-list-set">set</dfn></li>
<li><dfn data-x="concept-fetch-terminate" data-x-href="https://fetch.spec.whatwg.org/#concept-fetch-terminate">terminate</dfn></li>
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#requestcredentials"><code>RequestCredentials</code></dfn> enumeration</li>
Expand Down Expand Up @@ -13411,7 +13418,7 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> {
<code>link</code> elements, it must not be specified.</p>

<p w-nodev>The processing model for how the <code data-x="attr-link-as">as</code> attribute is
used is given in the steps to obtain the resource, for <span data-x="concept-link-obtain">for
used is given in the steps to obtain the resource, <span data-x="concept-link-obtain">for
<code data-x="rel-preload">preload</code> links</span> and <a
href="#modulepreload-obtain-steps">for <code data-x="rel-modulepreload">modulepreload</code>
links</a>, respectively.</p>
Expand Down Expand Up @@ -13559,11 +13566,13 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> {

<p>For external resources that are represented in the DOM (for example, style sheets), the DOM
representation must be made available (modulo cross-origin restrictions) even if the resource is
not applied. To <dfn data-x="concept-link-obtain">obtain the resource</dfn>, the user agent must
run the following steps:</p>
not applied.</p> <!-- TODO: figure out what this actually means and state it better/add an
example. -->

<ol>
<p>The default steps to <dfn data-x="concept-link-obtain">obtain the resource</dfn> for a
<code>link</code> element are as follows:</p>

<ol>
<li><p>If the <code data-x="attr-link-href">href</code> attribute's value is the empty string,
then return.</p></li>

Expand Down Expand Up @@ -13612,38 +13621,66 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> {
</ol>
</li>

<!--FETCH--><li><p><span data-x="concept-fetch">Fetch</span> <var>request</var>.</p></li>
<!--FETCH-->
<li>
<p><span data-x="concept-fetch">Fetch</span> <var>request</var>.</p>

</ol>
<p>To <span>process response</span> given the <span data-x="concept-response">response</span>
<var>response</var>:</p>

<p>User agents may opt to only try to obtain such resources when they are needed, instead of
pro-actively fetching all the external resources that are not applied.</p>
<ol>
<li><p>If <var>response</var> is a <span>network error</span>, or its <span
data-x="concept-response-status">status</span> is not an <span>ok status</span>, or it has a
<dfn>resource-specific fetch error</dfn>, then <span>queue a task</span> using the <span>DOM
manipulation task source</span> to <span data-x="concept-event-fire">fire an event</span> named
<code data-x="event-error">error</code> at the <code>link</code> element, and abort these
steps. The resource was not <span>obtained successfully</span>.</p></li>

<li><p>At this point, the resource has been <span>obtained successfully</span>.</p></li>

<li><p><span data-x="concept-fetch">Fetch</span> any of the resource's <span>critical
subresources</span>, as specific to the resource type in question. If any of these fetches
result in a <span data-x="concept-response">response</span> that is a <span>network
error</span>, or whose <span data-x="concept-response-status">status</span> is not an <span>ok
status</span>, or that has a <span>resource-specific fetch error</span>, then <span>queue a
task</span> using the <span>DOM manipulation task source</span> to <span
data-x="concept-event-fire">fire an event</span> named <code data-x="event-error">error</code>
at the <code>link</code> element, and abort these steps.</p></li>

<p>The semantics of the protocol used (e.g. HTTP) must be followed when fetching external
resources. (For example, redirects will be followed and 404 responses will cause the external
resource to not be applied.)</p>
<li><p>Once the original fetch and all of the <span data-x="critical subresources">critical
subresource</span> fetches have completed (i.e. have reached the <span>process response
done</span> task), <span>queue a task</span> using the <span>DOM manipulation task
source</span> to <span data-x="concept-event-fire">fire an event</span> named <code
data-x="event-load">load</code> at the <code>link</code> element.</p></li>
</ol>

<!-- the next few paragraph are similar to text in the <style> element section -->
<p>Once the attempts to obtain the resource and its <span>critical subresources</span> are
complete, the user agent must, if the loads were successful, <span>queue a task</span> to
<span data-x="concept-event-fire">fire an event</span> named <code data-x="event-load">load</code>
at the <code>link</code> element, or, if the resource or one of its <span>critical
subresources</span> failed to completely load for any reason (e.g. DNS error, HTTP 404 response, a
connection being prematurely closed, unsupported Content-Type), <span>queue a task</span> to <span
data-x="concept-event-fire">fire an event</span> named <code data-x="event-error">error</code> at
the <code>link</code> element. Non-network errors in processing the resource or its subresources
(e.g. CSS parse errors, PNG decoding errors) are not failures for the purposes of this
paragraph.</p>
<p class="note">A resource whose <span>critical subresources</span> fail to fetch still counts
as being <span>obtained successfully</span>, and will be applied. However, it will fire an
<code data-x="event-error">error</code> event, instead of a <code
data-x="event-load">load</code> event.</p>

<p>The <span>task source</span> for these <span data-x="concept-task">tasks</span> is the
<span>DOM manipulation task source</span>.</p>
<p class="note">Errors in processing the resource or its subresources (such as CSS parse errors
or PNG decoding errors) will not trigger an <code data-x="event-error">error</code> event.</p>
</li>
</ol>

<p>User agents may opt to only try to <span data-x="concept-link-obtain">obtain</span> resources
when they are needed, instead of pro-actively obtaining all the external resources that are not
applied.</p>

<p>User agents must only apply resources that are <dfn>obtained successfully</dfn>.</p>

<p>Unless otherwise specified for a given <code data-x="attr-link-rel">rel</code> keyword, the
element must <span>delay the load event</span> of the element's <span>node document</span> until
all the attempts to obtain the resource and its <span>critical subresources</span> are complete.
(Resources that the user agent has not yet attempted to obtain, e.g. because it is waiting for the
resource to be needed, do not <span>delay the load event</span>.)</p>

<p>Different link types can specify more specific algorithms than the one above; in that case, the
user agent must use that more specific algorithm.</p>

<p class="note">This is done for <code data-x="rel-modulepreload">modulepreload</code> links.</p>

<h5>Processing `<code data-x="http-link">Link</code>` headers</h5>

<p>HTTP `<code data-x="http-link">Link</code>` headers, if supported, must be assumed to come
Expand Down Expand Up @@ -15029,26 +15066,26 @@ interface <dfn>HTMLStyleElement</dfn> : <span>HTMLElement</span> {

</li>

</ol>

<!-- the next few paragraph are similar to text in the <link> section -->
<p>Once the attempts to obtain the style sheet's <span>critical subresources</span>, if any, are
complete, or, if the style sheet has no <span>critical subresources</span>, once the style sheet
has been parsed and processed, the user agent must, if the loads were successful or there were
none, <span>queue a task</span> to <span data-x="concept-event-fire">fire an event</span> named
<code data-x="event-load">load</code> at the <code>style</code> element, or, if one of the style
sheet's <span>critical subresources</span> failed to completely load for any reason (e.g. DNS
error, HTTP 404 response, a connection being prematurely closed, unsupported Content-Type),
<span>queue a task</span> to <span data-x="concept-event-fire">fire an event</span> named <code
data-x="event-error">error</code> at the <code>style</code> element. Non-network errors in
processing the style sheet or its subresources (e.g. CSS parse errors, PNG decoding errors) are
not failures for the purposes of this paragraph.</p>
<li><p><span data-x="concept-fetch">Fetch</span> any of the style sheet's <span>critical
subresources</span>, if any. If any of these fetches result in a <span
data-x="concept-response">response</span> that is a <span>network error</span>, or whose <span
data-x="concept-response-status">status</span> is not an <span>ok status</span>, or that has a
<span>resource-specific fetch error</span>, then <span>queue a task</span> on the
<span>DOM manipulation task source</span> to <span data-x="concept-event-fire">fire an
event</span> named <code data-x="event-error">error</code> at the <code>style</code> element, and
abort these steps.</p></li>

<p>The <span>task source</span> for these <span data-x="concept-task">tasks</span> is the <span>DOM
manipulation task source</span>.</p>
<li><p>Once all of the <span data-x="critical subresources">critical subresource</span> fetches
have completed (i.e. have reached the <span>process response done</span> phase), <span>queue a
task</span> on the <span>DOM manipulation task source</span> to <span
data-x="concept-event-fire">fire an event</span> named <code data-x="event-load">load</code> at
the <code>style</code> element.</p></li>
</ol>

<p>The element must <span>delay the load event</span> of the element's <span>node document</span> until all the
attempts to obtain the style sheet's <span>critical subresources</span>, if any, are complete.</p>
<p>The element must <span>delay the load event</span> of the element's <span>node document</span>
until all the attempts to obtain the style sheet's <span>critical subresources</span>, if any, are
complete.</p>

</div>

Expand Down Expand Up @@ -24578,13 +24615,23 @@ document.body.appendChild(wbr);</pre>

</ul>

<p><strong>Quirk</strong>: If the document has been set to <span>quirks mode</span>, has the
<span>same origin</span> as the <span>URL</span> of the external resource<!-- CVE-2010-0654 -->,
and the <span data-x="Content-Type">Content-Type metadata</span> of the external resource is not a
supported style sheet type, the user agent must instead assume it to be <code>text/css</code>.</p>
<p>For style sheet resources, a <span data-x="concept-response">response</span>
<var>response</var> has a <span>resource-specific fetch error</span> if the following steps return
true:</p>

<ol>
<li><p>If <var>response</var>'s <span data-x="Content-Type">Content-Type metadata</span> is
<code>text/css</code>, return false.</p></li>

<li><p>If the document has been set to <span>quirks mode</span>, and <var>response</var>'s <span
data-x="concept-response-url">url</span>'s <span data-x="concept-url-origin">origin</span> is
<span>same origin</span> with the document's <span>origin</span><!-- CVE-2010-0654 -->, return
false.</p></li>

<li><p>Return true.</p></li>
</ol>

<p>Once a resource has been <span data-x="concept-link-obtain">obtained</span>, if its <span
data-x="Content-Type">Content-Type metadata</span> is <code>text/css</code>, then run these
<p>Once the style sheet resource has been <span>obtained successfully</span>, run these
steps:</p>

<!-- note that we can only get this far if we have a browsing context, since if you don't have a
Expand Down

0 comments on commit a4ccf1c

Please sign in to comment.