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

Support import maps in workers #10858

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
166 changes: 105 additions & 61 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2318,6 +2318,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>The <dfn data-x-href="https://infra.spec.whatwg.org/#forgiving-base64-encode">forgiving-base64 encode</dfn> and
<dfn data-x-href="https://infra.spec.whatwg.org/#forgiving-base64-decode">forgiving-base64 decode</dfn> algorithms</li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#the-exclusive-range">exclusive range</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#parse-a-json-string-to-a-javascript-value">parse a JSON string to a JavaScript value</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#parse-a-json-string-to-an-infra-value">parse a JSON string to an Infra value</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#html-namespace">HTML namespace</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#mathml-namespace">MathML namespace</dfn></li>
Expand Down Expand Up @@ -2878,6 +2879,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x="LegacyUnenumerableNamedProperties" data-x-href="https://webidl.spec.whatwg.org/#LegacyUnenumerableNamedProperties"><code>[LegacyUnenumerableNamedProperties]</code></dfn></li>
<li><dfn data-x="LegacyUnforgeable" data-x-href="https://webidl.spec.whatwg.org/#LegacyUnforgeable"><code>[LegacyUnforgeable]</code></dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#dfn-set-entries">set entries</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#dfn-convert-ecmascript-to-idl-value">convert to an IDL value</dfn></li>
</ul>

<p><cite>Web IDL</cite> also defines the following types that are used in Web IDL fragments in
Expand Down Expand Up @@ -106488,10 +106490,11 @@ new PaymentRequest(&hellip;); // Allowed to use
<p>A <span>global object</span> has an <dfn data-x="concept-global-import-map">import map</dfn>,
initially an <span>empty import map</span>.</p>

<p class="note">For now, only <code>Window</code> <span data-x="global object">global
objects</span> have their <span data-x="concept-global-import-map">import map</span> modified
from the initial empty one. The <span data-x="concept-global-import-map">import map</span> is
only accessed for the resolution of a root <span>module script</span>.</p>
<p class="note">For now, only <code>Window</code> and <code>DedicatedWorkerGlobalScope</code>
<span data-x="global object">global objects</span> have their <span
data-x="concept-global-import-map">import map</span> modified from the initial empty one. The
<span data-x="concept-global-import-map">import map</span> is only accessed for the resolution of
a root <span>module script</span>.</p>

<p>A <span>global object</span> has a <dfn>resolved module set</dfn>, a <span>set</span>
of <span data-x="specifier resolution record">specifier resolution records</span>, initially
Expand Down Expand Up @@ -109215,12 +109218,9 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
</ol>
</li>

<li><p>Let <var>importMap</var> be an <span>empty import map</span>.</p></li>

<li><p>If <var>settingsObject</var>'s <span data-x="concept-settings-object-global">global
object</span> implements <code>Window</code>, then set <var>importMap</var> to
<var>settingsObject</var>'s <span data-x="concept-settings-object-global">global object</span>'s
<span data-x="concept-global-import-map">import map</span>.</p></li>
<li><p>Let <var>importMap</var> be <var>settingsObject</var>'s <span
data-x="concept-settings-object-global">global object</span>'s <span
data-x="concept-global-import-map">import map</span>.</p></li>

<li><p>Let <var>serializedBaseURL</var> be <var>baseURL</var>, <span
data-x="concept-url-serializer">serialized</span>.</p></li>
Expand Down Expand Up @@ -109749,27 +109749,51 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
</ol>
<hr>

<pre><code class="idl">dictionary <dfn dictionary>ImportMap</dfn> {
record&lt;DOMString, any> imports;
record&lt;DOMString, record&lt;DOMString, any>> scopes;
record&lt;DOMString, any> integrity;
};</code></pre>

<p>To <dfn>parse an import map string</dfn>, given a <span>string</span> <var>input</var> and a
<span>URL</span> <var>baseURL</var>:</p>

<ol>
<li><p>Let <var>parsed</var> be the result of <span data-x="parse a JSON string to an Infra
value">parsing a JSON string to an Infra value</span> given <var>input</var>.</p></li>
<li><p>Let <var>jsVal</var> be the result of <span data-x="parse a JSON string to a JavaScript
value">parsing a JSON string to a JavaScript value</span> given <var>input</var>.</p></li>

<li><p>If <var>jsVal</var> is null or undefined, throw a <code>TypeError</code> indicating that
the top-level value needs to be a JSON object.</p></li>

<li><p>Let <var>parsed</var> be <var>jsVal</var> <span data-x="convert to an IDL
value">converted</span> to an <code>ImportMap</code>.</p>

<li><p>Let <var>importMap</var> be the result of <span data-x="create an import map">creating an
import map</span> given <var>parsed</var> and <var>baseURL</var>.</p></li>

<li>
<p>If <var>jsVal</var>.[[OwnPropertyKeys]]() <span data-x="list contains">contains</span> any
items besides "<code data-x="">imports</code>", "<code data-x="">scopes</code>", or "<code
data-x="">integrity</code>", then the user agent should <span>report a warning to the
console</span> indicating that an invalid top-level key was present in the import map.</p>

<p class="note">This can help detect typos. It is not an error, because that would prevent any
future extensions from being added backward-compatibly.</p>
</li>

<li><p>If <var>parsed</var> is not an <span>ordered map</span>, then throw a
<code>TypeError</code> indicating that the top-level value needs to be a JSON object.</p></li>
<li><p>Return <var>importMap</var>.</p></li>
</ol>

<p>To <dfn>create an import map</dfn>, given an <code>ImportMap</code> <var>parsed</var> and a
<span>URL</span> <var>baseURL</var>:</p>

<ol>
<li><p>Let <var>sortedAndNormalizedImports</var> be an empty <span>ordered map</span>.</p></li>

<li>
<p>If <var>parsed</var>["<code data-x="">imports</code>"] <span data-x="map
exists">exists</span>, then:</p>
<p>If <var>parsed</var>["<code data-x="">imports</code>"] is not undefined, then:</p>

<ol>
<li><p>If <var>parsed</var>["<code data-x="">imports</code>"] is not an <span>ordered
map</span>, then throw a <code>TypeError</code> indicating that the value for the "<code
data-x="">imports</code>" top-level key needs to be a JSON object.</p></li>

<li><p>Set <var>sortedAndNormalizedImports</var> to the result of <span>sorting and
normalizing a module specifier map</span> given <var>parsed</var>["<code
data-x="">imports</code>"] and <var>baseURL</var>.</p></li>
Expand All @@ -109779,14 +109803,9 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
<li><p>Let <var>sortedAndNormalizedScopes</var> be an empty <span>ordered map</span>.</p></li>

<li>
<p>If <var>parsed</var>["<code data-x="">scopes</code>"] <span data-x="map
exists">exists</span>, then:</p>
<p>If <var>parsed</var>["<code data-x="">scopes</code>"] is not undefined, then:</p>

<ol>
<li><p>If <var>parsed</var>["<code data-x="">scopes</code>"] is not an <span>ordered
map</span>, then throw a <code>TypeError</code> indicating that the value for the "<code
data-x="">scopes</code>" top-level key needs to be a JSON object.</p></li>

<li><p>Set <var>sortedAndNormalizedScopes</var> to the result of <span>sorting and normalizing
scopes</span> given <var>parsed</var>["<code data-x="">scopes</code>"] and
<var>baseURL</var>.</p></li>
Expand All @@ -109796,31 +109815,15 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
<li><p>Let <var>normalizedIntegrity</var> be an empty <span>ordered map</span>.</p></li>

<li>
<p>If <var>parsed</var>["<code data-x="">integrity</code>"] <span data-x="map
exists">exists</span>, then:</p>
<p>If <var>parsed</var>["<code data-x="">integrity</code>"] is not undefined, then:</p>

<ol>
<li><p>If <var>parsed</var>["<code data-x="">integrity</code>"] is not an <span>ordered
map</span>, then throw a <code>TypeError</code> indicating that the value for the "<code
data-x="">integrity</code>" top-level key needs to be a JSON object.</p></li>

<li><p>Set <var>normalizedIntegrity</var> to the result of <span>normalizing a module
integrity map</span> given <var>parsed</var>["<code data-x="">integrity</code>"] and
<var>baseURL</var>.</p></li>
</ol>
</li>

<li>
<p>If <var>parsed</var>'s <span data-x="map key">keys</span> <span data-x="list
contains">contains</span> any items besides "<code data-x="">imports</code>", "<code
data-x="">scopes</code>", or "<code data-x="">integrity</code>", then the user agent should
<span>report a warning to the console</span> indicating that an invalid top-level key was
present in the import map.</p>

<p class="note">This can help detect typos. It is not an error, because that would prevent any
future extensions from being added backward-compatibly.</p>
</li>

<li><p>Return an <span>import map</span> whose <span
data-x="concept-import-map-imports">imports</span> are <var>sortedAndNormalizedImports</var>,
whose <span data-x="concept-import-map-scopes">scopes</span> are
Expand Down Expand Up @@ -110199,8 +110202,8 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
</div>

<p>To <dfn data-x="sorting and normalizing a module specifier map">sort and normalize a module
specifier map</dfn>, given an <span>ordered map</span> <var>originalMap</var> and a
<span>URL</span> <var>baseURL</var>:</p>
specifier map</dfn>, given a <code data-x="">record&lt;DOMString, any></code>
<var>originalMap</var> and a <span>URL</span> <var>baseURL</var>:</p>

<ol>
<li><p>Let <var>normalized</var> be an empty <span>ordered map</span>.</p></li>
Expand Down Expand Up @@ -110271,8 +110274,9 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
<var>b</var>'s <span data-x="map key">key</span>.</p></li>
</ol>

<p>To <dfn data-x="sorting and normalizing scopes">sort and normalize scopes</dfn>, given an
<span>ordered map</span> <var>originalMap</var> and a <span>URL</span> <var>baseURL</var>:</p>
<p>To <dfn data-x="sorting and normalizing scopes">sort and normalize scopes</dfn>, given a <code
data-x="">record&lt;DOMString, record&lt;DOMString, any>></code> <var>originalMap</var> and a
<span>URL</span> <var>baseURL</var>:</p>

<ol>
<li><p>Let <var>normalized</var> be an empty <span>ordered map</span>.</p></li>
Expand All @@ -110282,10 +110286,6 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
<var>potentialSpecifierMap</var> of <var>originalMap</var>:</p>

<ol>
<li><p>If <var>potentialSpecifierMap</var> is not an <span>ordered map</span>, then throw a
<code>TypeError</code> indicating that the value of the scope with prefix
<var>scopePrefix</var> needs to be a JSON object.</p></li>

<li><p>Let <var>scopePrefixURL</var> be the result of <span data-x="URL parser">URL
parsing</span> <var>scopePrefix</var> with <var>baseURL</var>.</p></li>

Expand Down Expand Up @@ -110321,7 +110321,7 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
during <span data-x="resolve a module specifier">module specifier resolution</span>.</p>

<p>To <dfn data-x="normalizing a module integrity map">normalize a module integrity map</dfn>,
given an <span>ordered map</span> <var>originalMap</var>:</p>
given a <code data-x="">record&lt;DOMString, any></code> <var>originalMap</var>:</p>

<ol>
<li><p>Let <var>normalized</var> be an empty <span>ordered map</span>.</p></li>
Expand Down Expand Up @@ -120547,8 +120547,8 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
<p>When a user agent is to <dfn export>run a worker</dfn> for a script with <code>Worker</code> or
<code>SharedWorker</code> object <var>worker</var>, <span>URL</span> <var>url</var>,
<span>environment settings object</span> <var>outside settings</var>, <code>MessagePort</code>
<var>outside port</var>, and a <code>WorkerOptions</code> dictionary <var>options</var>, it must
run the following steps.</p>
<var>outside port</var>, a <code>WorkerOptions</code> dictionary <var>options</var>, and an
<span>import map</span> <var>importMap</var>, it must run the following steps.</p>

<ol>
<li><p>Let <var>is shared</var> be true if <var>worker</var> is a <code>SharedWorker</code>
Expand Down Expand Up @@ -120591,6 +120591,9 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
data-x="concept-WorkerGlobalScope-name">name</span> to the value of <var>options</var>'s
<code data-x="">name</code> member.</p></li>

<li><p>Set <var>worker global scope</var>'s <span
data-x="concept-global-import-map">import map</span> to <var>importMap</var>.</p></li>

<li><p><span data-x="set append">Append</span> <var>owner</var> to <var>worker global
scope</var>'s <span>owner set</span>.</p></li>

Expand Down Expand Up @@ -121005,7 +121008,7 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope

<pre><code class="idl">[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface <dfn interface>Worker</dfn> : <span>EventTarget</span> {
<span data-x="dom-Worker">constructor</span>((<code data-x="tt-trustedscripturl">TrustedScriptURL</code> or USVString) scriptURL, optional <span>WorkerOptions</span> options = {});
<span data-x="dom-Worker">constructor</span>((<code data-x="tt-trustedscripturl">TrustedScriptURL</code> or USVString) scriptURL, optional <span>DedicatedWorkerOptions</span> options = {});

undefined <span data-x="dom-Worker-terminate">terminate</span>();

Expand All @@ -121015,12 +121018,18 @@ interface <dfn interface>Worker</dfn> : <span>EventTarget</span> {

dictionary <dfn dictionary>WorkerOptions</dfn> {
<span>WorkerType</span> type = "classic";
<span>RequestCredentials</span> credentials = "same-origin"; // credentials is only used if type is "module"
<span>RequestCredentials</span> credentials = "same-origin"; // credentials is only used if type is "module"
DOMString name = "";
};

dictionary <dfn dictionary>DedicatedWorkerOptions</dfn> : <span>WorkerOptions</span> {
(<span>WorkerImportMapInheritance</span> or <span>ImportMap</span>) importMap = "none";
};

enum <dfn enum>WorkerType</dfn> { "classic", "module" };

enum <dfn enum>WorkerImportMapInheritance</dfn> { "none", "clone" };

<span>Worker</span> includes <span>AbstractWorker</span>;
<span>Worker</span> includes <span>MessageEventTarget</span>;</code></pre>

Expand Down Expand Up @@ -121108,6 +121117,33 @@ enum <dfn enum>WorkerType</dfn> { "classic", "module" };
<li><p>If <var>worker URL</var> is failure, then throw a <span>"<code>SyntaxError</code>"</span>
<code>DOMException</code>.</p></li>

<li><p>Let <var>importMap</var> be an <span>empty import map</span>.</p></li>

<li>
<p>If <var>options</var>'s <code data-x="">importMap</code> member is "<code
data-x="">clone</code>", then:</p>

<ol>
<li><p>If the <span>current global object</span> implements <code>Window</code> or
<code>DedicatedWorkerGlobalScope</code>, set <var>importMap</var> to a deep copy of the
<span>current global object</span>'s <span data-x="concept-global-import-map">import
map</span>.</p></li>

<li><p>Else, throw a <code>TypeError</code> exception.</p></li>
</ol>

<p class="note">The <span>current global object</span>'s <span
data-x="concept-global-import-map">import map</span> could be modified, by <span
data-x="merge existing and new import maps">merging it with a new import map</span>. Such
updates will not be reflected in the cloned import map.</p>
</li>

<li><p>Else, if <var>options</var>'s <code data-x="">importMap</code> member is an
<code>ImportMap</code>, set <var>importMap</var> to the result of <span data-x="create an import
map">creating an import map</span> given <var>options</var>'s <code data-x="">importMap</code>
member and <span class="XXX">TODO: which base URL? The worker's, or the
creator's?</span>.</p></li>

<li><p>Let <var>worker</var> be a new <code>Worker</code> object.</p></li>

<li><p>Let <var>outside port</var> be a <span>new</span> <code>MessagePort</code> in <var>outside
Expand All @@ -121123,7 +121159,7 @@ enum <dfn enum>WorkerType</dfn> { "classic", "module" };

<ol>
<li><p><span>Run a worker</span> given <var>worker</var>, <var>worker URL</var>, <var>outside
settings</var>, <var>outside port</var>, and <var>options</var>.</p></li>
settings</var>, <var>outside port</var> <var>options</var>, and <var>importMap</var>.</p></li>
</ol>
</li>

Expand All @@ -121137,10 +121173,15 @@ enum <dfn enum>WorkerType</dfn> { "classic", "module" };

<pre><code class="idl">[Exposed=Window]
interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
<span data-x="dom-SharedWorker">constructor</span>((<code data-x="tt-trustedscripturl">TrustedScriptURL</code> or USVString) scriptURL, optional (DOMString or <span>WorkerOptions</span>) options = {});
<span data-x="dom-SharedWorker">constructor</span>((<code data-x="tt-trustedscripturl">TrustedScriptURL</code> or USVString) scriptURL, optional (DOMString or <span>SharedWorkerOptions</span>) options = {});

readonly attribute <span>MessagePort</span> <span data-x="dom-SharedWorker-port">port</span>;
};

dictionary <dfn dictionary>SharedWorkerOptions</dfn> : <span>WorkerOptions</span> {
any importMap; // used to prevent passing DedicatedWorkerOptions' importMap option
};

<span>SharedWorker</span> includes <span>AbstractWorker</span>;</code></pre>

<dl class="domintro">
Expand Down Expand Up @@ -121193,7 +121234,7 @@ interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
"<code data-x="">script</code>".</p></li>

<li><p>If <var>options</var> is a <code data-x="idl-DOMString">DOMString</code>, set
<var>options</var> to a new <code>WorkerOptions</code> dictionary whose <code
<var>options</var> to a new <code>SharedWorkerOptions</code> dictionary whose <code
data-x="">name</code> member is set to the value of <var>options</var> and whose other members
are set to their default values.</p></li>

Expand All @@ -121212,6 +121253,9 @@ interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
<li><p>If <var>urlRecord</var> is failure, then throw a <span>"<code>SyntaxError</code>"</span>
<code>DOMException</code>.</p></li>

<li><p>If <var>options</var>'s <code data-x="">importMap</code> member is not undefined, throw
a <code>TypeError</code> exception.</p></li>

<li><p>Let <var>worker</var> be a new <code>SharedWorker</code> object.</p></li>

<li><p>Let <var>outside port</var> be a <span>new</span> <code>MessagePort</code> in <var>outside
Expand Down Expand Up @@ -121338,8 +121382,8 @@ interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
</li>

<li><p>Otherwise, <span>in parallel</span>, <span>run a worker</span> given <var>worker</var>,
<var>urlRecord</var>, <var>outside settings</var>, <var>outside port</var>, and
<var>options</var>.</p></li>
<var>urlRecord</var>, <var>outside settings</var>, <var>outside port</var>, <var>options</var>,
and an <span>empty import map</span>.</p></li>
</ol>
</li>

Expand Down