Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(WIP) Add worker modules
Browse files Browse the repository at this point in the history
jungkees committed Feb 26, 2016
1 parent ae76de0 commit 245f98d
Showing 3 changed files with 384 additions and 271 deletions.
230 changes: 133 additions & 97 deletions spec/service_worker/index.bs
Original file line number Diff line number Diff line change
@@ -187,19 +187,35 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
urlPrefix: interaction.html
text: has focus steps
urlPrefix: webappapis.html
text: classic script
text: creation url
text: dom manipulation task source
text: fetch a classic worker script
text: fetch a module script tree
text: fire a simple event
text: https state
text: module script
text: realm execution context
text: report the error
text: run a classic script
text: run a module script
text: script
text: task queue; for: event loop
urlPrefix: workers.html
text: get a fetch result
text: https state
text: import scripts into worker global scope
text: kill a worker
text: postprocess the fetch result
text: runtime script errors handling; url: runtime-script-errors-2
text: shared workers
text: terminate a worker
text: validate the state
text: web worker; url: workers
for: workerglobalscope; urlPrefix: #concept-workerglobalscope-
text: https state
text: type
text: url
type: event
urlPrefix: indices.html
text: DOMContentLoaded; for: Document; url: event-domcontentloaded
@@ -278,10 +294,11 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
<p>A <dfn id="dfn-service-worker">service worker</dfn> is a type of <a>web worker</a>. A <a href="#dfn-service-worker">service worker</a> executes in the registering <a href="#dfn-service-worker-client">service worker client</a>'s <a for="resource">origin</a>.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-state">state</dfn>, which is one of <em>parsed</em>, <em>installing</em>, <em>installed</em>, <em>activating</em>, <em>activated</em>, and <em>redundant</em>. It is initially <em>parsed</em>.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-script-url">script url</dfn> (a <a for="url">URL</a>).</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-execution-type">execution type</dfn> which is either "<code>classic</code>" or "<code>module</code>". Unless stated otherwise, it is "<code>classic</code>".</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-containing-service-worker-registration">containing service worker registration</dfn> (a <a href="#dfn-service-worker-registration">service worker registration</a>), which contains itself.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-service-worker-id">id</dfn> (an opaque string), which uniquely identifies itself during the lifetime of its <a href="#dfn-containing-service-worker-registration">containing service worker registration</a>.</p>
<p>A <a href="#dfn-service-worker">service worker</a> is dispatched a set of <dfn id="dfn-lifecycle-events">lifecycle events</dfn>, <a href="#service-worker-global-scope-install-event">install</a> and <a href="#service-worker-global-scope-activate-event">activate</a>, and <dfn id="dfn-functional-events">functional events</dfn> including <a href="#service-worker-global-scope-fetch-event">fetch</a>.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-script-resource">script resource</dfn>, which represents its own script resource. It is initially set to null. A <a href="#dfn-script-resource">script resource</a> has an associated <dfn id="dfn-has-ever-been-evaluated-flag">has ever been evaluated flag</dfn>. It is initially unset.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-script-resource">script resource</dfn>, which represents its own script resource. It is initially set to null. A <a href="#dfn-script-resource">script resource</a> has an associated <dfn id="dfn-has-ever-been-evaluated-flag">has ever been evaluated flag</dfn>. It is initially unset. A <a href="#dfn-script-resource">script resource</a> has an associated <dfn id="dfn-https-state">HTTPS state</dfn> which is "<code>none</code>", "<code>deprecated</code>", or "<code>modern</code>". Unless stated otherwise, it is "<code>none</code>".</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-script-resource-map">script resource map</dfn> which is a <a>List</a> of the <a>Record</a> {\[[key]], \[[value]]} where \[[key]] is a <a for="url">URL</a> and \[[value]] is a script resource.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-skip-waiting-flag">skip waiting flag</dfn>. Unless stated otherwise it is unset.</p>
<p>A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-imported-scripts-updated-flag">imported scripts updated flag</dfn>. It is initially unset.</p>
@@ -717,6 +734,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
<pre class="idl" id="registration-option-list-dictionary">
dictionary RegistrationOptions {
USVString scope;
WorkerType type = "classic";
};
</pre>

@@ -803,7 +821,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
<li>If <var>scopeURL</var> is failure, reject <var>p</var> with a <code>TypeError</code> and abort these steps.</li>
<li>If <var>scopeURL</var>'s <a for="url">scheme</a> is not one of "<code>http</code>" and "<code>https</code>", reject <var>p</var> with a <code>TypeError</code> and abort these steps.</li>
<li>If any of the strings in <var>scopeURL</var>'s <a for="url">path</a> contains either <a>ASCII case-insensitive</a> "<code>%2f</code>" or <a>ASCII case-insensitive</a> "<code>%5c</code>", reject <var>p</var> with a <code>TypeError</code> and abort these steps.</li>
<li>Let <var>job</var> be the result of running <a href="#create-job-algorithm">Create Job</a> with <em>register</em>, <var>scopeURL</var>, <var>scriptURL</var>, <var>p</var>, and <var>client</var>.</li>
<li>Let <var>job</var> be the result of running <a href="#create-job-algorithm">Create Job</a> with <em>register</em>, <var>scopeURL</var>, <var>scriptURL</var>, <var>options</var>.<a href="#dom-registrationoptions-type">type</a>, <var>p</var>, and <var>client</var>.</li>
<li>Run the following substep <a>in parallel</a>:
<ol>
<li>Invoke <a href="#schedule-job-algorithm">Schedule Job</a> with <var>job</var>.</li>
@@ -2760,6 +2778,8 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/

<P>A <a href="#dfn-job">job</a> has a <dfn id="dfn-job-script-url">script url</dfn> (a <a for="url">URL</a>).</P>

<P>A <a href="#dfn-job">job</a> has a <dfn id="dfn-job-worker-execution-type">worker execution type</dfn> ("<code>classic</code>" or "<code>module</code>").</P>

<P>A <a href="#dfn-job">job</a> has a <dfn id="dfn-job-client">client</dfn> (a <a href="#dfn-service-worker-client">service worker client</a>). It is initially null.</P>

<P>A <a href="#dfn-job">job</a> has a <dfn id="dfn-job-promise" lt="job promise">promise</dfn> (a <a>promise</a>). It is initially null.</P>
@@ -2785,6 +2805,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
<dd><var>jobType</var>, a <a href="#dfn-job-type">job type</a></dd>
<dd><var>scopeURL</var>, a <a for="url">URL</a></dd>
<dd><var>scriptURL</var>, a <a for="url">URL</a></dd>
<dd><var>workerExecutionType</var>, "<code>classic</code>" or "<code>module</code>"</dd>
<dd><var>promise</var>, a <a>promise</a></dd>
<dd><var>client</var>, a <a href="#dfn-service-worker-client">service worker client</a></dd>
<dt>Output</dt>
@@ -2795,6 +2816,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
<li>Set <var>job</var>'s <a href="#dfn-job-type">job type</a> to <var>jobType</var>.</li>
<li>Set <var>job</var>'s <a href="#dfn-job-scope-url">scope url</a> to <var>scopeURL</var>.</li>
<li>Set <var>job</var>'s <a href="#dfn-job-script-url">script url</a> to <var>scriptURL</var>.</li>
<li>Set <var>job</var>'s <a href="#dfn-job-worker-execution-type">worker execution type</a> to <var>workerExecutionType</var>.</li>
<li>Set <var>job</var>'s <a href="#dfn-job-promise">promise</a> to <var>promise</var>.</li>
<li>Set <var>job</var>'s <a href="#dfn-job-client">client</a> to <var>client</var>.</li>
<li>Return <var>job</var>.</li>
@@ -3008,95 +3030,99 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
</li>
<li>Let <var>newestWorker</var> be the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm passing <var>registration</var> as the argument.</li>
<li>If <var>job</var>'s <a href="#dfn-job-type">job type</a> is <em>update</em>, and <var>newestWorker</var>'s <a href="#dfn-script-url">script url</a> is not <var>job</var>'s <a href="#dfn-job-script-url">script url</a>, invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var>.</li>
<li>Let <var>r</var> be the associated <a for="request">request</a> of the result of invoking the initial value of {{Request}} as constructor with <var>job</var>'s <a for="url">serialized</a> <a href="#dfn-job-script-url">script url</a>. If this <a>throws</a> an exception, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and the exception.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>Set <var>r</var>'s <a for="request">initiator</a> to "" and <a for="request">destination</a> to "<code>serviceworker</code>".</li>
<li>Set <var>r</var>'s <a for="request">client</a> to <var>job</var>'s <a href="#dfn-job-client">client</a>.</li>
<li>Append `<code>Service-Worker</code>`/`<code>script</code>` to <var>r</var>'s <a for="request">header list</a>.
<p class="note">See the definition of the Service-Worker header in Appendix B: Extended HTTP headers.</p>
</li>
<li>Set <var>r</var>'s <a>skip service worker flag</a>, <var>r</var>'s <a>synchronous flag</a>, and <var>r</var>'s <a>redirect mode</a> to "<code>manual</code>".</li>
<li>If <var>newestWorker</var> is not null and <var>registration</var>'s <a href="#dfn-last-update-check-time">last update check time</a> is not null, then:
<ol>
<li>If the time difference in seconds calculated by the current time minus <var>registration</var>'s <a href="#dfn-last-update-check-time">last update check time</a> is greater than 86400, or <em>force bypass cache flag</em> is set, set <var>r</var>'s <a>cache mode</a> to "<code>reload</code>".</li>
</ol>
<p class="note">Even if the cache mode is not set to "reload", the user agent obeys Cache-Control header's max-age value in the network layer to determine if it should bypass the browser cache.</p>
</li>
<li>Let <var>response</var> be the result of running <a>fetch</a> using <var>r</var>.</li>
<li>If <var>response</var> is a <a>network error</a> or <var>response</var>'s <a for="response">status</a> is not in the range 200 to 299, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a <code>TypeError</code>.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li><a>Extract a MIME type</a> from the <var>response</var>'s <a for="response">header list</a>. If this MIME type (ignoring parameters) is not one of <code>text/javascript</code>, <code>application/x-javascript</code>, and <code>application/javascript</code>, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a "{{SecurityError}}" exception.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>Let <var>serviceWorkerAllowed</var> be the result of <a for="header">parsing</a> `<code>Service-Worker-Allowed</code>` in <var>response</var>'s <a for="response">header list</a>.
<p class="note">See the definition of the Service-Worker-Allowed header in Appendix B: Extended HTTP headers.</p>
</li>
<li>If <var>serviceWorkerAllowed</var> is failure, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a <code>TypeError</code>.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>Let <var>scopeURL</var> be <var>registration</var>'s <a href="#dfn-scope-url">scope url</a>.</li>
<li>Let <var>maxScopeString</var> be null.</li>
<li>If <var>serviceWorkerAllowed</var> is null, then:
<ol>
<li>Set <var>maxScopeString</var> to "<code>/</code>" concatenated with the strings, except the last string that denotes the script's file name, in <var>job</var>'s <a href="#dfn-job-script-url">script url</a>'s <a for="url">path</a> (including empty strings), separated from each other by "<code>/</code>".</li>
</ol>
</li>
<li>Else:
<ol>
<li>Let <var>maxScope</var> be the result of <a for="url">parsing</a> <var>serviceWorkerAllowed</var> with <var>job</var>'s <a href="#dfn-job-script-url">script url</a>.</li>
<li>Set <var>maxScopeString</var> to "<code>/</code>" concatenated with the strings in <var>maxScope</var>'s <a for="url">path</a> (including empty strings), separated from each other by "<code>/</code>".</li>
</ol>
</li>
<li>Let <var>scopeString</var> be "<code>/</code>" concatenated with the strings in <var>scopeURL</var>'s <a for="url">path</a> (including empty strings), separated from each other by "<code>/</code>".</li>
<li>If <var>scopeString</var> starts with <var>maxScopeString</var>, do nothing.</li>
<li>Else:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a "{{SecurityError}}" exception.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>If <var>response</var>'s <a for="response">cache state</a> is not "<code>local</code>", set <var>registration</var>'s <a href="#dfn-last-update-check-time">last update check time</a> to the current time.</li>
<li>If <var>newestWorker</var> is not null, <var>newestWorker</var>'s <a href="#dfn-script-url">script url</a> <a for="url">equals</a> <var>job</var>'s <a href="#dfn-job-script-url">script url</a> with the <em>exclude fragments flag</em> set, and <var>response</var> is a byte-for-byte match with the script resource of <var>newestWorker</var>, then:
<li>Switching on <var>job</var>'s <a>worker execution type</a>, run the following steps with the following options:
<dl>
<dt><em>"<code>classic</code>"</em></dt>
<dd><p><a>Fetch a classic worker script</a> given <var>job</var>’s <a>serialized</a> <a>script url</a>, <var>job</var>’s <a href="#dfn-job-client">client</a>, and "<code>serviceworker</code>".</p></dd>
<dt><em>"<code>module</code>"</em></dt>
<dd><p><a>Fetch a module script tree</a> given <var>job</var>’s <a>serialized</a> <a>script url</a>, "<code>omit</code>", "<code>serviceworker</code>", and <var>job</var>’s <a href="#dfn-job-client">client</a>.</p></dd>
</dl>
<p>To <a>set up the request</a> given <var>request</var>, run the following steps:</p>
<ol>
<li>Invoke <a href="#resolve-job-promise-algorithm">Resolve Job Promise</a> with <var>job</var> and the {{ServiceWorkerRegistration}} object, setting its <a href="#dfn-service-worker-registration-interface-client">service worker client</a> to <var>job</var>'s <a href="#dfn-job-client">client</a>, which represents <var>registration</var>.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
<li>Append `<code>Service-Worker</code>`/`<code>script</code>` to <var>request</var>'s <a for="request">header list</a>.
<p class="note">See the definition of the Service-Worker header in Appendix B: Extended HTTP headers.</p>
</li>
<li>Set <var>request</var>'s <a>skip service worker flag</a> and <var>request</var>'s <a>redirect mode</a> to "<code>manual</code>".</li>
<li>If <var>newestWorker</var> is not null and <var>registration</var>'s <a href="#dfn-last-update-check-time">last update check time</a> is not null, then:
<ol>
<li>If the time difference in seconds calculated by the current time minus <var>registration</var>'s <a href="#dfn-last-update-check-time">last update check time</a> is greater than 86400, or <em>force bypass cache flag</em> is set, set <var>request</var>'s <a>cache mode</a> to "<code>reload</code>".</li>
</ol>
<p class="note">Even if the cache mode is not set to "reload", the user agent obeys Cache-Control header's max-age value in the network layer to determine if it should bypass the browser cache.</p>
</li>
</ol>
</li>
<li>Else:
<p>To <a>validate the response</a> given <var>response</var>, run the following steps:</p>
<ol>
<li>Let <var>worker</var> be a new <a href="#dfn-service-worker">service worker</a>.</li>
<li>Generate a unique opaque string and set <var>worker</var>'s <a href="#dfn-service-worker-id">id</a> to the value.</li>
<li>Set <var>worker</var>'s <a href="#dfn-script-url">script url</a> to <var>job</var>'s <a href="#dfn-job-script-url">script url</a>, <var>worker</var>'s <a href="#dfn-script-resource">script resource</a> to the script resource retrieved from the fetched <var>response</var>.</li>
<li>Invoke <a href="#run-service-worker-algorithm">Run Service Worker</a> algorithm with <var>worker</var> as the argument.</li>
<li>If an uncaught runtime script error occurs during the above step, then:
<li>If <var>response</var>'s <a>type</a> is "<code>error</code>" or <var>response</var>'s <a for="response">status</a> is not an <a href="https://fetch.spec.whatwg.org/#ok-status">ok status</a>, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a <code>TypeError</code>.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li><a>Extract a MIME type</a> from the <var>response</var>'s <a for="response">header list</a>. If this MIME type (ignoring parameters) is not one of <code>text/javascript</code>, <code>application/x-javascript</code>, and <code>application/javascript</code>, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a "{{SecurityError}}" exception.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>Let <var>serviceWorkerAllowed</var> be the result of <a for="header">parsing</a> `<code>Service-Worker-Allowed</code>` in <var>response</var>'s <a for="response">header list</a>.
<p class="note">See the definition of the Service-Worker-Allowed header in Appendix B: Extended HTTP headers.</p>
</li>
<li>If <var>serviceWorkerAllowed</var> is failure, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a <code>TypeError</code>.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>Let <var>scopeURL</var> be <var>registration</var>'s <a href="#dfn-scope-url">scope url</a>.</li>
<li>Let <var>maxScopeString</var> be null.</li>
<li>If <var>serviceWorkerAllowed</var> is null, then:
<ol>
<li>Set <var>maxScopeString</var> to "<code>/</code>" concatenated with the strings, except the last string that denotes the script's file name, in <var>job</var>'s <a href="#dfn-job-script-url">script url</a>'s <a for="url">path</a> (including empty strings), separated from each other by "<code>/</code>".</li>
</ol>
</li>
<li>Else:
<ol>
<li>Let <var>maxScope</var> be the result of <a for="url">parsing</a> <var>serviceWorkerAllowed</var> with <var>job</var>'s <a href="#dfn-job-script-url">script url</a>.</li>
<li>Set <var>maxScopeString</var> to "<code>/</code>" concatenated with the strings in <var>maxScope</var>'s <a for="url">path</a> (including empty strings), separated from each other by "<code>/</code>".</li>
</ol>
</li>
<li>Let <var>scopeString</var> be "<code>/</code>" concatenated with the strings in <var>scopeURL</var>'s <a for="url">path</a> (including empty strings), separated from each other by "<code>/</code>".</li>
<li>If <var>scopeString</var> starts with <var>maxScopeString</var>, do nothing.</li>
<li>Else:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a "{{SecurityError}}" exception.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>If <var>response</var>'s <a for="response">cache state</a> is not "<code>local</code>", set <var>registration</var>'s <a href="#dfn-last-update-check-time">last update check time</a> to the current time.</li>
<li>If <var>newestWorker</var> is not null, <var>newestWorker</var>'s <a href="#dfn-script-url">script url</a> <a for="url">equals</a> <var>job</var>'s <a href="#dfn-job-script-url">script url</a> with the <em>exclude fragments flag</em> set, and <var>response</var> is a byte-for-byte match with the script resource of <var>newestWorker</var>, then:
<ol>
<li>Invoke <a href="#resolve-job-promise-algorithm">Resolve Job Promise</a> with <var>job</var> and the {{ServiceWorkerRegistration}} object, setting its <a href="#dfn-service-worker-registration-interface-client">service worker client</a> to <var>job</var>'s <a href="#dfn-job-client">client</a>, which represents <var>registration</var>.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
<li>Else:
<ol>
<li>Let <var>worker</var> be a new <a href="#dfn-service-worker">service worker</a>.</li>
<li>Generate a unique opaque string and set <var>worker</var>'s <a href="#dfn-service-worker-id">id</a> to the value.</li>
<li>Set <var>worker</var>'s <a href="#dfn-script-url">script url</a> to <var>job</var>'s <a href="#dfn-job-script-url">script url</a>, <var>worker</var>'s <a href="#dfn-script-resource">script resource</a> to the script resource retrieved from the fetched <var>response</var>, and <var>worker</var>'s <a href="#dfn-execution-type">execution type</a> to <var>job</var>'s <a>worker execution type</a>.</li>
<li>Invoke <a href="#run-service-worker-algorithm">Run Service Worker</a> algorithm with <var>worker</var> as the argument.</li>
<li>If an uncaught runtime script error occurs during the above step, then:
<ol>
<li>Invoke <a href="#reject-job-promise-algorithm">Reject Job Promise</a> with <var>job</var> and a <code>TypeError</code>.</li>
<li>If <var>newestWorker</var> is null, invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
<li>Invoke <a href="#finish-job-algorithm">Finish Job</a> with <var>job</var> and abort these steps.</li>
</ol>
</li>
</ol>
</li>
<li>Invoke <a href="#installation-algorithm">Install</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>job</var>, <var>worker</var>, and <var>registration</var> as its arguments.</li>
</ol>
</li>
<li>Invoke <a href="#installation-algorithm">Install</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>job</var>, <var>worker</var>, and <var>registration</var> as its arguments.</li>
</ol>
</section>

@@ -3285,45 +3311,55 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
<dd>None</dd>
</dl>
<ol>
<li>Assert: <var>serviceWorker</var> has the script resource successfully fetched against its <a href="#dfn-script-url">script url</a>.</li>
<li>Let <var>script</var> be <var>serviceWorker</var>'s <a for="service worker">script resource</a>.</li>
<li>Assert: <var>script</var> is not null.</li>
<li>If <var>serviceWorker</var> is already running, abort these steps.</li>
<li>Let <var>workerGlobalScope</var> be a new {{ServiceWorkerGlobalScope}} object.</li>
<li>Create a separate parallel execution environment (i.e. a separate thread or process or equivalent construct), and run the rest of these steps in that context.</li>
<li>Call the JavaScript <a href="https://tc39.github.io/ecma262/#sec-initializehostdefinedrealm">InitializeHostDefinedRealm()</a> abstract operation with the following customizations:
<ul>
<li>For the global object, create a new {{ServiceWorkerGlobalScope}} object. Let <var>workerGlobalScope</var> be the created object.</li>
<li>Let <var>realmExecutionContext</var> be the created <a href="https://tc39.github.io/ecma262/#sec-execution-contexts">JavaScript execution context</a>.</li>
</ul>
</li>
<li>Let <var>workerEventLoop</var> be a newly created <a>event loop</a>.</li>
<li>If <var>serviceWorker</var> is an <a href="#dfn-active-worker">active worker</a>, and there are any <a>tasks</a> queued in <var>serviceWorker</var>'s <a href="#dfn-containing-service-worker-registration">containing service worker registration</a>'s <a href="#dfn-service-worker-registration-task-queue">task queues</a>, <a lt="queue a task">queue</a> them to <var>serviceWorker</var>'s <a>event loop</a>'s <a for="event loop">task queues</a> in the same order using their original <a>task sources</a>.</li>
<li>Let <var>workerGlobalScope</var> be <var>realmExecutionContext</var>'s <a>global object</a>.</li>
<li>Let <var>settingsObject</var> be a new <a>environment settings object</a> whose algorithms are defined as follows:
<dl>
<dt>The <a>script execution environments</a></dt>
<dd>When the <a>environment settings object</a> is created, for each language supported by the user agent, create an appropriate execution environment as defined by the relevant specification.</dd>
<dd>When a <a>script execution environment</a> is needed, return the appropriate one from those created when the <a>environment settings object</a> was created.</dd>
<dt>The <a>realm execution context</a></dt>
<dd>Return <var>realmExecutionContext</var>.</dd>
<dt>The <a>global object</a></dt>
<dd>Return <var>workerGlobalScope</var>.</dd>
<dt>The <a>responsible event loop</a></dt>
<dd>Return <var>workerEventLoop</var>.</dd>
<dt>The <a>referrer source</a></dt>
<dd>Return <var>serviceWorker</var>'s <a href="#dfn-script-url">script url</a>.</dd>
<p class="issue">Remove this definition after sorting out the referencing sites.</p>
<dt>The <a>API URL character encoding</a></dt>
<dd>Return UTF-8.</dd>
<dt>The <a>API base URL</a></dt>
<dd>Return <var>serviceWorker</var>'s <a href="#dfn-script-url">script url</a>.</dd>
<dt>The <a for="resource">origin</a> and <a>effective script origin</a></dt>
<dd>Return its registering <a href="#dfn-service-worker-client">service worker client</a>'s <a for="resource">origin</a>.</dd>
<dt>The <a>creation URL</a></dt>
<dd>Return <var>workerGlobalScope</var>'s <a for="workerglobalscope">url</a>.</dd>
<dt>The <a>HTTPS state</a></dt>
<dd>Return <var>workerGlobalScope</var>'s <a for="workerglobalscope">HTTPS state</a>.</dd>
</dl>
</li>
<li>Create a separate parallel execution environment (i.e. a separate thread or process or equivalent construct), and run the rest of these steps in that context.</li>
<li>Let <var>source</var> be the result of running the <a>UTF-8 decode</a> algorithm on <var>serviceWorker</var>'s <a href="#dfn-script-resource">script resource</a> <var>scriptResource</var>.</li>
<li>Let <var>language</var> be JavaScript.</li>
<li>In the newly created execution environment, create a <a>JavaScript global environment</a> whose <em>global object</em> is <var>workerGlobalScope</var>. (The <a>JavaScript global environment</a> whose <em>global object</em> is a {{ServiceWorkerGlobalScope}} object is defined as the <dfn id="service-worker-environment">service worker environment</dfn>, which is a type of <a>worker environments</a>.)</li>
<li>Let <var>script</var> be a new <a>script</a>.</li>
<li>Obtain the appropriate <a>script execution environment</a> for the scripting language <var>language</var> from <var>settingsObject</var>.</li>
<li>Parse/compile/initialize <var>source</var> using that <a>script execution environment</a>, as appropriate for <var>language</var>, and thus obtain a <a>code entry-point</a>. If the script was not compiled successfully, let the <a>code entry-point</a> be a no-op script, and act as if a corresponding uncaught script error had occurred.</li>
<li>Let <var>script</var>'s <a>settings object</a> be <var>settingsObject</var>.</li>
<li><a lt="jump to a code entry point">Jump</a> to the <var>script</var>'s <a>code entry-point</a>, and let that run until it either returns, fails to catch an exception, or gets aborted by the <a>kill a worker</a> or <a href="#terminate-service-worker-algorithm">Terminate Service Worker</a> algorithms.</li>
<li>If <var>scriptResource</var>'s <a href="#dfn-has-ever-been-evaluated-flag">has ever been evaluated flag</a> is unset, then:
<li>Set <var>workerGlobalScope</var>'s <a for="workerglobalscope">url</a> to <var>serviceWorker</var>'s <a href="#dfn-script-url">script url</a>.</li>
<li>Set <var>workerGlobalScope</var>'s <a for="workerglobalscope">HTTPS state</a> to <var>serviceWorker</var>'s <a>script resource</a>'s <a href="#dfn-https-state">HTTPS state</a>.</li>
<li>Set <var>workerGlobalScope</var>'s <a for="workerglobalscope">type</a> to <var>serviceWorker</var>'s <a>execution type</a>.</li>
<li>Create a new {{WorkerLocation}} object and associate it with <var>workerGlobalScope</var>.</li>
<li>If <var>serviceWorker</var> is an <a href="#dfn-active-worker">active worker</a>, and there are any <a>tasks</a> queued in <var>serviceWorker</var>'s <a href="#dfn-containing-service-worker-registration">containing service worker registration</a>'s <a href="#dfn-service-worker-registration-task-queue">task queues</a>, <a lt="queue a task">queue</a> them to <var>serviceWorker</var>'s <a>event loop</a>'s <a for="event loop">task queues</a> in the same order using their original <a>task sources</a>.</li>
<li>If <var>script</var> is a <a>classic script</a>, then <a lt="run a classic script">run the classic script</a> <var>script</var>. Otherwise, it is a <a>module script</a>; <a lt="run a module script">run the module script</a> <var>script</var>.
<p class="note">In addition to the usual possibilities of returning a value or failing due to an exception, this could be prematurely aborted by the <a>kill a worker</a> or <a>terminate a worker</a> algorithms.</p>
</li>
<li>If <var>script</var>'s <a href="#dfn-has-ever-been-evaluated-flag">has ever been evaluated flag</a> is unset, then:
<ol>
<li>Set <var>workerGlobalScope</var>'s associated <a href="#dfn-service-worker-global-scope-service-worker">service worker</a>'s <a href="#dfn-set-of-event-types-to-handle">set of event types to handle</a> to the set of event types created from <var>settingsObject</var>'s <a>global object</a>'s associated list of <a>event listeners</a>' event types.
<p class="note">If the global object's associated list of event listeners does not have any event listener added at this moment, the service worker's set of event types to handle is set to an empty set. The user agents are encouraged to show a warning that the event listeners must be added on the very first evaluation of the worker script.</p>
</li>
<li>Set <var>scriptResource</var>'s <a href="#dfn-has-ever-been-evaluated-flag">has ever been evaluated flag</a>.</li>
<li>Set <var>script</var>'s <a href="#dfn-has-ever-been-evaluated-flag">has ever been evaluated flag</a>.</li>
</ol>
</li>
<li>Run the <a>responsible event loop</a> specified by <var>settingsObject</var> until it is destroyed.</li>
332 changes: 194 additions & 138 deletions spec/service_worker/index.html

Large diffs are not rendered by default.

93 changes: 57 additions & 36 deletions spec/service_worker_1/index.html

Large diffs are not rendered by default.

0 comments on commit 245f98d

Please sign in to comment.