Skip to content

Commit

Permalink
Editorial: refactor modules to use Infra Standard data structures
Browse files Browse the repository at this point in the history
Part of #2053.
  • Loading branch information
domenic authored and annevk committed Nov 17, 2016
1 parent 4ac633e commit 37ea5ac
Showing 1 changed file with 86 additions and 64 deletions.
150 changes: 86 additions & 64 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2395,6 +2395,19 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<p>The following terms are defined in the WHATWG Infra standard: <ref spec=INFRA></p>

<ul class="brief">
<li>The <dfn data-x-href="https://infra.spec.whatwg.org/#ordered-map">ordered map</dfn> data structure and the associated definitions for
<dfn data-x="map exists" data-x-href="https://infra.spec.whatwg.org/#map-exists">exists</dfn>,
<dfn data-x="map get" data-x-href="https://infra.spec.whatwg.org/#map-get">getting the value of an entry</dfn>, and
<dfn data-x="map set" data-x-href="https://infra.spec.whatwg.org/#map-set">setting the value of an entry</dfn></li>
<li>The <dfn data-x-href="https://infra.spec.whatwg.org/#list">list</dfn> data structure and the associated definitions for
<dfn data-x="list is empty" data-x-href="https://infra.spec.whatwg.org/#list-is-empty">is empty</dfn>,
<dfn data-x="list contains" data-x-href="https://infra.spec.whatwg.org/#list-contains">contains</dfn>,
<dfn data-x="list append" data-x-href="https://infra.spec.whatwg.org/#list-append">append</dfn>, and
<dfn data-x="list iterate" data-x-href="https://infra.spec.whatwg.org/#list-iterate">iterate</dfn></li>
<li>The <dfn data-x-href="https://infra.spec.whatwg.org/#stack">stack</dfn> data structure and the associated definitions for
<dfn data-x="stack push" data-x-href="https://infra.spec.whatwg.org/#stack-push">push</dfn> and
<dfn data-x="stack pop" data-x-href="https://infra.spec.whatwg.org/#stack-pop">pop</dfn></li>
<li>The <dfn data-x="set" data-x-href="https://infra.spec.whatwg.org/#ordered-set">ordered set</dfn> data structure</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>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#svg-namespace">SVG namespace</dfn></li>
Expand Down Expand Up @@ -2859,7 +2872,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>The <dfn data-x="js-prod-Script" data-x-href="https://tc39.github.io/ecma262/#prod-Script"><i>Script</i></dfn> production</li>

<li>The <dfn data-x="js-Type" data-x-href="https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values">Type</dfn> notation</li>
<li>The <dfn data-x-href="https://tc39.github.io/ecma262/#sec-list-and-record-specification-type">List</dfn> and
<li>The <dfn data-x="js-List" data-x-href="https://tc39.github.io/ecma262/#sec-list-and-record-specification-type">List</dfn> and
<dfn data-x-href="https://tc39.github.io/ecma262/#sec-list-and-record-specification-type">Record</dfn> specification types</li>
<li>The <dfn data-x="PropertyDescriptor" data-x-href="https://tc39.github.io/ecma262/#sec-property-descriptor-specification-type">Property Descriptor</dfn> specification type</li>
<li>The <dfn data-x-href="https://tc39.github.io/ecma262/#sec-source-text-module-records">Source Text Module Record</dfn> specification type and its
Expand Down Expand Up @@ -7763,7 +7776,7 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20html%3E.
<span>StructuredClone</span>(<var>input</var>, <var>targetRealm</var>,
<var>memory</var>).</p></li>

<li><p>Let <var>outputTransferList</var> be a new empty <span>List</span>.</p></li>
<li><p>Let <var>outputTransferList</var> be a new empty <span data-x="js-List">List</span>.</p></li>

<li>
<p>For each object <var>transferable</var> in <var>transferList</var>:
Expand Down Expand Up @@ -7904,7 +7917,7 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20html%3E.

<ol>
<li><p>Let <var>output</var> be a new Map object in <var>targetRealm</var> whose [[MapData]]
internal slot value is a new empty <span>List</span>.</p></li>
internal slot value is a new empty <span data-x="js-List">List</span>.</p></li>

<li><p>Set <var>deepClone</var> to true.</p></li>
</ol>
Expand All @@ -7915,7 +7928,7 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20html%3E.

<ol>
<li><p>Let <var>output</var> be a new Set object in <var>targetRealm</var> whose [[SetData]]
internal slot value is a new empty <span>List</span>.</p></li>
internal slot value is a new empty <span data-x="js-List">List</span>.</p></li>

<li><p>Set <var>deepClone</var> to true.</p></li>
</ol>
Expand Down Expand Up @@ -7985,7 +7998,7 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20html%3E.
<li><p>Let <var>inputList</var> the value of <var>input</var>'s [[MapData]] internal
slot.</p></li>

<li><p>Let <var>copiedList</var> be a new empty <span>List</span>.
<li><p>Let <var>copiedList</var> be a new empty <span data-x="js-List">List</span>.

<li>
<p>Repeat for each <span>Record</span> { [[Key]], [[Value]] } <var>entry</var> that is an
Expand Down Expand Up @@ -8050,7 +8063,8 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20html%3E.
<p>Otherwise:

<ol>
<li><p>Let <var>enumerableKeys</var> be a new empty <span>List</span>.</p></li>
<li><p>Let <var>enumerableKeys</var> be a new empty <span
data-x="js-List">List</span>.</p></li>

<li>
<p>For each <var>key</var> in ! <var>input</var>.[[OwnPropertyKeys]]():</p>
Expand Down Expand Up @@ -78221,7 +78235,7 @@ console.assert(iframeWindow.frameElement === null);
<h5><dfn>CrossOriginOwnPropertyKeys</dfn> ( <var>O</var> )</h5>

<ol>
<li><p>Let <var>keys</var> be a new empty <span>List</span>.</p></li>
<li><p>Let <var>keys</var> be a new empty <span data-x="js-List">List</span>.</p></li>

<li>
<p>Repeat for each <var>e</var> that is an element of
Expand Down Expand Up @@ -79243,7 +79257,7 @@ callback <dfn>FrameRequestCallback</dfn> = void (<span>DOMHighResTimeStamp</span
[[<span data-x="concept-windowproxy-window">Window</span>]] internal slot of
<b>this</b>.</p></li>

<li><p>Let <var>keys</var> be a new empty <span>List</span>.</p></li>
<li><p>Let <var>keys</var> be a new empty <span data-x="js-List">List</span>.</p></li>

<li><p>Let <var>maxProperties</var> be the <span>number of document-tree child browsing
contexts</span> of <var>W</var>.</p></li>
Expand Down Expand Up @@ -86760,58 +86774,63 @@ interface <dfn>NavigatorOnLine</dfn> {
</ol>

<p>In the above algorithm, a <span>module script</span> <var>script</var>'s <dfn>uninstantiated
inclusive descendant module scripts</dfn> is a set of <span data-x="module script">module
scripts</span> determined as follows:</p>
inclusive descendant module scripts</dfn> is a <span>set</span> of <span
data-x="module script">module scripts</span> determined as follows:</p>

<ol>
<li><p>Let <var>module map</var> be <var>script</var>'s <span>settings object</span>'s
<li><p>Let <var>moduleMap</var> be <var>script</var>'s <span>settings object</span>'s
<span data-x="concept-settings-object-module-map">module map</span>.</p></li>

<li><p>Let <var>stack</var> be a list containing <var>script</var>.</p></li>
<li><p>Let <var>stack</var> be the <span>stack</span> « <var>script</var> ».</p></li>

<li><p>Let <var>inclusive descendants</var> be an empty set.</p></li>
<li><p>Let <var>inclusive descendants</var> be an empty <span>set</span>.</p></li>

<li>
<p>While <var>stack</var> is not empty:</p>
<p>While <var>stack</var> <span data-x="list is empty">is not empty</span>:</p>

<ol>
<li><p>Let <var>current</var> be the last element of <var>stack</var>. Remove it from
<li><p>Let <var>current</var> the result of <span data-x="stack pop">popping</span> from
<var>stack</var>.</p></li>

<li>
<p>If <var>current</var> is not in <var>inclusive descendants</var> and is not in
<var>stack</var>, then:</p>
<p>If <var>inclusive descendants</var> and <var>stack</var> both do not <span
data-x="list contains">contain</span> <var>current</var>, then:</p>

<ol>
<li><p>Add <var>current</var> to <var>inclusive descendants</var>.</p></li>
<li><p><span data-x="list append">Append</span> <var>current</var> to
<var>inclusive descendants</var>.</p></li>

<li><p>Let <var>child specifiers</var> be the value of <var>current</var>'s <span
data-x="concept-module-script-module-record">module record</span>'s [[RequestedModules]]
internal slot.</p></li>

<li><p>Let <var>child URLs</var> be the set obtained by calling <span>resolve a module
specifier</span> once for each element of <var>child specifiers</var>, given
<var>current</var> and that element. Omit any failures.</p></li>
<li><p>Let <var>child URLs</var> be the <span>list</span> obtained by calling
<span>resolve a module specifier</span> once for each item of <var>child specifiers</var>,
given <var>current</var> and that item. Omit any failures.</p></li>

<li><p>Let <var>child modules</var> be the set obtained by looking up each value in
<var>module map</var> whose key is given by an element of <var>child URLs</var>.</p></li>
<li><p>Let <var>child modules</var> be the <span>list</span> obtained by <span
data-x="map get">getting each value</span> in <var>moduleMap</var> whose key is given by an
item of <var>child URLs</var>.</p></li>

<li><p>For each <var>s</var> in <var>child modules</var> that is not in <var>inclusive
descendants</var>, add <var>s</var> to <var>stack</var>.</p></li>
<li><p><span data-x="list iterate">For each</span> <var>s</var> in <var>child modules</var>
that is not <span data-x="list contains">contained by</span> <var>inclusive
descendants</var>, <span data-x="stack push">push</span> <var>s</var> onto
<var>stack</var>.</p></li>
</ol>
</li>
</ol>
</li>

<li><p>Return a list containing all elements of <var>inclusive descendants</var> whose <span
data-x="concept-module-script-instantiation-state">instantiation state</span> is "<code
<li><p>Return a <span>set</span> containing all items of <var>inclusive descendants</var> whose
<span data-x="concept-module-script-instantiation-state">instantiation state</span> is "<code
data-x="">uninstantiated</code>".</p></li>
</ol>

<p class="note">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 an unordered set.</p>
that the output is a <span>set</span> only used for membership testing and whose order is thus not
important.</p>

<p>To <dfn>fetch a single module script</dfn>, given a <var>url</var>, a <var>fetch client
settings object</var>, a <var>destination</var>, a <var>cryptographic nonce</var>, a <var>parser
Expand All @@ -86821,17 +86840,18 @@ interface <dfn>NavigatorOnLine</dfn> {
success).</p>

<ol>
<li><p>Let <var>module map</var> be <var>module map settings object</var>'s <span
<li><p>Let <var>moduleMap</var> be <var>module map settings object</var>'s <span
data-x="concept-settings-object-module-map">module map</span>.</p></li>

<li><p>If <var>module map</var> contains an entry with key <var>url</var> whose value is "<code
data-x="">fetching</code>", wait (<span>in parallel</span>) until that entry's value changes,
then proceed to the next step.</p></li>
<li><p>If <var>moduleMap</var>[<var>url</var>] is "<code data-x="">fetching</code>", wait
(<span>in parallel</span>) until that entry's value changes, then proceed to the next
step.</p></li>

<li><p>If <var>module map</var> contains an entry with key <var>url</var>, asynchronously
complete this algorithm with that entry's value, and abort these steps.</p></li>
<li><p>If <var>moduleMap</var>[<var>url</var>] <span data-x="map exists">exists</span>,
asynchronously complete this algorithm with <var>moduleMap</var>[<var>url</var>], and abort these
steps.</p></li>

<li><p>Create an entry in <var>module map</var> with key <var>url</var> and value "<code
<li><p><span data-x="map set">Set</span> <var>moduleMap</var>[<var>url</var>] to "<code
data-x="">fetching</code>".</p>

<li><p>Let <var>request</var> be a new <span data-x="concept-request">request</span> whose
Expand Down Expand Up @@ -86864,9 +86884,9 @@ interface <dfn>NavigatorOnLine</dfn> {
</li>

<li>
<p>If any of the following conditions are met, set the value of the entry in <var>module
map</var> whose key is <var>url</var> to null, asynchronously complete this algorithm with
null, and abort these steps:</p>
<p>If any of the following conditions are met, <span data-x="map set">set</span>
<var>moduleMap</var>[<var>url</var>] to null, asynchronously complete this algorithm with null,
and abort these steps:</p>

<ul class="compact">
<li><p><var>response</var>'s <span data-x="concept-response-type">type</span> is "<code
Expand Down Expand Up @@ -86896,9 +86916,8 @@ interface <dfn>NavigatorOnLine</dfn> {
nonce</var>, <var>parser state</var>, and <var>credentials mode</var>.</p></li>

<li>
<p>Set the value of the entry in <var>module map</var> whose key is <var>url</var> to
<var>module script</var>, and asynchronously complete this algorithm with <var>module
script</var>.</p>
<p><span data-x="map set">Set</span> <var>moduleMap</var>[<var>url</var>] to <var>module
script</var>, and asynchronously complete this algorithm with <var>module script</var>.</p>

<p class="note">It is intentional that the <span>module map</span> is keyed by the <span
data-x="concept-request-url">request URL</span>, whereas the <span
Expand All @@ -86917,13 +86936,14 @@ interface <dfn>NavigatorOnLine</dfn> {
<li><p>Let <var>record</var> be <var>module script</var>'s <span
data-x="concept-module-script-module-record">module record</span>.</p></li>

<li><p>If <var>record</var>.[[RequestedModules]] is empty, asynchronously complete this
algorithm with <var>module script</var>.</p></li>
<li><p>If <var>record</var>.[[RequestedModules]] <span data-x="list is empty">is empty</span>,
asynchronously complete this algorithm with <var>module script</var>.</p></li>

<li><p>Let <var>urls</var> be a new empty list.</p></li>
<li><p>Let <var>urls</var> be a new empty <span>list</span>.</p></li>

<li>
<p>For each string <var>requested</var> of <var>record</var>.[[RequestedModules]],</p>
<p><span data-x="list iterate">For each</span> string <var>requested</var> of
<var>record</var>.[[RequestedModules]],</p>

<ol>
<li><p>Let <var>url</var> be the result of <span data-x="resolve a module specifier">resolving
Expand All @@ -86942,19 +86962,20 @@ interface <dfn>NavigatorOnLine</dfn> {
</ol>
</li>

<li><p>Otherwise, if <var>url</var> is not in <var>ancestor list</var>, add <var>url</var> to
<var>urls</var>.</p></li>
<li><p>Otherwise, if <var>ancestor list</var> does not <span
data-x="list contains">contain</span> <var>url</var>, <span data-x="list append">append</span>
<var>url</var> to <var>urls</var>.</p></li>
</ol>
</li>

<li>
<p>For each <var>url</var> in <var>urls</var>, perform the <span>internal module script tree
fetching procedure</span> given <var>url</var>, <var>module script</var>'s <span
data-x="concept-module-script-credentials-mode">credentials mode</span>, <var>module
script</var>'s <span data-x="concept-module-script-nonce">cryptographic nonce</span>,
<var>module script</var>'s <span data-x="concept-module-script-parser">parser state</span>,
<var>destination</var>, <var>module script</var>'s <span>settings object</span>, <var>module
script</var>'s <span>settings object</span>, <var>ancestor list</var>, <var>module
<p><span data-x="list iterate">For each</span> <var>url</var> in <var>urls</var>, perform the
<span>internal module script tree fetching procedure</span> given <var>url</var>, <var>module
script</var>'s <span data-x="concept-module-script-credentials-mode">credentials mode</span>,
<var>module script</var>'s <span data-x="concept-module-script-nonce">cryptographic
nonce</span>, <var>module script</var>'s <span data-x="concept-module-script-parser">parser
state</span>, <var>destination</var>, <var>module script</var>'s <span>settings object</span>,
<var>module script</var>'s <span>settings object</span>, <var>ancestor list</var>, <var>module
script</var>'s <span data-x="concept-module-script-base-url">base URL</span>, and with the
<var>top-level module fetch</var> flag unset. If the caller of this algorithm specified custom
<span data-x="fetching-scripts-perform-fetch">perform the fetch</span> steps, pass those along
Expand Down Expand Up @@ -87881,11 +87902,11 @@ document.querySelector("button").addEventListener("click", bound);
scripts</span> versus <span data-x="module script">module scripts</span>, since both of them use
the <code>script</code> element.</p>

<p>A <dfn>module map</dfn> is a map of <span>absolute URL</span>s to values that are either a
<span>module script</span>, null (used to represent failed fetches), or a placeholder value "<code
data-x="">fetching</code>". <span data-x="module map">Module maps</span> are used to ensure that
imported JavaScript modules are only fetched, parsed, and evaluated once per <code>Document</code>
or <a href="#workers">worker</a>.</p>
<p>A <dfn>module map</dfn> is a <span data-x="ordered map">map</span> of <span data-x="absolute
URL">absolute URLs</span> to values that are either a <span>module script</span>, null (used to
represent failed fetches), or a placeholder value "<code data-x="">fetching</code>". <span
data-x="module map">Module maps</span> are used to ensure that imported JavaScript modules are
only fetched, parsed, and evaluated once per <code>Document</code> or <a href="#workers">worker</a>.</p>

<p>To <dfn>resolve a module specifier</dfn> given a <span>module script</span> <var>script</var>
and a string <var>specifier</var>, perform the following steps. It will return either an
Expand Down Expand Up @@ -87967,16 +87988,17 @@ document.querySelector("button").addEventListener("click", bound);
<li><p>Let <var>referencing module script</var> be
<var>referencingModule</var>.[[HostDefined]].</p></li>

<li><p>Let <var>module map</var> be <var>referencing module script</var>'s <span>settings
<li><p>Let <var>moduleMap</var> be <var>referencing module script</var>'s <span>settings
object</span>'s <span data-x="concept-settings-object-module-map">module map</span>.</p></li>

<li><p>Let <var>url</var> be the result of <span data-x="resolve a module specifier">resolving a
module specifier</span> given <var>referencing module script</var> and <var>specifier</var>. If
the result is failure, throw a <code>TypeError</code> exception and abort these steps.</p></li>
the result is failure, then throw a <code>TypeError</code> exception and abort these
steps.</p></li>

<li><p>Let <var>resolved module script</var> be the value of the entry in <var>module map</var>
whose key is <var>url</var>. If no such entry exists, or if the value is null or "<code
data-x="">fetching</code>", throw a <code>TypeError</code> exception and abort these
<li><p>Let <var>resolved module script</var> be <var>moduleMap</var>[<var>url</var>]. If no such
entry <span data-x="map exists">exists</span>, or if <var>resolved module script</var> is null or
"<code data-x="">fetching</code>", then throw a <code>TypeError</code> exception and abort these
steps.</p></li>

<li><p>If <var>resolved module script</var>'s <span
Expand Down

0 comments on commit 37ea5ac

Please sign in to comment.