From 3d45584d286e9455cc24ebae1f3aca3db120dc9d Mon Sep 17 00:00:00 2001 From: Dan Clark Date: Wed, 14 Jul 2021 11:40:22 -0700 Subject: [PATCH] Introduce CSS module scripts This change extends the JavaScript module system integration to include CSS module scripts, in addition to JavaScript module scripts. These allow web developers to load CSS into a component definition in a manner that interacts seamlessly with other module script types. Explainer document: https://github.com/w3c/webcomponents/blob/gh-pages/proposals/css-modules-v1-explainer.md Closes https://github.com/w3c/webcomponents/issues/759. Part of #4321. This change includes the integration for the import assertions proposal (https://github.com/tc39/proposal-import-assertions/), thus closing #5640 and closing #5883 by superseding it. --- source | 575 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 429 insertions(+), 146 deletions(-) diff --git a/source b/source index aaabd4fcf9e..92fa4d6e423 100644 --- a/source +++ b/source @@ -2450,6 +2450,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute -
DOM
@@ -3636,9 +3653,12 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • style IDL attribute
  • cssText attribute of CSSStyleDeclaration
  • StyleSheet interface
  • +
  • CSSStyleSheet inteface
  • create a CSS style sheet
  • remove a CSS style sheet
  • associated CSS style sheet
  • +
  • create a constructed CSSStyleSheet
  • +
  • synchronously replace the rules of a CSSStyleSheet
  • CSS style sheets and their @@ -58401,11 +58421,12 @@ interface HTMLScriptElement : HTMLElement { redundantly setting it.

  • Setting the attribute to an ASCII case-insensitive match for the string - "module" means that the script is a module script, to be - interpreted according to the JavaScript Module top-level - production. Module scripts are not affected by the defer - attribute, but are affected by the async attribute - (regardless of the state of the src attribute).

  • + "module" means that the script is a JavaScript module + script, to be interpreted according to the JavaScript Module top-level production. Module scripts are not affected by the + defer attribute, but are affected by the async attribute (regardless of the state of the src attribute).

  • Setting the attribute to any other value means that the script is a data block, which is not processed. None of the script attributes (except HTMLScriptElement : HTMLElement { scripts. By using a valid MIME type string now, you ensure that your data block will not ever be reinterpreted as a different script type, even in future user agents.

    -

    Classic scripts and module - scripts can be embedded inline, or be imported from an external file using the src attribute, which if - specified gives the URL of the external script resource to use. If src is specified, it must be a valid non-empty URL - potentially surrounded by spaces. The contents of inline script elements, or - the external script resource, must conform with the requirements of the JavaScript specification's - Script or Module productions, for - classic scripts and module - scripts respectively.

    +

    Classic scripts and JavaScript module scripts can be embedded inline, or be + imported from an external file using the src attribute, which if specified gives the URL + of the external script resource to use. If src is specified, + it must be a valid non-empty URL potentially surrounded by spaces.

    + +

    The contents of inline script elements, or the external script resource, must + conform with the requirements of the JavaScript specification's Script or Module productions, for classic scripts and JavaScript module scripts respectively.

    + +

    The contents of the external script resource for CSS module + scripts must conform to the requirements of the CSS specification.

    When used to include data blocks, the data must be embedded inline, the format of the data must be given using the type @@ -58674,7 +58700,7 @@ o............A....e

    The following sample shows how a script element can be used to include an - external module script. + external JavaScript module script.

    <script type="module" src="app.mjs"></script>
    @@ -58685,37 +58711,37 @@ o............A....e

    Additionally, if code from another script element in the same Window imports the module from app.mjs (e.g. via import - "./app.mjs";), then the same module script created by the + "./app.mjs";), then the same JavaScript module script created by the former script element will be imported.

    -

    This example shows how to include a module script for modern user agents, and a - classic script for older user agents:

    +

    This example shows how to include a JavaScript module script for modern user + agents, and a classic script for older user agents:

    <script type="module" src="app.mjs"></script>
     <script nomodule defer src="classic-app-bundle.js"></script>
    -

    In modern user agents that support module scripts, the - script element with the nomodule attribute - will be ignored, and the script element with a type of "module" will be fetched and - evaluated (as a module script). Conversely, older user agents will ignore the +

    In modern user agents that support JavaScript module + scripts, the script element with the nomodule attribute will be ignored, and the script element with a type of "module", as that is an unknown script type for them — but they will have no - problem fetching and evaluating the other script element (as a classic - script), since they do not implement the nomodule attribute.

    + data-x="">module" will be fetched and evaluated (as a JavaScript module + script). Conversely, older user agents will ignore the script element with a + type of "module", as that is an + unknown script type for them — but they will have no problem fetching and evaluating the other + script element (as a classic script), since they do not implement the + nomodule attribute.

    The following sample shows how a script element can be used to write an inline - module script that performs a number of substitutions on the document's text, in - order to make for a more interesting reading experience (e.g. on a news site): JavaScript module script that performs a number of substitutions on the document's + text, in order to make for a more interesting reading experience (e.g. on a news site):

    <script type="module">
    @@ -58747,12 +58773,12 @@ o............A....e
      walkAllTextNodeDescendants(document.body, substitute);
     </script>
    -

    Some notable features gained by using a module script include the ability to import functions - from other JavaScript modules, strict mode by default, and how top-level declarations do not - introduce new properties onto the global object. Also note that no matter where - this script element appears in the document, it will not be evaluated until both - document parsing has complete and its dependency (dom-utils.mjs) has been - fetched and evaluated.

    +

    Some notable features gained by using a JavaScript module script include the ability to import + functions from other JavaScript modules, strict mode by default, and how top-level declarations + do not introduce new properties onto the global object. Also note that no matter + where this script element appears in the document, it will not be evaluated until + both document parsing has complete and its dependency (dom-utils.mjs) has + been fetched and evaluated.

    @@ -90125,7 +90151,7 @@ document.querySelector("button").addEventListener("click", bound);
    Scripts
    -

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

    @@ -90136,10 +90162,22 @@ document.querySelector("button").addEventListener("click", bound);
    A record
    -

    Either a Script Record, for classic - scripts; a Source Text Module Record, for module scripts; or null. In the former two cases, it represents a parsed script; - null represents a failure parsing.

    +
    +

    One of the following:

    + +
      +
    • a script record, for classic + scripts;

    • + +
    • a Source Text Module Record, for JavaScript module scripts;

    • + +
    • a Synthetic Module Record, for CSS + module scripts; or

    • + +
    • null, representing a parsing failure.

    • +
    +
    A parse error
    @@ -90201,6 +90239,35 @@ document.querySelector("button").addEventListener("click", bound); data-x="concept-script">script. It has no additional items.

    +

    Module scripts can be classified into two types:

    + +
      +
    • A module script is a JavaScript module script if + its record is a Source Text Module + Record.

    • + +
    • +

      A module script is a CSS module script if its record is a Synthetic Module Record, and it + was created via the create a CSS module + script algorithm. CSS module scripts represent a parsed CSS stylesheet.

      + + +

      As CSS stylesheets do not import dependent modules, and do not throw exceptions + on evaluation, the fetch options and + base URL of a CSS module script are + always null.

      +
    • +
    +

    The active script is determined by the following algorithm:

      @@ -90567,7 +90634,8 @@ document.querySelector("button").addEventListener("click", bound);
    1. If result is null, asynchronously complete this algorithm with null, and return.

    2. -
    3. Let visited set be « url ».

    4. +
    5. Let visited set be « (url, "javascript") + ».

    6. Fetch the descendants of and link result given settings object, @@ -90576,29 +90644,42 @@ document.querySelector("button").addEventListener("click", bound); result.

    -

    To fetch an import() module script graph given a specifier, a base - URL, a settings object, and some options, run these steps. The - algorithm will asynchronously complete with either null (on failure) or a module +

    To fetch an import() module script graph given a moduleRequest, a + base URL, a settings object, and some options, run these steps. + The algorithm will asynchronously complete with either null (on failure) or a module script (on success).

    1. Let url be the result of resolving a - module specifier given base URL and specifier.

    2. + module specifier given base URL and moduleRequest.[[Specifier]].

    3. If url is failure, then asynchronously complete this algorithm with null, and return.

    4. +
    5. Assert: moduleRequest.[[Assertions]] does not contain any Record + entry such that entry.[[Key]] is not "type", because + we only asked for "type" assertions in + HostGetSupportedImportAssertions.

    6. + +
    7. If moduleRequest.[[Assertions]] has a Record entry + such that entry.[[Key]] is "type", then let module + type be entry.[[Value]]. Otherwise let module type be "javascript".

    8. + +
    9. If module type is neither "javascript" nor "css", then asynchronously complete this algorithm with null, and return.

    10. +
    11. Fetch a single module script given url, settings object, "script", options, settings object, - "client", and with the top-level module fetch flag set. If the - caller of this algorithm specified custom perform - the fetch steps, pass those along as well. Wait until the algorithm asynchronously - completes with result.

    12. + "client", moduleRequest, and with the + top-level module fetch flag set. If the caller of this algorithm specified custom + perform the fetch steps, pass those along as + well. Wait until the algorithm asynchronously completes with result.

    13. If result is null, asynchronously complete this algorithm with null, and return.

    14. -
    15. Let visited set be « url ».

    16. +
    17. Let visited set be « (url, module type) ».

    18. Fetch the descendants of and link result given settings object, @@ -90625,7 +90706,8 @@ document.querySelector("button").addEventListener("click", bound);

      If result is not null, optionally perform the following steps:

        -
      1. Let visited set be « url ».

      2. +
      3. Let visited set be « (url, "javascript") + ».

      4. Fetch the descendants of and link result given settings object, @@ -90646,8 +90728,8 @@ document.querySelector("button").addEventListener("click", bound); success).

          -
        1. Let script be the result of creating a module script using - source text, settings object, base URL, and +

        2. Let script be the result of creating a JavaScript module script + using source text, settings object, base URL, and options.

        3. If script is null, asynchronously complete this algorithm with null, and @@ -90853,7 +90935,8 @@ document.querySelector("button").addEventListener("click", bound);

        4. If result is null, asynchronously complete this algorithm with null, and return.

        5. -
        6. Let visited set be « url ».

        7. +
        8. Let visited set be « (url, "javascript") + ».

        9. Fetch the descendants of and link result given fetch client settings @@ -90927,31 +91010,38 @@ document.querySelector("button").addEventListener("click", bound); record.[[RequestedModules]] is empty, asynchronously complete this algorithm with module script.

        10. -
        11. Let urls be a new empty list.

        12. +
        13. Let moduleRequests be a new empty list.

        14. -

          For each string requested of - record.[[RequestedModules]],

          +

          For each ModuleRequest Record + requested of record.[[RequestedModules]],

          1. Let url be the result of resolving a module specifier given module script's base URL and requested.

          2. + data-x="concept-script-base-url">base URL and + requested.[[Specifier]].

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

          4. +
          5. If moduleRequest.[[Assertions]] has a Record entry + such that entry.[[Key]] is "type", then let module + type be entry.[[Value]]. Otherwise let module type be "javascript".

          6. +
          7. If visited set does not contain - url, then:

            + (url, module type), then:

              -
            1. Append url to urls.

            2. +
            3. Append requested to + moduleRequests.

            4. -
            5. Append url to visited - set.

            6. +
            7. Append (url, module type) to + visited set.

          @@ -90960,15 +91050,16 @@ document.querySelector("button").addEventListener("click", bound);
        15. Let options be the descendant script fetch options for module script's fetch options.

        16. -
        17. Assert: options is not null, as module script is a module - script.

        18. +
        19. Assert: options is not null, as module script is a JavaScript + module script.

        20. -

          For each url in urls, perform the - internal module script graph fetching procedure given url, fetch - client settings object, destination, options, module - script's settings object, visited set, and module - script's base URL. If the caller of this +

          For each moduleRequest in + moduleRequests, perform the internal module script graph fetching + procedure given moduleRequest, fetch client settings object, + destination, options, module script's settings + object, visited set, and module script's base URL. If the caller of this algorithm specified custom perform the fetch steps, pass those along while performing the internal module script graph fetching procedure.

          @@ -90987,21 +91078,35 @@ document.querySelector("button").addEventListener("click", bound);

        To perform the internal module script graph fetching procedure given a - url, a fetch client settings object, a destination, some - options, a module map settings object, a visited set, and a + moduleRequest, a fetch client settings object, a destination, + some options, a module map settings object, a visited set, and a referrer, perform these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).

          +
        1. Let url be the result of resolving + a module specifier given referrer and + moduleRequest.[[Specifier]].

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

        4. + +
        5. If moduleRequest.[[Assertions]] has a Record entry + such that entry.[[Key]] is "type", then let module + type be entry.[[Value]]. Otherwise let module type be "javascript".

        6. +
        7. Assert: visited set contains - url.

        8. + (url, module type).

        9. Fetch a single module script given url, fetch client settings object, destination, options, module map settings object, - referrer, and with the top-level module fetch flag unset. If the caller of - this algorithm specified custom perform the - fetch steps, pass those along while fetching a - single module script.

          + referrer, moduleRequest, and with the + top-level module fetch flag unset. If the caller of this algorithm specified custom + perform the fetch steps, pass those along + while fetching a single module script.

        10. Return from this algorithm, and run the following steps when fetching a single module script asynchronously completes with @@ -91020,24 +91125,45 @@ document.querySelector("button").addEventListener("click", bound);

          To fetch a single module script, given a url, a fetch client settings object, a destination, some options, a module map - settings object, a referrer, and a top-level module fetch flag, run - these steps. The algorithm will asynchronously complete with either null (on failure) or a - module script (on success).

          + settings object, a referrer, an optional moduleRequest, and a + top-level module fetch flag, run these steps. The algorithm will asynchronously + complete with either null (on failure) or a module script (on success).

            +
          1. Let module type be "javascript".

          2. + +
          3. +

            If moduleRequest was given and moduleRequest.[[Assertions]] has a + Record entry such that entry.[[Key]] is "type", then:

            + +
              +
            1. Assert: No more than one such Record exists.

            2. + +
            3. Set module type to entry.[[Value]].

            4. +
            +
          4. + +
          5. Assert: module type is either "javascript" or "css". Otherwise we would not have reached this point because a failure would + have been raised when inspecting moduleRequest.[[Assertions]] in create a JavaScript module script or fetch + an import() module script graph.

          6. +
          7. Let moduleMap be module map settings object's module map.

          8. -
          9. If moduleMap[url] is "fetching", wait - in parallel until that entry's value changes, then queue a task on - the networking task source to proceed with running the following steps.

          10. +
          11. If moduleMap[(url, module type)] is + "fetching", wait in parallel until that entry's value + changes, then queue a task on the networking task source to proceed + with running the following steps.

          12. -
          13. If moduleMap[url] exists, - asynchronously complete this algorithm with moduleMap[url], and - return.

          14. +
          15. If moduleMap[(url, module type)] exists, asynchronously complete this algorithm with + moduleMap[url / module type], and return.

          16. -
          17. Set moduleMap[url] to "fetching".

            +
          18. Set moduleMap[(url, module + type)] to "fetching".

          19. Let request be a new request whose URL is url,

          20. -

            If any of the following conditions are met:

            +

            If either of the following conditions are met:

            • response's type is "error"; or

            • response's status is not an - ok status; or

            • - -
            • the result of extracting a MIME type from - response's header list is not a - JavaScript MIME type,

            • + ok status.

            -

            then set moduleMap[url] to null, - asynchronously complete this algorithm with null, and return.

            +

            then set moduleMap[(url, module + type)] to null, asynchronously complete this algorithm with null, and return.

          21. Let source text be the result of UTF-8 decoding response's body.

          22. -
          23. Let module script be the result of creating a module script given - source text, module map settings object, response's url, and options.

          24. +
          25. Let module script be null.

          26. + +
          27. If MIME type is a JavaScript MIME type and module type + is "javascript", then set module script to the result of + creating a JavaScript module script given source text, module map + settings object, response's url, and + options.

          28. + +
          29. If the MIME type essence of MIME type is text/css and + module type is "css", then set module script to the + result of creating a CSS module script given source text and module + map settings object.

          30. -

            Set moduleMap[url] to module - script, and asynchronously complete this algorithm with module script.

            +

            Set moduleMap[(url, module + type)] to module script, and asynchronously complete this algorithm with + module script.

            It is intentional that the module map is keyed by the request URL, whereas the moduleScript's parse error.

          31. -
          32. Let childSpecifiers be the value of moduleScript's record's [[RequestedModules]] internal slot.

          33. - -
          34. Let childURLs be the list obtained by calling - resolve a module specifier once for each item of childSpecifiers, given - moduleScript's base URL and that item. - (None of these will ever fail, as otherwise moduleScript would have been marked as itself having a parse error.)

          35. +
          36. If moduleScript's record is not a + Cyclic Module Record, then return null.

          37. -
          38. Let childModules be the list obtained by getting each value in moduleMap whose key is given by an - item of childURLs.

          39. +
          40. Let moduleRequests be the value of moduleScript's record's [[RequestedModules]] internal slot.

          41. -

            For each childModule of - childModules:

            +

            For each moduleRequest of + moduleRequests:

              +
            1. Let childURL be the result of resolving a module specifier given moduleScript's base URL and moduleRequest.[[Specifier]]. + (This will never fail, as otherwise moduleScript would have been marked as itself having a parse + error.)

            2. + +
            3. If moduleRequest.[[Assertions]] has a Record entry + such that entry.[[Key]] is "type", then let module + type be entry.[[Value]]. Otherwise let module type be "javascript".

            4. + +
            5. Let childModule be moduleMap[(childURL, module + type)].

            6. +
            7. Assert: childModule is a module script (i.e., it is not "fetching" or null); by now all module scripts in the graph rooted at moduleScript will have successfully been @@ -91232,10 +91372,10 @@ document.querySelector("button").addEventListener("click", bound);

            8. Return script.

            -

            To create a module script, given a - string source, an environment settings object - settings, a URL baseURL, and some script fetch - options options:

            +

            To create a JavaScript module script, + given a string source, an environment settings + object settings, a URL baseURL, and some script + fetch options options:

            1. If scripting is disabled for @@ -91275,18 +91415,28 @@ document.querySelector("button").addEventListener("click", bound);

          42. +
          43. Assert: requested.[[Assertions]] does not contain any Record + entry such that entry.[[Key]] is not "type", because + we only asked for "type" assertions in + HostGetSupportedImportAssertions.

          44. +
          45. -

            For each string requested of - result.[[RequestedModules]]:

            +

            For each ModuleRequest record + requested of result.[[RequestedModules]]:

            1. Let url be the result of resolving a module specifier given script's base - URL and requested.

            2. + URL and requested.[[Specifier]].

              -
            3. -

              If url is failure, then:

              +
            4. If requested.[[Assertions]] has a Record entry such + that entry.[[Key]] is "type", then let module type + be entry.[[Value]]. Otherwise let module type be "javascript".

            5. +
            6. +

              If url is failure, or if module type is neither "javascript" nor "css", then:

              1. Let error be a new TypeError exception.

              2. @@ -91298,10 +91448,10 @@ document.querySelector("button").addEventListener("click", bound);
              -

              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 linking the module - later.

              +

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

            7. Set script's record to @@ -91310,6 +91460,67 @@ document.querySelector("button").addEventListener("click", bound);

            8. Return script.

            +

            To create a CSS module script, given a + string source and an environment settings object settings:

            + +
              +
            1. If the CSSStyleSheet interface is not exposed in setting's Realm, then return null.

            2. + +
            3. Let script be a new module script that this algorithm will + subsequently initialize.

            4. + +
            5. Set script's settings object to settings.

            6. + +
            7. Set script's base URL and + fetch options to null.

            8. + +
            9. Set script's parse error and + error to rethrow to null.

            10. + +
            11. Let sheet be the result of running the steps to create a constructed + CSSStyleSheet with an empty dictionary as the argument.

            12. + +
            13. +

              Run the steps to synchronously replace the rules of a CSSStyleSheet + on sheet given source.

              + +

              If this throws an exception, set script's parse error to that exception, and return + script.

              + +

              The steps to synchronously replace the rules of a + CSSStyleSheet will throw if source contains any @import rules. This is by-design for now because there is not yet an + agreement on how to handle these for CSS module scripts; therefore they are blocked altogether + until a consensus is reached.

              +
            14. + +
            15. Set script's record to the result + of creating a synthetic + module record with a default export of sheet with settings.

              +
            16. + +
            17. Return script.

            18. +
            + +

            To create a synthetic module record with a default export of a JavaScript value + value with an environment settings object settings:

            + +
              +
            1. +

              Return CreateSyntheticModule(« "default" », the following + steps, settings's Realm, + value) with the following steps given module as an argument:

              + +
                +
              1. Perform ! SetSyntheticModuleExport(module, "default", module.[[HostDefined]]).
              2. +
              +
            2. +
            +
            Calling scripts

            To run a classic script given a classic script script @@ -92126,17 +92337,21 @@ dictionary PromiseRejectionEventInit : EventInit

    -

    A module map is a map of URL records to values that are either a module script, - null (used to represent failed fetches), or a placeholder value "A module map is a map keyed by tuples consisting of a URL record and a string. + The URL record is the request URL at which + the module was fetched, and the string indicates the type of the module (e.g. "javascript"). The module map's values are either a module + script, null (used to represent failed fetches), or a placeholder value "fetching". Module maps are used to ensure - that imported JavaScript modules are only fetched, parsed, and evaluated once per + that imported module scripts are only fetched, parsed, and evaluated once per Document or worker.

    -

    Since module maps are keyed by URL, the following code will - create three separate entries in the module map, since it results in three different - URLs:

    +

    Since module maps are keyed by (URL, module type), the + following code will create three separate entries in the module map, since it + results in three different (URL, module type) tuples (all with "javascript" type):

    import "https://example.com/module.mjs";
     import "https://example.com/module.mjs#map-buster";
    @@ -92163,6 +92378,36 @@ import "https://example.com/foo/../module2.mjs";
    data-x="concept-SharedWorkerGlobalScope-constructor-url">constructor url.

    +
    +

    Since module type is also part of the module map key, the following code will + create two separate entries in the module map (the type is "javascript" for the first, and "css" for the second): + +

    <script>
    +  import "https://example.com/module";
    +</script>
    +<script>
    +  import "https://example.com/module" assert { type: "css" };
    +</script>
    + +

    This can result in two separate fetches and two separate module evaluations being performed. + This is a willful violation of a constraint recommended (but not required) by the + import assertions specification stating that each call to HostResolveImportedModule + with the same (referencingScriptOrModule, moduleRequest.[[Specifier]]) pair + must return the same Module Record.

    + +

    In practice, due to the as-yet-unspecified memory cache (see issue #6110) the resource may only be fetched + once in WebKit and Blink-based browsers. Additionally, as long as all module types are mutually + exclusive, the module type check in fetch a single module script will fail for at + least one of the imports, so at most one module evaluation will occur.

    + +

    The purpose of including the type in the module map key is so that an import + with the wrong type assertion does not prevent a different import of the same specifier but with + the correct type from succeeding.

    +
    +

    To resolve a module specifier given a URL base URL and a @@ -92256,6 +92501,10 @@ import "https://example.com/foo/../module2.mjs";

    1. Let module script be moduleRecord.[[HostDefined]].

    2. +
    3. Assert: module script's base + URL is not null, as module script is a JavaScript module + script.

    4. +
    5. Let urlString be module script's base URL, serialized.

    6. @@ -92264,7 +92513,7 @@ import "https://example.com/foo/../module2.mjs";
    HostImportModuleDynamically(referencingScriptOrModule, - specifier, promiseCapability)
    + moduleRequest, promiseCapability)

    JavaScript contains an implementation-defined HostImportModuleDynamically abstract operation. @@ -92283,7 +92532,7 @@ import "https://example.com/foo/../module2.mjs"; TypeError, [[Target]]: empty }.

  • Perform FinishDynamicImport(referencingScriptOrModule, - specifier, promiseCapability, completion).

  • + moduleRequest, promiseCapability, completion).

  • Return.

  • @@ -92311,15 +92560,19 @@ import "https://example.com/foo/../module2.mjs";
  • Set fetch options to the descendant script fetch options for referencing script's fetch options.

  • + +
  • Assert: Neither base URL nor fetch options is null, as + referencing script is a classic script or a JavaScript module + script.

  • As explained above for HostResolveImportedModule, in the common case, referencingScriptOrModule is non-null.

    -
  • Fetch an import() module script graph given specifier, base - URL, settings object, and fetch options. Wait until the algorithm - asynchronously completes with result.

  • +
  • Fetch an import() module script graph given moduleRequest, + base URL, settings object, and fetch options. Wait until the + algorithm asynchronously completes with result.

  • Let promise be null. @@ -92330,13 +92583,13 @@ import "https://example.com/foo/../module2.mjs"; script">running a module script given result and true.

  • Perform FinishDynamicImport(referencingScriptOrModule, - specifier, promiseCapability, promise).

  • + moduleRequest, promiseCapability, promise).

  • Return undefined.

  • HostResolveImportedModule(referencingScriptOrModule, - specifier)
    + moduleRequest)

    JavaScript contains an implementation-defined HostResolveImportedModule abstract operation. User @@ -92360,6 +92613,9 @@ import "https://example.com/foo/../module2.mjs";

  • Set base URL to referencing script's base URL.

  • + +
  • Assert: base URL is not null, as referencing script is a + classic script or a JavaScript module script.

  • @@ -92381,15 +92637,22 @@ import "https://example.com/foo/../module2.mjs"; data-x="concept-settings-object-module-map">module map.

  • Let url be the result of resolving a - module specifier given base URL and specifier.

  • + module specifier given base URL and + moduleRequest.[[Specifier]].

  • Assert: url is never failure, because resolving a module specifier must have been previously successful with these same two arguments (either while creating the corresponding module script, or in fetch an import() module script graph).

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

  • +
  • If moduleRequest.[[Assertions]] has a Record entry such + that entry.[[Key]] is "type", then let module type + be entry.[[Value]]. Otherwise let module type be "javascript".

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

  • Assert: resolved module script is a module script (i.e., is not null or "fetching").

  • @@ -92401,6 +92664,17 @@ import "https://example.com/foo/../module2.mjs"; data-x="concept-script-record">record.

    +
    HostGetSupportedImportAssertions()
    + +

    The Import Assertions proposal contains an implementation-defined + HostGetSupportedImportAssertions + abstract operation. User agents must use the following implementation:

    + +
      +
    1. Return « "type" ».

    2. +
    +

    Event loops

    @@ -95400,6 +95674,9 @@ enum DOMParserSupportedType {
  • Let base URL be initiating script's base URL.

  • +
  • Assert: base URL is not null, as initiating script is a + classic script or a JavaScript module script.

  • +
  • Let fetch options be a script fetch options whose cryptographic nonce is initiating @@ -125044,6 +125321,12 @@ INSERT INTERFACES HERE

    [JSERRORSTACKS]
    (Non-normative) Error Stacks. Ecma International.
    +
    [JSIMPORTASSERTIONS]
    +
    Import Assertions. Ecma International.
    + +
    [JSJSONMODULES]
    +
    JSON Modules. Ecma International.
    +
    [JSINTL]
    ECMAScript Internationalization API Specification. Ecma International.