diff --git a/source b/source index 9a7c3ac5a18..288df4e4c2d 100644 --- a/source +++ b/source @@ -2448,6 +2448,8 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute pop
  • The ordered set data structure and the associated definition for append
  • +
  • The struct specification type and the associated definition for + item
  • HTML namespace
  • MathML namespace
  • SVG namespace
  • @@ -2922,8 +2924,8 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute Record specification types
  • The Property Descriptor specification type
  • The Source Text Module Record specification type and its - ModuleEvaluation and - ModuleDeclarationInstantiation methods
  • + Evaluate and + Instantiate methods
  • The ArrayCreate abstract operation
  • The Call abstract operation
  • @@ -86176,8 +86178,8 @@ interface NavigatorOnLine {
    Definitions
    -

    A script is one of two possible structures. - All scripts have:

    +

    A script is one of two possible structs. All scripts have:

    @@ -86194,7 +86196,7 @@ interface NavigatorOnLine {

    A classic script is a script - that has the following additional fields:

    + that has the following additional items:

    @@ -86220,7 +86222,7 @@ interface NavigatorOnLine {

    A module script is a script - that has the following additional fields:

    + that has the following additional items:

    @@ -86230,7 +86232,7 @@ interface NavigatorOnLine {

    A Source Text Module Record representing the parsed module, ready to be - evaluated.

    + evaluated, or null if the module could not be parsed or instantiated.

    @@ -86245,24 +86247,19 @@ interface NavigatorOnLine { -
    A state
    - -
    - -

    One of "uninstantiated", "errored", or "instantiated", used to prevent reinvocation of ModuleDeclarationInstantiation on modules that - failed to instantiate previously, and to ensure errors during parsing, instantiation, or - evaluation are remembered and propagated correctly.

    - -
    - -
    An error
    +
    A pre-instantiation + error

    A JavaScript value, which has meaning only if the state is "errored".

    + data-x="concept-module-script-module-record">module record is null.

    + +

    This stores errors that will prevent the module from successfully instantiating, + such as parse errors or errors in its dependencies. A module script can also be errored due to errors recorded by the + JavaScript specification as part of its module record.

    @@ -86295,33 +86292,42 @@ interface NavigatorOnLine {
    -

    To error a module script script with a given value error, - perform the following steps:

    +

    We say that a module script is + errored if either its module + record is null, or its module + record's [[Status]] field has the value "errored".

    -
      -
    1. Assert: script's state is not - "errored".

    2. +

      When a module script is + errored, we say that its error is either + its pre-instantiation error, + when its module record is null, or its + module record's [[ErrorCompletion]] + field's [[Value]] field, otherwise.

      -
    3. -

      If script's module - record is set, then:

      +

      To set the pre-instantiation + error of a module script script:

      -
        -
      1. Set script module - record's [[HostDefined]] field to undefined.

      2. +
          +
        1. Let moduleRecord be script's module record.

        2. -
        3. Set script's module - record to null.

        4. -
        - +
      3. If moduleRecord is not null, set moduleRecord.[[HostDefined]] to + undefined.

      4. -
      5. Set script's state to - "errored".

      6. +
      7. Set script's module + record to null.

      8. -
      9. Set script's error to +

      10. Set script's pre-instantiation error to error.

      +

      We say that a module script has instantiated if its module record is not null, and its module record's [[Status]] field is either + "instantiated" or "evaluated".

      +

      An environment is an object that identifies the settings of a @@ -86376,8 +86382,9 @@ interface NavigatorOnLine { JavaScript realm. When we run a classic script or run a module script, this execution context becomes the top of the JavaScript execution context stack, on top of which another execution context specific to the script in question is - pushed. (This setup ensures ParseScript and ModuleEvaluation know which Realm to use.)

      + pushed. (This setup ensures ParseScript and Source + Text Module Record's Evaluate know which Realm to + use.)

      @@ -86753,23 +86760,22 @@ interface NavigatorOnLine { module script">fetching a single module script asynchronously completes with result:

    4. -
    5. If result is null, asynchronously complete this algorithm with null and abort - these steps.

    6. - -
    7. If result's state is "instantiated" or "errored", asynchronously complete this - algorithm with result, and abort these steps.

    8. +
    9. If result is null, is + errored, or has instantiated, + asynchronously complete this algorithm with result, and abort these steps.

    10. -
    11. Assert: result's state is - "uninstantiated".

    12. +
    13. Assert: result's module + record's [[Status]] is "uninstantiated".

    14. -
    15. Fetch the - descendants of and instantiate result given destination and an - ancestor list obtained by appending url to ancestor list.

    16. +
    17. If the top-level module fetch flag is set, fetch the descendants of and instantiate + result given destination and an ancestor list obtained by appending url to ancestor list. Otherwise, + fetch the descendants of + result given the same arguments.

    18. -
    19. When the fetch the descendants of and instantiate a module script algorithm - asynchronously completes with final result, asynchronously complete this algorithm - with final result.

    20. +
    21. When the appropriate algorithm asynchronously completes with final result, + asynchronously complete this algorithm with final result.

    To fetch a single module script, given a url, a fetch client @@ -86867,20 +86873,18 @@ interface NavigatorOnLine { -

    To fetch the descendants of and instantiate a module script module - script, given a destination and an optional ancestor list, run these - steps. The algorithm will asynchronously complete with either null (on failure) or with - module script (on success).

    +

    To fetch the descendants of a module script module script, given a + destination and an optional ancestor list, run these steps. The algorithm + will asynchronously complete with either null (on failure) or with module script (on + success).

      -
    1. If ancestor list was not given, let it be the empty list.

    2. +
    3. If ancestor list was not given, let it be an empty list.

    4. -
    5. If module script's state is - "instantiated" or "errored", asynchronously - complete this algorithm with module script, and abort these steps.

    6. - -
    7. Assert: module script's state - is "uninstantiated".

    8. +
    9. If module script is + errored or has instantiated, + asynchronously complete this algorithm with module script, and abort these + steps.

    10. Let record be module script's module record.

    11. @@ -86898,28 +86902,17 @@ interface NavigatorOnLine {
    12. Let url be the result of resolving a module specifier given module script and requested.

    13. -
    14. -

      If url is failure:

      +
    15. Assert: url is never failure, because resolving a module specifier must have been previously successful with these same two + arguments.

    16. -
        -
      1. Let error be a new TypeError exception.

      2. - -
      3. Error module script with - error.

      4. - -
      5. Abort this algorithm, and asynchronously complete it with module - script.

      6. -
      - - -
    17. Otherwise, if ancestor list does not contain url, append - url to urls.

    18. +
    19. If ancestor list does not contain + url, append url to + urls.

    -
  • Let descendants result be null.

  • -
  • For each url in urls, perform the internal module script graph fetching procedure given url, module @@ -86936,133 +86929,80 @@ interface NavigatorOnLine {

    These invocations of the internal module script graph fetching procedure should be performed in parallel to each other.

    -

    If any invocation of the internal module script graph fetching procedure - asynchronously completes with null, then optionally abort all other invocations, set - descendants result to null, and proceed to the next step. (The un-fetched descendant - will cause errors during instantiation.)

    - -

    If any invocation of the internal module script graph fetching procedure - asynchronously completes with a module script whose state is "errored", then - optionally abort all other invocations, set descendants result to module - script, and proceed to the next step. (The errored descendant will cause errors during - instantiation.)

    - -

    Otherwise, wait for all of the internal module script graph fetching procedure - invocations to asynchronously complete, with module scripts - whose states are not "errored". Then, set descendants result to module script, - and proceed to the next step.

    -
  • - -
  • -

    Let instantiationStatus be record.ModuleDeclarationInstantiation().

    - -

    This step will recursively call ModuleDeclarationInstantiation all of the - module's uninstantiated dependencies.

    -
  • - -
  • -

    For each script in module script's uninstantiated inclusive - descendant module scripts, perform the following steps:

    +

    Wait for all invocations of the internal module script graph fetching procedure + to asynchronously complete, and let results be a list of the results, + corresponding to the same order they appeared in urls. Then, for each result of results:

      -
    1. If instantiationStatus is an abrupt completion, then error script with - instantiationStatus.[[Value]].

    2. +
    3. If result is null, asynchronously complete this algorithm with null, aborting + these steps.

    4. -
    5. Otherwise, set script's state to "instantiated".

    6. +
    7. If result is errored, + then set the pre-instantiation + error for module script to result's error. Asynchronously complete this algorithm with + module script, aborting these steps.

    -
  • -
  • -

    Asynchronously complete this algorithm with descendants result.

    +
    +

    It is important to wait for all invocations to complete, and then iterate the results in + order, so that any fetching or pre-instantiation errors are deterministically surfaced to the + developer. Otherwise, a module script graph with multiple errors would surface a + nondeterministically chosen error, making debugging quite difficult.

    + +

    As an unobservable optimization, implementations can quit early if an invocation returns + null or an errored module + script, and all previous invocations have completed already. However, this is optimizing + for the rare failure case, so likely not worth the trouble.

    +
    -

    It is intentional that we complete with descendants result here, and - not module script, as this allows us to notify the caller of fetching errors.

    +

    If we've reached this point, all of the internal module script graph fetching + procedure invocations have asynchronously completed, with module scripts that are not errored. Asynchronously complete this algorithm + with module script.

  • -

    In the above algorithm, a module script script's uninstantiated - inclusive descendant module scripts is a set of module scripts determined as follows:

    +

    To fetch the descendants of and instantiate a module script module + script, given a destination and an optional ancestor list, run these + steps. The algorithm will asynchronously complete with either null (on failure) or with + module script (on success).

      -
    1. If script's module - record is null, return the empty set.

    2. +
    3. Fetch the descendants of + module script, given destination and ancestor list.

    4. -
    5. Let moduleMap be script's settings object's - module map.

    6. - -
    7. Let stack be the stack « script ».

    8. - -
    9. Let inclusive descendants be an empty set.

    10. +
    11. Return from this algorithm, and run the following steps when fetching the descendants of a module script asynchronously + completes with result.

    12. -

      While stack is not empty:

      +

      If result is null or is + errored, then asynchronously complete this algorithm with result.

      -
        -
      1. Let current the result of popping from - stack.

      2. - -
      3. Assert: current is a module script (i.e., it is not "fetching" or null).

      4. - -
      5. -

        If inclusive descendants and stack both do not contain current, then:

        - -
          -
        1. Append current to - inclusive descendants.

        2. - -
        3. Let child specifiers be the value of current's module record's [[RequestedModules]] - internal slot.

        4. - -
        5. Let child URLs be the list obtained by calling - resolve a module specifier once for each item of child specifiers, - given current and that item. Omit any failures.

        6. - -
        7. Let child modules be the list obtained by getting each value in moduleMap whose key is given by an - item of child URLs.

        8. - -
        9. -

          For each s of child modules:

          +

          In this case, there was an error fetching the descendants, or one of them + failed to parse, or was previously marked as errored. We will not attempt to instantiate.

          +
        10. -
            -
          1. If inclusive descendants already contains s, continue.

          2. +
          3. Let record be result's module record.

          4. -
          5. If s is null, continue.

          6. +
          7. +

            Perform record.Instantiate().

            -
          8. Assert: s is a module script (i.e., it is not - "fetching", since by this point all child modules must have been - fetched).

          9. +

            This step will recursively call Instantiate + on all of the module's uninstantiated dependencies.

            -
          10. Push s onto stack.

          11. -
          -
        -
      6. -
      +

      If this throws an exception, ignore it for now; it is stored as result's error, and will be reported when we run result.

    13. -
    14. Return a set containing all items of inclusive descendants whose - state is "uninstantiated".

    15. +
    16. Asynchronously complete this algorithm with result.

    -

    The above algorithm gives a depth-first search of the module dependency graph. The - main interesting part is in how the "edges" of this graph are determined. The actual search - implementation is not important; any other technique for exploring the graph will suffice, given - that the output is a set only used for membership testing and whose order is thus not - important.

    -
    Creating scripts

    To create a classic script, given some script @@ -87098,7 +87038,8 @@ interface NavigatorOnLine {

    1. Let script be a new module script that this algorithm will - subsequently initialize.

    2. + subsequently initialize, with its module + record initially set to null.

    3. Set script's settings object to the environment settings object provided.

    4. @@ -87124,15 +87065,40 @@ interface NavigatorOnLine {

      If result is a List of errors, then:

        -
      1. Error script with - errors[0].

      2. +
      3. Set the + pre-instantiation error of script to errors[0].

      4. Return script.

      -
    5. Set script's state to "uninstantiated".

    6. +
    7. +

      For each string requested of + record.[[RequestedModules]]:

      + +
        +
      1. Let url be the result of resolving + a module specifier given module script and requested.

      2. + +
      3. +

        If url is failure:

        + +
          +
        1. Let error be a new TypeError exception.

        2. + +
        3. Set the + pre-instantiation error of script to error.

        4. + +
        5. Return script.

        6. +
        +
      4. +
      + +

      This step is essentially validating all of the requested module specifiers. We + treat a module with unresolvable module specifiers the same as one that cannot be parsed; in + both cases, a syntactic issue makes it impossible to ever contemplate instantiating the module + later.

      +
    8. Set script's module record to result.

    9. @@ -87230,43 +87196,29 @@ interface NavigatorOnLine {
    10. Check if we can run script with settings. If this returns "do not run" then abort these steps.

    11. -
    12. If s's state is "errored", then report the exception given by s's error for s and abort these - steps.

    13. +
    14. If s is errored, then + report the exception given by s's error and abort these steps.

    15. -
    16. Assert: s's state is "instantiated" (and thus its module record is not null).

    17. +
    18. Prepare to run script given settings.

    19. Let record be s's module record.

      -
    20. Prepare to run script given settings.

    21. -
    22. Let evaluationStatus be record.ModuleEvaluation().

      + data-x="js-Evaluate">Evaluate().

      This step will recursively evaluate all of the module's dependencies.

      -

      If ModuleEvaluation fails to complete as a result - of the user agent aborting the running script, then - set evaluationStatus to Completion { [[Type]]: throw, [[Value]]: a new +

      If Evaluate fails to complete as a result of the user agent + aborting the running script, then set + evaluationStatus to Completion { [[Type]]: throw, [[Value]]: a new "QuotaExceededError" DOMException, [[Target]]: empty }.

    23. -
    24. -

      If evaluationStatus is an abrupt completion, then:

      - -
        -
      1. Error script with - evaluationStatus.[[Value]].

      2. - -
      3. Report the exception given by evaluationStatus.[[Value]] for - s.

        -
      -
    25. +
    26. If evaluationStatus is an abrupt completion, then report the + exception given by evaluationStatus.[[Value]] for s.

    27. Clean up after running script with settings.

    @@ -87865,8 +87817,8 @@ document.querySelector("button").addEventListener("click", bound);

    Although the JavaScript specification does not account for this possibility, it's sometimes necessary to abort a running script. This causes any ScriptEvaluation or ModuleEvaluation to cease immediately, emptying the + data-x="js-ScriptEvaluation">ScriptEvaluation or Source Text Module Record + Evaluate invocations to cease immediately, emptying the JavaScript execution context stack without triggering any of the normal mechanisms like finally blocks.

    @@ -88116,43 +88068,18 @@ import "https://example.com/foo/../module2.js"; specifier.

  • Assert: url is never failure, because resolving a module specifier must have been previously successful with these - same two arguments during the appropriate invocation of fetch the descendants of and - instantiate a module script.

  • + specifier">resolving a module specifier must have been previously successful with these + same two arguments.

  • Let resolved module script be moduleMap[url]. (This entry must exist for us to have gotten to this point.)

  • -
  • -

    If resolved module script is null, then throw a TypeError - exception and abort these steps.

    - -
    -

    This occurs when we have previously tried to fetch url, and failed, but are now rediscovering that fact in a new - module script graph. For example, given a file module.js whose contents - are

    - -
    import "./404.js";
    - -

    then we could get here as part of fetching the - graph for the second script element in the following HTML:

    - -
    <script type="module" src="404.js"></script>
    -<script type="module" src="module.js"></script>
    -
    -
  • -
  • Assert: resolved module script is a module script (i.e., is not - "fetching").

  • - -
  • If resolved module script's state is "errored", then throw - resolved module script's error.

  • + null or "fetching").

    -
  • Assert: resolved module script's module record is not null.

  • +
  • Assert: resolved module script is not errored.

  • Return resolved module script's module record.