diff --git a/source b/source
index 426157e0844..81701d8a63a 100644
--- a/source
+++ b/source
@@ -2755,6 +2755,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
This diagram illustrates how these algorithms relate to the ones above, as well as to each
other:
-
-
-
+
@@ -96374,7 +96296,7 @@ document.querySelector("button").addEventListener("click", bound);
- fetch an import() module script graph
+ fetch a modulepreload module script graph
@@ -96382,42 +96304,34 @@ document.querySelector("button").addEventListener("click", bound);
- fetch a modulepreload module script graph
+ fetch an inline module script graph
-
-
- fetch an inline module script graph
-
-
-
-
-
fetch a module worker script graph
-
+
-
+
fetch a worklet script graph
-
+
-
+
fetch a worklet/module worker script graph
-
+
@@ -96425,23 +96339,6 @@ document.querySelector("button").addEventListener("click", bound);
fetch the descendants of and link a module script
-
-
-
-
-
- fetch the descendants of a module script
-
-
-
-
-
-
-
- internal module script graph fetching procedure
-
-
-
To fetch a worklet/module worker script graph given a url , a fetch
@@ -96473,211 +96370,86 @@ document.querySelector("button").addEventListener("click", bound);
If result is null, run onComplete given null, and abort these
steps.
- Let visited set be « (url , "javascript
")
- ».
-
- Fetch the
- descendants of and link result given fetch client settings
- object , destination , visited set , and
- onComplete . If performFetch was given, pass it along as well.
+ Fetch the descendants
+ of and link result given fetch client settings object ,
+ destination , and onComplete . If performFetch was given, pass
+ it along as well.
To fetch the descendants of and link a module script module
- script , given a fetch client settings object , a destination , a
- visited set , an onComplete algorithm, and an optional perform the fetch hook performFetch , run
- these steps. onComplete must be an algorithm accepting null (on failure) or a
- module script (on success).
-
-
-
- Fetch the descendants of
- module script , given fetch client settings object , destination ,
- visited set , and onFetchDescendantsComplete as defined below. If
- performFetch was given, pass it along as well.
-
- onFetchDescendantsComplete given result is the following algorithm:
-
-
-
- If result is null, then run onComplete given result , and
- abort these steps.
-
- In this case, there was an error fetching one or more of the descendants. We
- will not attempt to link.
-
-
- Let parse error be the result of finding the first parse error
- given result .
-
-
- If parse error is null, then:
-
-
- Let record be result 's record .
-
-
- Perform record .Link ().
-
- This step will recursively call Link on all of
- the module's unlinked dependencies.
-
- If this throws an exception, set result 's error to rethrow to that exception.
-
-
-
-
- Otherwise, set result 's error
- to rethrow to parse error .
-
- Run onComplete given result .
-
-
-
-
- To fetch the descendants of a module script module script , given a
- fetch client settings object , a destination , a visited set , an
+ script
, given a fetch client settings object , a destination , an
onComplete algorithm, and an optional perform the fetch hook performFetch , run
these steps. onComplete must be an algorithm accepting null (on failure) or a
module script (on success).
- If module script 's record is null,
- run onComplete with module script and return.
-
Let record be module script 's record .
- If record is not a Cyclic Module Record , or if
- record .[[RequestedModules]] is empty , run
- onComplete with module script and return.
-
- Let moduleRequests be a new empty list .
-
- For each ModuleRequest Record
- requested of record .[[RequestedModules]],
+ If record is null, then:
- Let url be the result of resolving
- a module specifier given module script and
- requested .[[Specifier]].
-
- Assert : the previous step never throws an exception, because resolving a module specifier must have been previously successful with these same two
- arguments.
+ Set module script 's error to
+ rethrow to module script 's parse error .
- Let moduleType be the result of running the module type from module
- request steps given requested .
-
-
- If visited set does not contain
- (url , moduleType ), then:
+ Run onComplete given module script .
-
- Append requested to
- moduleRequests .
-
- Append (url , moduleType ) to
- visited set .
-
-
+ Return.
- Let options be the descendant script fetch options for module
- script 's fetch options .
-
- Assert : options is not null, as module script is a
- JavaScript module script .
+ Let state be Record { [[ParseError]]: null, [[Destination]]:
+ destination , [[PerformFetch]]: null }.
- Let pendingCount be the length of moduleRequests .
+ If performFetch was given, set state .[[PerformFetch]] to
+ performFetch .
- If pendingCount is zero, run onComplete with module
- script .
+
+ Let loadingPromise be record .LoadRequestedModules (state ).
- Let failed be false.
+ This step will recursively load all the module transitive dependencies.
+
- For each moduleRequest in
- moduleRequests , perform the internal module script graph fetching
- procedure given moduleRequest , fetch client settings object ,
- destination , options , module script , visited set ,
- and onInternalFetchingComplete as defined below. If performFetch was
- given, pass it along as well.
-
- onInternalFetchingComplete given result is the following algorithm:
+ Upon fulfillment of loadingPromise , run the following steps:
- If failed is true, then abort these steps.
-
- If result is null, then set failed to true, run
- onComplete with null, and abort these steps.
+
+ Perform record .Link ().
- Assert : pendingCount is greater than zero.
+ This step will recursively call Link on all of
+ the module's unlinked dependencies.
- Decrement pendingCount by one.
+ If this throws an exception, catch it, and set module script 's error to rethrow to that exception.
+
- If pendingCount is zero, run onComplete with module
- script .
+ Run onComplete given module script .
-
- The fetches performed by the internal module script graph fetching
- procedure are performed in parallel to each other.
-
-
- To perform the internal module script graph fetching procedure given a
- moduleRequest , a fetch client settings object , a destination ,
- some options , a referringScript , a visited set , an
- onComplete algorithm, and an optional perform the fetch hook performFetch , run
- these steps. onComplete must be an algorithm accepting null (on failure) or a
- module script (on success).
-
-
- Let url be the result of resolving
- a module specifier given referringScript and
- moduleRequest .[[Specifier]].
-
- Assert : the previous step never throws an exception, because resolving a module specifier must have been previously successful with these same two
- arguments.
-
- Let moduleType be the result of running the module type from module
- request steps given moduleRequest .
-
- Assert : visited set contains
- (url , moduleType ).
- Fetch a single module script given url , fetch client settings
- object , destination , options , referringScript 's
- settings object , referringScript 's base URL , moduleRequest , false, and
- onSingleFetchComplete as defined below. If performFetch was given, pass
- it along as well.
-
- onSingleFetchComplete given result is the following algorithm:
+ Upon rejection of loadingPromise , run the
+ following steps:
- If result is null, run onComplete with null, and abort these
- steps.
+ If state .[[ParseError]] is not null, set module script 's error to rethrow to
+ state .[[ParseError]] and run onComplete given module
+ script .
- Fetch the descendants of
- result given fetch client settings object , destination ,
- visited set , and with onComplete . If performFetch was given,
- pass it along as well.
-
+
+ Otherwise, run onComplete given null.
-
+ state .[[ParseError]] is null when loadingPromise is
+ rejected due to a loading error.
+
+
@@ -96696,12 +96468,11 @@ document.querySelector("button").addEventListener("click", bound);
running the module type from module request steps given
moduleRequest .
- Assert : the result of running the module type allowed steps
- given moduleType and module map settings object is true. 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 .
+ Assert : the result of running the module type allowed steps given
+ moduleType and module map settings object is true. 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 a single imported module script .
Let moduleMap be module map settings object 's module map .
@@ -96813,61 +96584,30 @@ document.querySelector("button").addEventListener("click", bound);
- To find the first parse error given a root
- moduleScript and an optional discoveredSet :
+ To fetch a single imported module script , given a url , a settings
+ object , a destination , some options , a referrer , a
+ moduleRequest , an onComplete algorithm, and an optional perform the fetch hook performFetch , run
+ these steps. onComplete must be an algorithm accepting null (on failure) or a
+ module script (on success).
- Let moduleMap be moduleScript 's settings object 's
- module map .
-
- If discoveredSet was not given, let it be an empty set .
-
- Append moduleScript to
- discoveredSet .
-
- If moduleScript 's record is null,
- then return moduleScript 's parse
- error .
-
- If moduleScript 's record is not a
- Cyclic Module Record , then return null.
-
- Let moduleRequests be the value of moduleScript 's record 's [[RequestedModules]] internal slot.
-
-
- For each moduleRequest of
- moduleRequests :
-
-
- Let childURL be the result of resolving a module specifier given moduleScript and
- moduleRequest .[[Specifier]]. (This will never throw an exception, as otherwise
- moduleScript would have been marked
- as itself having a parse error .)
-
- Let moduleType be the result of running the module type from module
- request steps given moduleRequest .
-
- Let childModule be moduleMap [(childURL ,
- moduleType )].
-
- 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
- fetched.
-
- If discoveredSet already contains
- childModule , continue .
+ 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 .
- Let childParseError be the result of finding the first parse
- error given childModule and discoveredSet .
+ Let moduleType be the result of running the module type from module
+ request steps given moduleRequest .
- If childParseError is not null, return childParseError .
-
-
+ If the result of running the module type allowed steps given
+ moduleType and settings object is false, then run onComplete
+ given null, and return.
- Return null.
+ Fetch a single module script given url , settings
+ object , destination , options , settings object ,
+ referrer , moduleRequest , false, and onComplete . If
+ performFetch was given, pass it along as well.
Creating scripts
@@ -97054,7 +96794,7 @@ document.querySelector("button").addEventListener("click", bound);
Run the steps to synchronously replace the rules of a CSSStyleSheet
on sheet given source .
- If this throws an exception, set script 's If this throws an exception, catch it, and set script 's parse error to that exception, and return
script .
@@ -97089,7 +96829,7 @@ document.querySelector("button").addEventListener("click", bound);
Let result be ParseJSONModule (source ).
- If this throws an exception, set script 's If this throws an exception, catch it, and set script 's parse error to that exception, and return
script .
@@ -98759,9 +98499,8 @@ dictionary PromiseRejectionEventInit : EventInitAs a consequence, this means that when the import()
expression is evaluated,
there will still be no active script . Fortunately that is handled by our
- implementations of HostResolveImportedModule and
- HostImportModuleDynamically , by falling back to using the current settings
- object 's API base URL .
+ implementation of HostLoadImportedModule by falling back to using the
+ current settings object 's API base URL .
@@ -98797,8 +98536,8 @@ dictionary PromiseRejectionEventInit : EventInit.
The returned promise will be rejected if an invalid specifier is given, or if a failure is
- encountered while fetching or evaluating the resulting module graph.
+ encountered while fetching or evaluating the
+ resulting module graph.
This syntax can be used inside both classic and module scripts . It thus provides a bridge into the module-script
@@ -98882,8 +98621,8 @@ import "https://example.com/foo/../module2.mjs";
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
+ import assertions specification stating that each call to HostLoadImportedModule
+ with the same (referrer , moduleRequest .[[Specifier]]) pair
must return the same Module Record .
@@ -98955,169 +98694,185 @@ import "https://example.com/foo/../module2.mjs";
Let resolveFunction be ! CreateBuiltinFunction (steps , 1,
"resolve
", « »).
- Return « Record { [[Key]]: "url
",
- [[Value]]: urlString }, Record { [[Key]]: "Return « Record { [[Key]]: "url
",
+ [[Value]]: urlString }, Record { [[Key]]: "resolve
", [[Value]]: resolveFunction }
».
- HostImportModuleDynamically (referencingScriptOrModule ,
- moduleRequest , promiseCapability )
+ HostGetSupportedImportAssertions ()
+
+ The Import Assertions proposal contains an implementation-defined
+ HostGetSupportedImportAssertions
+ abstract operation. User agents must use the following implementation:
+
+
+ Return « "type
" ».
+
+
+ HostLoadImportedModule (referrer ,
+ moduleRequest , loadState , payload )
JavaScript contains an implementation-defined HostImportModuleDynamically abstract operation.
- User agents must use the following implementation:
+ data-x="js-HostLoadImportedModule">HostLoadImportedModule abstract operation. User agents
+ must use the following implementation: [
+
+ ]This specification expects the second parameter to be a ModuleRequest
+ Record , instead of a string as specified by ECMA-262. This is under the assumption that the
+ import assertions proposal, when updated to use HostLoadImportedModule
+ instead of the previous module loading hooks, will update the abstract operation passing a
+ ModuleRequest Record .
- Let settings object be the current settings object .
+ Let settingsObject be the current settings object .
- If settings object 's global
- object implements WorkletGlobalScope
or
- ServiceWorkerGlobalScope
, then:
+ If settingsObject 's global
+ object implements WorkletGlobalScope
or ServiceWorkerGlobalScope
+ and loadState is undefined, then:
+
+ loadState is undefined when the current fetching process has been
+ initiated by a dynamic import()
call, either directly or when loading the
+ transitive dependencies of the dynamically imported module.
- Let completion be Completion { [[Type]]: throw, [[Value]]: a new
- TypeError
, [[Target]]: empty }.
+ Let completion be Completion Record { [[Type]]: throw,
+ [[Value]]: a new TypeError
, [[Target]]: empty }.
- Perform FinishDynamicImport (referencingScriptOrModule ,
- moduleRequest , promiseCapability , completion ).
+ Perform FinishLoadingImportedModule (referrer ,
+ moduleRequest , payload , completion ).
Return.
- Let referencing script be null.
+ Let referencingScript be null.
- Let fetch options be the default classic script fetch
+ Let fetchOptions be the default classic script fetch
options .
+ Let fetchReferrer be "client
".
+
- If referencingScriptOrModule is not null, then:
+ If referrer is a Script Record or a Module Record , then:
- Set referencing script to
- referencingScriptOrModule .[[HostDefined]].
+ Set referencingScript to referrer .[[HostDefined]].
- Set settings object to referencing script 's settings
+ Set settingsObject to referencingScript 's settings
object .
- Set fetch options to the descendant script fetch options for
- referencing script 's fetch
+ Set fetchOptions to the descendant script fetch options for
+ referencingScript 's fetch
options .
- Assert : fetch options is not null, as referencing
- script is a classic script or a JavaScript module
+ Assert : fetchOptions is not null, as
+ referencingScript is a classic script or a JavaScript module
script .
-
-
- As explained for HostResolveImportedModule , in the common
- case, referencingScriptOrModule is non-null.
-
-
- Fetch an import() module script graph given moduleRequest ,
- referencing script , settings object , fetch options , and with
- the following steps given result :
+
+ If neither of the following conditions are true:
-
- Let promise be null.
+
- Otherwise, set promise to the result of running a module script given result and true.
+ then set fetchReferrer to referrer 's base URL .
- Perform FinishDynamicImport (referencingScriptOrModule ,
- moduleRequest , promiseCapability , promise ).
+ We set fetchReferrer conditionally to not propagate the referrer
+ when using import()
. Issue
+ #3744 looks into aligning dynamic imports with static imports.
+
-
-
-
- HostResolveImportedModule (referencingScriptOrModule ,
- moduleRequest )
- JavaScript contains an implementation-defined HostResolveImportedModule abstract operation. User
- agents must use the following implementation:
+
+
referrer is usually a Script Record or a Module Record , but it will not be so for event handlers per the get the current value of the event
+ handler algorithm. For example, given:
-
- Let moduleMap and referencingScript be null.
+ <button onclick="import('./foo.mjs')">Click me</button>
-
- If referencingScriptOrModule is not null, then:
+ If a click
event occurs, then at the time the
+ import()
expression runs, GetActiveScriptOrModule will return null,
+ and this operation will receive the current realm as a fallback
+ referrer .
+
+
-
- Set referencingScript to
- referencingScriptOrModule .[[HostDefined]].
+ Disallow further import maps given settingsObject .
- Set moduleMap to referencingScript 's settings
- object 's module map .
-
-
+ Let url be the result of resolving a
+ module specifier given referencingScript and
+ moduleRequest .[[Specifier]], catching any exceptions. If they throw an exception, let
+ resolutionError be the thrown exception.
- Otherwise:
+ If the previous step threw an exception, then:
- Assert : there is a current settings object .
+ Let completion be Completion Record { [[Type]]: throw,
+ [[Value]]: resolutionError , [[Target]]: empty }.
- Set moduleMap to the current settings object 's module map .
-
+ Perform FinishLoadingImportedModule (referrer ,
+ moduleRequest , payload , completion ).
-
-
referencingScriptOrModule is not usually null, but will be so for event handlers
- per the get the current value of
- the event handler algorithm. For example, given:
+
Return.
+
+
-
<button onclick="import('./foo.mjs')">Click me</button>
+
Let destination be "script"
.
-
If a click
event occurs, then at the time the
- import()
expression runs, GetActiveScriptOrModule will return null,
- which will be passed to this abstract operation when HostResolveImportedModule is called by
- FinishDynamicImport .
-
-
+ If loadState is not undefined, then set destination to
+ loadState .[[Destination]].
- Let url be the result of resolving a
- module specifier given referencingScript and
- moduleRequest .[[Specifier]].
+
+ Fetch a single imported module script given url , settings
+ object , destination , fetchOptions , fetchReferrer ,
+ moduleRequest , and onSingleFetchComplete as defined below. If
+ loadState is not undefined and loadState .[[PerformFetch]] is not null,
+ pass loadState .[[PerformFetch]] along as well.
- Assert : the previous step never throws an exception, 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 ).
+ onSingleFetchComplete given moduleScript is the following
+ algorithm:
- Let moduleType be the result of running the module type from module
- request steps given moduleRequest .
+
+ Let completion be null.
- Let resolvedModuleScript be moduleMap [(url ,
- moduleType )]. (This entry must exist for us to have
- gotten to this point.)
+ If moduleScript is null, then set completion to Completion
+ Record { [[Type]]: throw, [[Value]]: a new TypeError
, [[Target]]: empty
+ }.
- Assert : resolvedModuleScript is a module script
- (i.e., is not null or "fetching
").
+
+ Otherwise, if moduleScript 's parse
+ error is not null, then:
- Assert : resolvedModuleScript 's record is not null.
+
+ Let parseError be moduleScript 's parse error .
- Return resolvedModuleScript 's record .
-
+ Set completion to Completion Record { [[Type]]: throw,
+ [[Value]]: parseError , [[Target]]: empty }.
- HostGetSupportedImportAssertions ()
+ If loadState is not undefined and loadState .[[ParseError]] is
+ null, set loadState .[[ParseError]] to parseError .
+
+
- The Import Assertions proposal contains an implementation-defined
- HostGetSupportedImportAssertions
- abstract operation. User agents must use the following implementation:
+ Otherwise, set completion to Completion Record { [[Type]]:
+ normal, [[Value]]: result 's record ,
+ [[Target]]: empty }.
-
- Return « "type
" ».
+ Perform FinishLoadingImportedModule (referrer ,
+ moduleRequest , payload , completion ).
+
+
@@ -101085,9 +100840,8 @@ typedef OnBeforeUnloadEventHandlerNonNull ? OnBeforeUnl
In practice, this only affects the resolution of relative URLs via import()
,
which consult the base URL of the associated
- script. Nulling out [[ScriptOrModule]] means that HostResolveImportedModule and
- HostImportModuleDynamically will fall back to the current settings
- object 's API base URL .
+ script. Nulling out [[ScriptOrModule]] means that HostLoadImportedModule will
+ fall back to the current settings object 's API base URL .
diff --git a/styles.css b/styles.css
index 5ad4abcc5c3..706560cec4f 100644
--- a/styles.css
+++ b/styles.css
@@ -111,6 +111,32 @@ td.eg { border-width: thin; text-align: center; }
#abstractimg .horizontal, #abstractimg .left { word-spacing: 12px; font-size: 18px; text-anchor: middle; }
#abstractimg .right { font-size: 25px; }
+#module-script-fetching-diagram {
+ display: block;
+ margin: 0 auto;
+ width: 100%;
+ max-width: 1024px;
+}
+
+#module-script-fetching-diagram rect {
+ stroke: black;
+ fill: transparent;
+}
+
+#module-script-fetching-diagram path {
+ stroke: black;
+}
+#module-script-fetching-diagram path[marker-end] {
+ fill: transparent;
+}
+
+#module-script-fetching-diagram a {
+ text-align: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
.jake-diagram {
border-style: hidden none hidden hidden;
table-layout: fixed;