From dae43b1a9f6087aa31f00643e1ee60c157d34c88 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Wed, 19 Oct 2016 18:06:11 -0400 Subject: [PATCH 1/4] Add document.{interactive,contentLoaded,loaded} promises This closes #127, although that thread also contains discussion about adding other "loaded" promises for various elements, which will move elsewhere. For a discussion of the names, including why jQuery's "ready" naming was not used, see https://github.com/whatwg/html/issues/127#issuecomment-254931526. --- source | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 128 insertions(+), 11 deletions(-) diff --git a/source b/source index 0cd7b0f2b4f..2c817e8b254 100644 --- a/source +++ b/source @@ -8344,6 +8344,9 @@ partial interface Document { attribute USVString cookie; readonly attribute DOMString lastModified; readonly attribute DocumentReadyState readyState; + readonly attribute Promise<void> interactive; + readonly attribute Promise<void> contentLoaded; + readonly attribute Promise<void> loaded; // DOM tree accessors getter object (DOMString name); @@ -8403,6 +8406,12 @@ partial interface Document { data-x="concept-document-module-map">module map, which is a module map, initially empty.

+

The Document has three promises, the interactive promise, the content loaded promise, and the loaded promise. They are all initially new + pending promises, created along with the Document object.

+

Resource metadata management

@@ -8571,29 +8580,129 @@ partial interface Document {

Returns "loading" while the Document is loading, "interactive" once it is finished parsing but still loading sub-resources, and "complete" once it has loaded.

+

The readystatechange event fires on the Document object when this value changes.

+
document . interactive
+
+

A promise that fulfills with undefined when the document's readyState becomes "interactive", + i.e., when the document has finished parsing.

+ +

This promise never rejects, but it can reset to a new pending promise if document.open() is used.

+
+ +
document . contentLoaded
+
+

A promise that fulfills with undefined when the DOMContentLoaded event fires on the document, i.e., when + the document has finished parsing and has finished executing any script elements + not marked with the async attribute.

+ +

This promise never rejects, but it can reset to a new pending promise if document.open() is used.

+
+ +
document . loaded
+
+

A promise that fulfills with undefined when the document's readyState becomes "complete", + i.e., when the document has finished parsing and loading sub-resources. This is also the time + that the load event fires on the document's Window + object.

+ +

This promise never rejects, but it can reset to a new pending promise if document.open() is used.

+
+
-

Each document has a current document readiness. When a Document object - is created, it must have its current document readiness set to the string "loading" if the document is associated with an HTML parser, an - XML parser, or an XSLT processor, and to the string "complete" - otherwise. Various algorithms during page loading affect this value. When the value is set, the - user agent must fire an event named readystatechange at the Document object.

+

Each document has a current document readiness, which is one of the + DocumentReadyState values. It must initially be "loading". + When this value is set to newValue, the user agent must run the following + steps:

-

A Document is said to have an active parser if it is associated with an - HTML parser or an XML parser that has not yet been stopped or aborted.

+
    +
  1. +

    If newValue is "loading", then set the document's + interactive promise, content loaded promise, and loaded promise all to distinct new promises.

    + +

    This can occur due to document.open().

    +
  2. + +
  3. If newValue is "interactive", then resolve the document's + interactive promise with + undefined.

  4. + +
  5. +

    If newValue is "complete", then:

    + +
      +
    1. +

      Resolve the document's interactive + promise with undefined.

      + +

      If the old value is "interactive", this will be + a no-op, as a previous invocation of this algorithm will have already resolved the interactive promise. But in various + cases, the current document readiness transitions directly from "loading" to "complete", in which case this step + ensures that the interactive + promise is resolved.

      +
    2. + +
    3. +

      Resolve the document's content + loaded promise with undefined.

      + +

      In normal scenarios this will be a no-op, as by the time the current + document readiness becomes "complete", the content loaded promise has already + been resolved at the same time the DOMContentLoaded event was fired. However, if document.close() is in play, or if the parser is aborted, then that might not have happened.

      +
    4. + +
    5. Resolve the document's loaded + promise with undefined.

    6. +
    +
  6. + +
  7. Fire an event named readystatechange at the Document + object.

  8. +
+ +

When a Document object is created that is not associated with an + HTML parser, an XML parser, or an XSLT processor, its current + document readiness must be set to "complete" (which of course runs + the above algorithm, updating the Document's relevant promises).

The readyState IDL attribute must, on getting, return the current document readiness.

+

The interactive IDL attribute must, + on getting, return this document's interactive + promise.

+ +

The contentLoaded IDL attribute + must, on getting, return this document's content loaded promise.

+ +

The loaded IDL attribute must, + on getting, return this document's loaded + promise.

+
@@ -108048,6 +108157,10 @@ document.body.appendChild(text); object, with its bubbles attribute initialized to true.

+
  • Resolve the Document object's content loaded promise with + undefined.

  • +
  • Enable the client message queue of the ServiceWorkerContainer object whose associated service worker client is the @@ -108146,6 +108259,10 @@ document.body.appendChild(text); +

    A Document is said to have an active parser if it is associated with an + HTML parser or an XML parser that has not yet been stopped or aborted.

    +

    Except where otherwise specified, the task source for the tasks mentioned in this section is the DOM manipulation task source.

    @@ -118595,7 +118712,7 @@ INSERT INTERFACES HERE DOMContentLoaded Event Document - Fired at the Document once the parser has finished + Fired at the Document once the parser has finished and any non-async scripts have executed afterprint From a303f9f0d7ba4991be3d103fb66caff725585f66 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 4 Nov 2016 16:30:26 -0400 Subject: [PATCH 2/4] Make unscopable --- source | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source b/source index 2c817e8b254..7d5cebb2f66 100644 --- a/source +++ b/source @@ -8344,9 +8344,9 @@ partial interface Document { attribute USVString cookie; readonly attribute DOMString lastModified; readonly attribute DocumentReadyState readyState; - readonly attribute Promise<void> interactive; - readonly attribute Promise<void> contentLoaded; - readonly attribute Promise<void> loaded; + [Unscopable] readonly attribute Promise<void> interactive; + [Unscopable] readonly attribute Promise<void> contentLoaded; + [Unscopable] readonly attribute Promise<void> loaded; // DOM tree accessors getter object (DOMString name); From 625b6afae5ab23f3eaac5c94d634ad040e9ef60c Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Mon, 7 Nov 2016 15:34:51 -0500 Subject: [PATCH 3/4] Fix order in #the-end per bzbarsky's comment --- source | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source b/source index 7d5cebb2f66..d306352c3c5 100644 --- a/source +++ b/source @@ -108152,15 +108152,15 @@ document.body.appendChild(text);

    Queue a task to run the following substeps:

      +
    1. Resolve the Document object's content loaded promise with + undefined.

    2. +
    3. Fire an event named DOMContentLoaded at the Document object, with its bubbles attribute initialized to true.

    4. -
    5. Resolve the Document object's content loaded promise with - undefined.

    6. -
    7. Enable the client message queue of the ServiceWorkerContainer object whose associated service worker client is the From 58db4cb1b73a5beea9675cf8266cd6fba1d389e1 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Thu, 8 Dec 2016 17:26:39 -0800 Subject: [PATCH 4/4] rename to parsed --- source | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/source b/source index d306352c3c5..b0fe3ac4526 100644 --- a/source +++ b/source @@ -8344,7 +8344,7 @@ partial interface Document { attribute USVString cookie; readonly attribute DOMString lastModified; readonly attribute DocumentReadyState readyState; - [Unscopable] readonly attribute Promise<void> interactive; + [Unscopable] readonly attribute Promise<void> parsed; [Unscopable] readonly attribute Promise<void> contentLoaded; [Unscopable] readonly attribute Promise<void> loaded; @@ -8407,7 +8407,7 @@ partial interface Document { initially empty.

      The Document has three promises, the interactive promise, the parsed promise, the content loaded promise, and the loaded promise. They are all initially new pending promises, created along with the Document object.

      @@ -8585,7 +8585,7 @@ partial interface Document { Document object when this value changes.

      -
      document . interactive
      +
      document . parsed

      A promise that fulfills with undefined when the document's readyState becomes "interactive", @@ -8631,7 +8631,7 @@ partial interface Document {

      1. If newValue is "loading", then set the document's - interactive promise, parsed promise, content loaded promise, and loaded promise all to distinct new promises.

        @@ -8640,24 +8640,23 @@ partial interface Document {
      2. If newValue is "interactive", then resolve the document's - interactive promise with - undefined.

      3. + parsed promise with undefined.

      4. If newValue is "complete", then:

        1. -

          Resolve the document's interactive - promise with undefined.

          +

          Resolve the document's parsed promise + with undefined.

          If the old value is "interactive", this will be a no-op, as a previous invocation of this algorithm will have already resolved the interactive promise. But in various - cases, the current document readiness transitions directly from "parsed promise. But in various cases, the + current document readiness transitions directly from "loading" to "complete", in which case this step - ensures that the interactive - promise is resolved.

          + ensures that the parsed promise is + resolved.

        2. @@ -8691,9 +8690,8 @@ partial interface Document {

          The readyState IDL attribute must, on getting, return the current document readiness.

          -

          The interactive IDL attribute must, - on getting, return this document's interactive - promise.

          +

          The parsed IDL attribute must, on getting, + return this document's parsed promise.

          The contentLoaded IDL attribute must, on getting, return this document's