Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add document.{parsed,contentLoaded,loaded} promises #1936

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 126 additions & 11 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -8344,6 +8344,9 @@ partial interface <dfn id="document" data-lt="">Document</dfn> {
attribute USVString <span data-x="dom-document-cookie">cookie</span>;
readonly attribute DOMString <span data-x="dom-document-lastModified">lastModified</span>;
readonly attribute <span>DocumentReadyState</span> <span data-x="dom-document-readyState">readyState</span>;
[Unscopable] readonly attribute Promise&lt;void> <span data-x="dom-document-parsed">parsed</span>;
[Unscopable] readonly attribute Promise&lt;void> <span data-x="dom-document-contentLoaded">contentLoaded</span>;
[Unscopable] readonly attribute Promise&lt;void> <span data-x="dom-document-loaded">loaded</span>;

// <span>DOM tree accessors</span>
<a href="#dom-document-nameditem">getter</a> object (DOMString name);
Expand Down Expand Up @@ -8403,6 +8406,12 @@ partial interface <dfn id="document" data-lt="">Document</dfn> {
data-x="concept-document-module-map">module map</dfn>, which is a <span>module map</span>,
initially empty.</p>

<p>The <code>Document</code> has three promises, the <dfn
data-x="concept-document-parsed-promise">parsed promise</dfn>, the <dfn
data-x="concept-document-content-loaded-promise">content loaded promise</dfn>, and the <dfn
data-x="concept-document-loaded-promise">loaded promise</dfn>. They are all initially new
pending promises, created along with the <code>Document</code> object.</p>


<h4><dfn>Resource metadata management</dfn></h4>

Expand Down Expand Up @@ -8571,29 +8580,127 @@ partial interface <dfn id="document" data-lt="">Document</dfn> {
<p>Returns "<code data-x="">loading</code>" while the <code>Document</code> is loading, "<code
data-x="">interactive</code>" once it is finished parsing but still loading sub-resources, and
"<code data-x="">complete</code>" once it has loaded.</p>

<p>The <code data-x="event-readystatechange">readystatechange</code> event fires on the
<code>Document</code> object when this value changes.</p>
</dd>

<dt><var>document</var> . <code subdfn data-x="dom-document-parsed">parsed</code></dt>
<dd>
<p>A promise that fulfills with undefined when the document's <code
data-x="dom-document-readyState">readyState</code> becomes "<code data-x="">interactive</code>",
i.e., when the document has finished parsing.</p>

<p>This promise never rejects, but it can reset to a new pending promise if <code
data-x="dom-document-open">document.open()</code> is used.</p>
</dd>

<dt><var>document</var> . <code subdfn
data-x="dom-document-contentLoaded">contentLoaded</code></dt>
<dd>
<p>A promise that fulfills with undefined when the <code
data-x="event-DOMContentLoaded">DOMContentLoaded</code> event fires on the document, i.e., when
the document has finished parsing and has finished executing any <code>script</code> elements
not marked with the <code data-x="attr-script-async">async</code> attribute.</p>

<p>This promise never rejects, but it can reset to a new pending promise if <code
data-x="dom-document-open">document.open()</code> is used.</p>
</dd>

<dt><var>document</var> . <code subdfn data-x="dom-document-loaded">loaded</code></dt>
<dd>
<p>A promise that fulfills with undefined when the document's <code
data-x="dom-document-readyState">readyState</code> becomes "<code data-x="">complete</code>",
i.e., when the document has finished parsing and loading sub-resources. This is also the time
that the <code data-x="event-load">load</code> event fires on the document's <code>Window</code>
object.</p>

<p>This promise never rejects, but it can reset to a new pending promise if <code
data-x="dom-document-open">document.open()</code> is used.</p>
</dd>

</dl>

<div w-nodev>

<p>Each document has a <dfn>current document readiness</dfn>. When a <code>Document</code> object
is created, it must have its <span>current document readiness</span> set to the string "<code
data-x="">loading</code>" if the document is associated with an <span>HTML parser</span>, an
<span>XML parser</span>, or an XSLT processor, and to the string "<code data-x="">complete</code>"
otherwise. Various algorithms during page loading affect this value. When the value is set, the
user agent must <span data-x="concept-event-fire">fire an event</span> named <code
data-x="event-readystatechange">readystatechange</code> at the <code>Document</code> object.</p>
<p>Each document has a <dfn>current document readiness</dfn>, which is one of the
<code>DocumentReadyState</code> values. It must initially be "<code data-x="">loading</code>".
When this value is set to <var>newValue</var>, the user agent must run the following
steps:</p>

<p>A <code>Document</code> is said to have an <dfn>active parser</dfn> if it is associated with an
<span>HTML parser</span> or an <span>XML parser</span> that has not yet been <span data-x="stop
parsing">stopped</span> or <span data-x="abort a parser">aborted</span>.</p>
<ol>
<li>
<p>If <var>newValue</var> is "<code data-x="">loading</code>", then set the document's
<span data-x="concept-document-parsed-promise">parsed promise</span>, <span
data-x="concept-document-content-loaded-promise">content loaded promise</span>, and <span
data-x="concept-document-loaded-promise">loaded promise</span> all to distinct new promises.</p>

<p class="note">This can occur due to <code
data-x="dom-document-open">document.open()</code>.</p>
</li>

<li><p>If <var>newValue</var> is "<code data-x="">interactive</code>", then resolve the document's
<span data-x="concept-document-parsed-promise">parsed promise</span> with undefined.</p></li>

<li>
<p>If <var>newValue</var> is "<code data-x="">complete</code>", then:</p>

<ol>
<li>
<p>Resolve the document's <span data-x="concept-document-parsed-promise">parsed promise</span>
with undefined.</p>

<p class="note">If the old value is "<code data-x="">interactive</code>", this will be
a no-op, as a previous invocation of this algorithm will have already resolved the <span
data-x="concept-document-parsed-promise">parsed promise</span>. But in various cases, the
<span>current document readiness</span> transitions directly from "<code
data-x="">loading</code>" to "<code data-x="">complete</code>", in which case this step
ensures that the <span data-x="concept-document-parsed-promise">parsed promise</span> is
resolved.</p>
</li>

<li>
<p>Resolve the document's <span data-x="concept-document-content-loaded-promise">content
loaded promise</span> with undefined.</p>

<p class="note">In normal scenarios this will be a no-op, as by the time the <span>current
document readiness</span> becomes "<code data-x="">complete</code>", the <span
data-x="concept-document-content-loaded-promise">content loaded promise</span> has already
been resolved at the same time the <code
data-x="event-DOMContentLoaded">DOMContentLoaded</code> event was fired. However, if <code
data-x="dom-document-close">document.close()</code> is in play, or if the parser is <span
data-x="abort a parser">aborted</span>, then that might not have happened.</p>
</li>

<li><p>Resolve the document's <span data-x="concept-document-loaded-promise">loaded
promise</span> with undefined.</p></li>
</ol>
</li>

<li><p><span data-x="concept-event-fire">Fire an event</span> named <code
data-x="event-readystatechange">readystatechange</code> at the <code>Document</code>
object.</p></li>
</ol>

<p>When a <code>Document</code> object is created that is not associated with an
<span>HTML parser</span>, an <span>XML parser</span>, or an XSLT processor, its <span>current
document readiness</span> must be set to "<code data-x="">complete</code>" (which of course runs
the above algorithm, updating the <code>Document</code>'s relevant promises).</p>

<p>The <dfn><code data-x="dom-document-readyState">readyState</code></dfn> IDL attribute must, on
getting, return the <span>current document readiness</span>.</p>

<p>The <dfn><code data-x="dom-document-parsed">parsed</code></dfn> IDL attribute must, on getting,
return this document's <span data-x="concept-document-parsed-promise">parsed promise</span>.</p>

<p>The <dfn><code data-x="dom-document-contentLoaded">contentLoaded</code></dfn> IDL attribute
must, on getting, return this document's <span
data-x="concept-document-content-loaded-promise">content loaded promise</span>.</p>

<p>The <dfn><code data-x="dom-document-loaded">loaded</code></dfn> IDL attribute must,
on getting, return this document's <span data-x="concept-document-loaded-promise">loaded
promise</span>.</p>

</div>


Expand Down Expand Up @@ -108043,6 +108150,10 @@ document.body.appendChild(text);
<p><span>Queue a task</span> to run the following substeps:</p>

<ol>
<li><p>Resolve the <code>Document</code> object's <span
data-x="concept-document-content-loaded-promise">content loaded promise</span> with
undefined.</p></li>

<li><p><span data-x="concept-event-fire">Fire an event</span> named <code
data-x="event-DOMContentLoaded">DOMContentLoaded</code> at the <code>Document</code>
object, with its <code data-x="dom-Event-bubbles">bubbles</code> attribute initialized to
Expand Down Expand Up @@ -108146,6 +108257,10 @@ document.body.appendChild(text);

</ol>

<p>A <code>Document</code> is said to have an <dfn>active parser</dfn> if it is associated with an
<span>HTML parser</span> or an <span>XML parser</span> that has not yet been <span data-x="stop
parsing">stopped</span> or <span data-x="abort a parser">aborted</span>.</p>

<p>Except where otherwise specified, the <span>task source</span> for the <span
data-x="concept-task">tasks</span> mentioned in this section is the <span>DOM manipulation task
source</span>.</p>
Expand Down Expand Up @@ -118595,7 +118710,7 @@ INSERT INTERFACES HERE
<td> <dfn data-dfn-type="event" data-dfn-for="Document" data-export=""><code data-x="event-DOMContentLoaded">DOMContentLoaded</code></dfn>
<td> <code>Event</code>
<td> <code>Document</code>
<td> Fired at the <code>Document</code> once the parser has finished
<td> Fired at the <code>Document</code> once the parser has finished and any non-<code data-x="attr-script-async">async</code> scripts have executed

<tr> <!-- afterprint -->
<td> <dfn data-dfn-type="event" data-dfn-for="Window" data-export=""><code data-x="event-afterprint">afterprint</code></dfn>
Expand Down