/[suikacvs]/markup/html/html5/spec-ja/.workers-spec.en.html
Suika

Contents of /markup/html/html5/spec-ja/.workers-spec.en.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.205 - (hide annotations) (download) (as text)
Tue Jun 1 06:18:20 2010 UTC (15 years, 10 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.204: +4 -2 lines
File MIME type: text/html
make

1 wakaba 1.190 <!DOCTYPE html><html lang=en-US-x-hixie><meta charset=ascii><title>Web Workers</title><link href=/style/specification rel=stylesheet><link href=/images/icon rel=icon><body class=cfc>
2    
3     <header class=head><p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG src=/images/logo></a></p>
4     <hgroup><h1>Web Workers</h1>
5 wakaba 1.205 <h2 class="no-num no-toc">Draft Recommendation &mdash; 1 June 2010</h2>
6 wakaba 1.190 </hgroup><p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
7     <p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
8     <dl><dt>This version:</dt>
9     <dd><a href=http://www.whatwg.org/specs/web-workers/current-work/>http://whatwg.org/ww</a></dd>
10     <dt>Version history:</dt>
11     <dd>Twitter messages (non-editorial changes only): <a href=http://twitter.com/WHATWG>http://twitter.com/WHATWG</a></dd>
12     <dd>Commit-Watchers mailing list: <a href=http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org>http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org</a></dd>
13     <dd>Interactive Web interface: <a href=http://html5.org/tools/web-workers-tracker>http://html5.org/tools/web-workers-tracker</a></dd>
14     <dd>Subversion interface: <a href=http://svn.whatwg.org/webworkers/>http://svn.whatwg.org/webworkers/</a></dd>
15     <dt>Issues:</dt>
16     <dd>To send feedback: <a href=http://www.whatwg.org/mailing-list>whatwg@whatwg.org</a></dd>
17     <dd>To view and vote on feedback: <a href=http://www.whatwg.org/issues/>http://www.whatwg.org/issues/</a></dd>
18     <dt>Editor:</dt>
19     <dd>Ian Hickson, Google, ian@hixie.ch</dd>
20 wakaba 1.195 </dl><p class=copyright>&copy; Copyright 2004-2010 Apple Computer, Inc.,
21 wakaba 1.190 Mozilla Foundation, and Opera Software ASA.</p>
22     <p class=copyright>You are granted a license to use, reproduce
23     and create derivative works of this document.</p>
24     </header><hr><h2 class="no-num no-toc" id=abstract>Abstract</h2>
25    
26     <p>This specification defines an API that allows Web application
27     authors to spawn background workers running scripts in parallel to
28     their main page. This allows for thread-like operation with
29     message-passing as the coordination mechanism.</p>
30    
31    
32     <h2 class="no-num no-toc" id=status>Status of this document</h2>
33    
34     <p><strong>This is a work in progress!</strong> This document is
35     changing on a daily if not hourly basis in response to comments and
36     as a general part of its development process. Comments are very
37     welcome, please send them to <a href=mailto:whatwg@whatwg.org>whatwg@whatwg.org</a>. Thank
38     you.</p>
39    
40     <p>The current focus is in developing a first draft proposal.</p>
41    
42     <p>Implementors should be aware that this specification is not
43     stable. <strong>Implementors who are not taking part in the
44     discussions are likely to find the specification changing out from
45     under them in incompatible ways.</strong> Vendors interested in
46     implementing this specification before it eventually reaches the
47     call for implementations should join the <a href=/mailing-list>WHATWG mailing list</a> and take part in the
48     discussions.</p>
49    
50     <p>This specification is also being produced by the <a href=http://www.w3.org/2008/webapps/>W3C Web Apps WG</a>. The two
51     specifications are identical from the table of contents onwards.</p>
52    
53    
54    
55     <h2 class="no-num no-toc" id=contents>Table of contents</h2>
56    
57     <!--begin-toc-->
58     <ol class=toc>
59     <li><a href=#introduction><span class=secno>1 </span>Introduction</a>
60     <ol>
61     <li><a href=#scope><span class=secno>1.1 </span>Scope</a></li>
62     <li><a href=#tutorial><span class=secno>1.2 </span>Tutorial</a>
63     <ol>
64     <li><a href=#a-background-number-crunching-worker><span class=secno>1.2.1 </span>A background number-crunching worker</a></li>
65     <li><a href=#a-worker-for-updating-a-client-side-database><span class=secno>1.2.2 </span>A worker for updating a client-side database</a></li>
66     <li><a href=#worker-used-for-background-i/o><span class=secno>1.2.3 </span>Worker used for background I/O</a></li>
67 wakaba 1.197 <li><a href=#shared-workers-introduction><span class=secno>1.2.4 </span>Shared workers introduction</a></li>
68     <li><a href=#shared-state-using-a-shared-worker><span class=secno>1.2.5 </span>Shared state using a shared worker</a></li>
69     <li><a href=#delegation><span class=secno>1.2.6 </span>Delegation</a></li>
70     <li><a href=#providing-libraries><span class=secno>1.2.7 </span>Providing libraries</a></ol></ol></li>
71 wakaba 1.190 <li><a href=#conformance-requirements><span class=secno>2 </span>Conformance requirements</a>
72     <ol>
73     <li><a href=#dependencies><span class=secno>2.1 </span>Dependencies</a></ol></li>
74     <li><a href=#terminology><span class=secno>3 </span>Terminology</a></li>
75     <li><a href=#infrastructure><span class=secno>4 </span>Infrastructure</a>
76     <ol>
77     <li><a href=#the-global-scope><span class=secno>4.1 </span>The global scope</a>
78     <ol>
79     <li><a href=#the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code>WorkerGlobalScope</code> abstract interface</a></li>
80     <li><a href=#dedicated-workers-and-the-dedicatedworkerglobalscope-interface><span class=secno>4.1.2 </span>Dedicated workers and the <code>DedicatedWorkerGlobalScope</code> interface</a></li>
81     <li><a href=#shared-workers-and-the-sharedworkerglobalscope-inteface><span class=secno>4.1.3 </span>Shared workers and the <code>SharedWorkerGlobalScope</code> inteface</a></ol></li>
82     <li><a href=#origins-of-workers><span class=secno>4.2 </span>Origins of workers</a></li>
83     <li><a href=#the-event-loop><span class=secno>4.3 </span>The event loop</a></li>
84     <li><a href="#the-worker's-lifetime"><span class=secno>4.4 </span>The worker's lifetime</a></li>
85     <li><a href=#processing-model><span class=secno>4.5 </span>Processing model</a></li>
86     <li><a href=#runtime-script-errors><span class=secno>4.6 </span>Runtime script errors</a></li>
87     <li><a href=#creating-workers><span class=secno>4.7 </span>Creating workers</a>
88     <ol>
89     <li><a href=#the-abstractworker-abstract-interface><span class=secno>4.7.1 </span>The <code>AbstractWorker</code> abstract interface</a></li>
90     <li><a href=#dedicated-workers-and-the-worker-interface><span class=secno>4.7.2 </span>Dedicated workers and the <code>Worker</code> interface</a></li>
91     <li><a href=#shared-workers-and-the-sharedworker-interface><span class=secno>4.7.3 </span>Shared workers and the <code>SharedWorker</code> interface</a></ol></ol></li>
92     <li><a href=#apis-available-to-workers><span class=secno>5 </span>APIs available to workers</a>
93     <ol>
94     <li><a href=#importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</a></li>
95     <li><a href=#the-workernavigator-object><span class=secno>5.2 </span>The <code>WorkerNavigator</code> object</a></li>
96     <li><a href=#apis-defined-in-other-specifications><span class=secno>5.3 </span>APIs defined in other specifications</a></li>
97     <li><a href=#interface-objects-and-constructors><span class=secno>5.4 </span>Interface objects and constructors</a></li>
98     <li><a href=#worker-locations><span class=secno>5.5 </span>Worker locations</a></ol></li>
99     <li><a class=no-num href=#references>References</a></li>
100     <li><a class=no-num href=#acknowledgements>Acknowledgements</a></ol>
101     <!--end-toc-->
102     <hr><h2 id=introduction><span class=secno>1 </span>Introduction</h2>
103    
104     <h3 id=scope><span class=secno>1.1 </span>Scope</h3>
105    
106     <p><i>This section is non-normative.</i></p>
107    
108     <p>This specification defines an API for running scripts in the
109     background independently of any user interface scripts.</p>
110    
111     <p>This allows for long-running scripts that are not interrupted by
112     scripts that respond to clicks or other user interactions, and
113     allows long tasks to be executed without yielding to keep the page
114     responsive.</p>
115    
116     <p>Workers (as these background scripts are called herein) are
117     relatively heavy-weight, and are not intended to be used in large
118     numbers. For example, it would be inappropriate to launch one worker
119     for each pixel of a four megapixel image. The examples below show
120     some appropriate uses of workers.</p>
121    
122     <p>Generally, workers are expected to be long-lived, have a high
123     start-up performance cost, and a high per-instance memory cost.</p>
124    
125    
126     <h3 id=tutorial><span class=secno>1.2 </span>Tutorial</h3>
127    
128     <p><i>This section is non-normative.</i></p>
129    
130     <p>There are a variety of uses that workers can be put to. The
131     following subsections show various examples of this use.</p>
132    
133     <h4 id=a-background-number-crunching-worker><span class=secno>1.2.1 </span>A background number-crunching worker</h4>
134    
135     <p><i>This section is non-normative.</i></p>
136    
137     <p>The simplest use of workers is for performing a computationally
138     expensive task without interrupting the user interface.</p>
139    
140     <p>In this example, the main document spawns a worker to
141     (na&iuml;vely) compute prime numbers, and progressively displays the
142     most recently found prime number.</p>
143    
144     <p>The main page is as follows:</p>
145    
146     <pre>&lt;!DOCTYPE HTML&gt;
147     &lt;html&gt;
148     &lt;head&gt;
149     &lt;title&gt;Worker example: One-core computation&lt;/title&gt;
150     &lt;/head&gt;
151     &lt;body&gt;
152     &lt;p&gt;The highest prime number discovered so far is: &lt;output id="result"&gt;&lt;/output&gt;&lt;/p&gt;
153     &lt;script&gt;
154     var worker = new Worker('worker.js');
155     worker.onmessage = function (event) {
156     document.getElementById('result').textContent = event.data;
157     };
158     &lt;/script&gt;
159     &lt;/body&gt;
160     &lt;/html&gt;</pre>
161    
162     <p>The <code title=dom-Worker><a href=#dom-worker>Worker()</a></code> constructor call
163     creates a worker and returns a <code><a href=#worker>Worker</a></code> object
164     representing that worker, which is used to communicate with the
165     worker. That object's <code title=handler-Worker-onmessage><a href=#handler-worker-onmessage>onmessage</a></code> event handler allows the code to receive messages from the worker.</p>
166    
167     <p>The worker itself is as follows:</p>
168    
169     <pre>var n = 1;
170     search: while (true) {
171     n += 1;
172     for (var i = 2; i &lt;= Math.sqrt(n); i += 1)
173     if (n % i == 0)
174     continue search;
175     // found a prime!
176     postMessage(n);
177     }</pre>
178    
179     <p>The bulk of this code is simply an unoptimized search for a prime
180     number. To send a message back to the page, the <code title=dom-DedicatedWorkerGlobalScope-postMessage><a href=#dom-dedicatedworkerglobalscope-postmessage>postMessage()</a></code>
181     method is used to post a message when a prime is found.</p>
182    
183     <p><a href=http://www.whatwg.org/demos/workers/primes/page.html>View this example online</a>.</p>
184    
185    
186    
187     <h4 id=a-worker-for-updating-a-client-side-database><span class=secno>1.2.2 </span>A worker for updating a client-side database</h4>
188    
189     <p><i>This section is non-normative.</i></p>
190    
191     <p>In this example, the main document spawns a worker whose only
192     task is to listen for notifications from the server, and, when
193     appropriate, either add or remove data from the client-side
194     database.</p>
195    
196     <p>Since no communication occurs between the worker and the main
197     page, the main page can start the worker by just doing:</p>
198    
199     <pre>&lt;script&gt;
200     new Worker('worker.js');
201     &lt;/script&gt;</pre>
202    
203     <p>The worker itself is as follows:</p>
204    
205     <pre>var server = new WebSocket('ws://whatwg.org/database');
206     var database = openDatabase('demobase', '1.0', 'Demo Database', 10240);
207     server.onmessage = function (event) {
208     // data is in the format "command key value"
209     var data = event.data.split(' ');
210     switch (data[0]) {
211     case '+':
212     database.transaction(function(tx) {
213     tx.executeSql('INSERT INTO pairs (key, value) VALUES (?, ?)', data[1], data[2]);
214     });
215     case '-':
216     database.transaction(function(tx) {
217     tx.executeSql('DELETE FROM pairs WHERE key=? AND value=?', data[1], data[2]);
218     });
219     }
220     };</pre>
221    
222     <p>This connects to the server using the <code>WebSocket</code>
223     mechanism and opens the local database (which, we presume, has been
224     created earlier). The worker then just listens for messages from the
225     server and acts on them as appropriate, forever (or until the main
226     page is closed).</p>
227    
228     <p><a href=http://www.whatwg.org/demos/workers/database-updater/page.html>View
229     this example online</a>. (This example will not actually function,
230     since the server does not actually exist and the database is not
231     created by this sample code.)</p>
232    
233    
234    
235     <h4 id=worker-used-for-background-i/o><span class=secno>1.2.3 </span>Worker used for background I/O</h4>
236    
237     <p><i>This section is non-normative.</i></p>
238    
239     <p>In this example, the main document uses two workers, one for
240     fetching stock updates for at regular intervals, and one for
241     fetching performing search queries that the user requests.</p>
242    
243     <p>The main page is as follows:</p>
244    
245     <pre>&lt;!DOCTYPE HTML&gt;
246     &lt;html&gt;
247     &lt;head&gt;
248     &lt;title&gt;Worker example: Stock ticker&lt;/title&gt;
249     &lt;script&gt;
250     // TICKER
251     var symbol = 'GOOG'; // default symbol to watch
252     var ticker = new Worker('ticker.js');
253    
254     // SEARCHER
255     var searcher = new Worker('searcher.js');
256     function search(query) {
257     searcher.postMessage(query);
258     }
259    
260     // SYMBOL SELECTION UI
261     function select(newSymbol) {
262     symbol = newSymbol;
263     ticker.postMessage(symbol);
264     }
265     &lt;/script&gt;
266     &lt;/head&gt;
267     &lt;body onload="search('')"&gt;
268     &lt;p&gt;&lt;output id="symbol"&gt;&lt;/output&gt; &lt;output id="value"&gt;&lt;/output&gt;&lt;/p&gt;
269     &lt;script&gt;
270     ticker.onmessage = function (event) {
271     var data = event.data.split(' ');
272     document.getElementById('symbol').textContent = data[0];
273     document.getElementById('value').textContent = data[1];
274     };
275     ticker.postMessage(symbol);
276     &lt;/script&gt;
277     &lt;p&gt;&lt;label&gt;Search: &lt;input type="text" autofocus oninput="search(this.value)"&gt;&lt;/label&gt;&lt;/p&gt;
278     &lt;ul id="results"&gt;&lt;/ul&gt;
279     &lt;script&gt;
280     searcher.onmessage = function (event) {
281     var data = event.data.split(' ');
282     var results = document.getElementById('results');
283     while (results.hasChildNodes()) // clear previous results
284     results.removeChild(results.firstChild);
285     for (var i = 0; i &lt; data.length; i += 1) {
286     // add a list item with a button for each result
287     var li = document.createElement('li');
288     var button = document.createElement('button');
289     button.value = data[i];
290     button.type = 'button';
291     button.onclick = function () { select(this.value); };
292     button.textContent = data[i];
293     li.appendChild(button);
294     results.appendChild(li);
295     }
296     };
297     &lt;/script&gt;
298     &lt;p&gt;(The data in this example is not real. Try searching for "Google" or "Apple".)&lt;/p&gt;
299     &lt;/body&gt;
300     &lt;/html&gt;</pre>
301    
302     <p>The two workers use a common library for performing the actual
303     network calls. This library is as follows:</p>
304    
305     <pre>function get(url) {
306     try {
307     var xhr = new XMLHttpRequest();
308     xhr.open('GET', url, false);
309     xhr.send();
310     return xhr.responseText;
311     } catch (e) {
312     return ''; // turn all errors into empty results
313     }
314     }</pre>
315    
316     <p>The stock updater worker is as follows:</p>
317    
318     <pre>importScripts('io.js');
319     var timer;
320     var symbol;
321     function update() {
322     postMessage(symbol + ' ' + get('stock.cgi?' + symbol));
323     timer = setTimeout(update, 10000);
324     }
325     onmessage = function (event) {
326     if (timer)
327     clearTimeout(timer);
328     symbol = event.data;
329     update();
330     };</pre>
331    
332     <p>The search query worker is as follows:</p>
333    
334     <pre>importScripts('io.js');
335     onmessage = function (event) {
336     postMessage(get('search.cgi?' + event.data));
337     };</pre>
338    
339     <p><a href=http://www.whatwg.org/demos/workers/stocks/page.html>View this example online</a>.</p>
340    
341    
342 wakaba 1.197 <h4 id=shared-workers-introduction><span class=secno>1.2.4 </span>Shared workers introduction</h4>
343    
344     <p><i>This section is non-normative.</i></p>
345    
346     <p>This section introduces shared workers using a Hello World
347     example. Shared workers use slightly different APIs, since each
348     worker can have multiple connections.</p>
349    
350     <p>This first example shows how you connect to a worker and how a
351     worker can send a message back to the page when it connects to
352     it. Received messages are displayed in a log.</p>
353    
354     <p>Here is the HTML page:</p>
355    
356 wakaba 1.198 <pre>&lt;!DOCTYPE HTML&gt;
357     &lt;title&gt;Shared workers: demo 1&lt;/title&gt;
358     &lt;pre id="log"&gt;Log:&lt;/pre&gt;
359     &lt;script&gt;
360     var worker = new SharedWorker('test.js');
361     var log = document.getElementById('log');
362     worker.port.onmessage = function(e) { // note: not worker.onmessage!
363     log.textContent += '\n' + e.data;
364     }
365     &lt;/script&gt;
366     </pre>
367 wakaba 1.197
368     <p>Here is the JavaScript worker:</p>
369    
370 wakaba 1.198 <pre>onconnect = function(e) {
371     var port = e.ports[0];
372     port.postMessage('Hello World!');
373     }
374     </pre>
375 wakaba 1.197
376 wakaba 1.201 <p><a href=http://www.whatwg.org/demos/workers/shared/001.html>View this example online</a>.</p>
377    
378 wakaba 1.197 <hr><p>This second example extends the first one by changing two things:
379     first, messages are received using <code title="">addEventListener()</code> instead of an <span title="event
380     handler IDL attributes">event handler IDL attribute</span>, and
381     second, a message is sent <em>to</em> the worker, causing the worker
382     to send another message in return. Received messages are again
383 wakaba 1.198 displayed in a log.</p>
384 wakaba 1.197
385     <p>Here is the HTML page:</p>
386    
387 wakaba 1.198 <pre>&lt;!DOCTYPE HTML&gt;
388     &lt;title&gt;Shared workers: demo 2&lt;/title&gt;
389     &lt;pre id="log"&gt;Log:&lt;/pre&gt;
390     &lt;script&gt;
391     var worker = new SharedWorker('test.js');
392     var log = document.getElementById('log');
393     worker.port.addEventListener('message', function(e) {
394     log.textContent += '\n' + e.data;
395     }, false);
396     worker.port.start(); // note: need this when using addEventListener
397     worker.port.postMessage('ping');
398     &lt;/script&gt;
399     </pre>
400 wakaba 1.197
401     <p>Here is the JavaScript worker:</p>
402    
403 wakaba 1.198 <pre>onconnect = function(e) {
404     var port = e.ports[0];
405     port.postMessage('Hello World!');
406     port.onmessage = function(e) {
407     port.postMessage('pong'); // not e.ports[0].postMessage!
408     // e.target.postMessage('pong'); would work also
409     }
410     }
411     </pre>
412 wakaba 1.197
413 wakaba 1.201 <p><a href=http://www.whatwg.org/demos/workers/shared/002.html>View this example online</a>.</p>
414    
415 wakaba 1.197 <hr><p>Finally, the example is extended to show how two pages can
416     connect to the same worker; in this case, the second page is merely
417     in an <code>iframe</code> on the first page, but the same principle
418     would apply to an entirely separate page in a separate
419     <span>top-level browsing context</span>.</p>
420    
421     <p>Here is the outer HTML page:</p>
422    
423 wakaba 1.198 <pre>&lt;!DOCTYPE HTML&gt;
424     &lt;title&gt;Shared workers: demo 3&lt;/title&gt;
425     &lt;pre id="log"&gt;Log:&lt;/pre&gt;
426     &lt;script&gt;
427     var worker = new SharedWorker('test.js');
428     var log = document.getElementById('log');
429     worker.port.addEventListener('message', function(e) {
430     log.textContent += '\n' + e.data;
431     }, false);
432     worker.port.start();
433     worker.port.postMessage('ping');
434     &lt;/script&gt;
435     &lt;iframe src="inner.html"&gt;&lt;/iframe&gt;
436     </pre>
437 wakaba 1.197
438     <p>Here is the inner HTML page:</p>
439    
440 wakaba 1.198 <pre>&lt;!DOCTYPE HTML&gt;
441     &lt;title&gt;Shared workers: demo 3 inner frame&lt;/title&gt;
442     &lt;pre id=log&gt;Inner log:&lt;/pre&gt;
443     &lt;script&gt;
444     var worker = new SharedWorker('test.js');
445     var log = document.getElementById('log');
446     worker.port.onmessage = function(e) {
447     log.textContent += '\n' + e.data;
448     }
449     &lt;/script&gt;
450     </pre>
451 wakaba 1.197
452     <p>Here is the JavaScript worker:</p>
453    
454 wakaba 1.198 <pre>var count = 0;
455     onconnect = function(e) {
456     count += 1;
457     var port = e.ports[0];
458     port.postMessage('Hello World! You are connection #' + count);
459     port.onmessage = function(e) {
460     port.postMessage('pong');
461     }
462     }
463     </pre>
464 wakaba 1.201
465     <p><a href=http://www.whatwg.org/demos/workers/shared/003.html>View this example online</a>.</p>
466 wakaba 1.197
467    
468     <h4 id=shared-state-using-a-shared-worker><span class=secno>1.2.5 </span>Shared state using a shared worker</h4>
469 wakaba 1.190
470     <p><i>This section is non-normative.</i></p>
471    
472     <p>In this example, multiple windows (viewers) can be opened that
473     are all viewing the same map. All the windows share the same map
474     information, with a single worker coordinating all the viewers. Each
475     viewer can move around independently, but if they set any data on
476     the map, all the viewers are updated.</p>
477    
478     <p>The main page isn't interesting, it merely provides a way to open
479     the viewers:</p>
480    
481     <pre>&lt;!DOCTYPE HTML&gt;
482     &lt;html&gt;
483     &lt;head&gt;
484     &lt;title&gt;Workers example: Multiviewer&lt;/title&gt;
485     &lt;script&gt;
486     function openViewer() {
487     window.open('viewer.html');
488     }
489     &lt;/script&gt;
490     &lt;/head&gt;
491     &lt;body&gt;
492     &lt;p&gt;&lt;button type=button onclick="openViewer()"&gt;Open a new
493     viewer&lt;/button&gt;&lt;/p&gt;
494     &lt;p&gt;Each viewer opens in a new window. You can have as many viewers
495     as you like, they all view the same data.&lt;/p&gt;
496     &lt;/body&gt;
497     &lt;/html&gt;</pre>
498    
499     <p>The viewer is more involved:</p>
500    
501     <pre>&lt;!DOCTYPE HTML&gt;
502     &lt;html&gt;
503     &lt;head&gt;
504     &lt;title&gt;Workers example: Multiviewer viewer&lt;/title&gt;
505     &lt;script&gt;
506     var worker = new SharedWorker('worker.js', 'core');
507    
508     // CONFIGURATION
509     function configure(event) {
510     if (event.data.substr(0, 4) != 'cfg ') return;
511     var name = event.data.substr(4).split(' ', 1);
512     // update display to mention our name is name
513     document.getElementsByTagName('h1')[0].textContent += ' ' + name;
514     // no longer need this listener
515     worker.port.removeEventListener('message', configure, false);
516     }
517     worker.port.addEventListener('message', configure, false);
518    
519     // MAP
520     function paintMap(event) {
521     if (event.data.substr(0, 4) != 'map ') return;
522     var data = event.data.substr(4).split(',');
523     // display tiles data[0] .. data[8]
524     var canvas = document.getElementById('map');
525     var context = canvas.getContext('2d');
526     for (var y = 0; y &lt; 3; y += 1) {
527     for (var x = 0; x &lt; 3; x += 1) {
528     var tile = data[y * 3 + x];
529     if (tile == '0')
530     context.fillStyle = 'green';
531     else
532     context.fillStyle = 'maroon';
533     fillRect(x * 50, y * 50, 50, 50);
534     }
535     }
536     }
537     worker.port.addEventListener('message', paintMap, false);
538    
539     // PUBLIC CHAT
540     function updatePublicChat(event) {
541     if (event.data.substr(0, 4) != 'txt ') return;
542     var name = event.data.substr(4).split(' ', 1);
543     var message = event.data.substr(4 + length(name) + 1);
544     // display "&lt;name&gt; message" in public chat
545     var dialog = document.getElementById('public');
546     var dt = document.createElement('dt');
547     dt.textContent = name;
548     dialog.appendChild(dt);
549     var dd = document.createElement('dd');
550     dd.textContent = message;
551     dialog.appendChild(dd);
552     }
553     worker.port.addEventListener('message', updatePublicChat, false);
554    
555     // PRIVATE CHAT
556     function startPrivateChat(event) {
557     if (event.data.substr(0, 4) != 'msg ') return;
558     var name = event.data.substr(4).split(' ', 1);
559     var port = event.ports[0];
560     // display a private chat UI
561     var ul = document.getElementById('private');
562     var li = document.createElement('li');
563     var h3 = document.createElement('h3');
564     h3.textContent = 'Private chat with ' + name;
565     li.appendChild(h3);
566     var dialog = document.createElement('dialog');
567     var addMessage = function(name, message) {
568     var dt = document.createElement('dt');
569     dt.textContent = name;
570     dialog.appendChild(dt);
571     var dd = document.createElement('dd');
572     dd.textContent = message;
573     dialog.appendChild(dd);
574     };
575     port.onmessage = function (event) {
576     addMessage(name, event.data);
577     };
578     li.appendChild(dialog);
579     var form = document.createElement('form');
580     var p = document.createElement('p');
581     var input = document.createElement('input');
582     input.size = 50;
583     p.appendChild(input);
584     p.appendChild(document.createTextNode(' '));
585     var button = document.createElement('button');
586     button.textContent = 'Post';
587     p.appendChild(button);
588     form.onsubmit = function () {
589     port.postMessage(input.value);
590     addMessage('me', input.value);
591     input.value = '';
592     return false;
593     };
594     form.appendChild(p);
595     li.appendChild(form);
596     }
597     worker.port.addEventListener('message', startPrivateChat, false);
598    
599     worker.port.start();
600     &lt;/script&gt;
601     &lt;/head&gt;
602     &lt;body&gt;
603     &lt;h1&gt;Viewer&lt;/h1&gt;
604     &lt;h2&gt;Map&lt;/h2&gt;
605     &lt;p&gt;&lt;canvas id="map" height=150 width=150&gt;&lt;/canvas&gt;&lt;/p&gt;
606     &lt;p&gt;
607     &lt;button type=button onclick="worker.port.postMessage('mov left')"&gt;Left&lt;/button&gt;
608     &lt;button type=button onclick="worker.port.postMessage('mov up')"&gt;Up&lt;/button&gt;
609     &lt;button type=button onclick="worker.port.postMessage('mov down')"&gt;Down&lt;/button&gt;
610     &lt;button type=button onclick="worker.port.postMessage('mov right')"&gt;Right&lt;/button&gt;
611     &lt;button type=button onclick="worker.port.postMessage('set 0')"&gt;Set 0&lt;/button&gt;
612     &lt;button type=button onclick="worker.port.postMessage('set 1')"&gt;Set 1&lt;/button&gt;
613     &lt;/p&gt;
614     &lt;h2&gt;Public Chat&lt;/h2&gt;
615     &lt;dialog id="public"&gt;&lt;/dialog&gt;
616     &lt;form onsubmit="worker.port.postMessage('txt ' + message.value); message.value = ''; return false;"&gt;
617     &lt;p&gt;
618     &lt;input type="text" name="message" size="50"&gt;
619     &lt;button&gt;Post&lt;/button&gt;
620     &lt;/p&gt;
621     &lt;/form&gt;
622     &lt;h2&gt;Private Chat&lt;/h2&gt;
623     &lt;ul id="private"&gt;&lt;/ul&gt;
624     &lt;/body&gt;
625     &lt;/html&gt;
626     </pre>
627    
628     <p>There are several key things worth noting about the way the
629     viewer is written.</p>
630    
631     <p><strong>Multiple listeners</strong>. Instead of a single message
632     processing function, the code here attaches multiple event
633     listeners, each one performing a quick check to see if it is
634     relevant for the message. In this example it doesn't make much
635     difference, but if multiple authors wanted to collaborate using a
636     single port to communicate with a worker, it would allow for
637     independent code instead of changes having to all be made to a
638     single event handling function.</p>
639    
640     <p>Registering event listeners in this way also allows you to
641     unregister specific listeners when you are done with them, as is
642     done with the <code title="">configure()</code> method in this
643     example.</p>
644    
645     <p>Finally, the worker:</p>
646    
647     <pre>
648     var nextName = 0;
649     function getNextName() {
650     // this could use more friendly names
651     // but for now just return a number
652     return nextName++;
653     }
654    
655     var map = [
656     [0, 0, 0, 0, 0, 0, 0],
657     [1, 1, 0, 1, 0, 1, 1],
658     [0, 1, 0, 1, 0, 0, 0],
659     [0, 1, 0, 1, 0, 1, 1],
660     [0, 0, 0, 1, 0, 0, 0],
661     [1, 0, 0, 1, 1, 1, 1],
662     [1, 1, 0, 1, 1, 0, 1],
663     ];
664    
665     function wrapX(x) {
666     if (x &lt; 0) return wrapX(x + map[0].length);
667     if (x &gt;= map[0].length) return wrapX(x - map[0].length);
668     return x;
669     }
670    
671     function wrapY(y) {
672     if (y &lt; 0) return wrapY(y + map.length);
673     if (y &gt;= map[0].length) return wrapY(y - map.length);
674     return y;
675     }
676    
677     function sendMapData(callback) {
678     var data = '';
679     for (var y = viewer.y-1; y &lt;= viewer.y+1; y += 1) {
680     for (var x = viewer.x-1; x &lt;= viewer.x+1; x += 1) {
681     if (data != '')
682     data += ',';
683     data += map[y][x];
684     }
685     }
686     callback('map ' + data);
687     }
688    
689     var viewers = {};
690     onconnect = function (event) {
691     event.ports[0]._name = getNextName();
692     event.ports[0]._data = { port: event.port, x: 0, y: 0, };
693     viewers[event.ports[0]._name] = event.port._data;
694     event.ports[0].postMessage('cfg ' + name);
695     event.ports[0].onmessage = getMessage;
696     sendMapData(event.ports[0].postMessage);
697     };
698    
699     function getMessage(event) {
700     switch (event.data.substr(0, 4)) {
701     case 'mov ':
702     var direction = event.data.substr(4);
703     var dx = 0;
704     var dy = 0;
705     switch (direction) {
706     case 'up': dy = -1; break;
707     case 'down': dy = 1; break;
708     case 'left': dx = -1; break;
709     case 'right': dx = 1; break;
710     }
711     event.target._data.x = wrapX(event.target._data.x + dx);
712     event.target._data.y = wrapY(event.target._data.y + dy);
713     sendMapData(event.target.postMessage);
714     break;
715     case 'set ':
716     var value = event.data.substr(4);
717     map[event.target._data.y][event.target._data.x] = value;
718     for (var viewer in viewers)
719     sendMapData(viewers[viewer].port.postMessage);
720     break;
721     case 'txt ':
722     var name = event.target._name;
723     var message = event.data.substr(4);
724     for (var viewer in viewers)
725     viewers[viewer].port.postMessage('txt ' + name + ' ' + message);
726     break;
727     case 'msg ':
728     var party1 = event._data;
729     var party2 = viewers[event.data.substr(4).split(' ', 1)];
730     if (party2) {
731     var channel = new MessageChannel();
732     party1.port.postMessage('msg ' + party2.name, [channel.port1]);
733     party2.port.postMessage('msg ' + party1.name, [channel.port2]);
734     }
735     break;
736     }
737     }</pre>
738    
739     <p><strong>Connecting to multiple pages</strong>. The script uses
740     the <code title=handler-SharedWorkerGlobalScope-onconnect><a href=#handler-sharedworkerglobalscope-onconnect>onconnect</a></code>
741     event listener to listen for multiple connections.</p>
742    
743     <p><strong>Direct channels</strong>. When the worker receives a
744     "msg" message from one viewer naming another viewer, it sets up a
745     direct connection between the two, so that the two viewers can
746     communicate directly without the worker having to proxy all the
747     messages.</p>
748    
749     <p><a href=http://www.whatwg.org/demos/workers/multiviewer/page.html>View this example online</a>.</p>
750    
751    
752 wakaba 1.197 <h4 id=delegation><span class=secno>1.2.6 </span>Delegation</h4>
753 wakaba 1.190
754     <p><i>This section is non-normative.</i></p>
755    
756     <p>With multicore CPUs becoming prevalent, one way to obtain better
757     performance is to split computationally expensive tasks amongst
758     multiple workers. In this example, a computationally expensive task
759     that is to be performed for every number from 1 to 10,000,000 is
760     farmed out to ten subworkers.</p>
761    
762     <p>The main page is as follows, it just reports the result:</p>
763    
764     <pre>&lt;!DOCTYPE HTML&gt;
765     &lt;html&gt;
766     &lt;head&gt;
767     &lt;title&gt;Worker example: Multicore computation&lt;/title&gt;
768     &lt;/head&gt;
769     &lt;body&gt;
770     &lt;p&gt;Result: &lt;output id="result"&gt;&lt;/output&gt;&lt;/p&gt;
771     &lt;script&gt;
772     var worker = new Worker('worker.js');
773     worker.onmessage = function (event) {
774     document.getElementById('result').textContent = event.data;
775     };
776     &lt;/script&gt;
777     &lt;/body&gt;
778     &lt;/html&gt;</pre>
779    
780     <p>The worker itself is as follows:</p>
781    
782     <pre>// settings
783     var num_workers = 10;
784     var items_per_worker = 1000000;
785    
786     // start the workers
787     var result = 0;
788     var pending_workers = num_workers;
789     for (var i = 0; i &lt; num_workers; i += 1) {
790     var worker = new Worker('core.js');
791     worker.postMessage(i * items_per_worker);
792     worker.postMessage((i+1) * items_per_worker);
793     worker.onmessage = storeResult;
794     }
795    
796     // handle the results
797     function storeResult(event) {
798     result += 1*event.data;
799     pending_workers -= 1;
800     if (pending_workers &lt;= 0)
801     postMessage(result); // finished!
802     }</pre>
803    
804     <p>It consists of a loop to start the subworkers, and then a handler
805     that waits for all the subworkers to respond.</p>
806    
807     <p>The subworkers are implemented as follows:</p>
808    
809     <pre>var start;
810     onmessage = getStart;
811     function getStart(event) {
812     start = 1*event.data;
813     onmessage = getEnd;
814     }
815    
816     var end;
817     function getEnd(event) {
818     end = 1*event.data;
819     onmessage = null;
820     work();
821     }
822    
823     function work() {
824     var result = 0;
825     for (var i = start; i &lt; end; i += 1) {
826     // perform some complex calculation here
827     result += 1;
828     }
829     postMessage(result);
830     close();
831     }</pre>
832    
833     <p>They receive two numbers in two events, perform the computation
834     for the range of numbers thus specified, and then report the result
835     back to the parent.</p>
836    
837     <p><a href=http://www.whatwg.org/demos/workers/multicore/page.html>View this example online</a>.</p>
838    
839    
840 wakaba 1.197 <h4 id=providing-libraries><span class=secno>1.2.7 </span>Providing libraries</h4>
841 wakaba 1.190
842     <p><i>This section is non-normative.</i></p>
843    
844     <p>Suppose that a cryptography library is made available that
845     provides three tasks:</p>
846    
847     <dl><dt>Generate a public/private key pair</dt>
848    
849     <dd>Takes a port, on which it will send two messages, first the
850     public key and then the private key.</dd>
851    
852     <dt>Given a plaintext and a public key, return the corresponding cyphertext</dt>
853    
854     <dd>Takes a port, to which any number of messages can be sent, the
855     first giving the public key, and the remainder giving the
856     plaintext, each of which is encrypted and then sent on that same
857     channel as the cyphertext. The user can close the port when it is
858     done encrypting content.</dd>
859    
860     <dt>Given a cyphertext and a private key, return the corresponding plaintext</dt>
861    
862     <dd>Takes a port, to which any number of messages can be sent, the
863     first giving the private key, and the remainder giving the
864     cyphertext, each of which is decrypted and then sent on that same
865     channel as the plaintext. The user can close the port when it is
866     done decrypting content.</dd>
867    
868     </dl><p>The library itself is as follows:</p>
869    
870     <pre>function handleMessage(e) {
871     if (e.data == "genkeys")
872     genkeys(e.ports[0]);
873     else if (e.data == "encrypt")
874     encrypt(e.ports[0]);
875     else if (e.data == "decrypt")
876     decrypt(e.ports[0]);
877     }
878    
879     function genkeys(p) {
880     var keys = _generateKeyPair();
881     p.postMessage(keys[0]);
882     p.postMessage(keys[1]);
883     }
884    
885     function encrypt(p) {
886     var key, state = 0;
887     p.onmessage = function (e) {
888     if (state == 0) {
889     key = e.data;
890     state = 1;
891     } else {
892     p.postMessage(_encrypt(key, e.data));
893     }
894     };
895     }
896    
897     function decrypt(p) {
898     var key, state = 0;
899     p.onmessage = function (e) {
900     if (state == 0) {
901     key = e.data;
902     state = 1;
903     } else {
904     p.postMessage(_decrypt(key, e.data));
905     }
906     };
907     }
908    
909     // support being used as a shared worker as well as a dedicated worker
910     if ('onmessage' in this) // dedicated worker
911     onmessage = handleMessage;
912     else // shared worker
913     onconnect = function (e) { e.port.onmessage = handleMessage; }
914    
915    
916     // the "crypto" functions:
917    
918     function _generateKeyPair() {
919     return [Math.random(), Math.random()];
920     }
921    
922     function _encrypt(k, s) {
923     return 'encrypted-' + k + ' ' + s;
924     }
925    
926     function _decrypt(k, s) {
927     return s.substr(s.indexOf(' ')+1);
928     }</pre>
929    
930     <p>Note that the crypto functions here are just stubs and don't do
931     real cryptography.</p>
932    
933     <p>This library could be used as follows:</p>
934    
935     <pre>&lt;!DOCTYPE HTML&gt;
936     &lt;html&gt;
937     &lt;head&gt;
938     &lt;title&gt;Worker example: Crypto library&lt;/title&gt;
939     &lt;script&gt;
940     var crytoLib = new Worker('libcrypto-v1.js'); // or could use 'libcrypto-v2.js'
941     function getKeys() {
942     var state = 0;
943     cryptoLib.startConversation("genkeys").onmessage = function (e) {
944     if (state == 0)
945     document.getElementById('public').value = e.data;
946     else if (state == 1)
947     document.getElementById('private').value = e.data;
948     state += 1;
949     };
950     }
951     function enc() {
952     var port = cryptoLib.startConversation("encrypt");
953     port.postMessage(document.getElementById('public').value);
954     port.postMessage(document.getElementById('input').value);
955     port.onmessage = function (e) {
956     document.getElementById('input').value = e.data;
957     port.close();
958     };
959     }
960     function dec() {
961     var port = cryptoLib.startConversation("decrypt");
962     port.postMessage(document.getElementById('private').value);
963     port.postMessage(document.getElementById('input').value);
964     port.onmessage = function (e) {
965     document.getElementById('input').value = e.data;
966     port.close();
967     };
968     }
969     &lt;/script&gt;
970     &lt;style&gt;
971     textarea { display: block; }
972     &lt;/style&gt;
973     &lt;/head&gt;
974     &lt;body onload="getKeys()"&gt;
975     &lt;fieldset&gt;
976     &lt;legend&gt;Keys&lt;/legend&gt;
977     &lt;p&gt;&lt;label&gt;Public Key: &lt;textarea id="public"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
978     &lt;p&gt;&lt;label&gt;Private Key: &lt;textarea id="private"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
979     &lt;/fieldset&gt;
980     &lt;p&gt;&lt;label&gt;Input: &lt;textarea id="input"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
981     &lt;p&gt;&lt;button onclick="enc()"&gt;Encrypt&lt;/button&gt; &lt;button onclick="dec()"&gt;Decrypt&lt;/button&gt;&lt;/p&gt;
982     &lt;/body&gt;
983     &lt;/html&gt;</pre>
984    
985     <p>A later version of the API, though, might want to offload all the
986     crypto work onto subworkers. This could be done as follows:</p>
987    
988     <pre>function handleMessage(e) {
989     if (e.data == "genkeys")
990     genkeys(e.ports[0]);
991     else if (e.data == "encrypt")
992     encrypt(e.ports[0]);
993     else if (e.data == "decrypt")
994     decrypt(e.ports[0]);
995     }
996    
997     function genkeys(p) {
998     var generator = new Worker('libcrypto-v2-generator.js');
999     generator.postMessage('', [p]);
1000     }
1001    
1002     function encrypt(p) {
1003     p.onmessage = function (e) {
1004     var key = e.data;
1005     var encryptor = new Worker('libcrypto-v2-encryptor.js');
1006     encryptor.postMessage(key, [p]);
1007     };
1008     }
1009    
1010     function encrypt(p) {
1011     p.onmessage = function (e) {
1012     var key = e.data;
1013     var decryptor = new Worker('libcrypto-v2-decryptor.js');
1014     decryptor.postMessage(key, [p]);
1015     };
1016     }
1017    
1018     // support being used as a shared worker as well as a dedicated worker
1019     if ('onmessage' in this) // dedicated worker
1020     onmessage = handleMessage;
1021     else // shared worker
1022     onconnect = function (e) { e.ports[0].onmessage = handleMessage };
1023     </pre>
1024    
1025     <p>The little subworkers would then be as follows.</p>
1026    
1027     <p>For generating key pairs:</p>
1028    
1029     <pre>onmessage = function (e) {
1030     var k = _generateKeyPair();
1031     e.ports[0].postMessage(k[0]);
1032     e.ports[0].postMessage(k[1]);
1033     close();
1034     }
1035    
1036     function _generateKeyPair() {
1037     return [Math.random(), Math.random()];
1038     }</pre>
1039    
1040     <p>For encrypting:</p>
1041    
1042     <pre>onmessage = function (e) {
1043     var key = e.data;
1044     e.ports[0].onmessage = function (e) {
1045     var s = e.data;
1046     postMessage(_encrypt(key, s));
1047     }
1048     }
1049    
1050     function _encrypt(k, s) {
1051     return 'encrypted-' + k + ' ' + s;
1052     }</pre>
1053    
1054     <p>For decrypting:</p>
1055    
1056     <pre>onmessage = function (e) {
1057     var key = e.data;
1058     e.ports[0].onmessage = function (e) {
1059     var s = e.data;
1060     postMessage(_decrypt(key, s));
1061     }
1062     }
1063    
1064     function _decrypt(k, s) {
1065     return s.substr(s.indexOf(' ')+1);
1066     }</pre>
1067    
1068     <p>Notice how the users of the API don't have to even know that this
1069     is happening &mdash; the API hasn't changed; the library can
1070     delegate to subworkers without changing its API, even though it is
1071     accepting data using message channels.</p>
1072    
1073     <p><a href=http://www.whatwg.org/demos/workers/crypto/page.html>View this example online</a>.</p>
1074    
1075    
1076 wakaba 1.205
1077 wakaba 1.190
1078     <h2 id=conformance-requirements><span class=secno>2 </span>Conformance requirements</h2>
1079    
1080     <p>All diagrams, examples, and notes in this specification are
1081     non-normative, as are all sections explicitly marked non-normative.
1082     Everything else in this specification is normative.</p>
1083    
1084     <p>The key words "MUST", "MUST NOT", "REQUIRED", <!--"SHALL", "SHALL
1085     NOT",--> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
1086     "OPTIONAL" in the normative parts of this document are to be
1087     interpreted as described in RFC2119. For readability, these words do
1088     not appear in all uppercase letters in this specification. <a href=#refsRFC2119>[RFC2119]</a></p>
1089    
1090     <p>Requirements phrased in the imperative as part of algorithms
1091     (such as "strip any leading space characters" or "return false and
1092     abort these steps") are to be interpreted with the meaning of the
1093     key word ("must", "should", "may", etc) used in introducing the
1094     algorithm.</p>
1095    
1096     <p>Some conformance requirements are phrased as requirements on
1097     attributes, methods or objects. Such requirements are to be
1098     interpreted as requirements on user agents.</p>
1099    
1100     <p>Conformance requirements phrased as algorithms or specific steps
1101     may be implemented in any manner, so long as the end result is
1102     equivalent. (In particular, the algorithms defined in this
1103     specification are intended to be easy to follow, and not intended to
1104     be performant.)</p>
1105    
1106     <p>The only conformance class defined by this specification is user
1107     agents.</p>
1108    
1109     <p>User agents may impose implementation-specific limits on
1110     otherwise unconstrained inputs, e.g. to prevent denial of service
1111     attacks, to guard against running out of memory, or to work around
1112     platform-specific limitations.</p>
1113 wakaba 1.191
1114     <p>When support for a feature is disabled (e.g. as an emergency
1115     measure to mitigate a security problem, or to aid in development, or
1116     for performance reasons), user agents must act as if they had no
1117     support for the feature whatsoever, and as if the feature was not
1118     mentioned in this specification. For example, if a particular
1119     feature is accessed via an attribute in a Web IDL interface, the
1120     attribute itself would be omitted from the objects that implement
1121     that interface &mdash; leaving the attribute on the object but
1122     making it return null or throw an exception is insufficient.</p>
1123 wakaba 1.190
1124    
1125     <h3 id=dependencies><span class=secno>2.1 </span>Dependencies</h3>
1126    
1127     <p>This specification relies on several other underlying
1128     specifications.</p>
1129    
1130     <dl><dt>HTML</dt>
1131    
1132     <dd>
1133    
1134     <p>Many fundamental concepts from HTML are used by this
1135     specification. <a href=#refsHTML>[HTML]</a></p>
1136    
1137     </dd>
1138    
1139     <dt>WebIDL</dt>
1140    
1141     <dd>
1142    
1143     <p>The IDL blocks in this specification use the semantics of the
1144     WebIDL specification. <a href=#refsWEBIDL>[WEBIDL]</a></p>
1145    
1146     </dd>
1147    
1148     </dl><h2 id=terminology><span class=secno>3 </span>Terminology</h2>
1149    
1150     <p>The construction "a <code title="">Foo</code> object", where
1151     <code title="">Foo</code> is actually an interface, is sometimes
1152     used instead of the more accurate "an object implementing the
1153     interface <code title="">Foo</code>".</p>
1154    
1155     <p>The term DOM is used to refer to the API set made available to
1156     scripts in Web applications, and does not necessarily imply the
1157     existence of an actual <code>Document</code> object or of any other
1158     <code>Node</code> objects as defined in the DOM Core
1159     specifications. <a href=#refsDOMCORE>[DOMCORE]</a></p>
1160    
1161     <p>An IDL attribute is said to be <em>getting</em> when its value is
1162     being retrieved (e.g. by author script), and is said to be
1163     <em>setting</em> when a new value is assigned to it.</p>
1164    
1165 wakaba 1.205
1166 wakaba 1.190 <p>The term "JavaScript" is used to refer to ECMA262, rather than
1167     the official term ECMAScript, since the term JavaScript is more
1168     widely known. <a href=#refsECMA262>[ECMA262]</a></p>
1169 wakaba 1.205
1170 wakaba 1.190
1171    
1172     <h2 id=infrastructure><span class=secno>4 </span>Infrastructure</h2>
1173    
1174     <p>There are two kinds of workers; dedicated workers, and shared
1175     workers. Dedicated workers, once created, and are linked to their
1176     creator; but message ports can be used to communicate from a
1177     dedicated worker to multiple other browsing contexts or
1178     workers. Shared workers, on the other hand, are named, and once
1179     created any script running in the same <span>origin</span> can
1180     obtain a reference to that worker and communicate with it.</p>
1181    
1182    
1183     <h3 id=the-global-scope><span class=secno>4.1 </span>The global scope</h3>
1184    
1185     <p>The global scope is the "inside" of a worker.</p>
1186    
1187     <h4 id=the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> abstract interface</h4>
1188    
1189     <pre class=idl>interface <dfn id=workerglobalscope>WorkerGlobalScope</dfn> {
1190     readonly attribute <a href=#workerglobalscope>WorkerGlobalScope</a> <a href=#dom-workerglobalscope-self title=dom-WorkerGlobalScope-self>self</a>;
1191     readonly attribute <a href=#workerlocation>WorkerLocation</a> <a href=#dom-workerglobalscope-location title=dom-WorkerGlobalScope-location>location</a>;
1192    
1193     void <a href=#dom-workerglobalscope-close title=dom-WorkerGlobalScope-close>close</a>();
1194     <!-- v2-onclose attribute <span>Function</span> <span title="handler-WorkerGlobalScope-onclose">onclose</span>;
1195     --> attribute <span>Function</span> <a href=#handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror>onerror</a>;
1196     };
1197     <a href=#workerglobalscope>WorkerGlobalScope</a> implements <a href=#workerutils>WorkerUtils</a>;
1198     <a href=#workerglobalscope>WorkerGlobalScope</a> implements <span>EventTarget</span>;</pre>
1199    
1200     <p>The <dfn id=dom-workerglobalscope-self title=dom-WorkerGlobalScope-self><code>self</code></dfn> attribute
1201     must return the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object itself.</p>
1202    
1203     <p>The <dfn id=dom-workerglobalscope-location title=dom-WorkerGlobalScope-location><code>location</code></dfn>
1204     attribute must return the <code><a href=#workerlocation>WorkerLocation</a></code> object created
1205     for the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object when the worker was
1206     created. It represents the <span>absolute URL</span> of the script
1207     that was used to initialize the worker, after any redirects.</p>
1208    
1209     <hr><p>When a script invokes the <dfn id=dom-workerglobalscope-close title=dom-WorkerGlobalScope-close><code>close()</code></dfn>
1210     method on a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent
1211     must run the following steps (atomically):</p>
1212    
1213     <ol><li><p>Discard any <span title=concept-task>tasks</span> that
1214     have been added to the <span>event loop</span>'s <span title="task
1215     queue">task queues</span>.</p>
1216    
1217     <!-- v2-onclose
1218     <li><p><span>Queue a task</span> to <span>fire a simple
1219     event</span> named <code title="event-close">close</code> at the
1220     <code>WorkerGlobalScope</code> object.</p></li>
1221     -->
1222    
1223     <li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1224     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1225     true. (This prevents any further tasks from being queued.)</li>
1226    
1227     </ol><p>The following are the <span>event handlers</span> (and their
1228     corresponding <span title="event handler event type">event handler
1229     event types</span>) that must be supported, as IDL attributes, by
1230     objects implementing the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
1231     interface:</p>
1232    
1233     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1234     <tbody><!-- v2-onclose <tr><td><dfn title="handler-WorkerGlobalScope-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> --><tr><td><dfn id=handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
1235     </table><hr><p>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface must not exist if
1236     the interface's <span>relevant namespace object</span> is a
1237     <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
1238    
1239    
1240    
1241     <h4 id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface><span class=secno>4.1.2 </span>Dedicated workers and the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> interface</h4>
1242    
1243     <pre class=idl>[Supplemental, NoInterfaceObject]
1244     interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1245     void <a href=#dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in any message, in optional <span>MessagePortArray</span> ports);<!--
1246     <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
1247     attribute <span>Function</span> <a href=#handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
1248     };</pre>
1249    
1250     <p><code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects act as if they
1251     had an implicit <code>MessagePort</code> associated with them. This
1252     port is part of a channel that is set up when the worker is created,
1253     but it is not exposed. This object must never be garbage collected
1254     before the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1255    
1256     <p>All messages received by that port must immediately be retargeted
1257     at the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1258    
1259     <p>The <dfn id=dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
1260     and <dfn
1261     title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
1262     method<!--s (startConversation)--> on
1263     <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects must act as if, when
1264     invoked, it<!--/they (startConversation)--> immediately invoked the
1265     method of the same name on the port, with the same arguments, and
1266     returned the same return value.</p>
1267    
1268     <p>The following are the <span>event handlers</span> (and their
1269     corresponding <span title="event handler event type">event handler
1270     event types</span>) that must be supported, as IDL attributes, by
1271     objects implementing the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1272     interface:</p>
1273    
1274     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1275     <tbody><tr><td><dfn id=handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
1276     </table><p>For the purposes of the <span>application cache</span> networking
1277     model, a dedicated worker is an extension of the <span>cache
1278     host</span> from which it was created.</p>
1279    
1280    
1281    
1282     <h4 id=shared-workers-and-the-sharedworkerglobalscope-inteface><span class=secno>4.1.3 </span>Shared workers and the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> inteface</h4>
1283    
1284     <pre class=idl>[Supplemental, NoInterfaceObject]
1285     interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1286     readonly attribute DOMString <a href=#dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name>name</a>;
1287     readonly attribute <span>ApplicationCache</span> <span title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</span>;
1288     attribute <span>Function</span> <a href=#handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect>onconnect</a>;
1289     };</pre>
1290    
1291     <p>Shared workers receive message ports through <code title=event-WorkerGlobalScope-connect>connect</code> events on
1292     their global object for each connection.</p>
1293    
1294     <p>The <dfn id=dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name><code>name</code></dfn>
1295     attribute must return the value it was assigned when the
1296     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object was created by the
1297     "<a href=#run-a-worker>run a worker</a>" algorithm. Its value represents the name
1298     that can be used to obtain a reference to the worker using the
1299     <code><a href=#sharedworker>SharedWorker</a></code> constructor.</p>
1300    
1301     <p>The following are the <span>event handlers</span> (and their
1302     corresponding <span title="event handler event type">event handler
1303     event types</span>) that must be supported, as IDL attributes, by
1304     objects implementing the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1305     interface:</p>
1306    
1307     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1308     <tbody><tr><td><dfn id=handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect><code>onconnect</code></dfn> <td> <code title=event-connect>connect</code>
1309     </table><p>For the purposes of the <span>application cache</span> networking
1310     model, a shared worker is its own <span>cache host</span>. The
1311     <a href=#run-a-worker>run a worker</a> algorithm takes care of associating the
1312     worker with an <span>application cache</span>.</p>
1313    
1314     <p class=note>The <code title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</code>
1315     attribute returns the <code>ApplicationCache</code> object for the
1316     worker.</p><!-- normative conf criteria is in the appcache section
1317     -->
1318    
1319    
1320     <h3 id=origins-of-workers><span class=secno>4.2 </span>Origins of workers</h3>
1321    
1322     <p>Both the <span>origin</span> and <span>effective script
1323     origin</span> of scripts running in workers are the
1324     <span>origin</span> of the <span>absolute URL</span> given in that
1325     the worker's <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
1326     represents.</p>
1327    
1328    
1329    
1330     <h3 id=the-event-loop><span class=secno>4.3 </span>The event loop</h3>
1331    
1332     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an <span>event
1333     loop</span> distinct from those defined for <span title="unit of
1334     related similar-origin browsing contexts">units of related
1335     similar-origin browsing contexts</span>. This <span>event
1336     loop</span> has no associated <span>browsing context</span>, and its
1337     <span title="task queue">task queues</span> only have events,
1338     callbacks, and networking activity as <span title=concept-task>tasks</span>. The processing model of these
1339     <span title="event loop">event loops</span> is defined below in the
1340     <a href=#run-a-worker>run a worker</a> algorithm.</p>
1341    
1342     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object also has a <dfn id=dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</dfn> flag, which must
1343     initially be false, but which can get set to true by the algorithms
1344     in the processing model section below.</p>
1345    
1346     <p>Once the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set to
1347     true, the <span>event loop</span>'s <span title="task queue">task
1348     queues</span> must discard any further <span title=concept-task>tasks</span> that would be added to them (tasks
1349     already on the queue are unaffected except where otherwise
1350     specified). Effectively, once the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is true,
1351     timers stop firing, notifications for all pending asynchronous
1352     operations are dropped, etc.</p>
1353    
1354    
1355    
1356     <h3 id="the-worker's-lifetime"><span class=secno>4.4 </span>The worker's lifetime</h3>
1357    
1358     <p>Workers communicate with other workers and with <span title="browsing context">browsing contexts</span> through <span title="channel messaging">message channels</span> and their
1359     <code>MessagePort</code> objects.</p>
1360    
1361     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var title="">worker global
1362     scope</var> has a list of <dfn id="the-worker's-ports">the worker's ports</dfn>, which
1363     consists of all the <code>MessagePort</code> objects that are
1364     entangled with another port and that have one (but only one) port
1365     owned by <var title="">worker global scope</var>. This list includes
1366     <!--all the <code>MessagePort</code> objects that are in events
1367     pending in the <span>event loop</span>, as well as (commented out
1368     because in practice it makes no difference either way as far as I
1369     can tell, and it would be hard to strictly implement since these
1370     ports might not yet be across the thread boundary)--> the implicit
1371     <code>MessagePort</code> in the case of <a href=#dedicatedworkerglobalscope title=DedicatedWorkerGlobalScope>dedicated workers</a>.</p>
1372    
1373     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> also has a list of <dfn id="the-worker's-workers">the
1374     worker's workers</dfn>. Initially this list is empty; it is
1375     populated when the worker creates or obtains further workers.</p>
1376    
1377     <p>Finally, each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> also has a list of
1378     <dfn id="the-worker's-documents">the worker's <code>Document</code>s</dfn>. Initially this list
1379     is empty; it is populated when the worker is created.</p>
1380    
1381     <p>Whenever a <code>Document</code> <var title="">d</var> is <dfn id="add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">added to the
1382     worker's <code>Document</code>s</dfn>, the user agent must, for each
1383     worker in the list of <a href="#the-worker's-workers">the worker's workers</a> whose list
1384     of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> does not contain
1385     <var title="">d</var>, <a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's
1386     documents">add <var title="">d</var> to <var title="">q</var>'s
1387     <code>WorkerGlobalScope</code> owner's list of <span>the worker's
1388     <code>Document</code>s</span></a>.</p> <!-- suggestions welcome
1389     on making this sentence into understandable English -->
1390    
1391     <p>Whenever a <code>Document</code> object is <span title="discard a
1392     Document">discarded</span>, it must be removed from the list of
1393     <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> of each worker
1394     whose list contains that <code>Document</code>.</p>
1395    
1396     <p>Given a <span>script's global object</span> <var title="">o</var>
1397     when creating or obtaining a worker, the <dfn id=list-of-relevant-document-objects-to-add>list of relevant
1398     <code>Document</code> objects to add</dfn> depends on the type of
1399     <var title="">o</var>. If <var title="">o</var> is a
1400     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object (i.e. if we are creating a
1401     nested worker), then the relevant <code>Document</code>s are the
1402     <code>Document</code>s that are in <var title="">o</var>'s own list
1403     of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a>. Otherwise, <var title="">o</var> is a <code>Window</code> object, and the relevant
1404     <code>Document</code> is just the <code>Document</code> that is the
1405     <span>active document</span> of the <code>Window</code> object <var title="">o</var>.</p>
1406    
1407     <hr><p>A worker is said to be a <dfn id=permissible-worker>permissible worker</dfn> if its
1408     list of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> is not
1409     empty.</p>
1410    
1411     <p>A worker is said to be a <dfn id=protected-worker>protected worker</dfn> if it is a
1412     <a href=#permissible-worker>permissible worker</a> and either it has outstanding
1413     timers, database transactions, or network connections, or its list
1414     of <a href="#the-worker's-ports">the worker's ports</a> is not empty, or its
1415     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> is actually a
1416     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
1417     shared worker).</p>
1418    
1419     <p>A worker is said to be an <dfn id=active-needed-worker>active needed worker</dfn> if any
1420     of the <code>Document</code> objects in <a href="#the-worker's-documents">the worker's
1421     <code>Document</code>s</a> are <span>fully active</span>.</p>
1422    
1423     <p>A worker is said to be a <dfn id=suspendable-worker>suspendable worker</dfn> if it is
1424     not an <a href=#active-needed-worker>active needed worker</a> but it is a
1425     <a href=#permissible-worker>permissible worker</a>.</p>
1426    
1427    
1428     <h3 id=processing-model><span class=secno>4.5 </span>Processing model</h3>
1429    
1430     <p>When a user agent is to <dfn id=run-a-worker>run a worker</dfn> for a script with
1431 wakaba 1.193 <span>URL</span> <var title="">url</var>, a <span>browsing
1432     context</span> <var title="">owner browsing context</var>, a
1433     <code>Document</code> <var title="">owner document</var>, an
1434     <span>origin</span> <var title="">owner origin</var>, and with
1435     global scope <var title="">worker global scope</var>, it must run
1436     the following steps:</p>
1437 wakaba 1.190
1438     <ol><li>
1439    
1440     <p>Create a completely separate and parallel execution environment
1441     (i.e. a separate thread or process or equivalent construct), and
1442     run the rest of these steps asynchronously in that context.</p>
1443    
1444     </li>
1445    
1446     <li><p>If <var title="">worker global scope</var> is actually a
1447     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
1448     shared worker), and there are any <span title="relevant application
1449     cache">relevant application caches</span> that are identified by a
1450     manifest URL with the <span>same origin</span> as <var title="">url</var> and that have <var title="">url</var> as one of
1451     their entries, <em>not</em> excluding entries marked as <span title=concept-appcache-foreign>foreign</span>, then associate the
1452     <var title="">worker global scope</var> with the <span title=concept-appcache-selection>most appropriate application
1453     cache</span> of those that match.</li>
1454    
1455     <li>
1456    
1457     <p>Attempt to <span>fetch</span> the resource identified by <var title="">url</var>, from the <var title="">owner origin</var>.</p>
1458     <!-- not http-origin privacy sensitive -->
1459    
1460     <p>If the attempt fails, or if the attempt involves any redirects
1461     to URIs that do not have the <span>same origin</span> as <var title="">url</var> (even if the final URI is at the <span>same
1462     origin</span> as the original <var title="">url</var>), then for
1463     each <code><a href=#worker>Worker</a></code> or <code><a href=#sharedworker>SharedWorker</a></code> object
1464     associated with <var title="">worker global scope</var>,
1465     <span>queue a task</span> to <span>fire a simple event</span>
1466     named <code title=event-error>error</code> at that
1467     object. Abort these steps.</p>
1468    
1469     <p>If the attempt succeeds, then convert the script resource to
1470     Unicode by assuming it was encoded as UTF-8, to obtain its <var title="">source</var>.</p>
1471    
1472     <p>Let <var title="">language</var> be JavaScript.</p>
1473    
1474     <p class=note>As with <code>script</code> elements, the MIME
1475     type of the script is ignored. Unlike with <code>script</code>
1476     elements, there is no way to override the type. It's always
1477     assumed to be JavaScript.</p>
1478    
1479     </li>
1480    
1481     <li>
1482    
1483     <p>A new <span title=concept-script>script</span> is now
1484     created, as follows.</p>
1485    
1486     <p>Create a new <span>script execution environment</span>
1487     set up as appropriate for the scripting language <var title="">language</var>.</p>
1488    
1489     <p>Parse/compile/initialize <var title="">source</var> using that
1490     <span>script execution environment</span>, as appropriate for <var title="">language</var>, and thus obtain a <span>list of code
1491     entry-points</span>; set the <i>initial code entry-point</i> to
1492     the entry-point for any executable code to be immediately run.</p>
1493    
1494     <p>Set the <span>script's global object</span> to <var title="">worker global scope</var>.</p>
1495    
1496     <p>Set the <span>script's browsing context</span> to <var title="">owner browsing context</var>.</p>
1497    
1498 wakaba 1.193 <p>Set the <span>script's document</span> to <var title="">owner
1499     document</var>.</p>
1500    
1501 wakaba 1.190 <p>Set the <span>script's URL character encoding</span> to
1502     UTF-8. (This is just used for encoding non-ASCII characters in the
1503     query component of URLs.)</p>
1504    
1505     <p>Set the <span>script's base URL</span> to <var title="">url</var>.</p>
1506    
1507     </li>
1508    
1509     <li>
1510    
1511     <p><strong>Closing orphan workers</strong>: Start monitoring the
1512     worker such that no sooner than it stops being either a
1513     <a href=#protected-worker>protected worker</a> or a <a href=#suspendable-worker>suspendable
1514     worker</a>, and no later than it stops being a
1515     <a href=#permissible-worker>permissible worker</a>, <var title="">worker global
1516     scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
1517     to true<!-- v2-onclose and <span title="queue a task">a task is
1518     queued</span> to <span>fire a simple event</span> named <code
1519     title="event-close">close</code> at <var title="">worker global
1520     scope</var>-->.</p>
1521    
1522     </li>
1523    
1524     <li>
1525    
1526     <p><strong>Suspending workers</strong>: Start monitoring the
1527     worker, such that whenever <var title="">worker global
1528     scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is false
1529     and the worker is a <a href=#suspendable-worker>suspendable worker</a>, the user
1530     agent suspends execution of script in that worker until such time
1531     as either the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag switches
1532     to true or the worker stops being a <a href=#suspendable-worker>suspendable
1533     worker</a>.</p>
1534    
1535     </li>
1536    
1537     <li>
1538    
1539     <p><span title="jump to a code entry-point">Jump</span> to the
1540     <span title=concept-script>script</span>'s <i>initial code
1541     entry-point</i>, and let that run until it either returns, fails
1542     to catch an exception, or gets prematurely aborted by the
1543     "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>"
1544     algorithms defined below.</p>
1545    
1546     <!-- v2-onclose
1547     <p class="note">If the script gets aborted by the "<span>kill a
1548     worker</span>" algorithm, then that same algorithm will cause
1549     there to only be a single <span title="concept-task">task</span>
1550     in the <span>event loop</span> at the next step, namely the task
1551     for the <code title="message-close">close</code> event. The
1552     "<span>terminate a worker</span>" algorithm removes all the
1553     events.</p>
1554     -->
1555    
1556     </li>
1557    
1558     <li><p>If <var title="">worker global scope</var> is actually a
1559     <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is
1560     a dedicated worker), then enable the <span>port message
1561     queue</span> of the worker's implicit port.</li>
1562    
1563     <li>
1564    
1565     <p><i title="">Event loop</i>: Wait until either there is a <span title=concept-task>task</span> in one of the <span>event
1566     loop</span>'s <span title="task queue">task queues</span> or <var title="">worker global scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
1567     to true.</p>
1568    
1569     </li>
1570    
1571     <li>
1572    
1573     <p>Run the oldest task on one of the <span>event loop</span>'s
1574     <span title="task queue">task queues</span>, if any. The user
1575     agent may pick any <span>task queue</span>.</p>
1576    
1577     <p class=note>The handling of events or the execution of
1578     callbacks might get prematurely aborted by the "<a href=#kill-a-worker>kill a
1579     worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>" algorithms
1580     defined below.</p>
1581    
1582     </li>
1583    
1584     <li>
1585    
1586 wakaba 1.203 <p>If the <span>storage mutex</span> is now owned by the worker's
1587     <span>event loop</span>, release it so that it is once again
1588     free.</p>
1589    
1590     </li>
1591    
1592     <li>
1593    
1594     <p>Remove the task just run in the earlier step, if any, from its
1595 wakaba 1.190 <span>task queue</span>.</p>
1596    
1597     </li>
1598    
1599     <li>
1600    
1601     <p>If there are any more events in the <span>event loop</span>'s
1602     <span title="task queue">task queues</span> or if <var title="">worker global scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
1603     to false, then jump back to the step above labeled <i>event
1604     loop</i>.</p>
1605    
1606     </li>
1607    
1608     <li>
1609    
1610     <p>If there are any outstanding transactions that have callbacks
1611     that involve <span title=concept-script>scripts</span> whose
1612     <span title="script's global object">global object</span> is the
1613     <var title="">worker global scope</var>, roll them back (without
1614     invoking any of the callbacks).</p>
1615    
1616     </li>
1617    
1618     <li>
1619    
1620     <p>Empty the <var title="">worker global scope</var>'s <span>list
1621     of active timeouts</span> and its <span>list of active
1622     intervals</span>.</p>
1623 wakaba 1.203
1624     </li>
1625    
1626     <li>
1627    
1628     <p>Disentangle all the ports in the list of <a href="#the-worker's-ports">the worker's
1629     ports</a>.</p>
1630 wakaba 1.190
1631     </li>
1632    
1633     <!-- v2-onclose
1634     <li>
1635    
1636     <p>For each <code>Worker</code> or <code>SharedWorker</code>
1637     object associated with <var title="">worker global scope</var>,
1638     <span>queue a task</span> to <span>fire a simple event</span>
1639     named <code title="event-close">close</code> at that object.</p>
1640    
1641     </li>
1642     -->
1643     </ol><hr><p>When a user agent is to <dfn id=kill-a-worker>kill a worker</dfn> it must
1644     run the following steps in parallel with the worker's main loop (the
1645     "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1646    
1647     <ol><!-- v2-onclose
1648     <li><p>If the worker's <code>WorkerGlobalScope</code> object's
1649     <span title="dom-WorkerGlobalScope-closing">closing</span> flag is
1650     false, <span>queue a task</span> to <span>fire a simple
1651     event</span> named <code title="event-close">close</code> at the
1652     worker's <code>WorkerGlobalScope</code> object.</p></li>
1653     --><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1654     true.</li>
1655    
1656     <!-- v2-onclose
1657     <li><p>Wait a user-agent-defined amount of time. If the "<span>run
1658     a worker</span>" processing model defined above immediately starts
1659     running event listeners registered for the <code
1660     title="event-close">close</code> event, this time should not be
1661     zero &mdash; the idea is that the <code
1662     title="event-close">close</code> event can be used to clean up
1663     when shutting down unexpectedly.</p></li>
1664     -->
1665    
1666     <li><p>If there are any <span title=concept-task>tasks</span>
1667     queued in the <span>event loop</span>'s <span title="task
1668     queue">task queues</span><!-- v2-onclose other than the <code
1669     title="event-close">close</code> event that this algorithm just
1670     added-->, discard them without processing them.</li>
1671    
1672     <!-- v2-onclose
1673     <li><p>If the <code title="event-close">close</code> event that
1674     this algorithm just queued hasn't yet been dispatched, then abort
1675     the script currently running in the worker.</p></li>
1676     -->
1677    
1678     <li><p>Wait a user-agent-defined amount of time.</li>
1679    
1680     <li><p>Abort the script currently running in the worker<!--
1681     v2-onclose (if any script is running, then it will be a handler for
1682     the <code title="event-close">close</code> event)-->.</li>
1683    
1684     </ol><p>User agents may invoke the "<a href=#kill-a-worker>kill a worker</a>"
1685     processing model on a worker at any time, e.g. in response to user
1686     requests, in response to CPU quota management, or when a worker
1687     stops being an <a href=#active-needed-worker>active needed worker</a> if the worker
1688     continues executing even after its <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag was
1689     set to true.</p>
1690    
1691     <hr><p>When a user agent is to <dfn id=terminate-a-worker>terminate a worker</dfn> it must run
1692     the following steps in parallel with the worker's main loop (the
1693     "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1694    
1695     <ol><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1696     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1697     true.</li>
1698    
1699     <li><p>If there are any <span title=concept-task>tasks</span>
1700     queued in the <span>event loop</span>'s <span title="task
1701     queue">task queues</span>, discard them without processing
1702     them.</li>
1703    
1704     <li><p>Abort the script currently running in the worker.</li>
1705    
1706     <li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is
1707     actually a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the
1708     worker is a dedicated worker), then empty the <span>port message
1709     queue</span> of the port that the worker's implicit port is
1710     entangled with.</li>
1711    
1712     </ol><hr><p>The <span>task source</span> for the tasks mentioned above is the
1713     <span>DOM manipulation task source</span>.</p>
1714    
1715    
1716     <h3 id=runtime-script-errors><span class=secno>4.6 </span>Runtime script errors</h3>
1717    
1718     <p>Whenever an uncaught runtime script error occurs in one of the
1719     worker's scripts, if the error did not occur while handling a
1720     previous script error, the user agent must <span>report the
1721     error</span> using the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's <code title=handler-WorkerGlobalScope-onerror><a href=#handler-workerglobalscope-onerror>onerror</a></code>
1722     attribute.
1723    
1724     <a href=#refsHTML>[HTML]</a>
1725    
1726     </p>
1727    
1728     <p>For shared workers, if the error is still <i title=concept-error-nothandled>not handled</i> afterwards, or if
1729     the error occurred while handling a previous script error, the error
1730     may be reported to the user.
1731    
1732     <a href=#refsHTML>[HTML]</a>
1733    
1734     </p>
1735    
1736     <p>For dedicated workers, if the error is still <i title=concept-error-nothandled>not handled</i> afterwards, or if
1737     the error occurred while handling a previous script error, the user
1738     agent must <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
1739     event</a> at the <code><a href=#worker>Worker</a></code> object associated with the
1740     worker.</p>
1741    
1742     <p>When the user agent is to <dfn id=fire-a-worker-error-event>fire a worker error event</dfn> at
1743     a <code><a href=#worker>Worker</a></code> object, it must dispatch an event that uses
1744     the <code><a href=#errorevent>ErrorEvent</a></code> interface, with the name <code title=event-error>error</code>, that doesn't bubble and is
1745     cancelable, with its <code title=dom-ErrorEvent-message><a href=#dom-errorevent-message>message</a></code>, <code title=dom-ErrorEvent-filename><a href=#dom-errorevent-filename>filename</a></code>, and <code title=dom-ErrorEvent-lineno><a href=#dom-errorevent-lineno>lineno</a></code> attributes set
1746     appropriately. The default action of this event depends on whether
1747     the <code><a href=#worker>Worker</a></code> object is itself in a worker. If it is, and
1748     that worker is also a dedicated worker, then the user agent must
1749     again <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
1750     event</a> at the <code><a href=#worker>Worker</a></code> object associated with
1751     <em>that</em> worker. Otherwise, then the error may be reported
1752     to the user.</p>
1753    
1754     <p>The <span>task source</span> for the tasks mentioned above is the
1755     <span>DOM manipulation task source</span>.</p>
1756    
1757 wakaba 1.194 <hr><pre class=idl>interface <dfn id=errorevent>ErrorEvent</dfn> : <span>Event</span> {
1758 wakaba 1.190 readonly attribute DOMString <a href=#dom-errorevent-message title=dom-ErrorEvent-message>message</a>;
1759     readonly attribute DOMString <a href=#dom-errorevent-filename title=dom-ErrorEvent-filename>filename</a>;
1760     readonly attribute unsigned long <a href=#dom-errorevent-lineno title=dom-ErrorEvent-lineno>lineno</a>;
1761     void <a href=#dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent>initErrorEvent</a>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString messageArg, in DOMString filenameArg, in unsigned long linenoArg);
1762     };</pre>
1763    
1764     <p>The <dfn id=dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent><code>initErrorEvent()</code></dfn>
1765     method must initialize the event in a manner analogous to the
1766     similarly-named method in the DOM Events interfaces. <a href=#refsDOMEVENTS>[DOMEVENTS]</a></p>
1767    
1768     <p>The <dfn id=dom-errorevent-message title=dom-ErrorEvent-message><code>message</code></dfn>
1769     attribute represents the error message.</p>
1770    
1771     <p>The <dfn id=dom-errorevent-filename title=dom-ErrorEvent-filename><code>filename</code></dfn>
1772     attribute represents the <span>absolute URL</span> of the script in
1773     which the error originally occurred.</p>
1774    
1775     <p>The <dfn id=dom-errorevent-lineno title=dom-ErrorEvent-lineno><code>lineno</code></dfn>
1776     attribute represents the line number where the error occurred in the
1777     script.</p>
1778    
1779    
1780    
1781     <h3 id=creating-workers><span class=secno>4.7 </span>Creating workers</h3>
1782    
1783     <h4 id=the-abstractworker-abstract-interface><span class=secno>4.7.1 </span>The <code><a href=#abstractworker>AbstractWorker</a></code> abstract interface</h4>
1784    
1785     <pre class=idl>[Supplemental, NoInterfaceObject]
1786     interface <dfn id=abstractworker>AbstractWorker</dfn> {
1787     attribute <span>Function</span> <a href=#handler-abstractworker-onerror title=handler-AbstractWorker-onerror>onerror</a>;
1788     <!-- v2-onclose attribute <span>Function</span> <span title="handler-AbstractWorker-onclose">onclose</span>; -->
1789     };
1790     <a href=#abstractworker>AbstractWorker</a> implements <span>EventTarget</span>;</pre>
1791    
1792     <p>The following are the <span>event handlers</span> (and their
1793     corresponding <span title="event handler event type">event handler
1794     event types</span>) that must be supported, as IDL attributes, by
1795     objects implementing the <code><a href=#abstractworker>AbstractWorker</a></code> interface:</p>
1796    
1797     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1798     <tbody><tr><td><dfn id=handler-abstractworker-onerror title=handler-AbstractWorker-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
1799     <!-- v2-onclose <tr><td><dfn title="handler-AbstractWorker-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> -->
1800     </table><h4 id=dedicated-workers-and-the-worker-interface><span class=secno>4.7.2 </span>Dedicated workers and the <code><a href=#worker>Worker</a></code> interface</h4>
1801    
1802     <pre class=idl>[<a href=#dom-worker title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
1803     interface <dfn id=worker>Worker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1804     void <a href=#dom-worker-terminate title=dom-Worker-terminate>terminate</a>();
1805    
1806     void <a href=#dom-worker-postmessage title=dom-Worker-postMessage>postMessage</a>(in any message, in optional <span>MessagePortArray</span> ports);<!--
1807     <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
1808     attribute <span>Function</span> <a href=#handler-worker-onmessage title=handler-Worker-onmessage>onmessage</a>;
1809     };</pre>
1810    
1811     <p>The <dfn id=dom-worker-terminate title=dom-Worker-terminate><code>terminate()</code></dfn> method,
1812     when invoked, must cause the "<a href=#terminate-a-worker>terminate a worker</a>"
1813     algorithm to be run on the worker with with the object is
1814     associated.</p>
1815    
1816     <p><code><a href=#worker>Worker</a></code> objects act as if they had an implicit
1817     <code>MessagePort</code> associated with them. This port is part of
1818     a channel that is set up when the worker is created, but it is not
1819     exposed. This object must never be garbage collected before the
1820     <code><a href=#worker>Worker</a></code> object.</p>
1821    
1822     <p>All messages received by that port must immediately be retargeted
1823     at the <code><a href=#worker>Worker</a></code> object.</p>
1824    
1825     <p>The <dfn id=dom-worker-postmessage title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
1826     and <dfn
1827     title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
1828     method<!--s (startConversation)--> on <code><a href=#worker>Worker</a></code> objects
1829     must act as if, when invoked, it<!--/they (startConversation)-->
1830     immediately invoked the method of the same name on the port, with
1831     the same arguments, and returned the same return value.</p>
1832    
1833     <p>The following are the <span>event handlers</span> (and their
1834     corresponding <span title="event handler event type">event handler
1835     event types</span>) that must be supported, as IDL attributes, by
1836     objects implementing the <code><a href=#worker>Worker</a></code> interface:</p>
1837    
1838     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1839     <tbody><tr><td><dfn id=handler-worker-onmessage title=handler-Worker-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
1840     </table><hr><p>When the <dfn id=dom-worker title=dom-Worker><code>Worker(<var title="">scriptURL</var>)</code></dfn> constructor is invoked, the
1841     user agent must run the following steps:</p>
1842    
1843     <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument relative to the <span>entry
1844     script</span>'s <span title="script's base URL">base URL</span>,
1845     when the method is invoked.</li>
1846    
1847     <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1848     exception.</li>
1849    
1850     <li>
1851    
1852     <p>If the <span>origin</span> of the resulting <span>absolute
1853     URL</span> is not the <span title="same origin">same</span> as the
1854     origin of the <span>entry script</span>, then throw a
1855     <code>SECURITY_ERR</code> exception.</p>
1856    
1857     <p class=note>Thus, scripts must be external files with the same
1858     scheme as the original page: you can't load a script from a <code title="">data:</code> URL or <code title="">javascript:</code>
1859     URL, and a <code>https:</code> page couldn't start workers using
1860     scripts with <code>http:</code> URLs.</p>
1861    
1862     </li>
1863    
1864     <li><p>Create a new <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1865     object. Let <var title="">worker global scope</var> be this new
1866     object.</li>
1867    
1868     <li><p>Create a new <code><a href=#worker>Worker</a></code> object, associated with
1869     <var title="">worker global scope</var>. Let <var title="">worker</var> be this new object.</li>
1870    
1871     <li><p><span>Create a new <code>MessagePort</code> object</span>
1872     owned by the <span title="script's global object">global
1873     object</span> of the <span title=concept-script>script</span> that
1874     invoked the constructor. Let this be the <var title="">outside
1875     port</var>.</li>
1876    
1877     <li><p>Associate the <var title="">outside port</var> with <var title="">worker</var>.</li>
1878    
1879     <li><p><span>Create a new <code>MessagePort</code> object</span>
1880     owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
1881    
1882     <li><p>Associate <var title="">inside port</var> with <var title="">worker global scope</var>.</li>
1883    
1884     <li><p><span>Entangle</span> <var title="">outside port</var> and
1885     <var title="">inside port</var>.</li>
1886    
1887     <li><p>Return <var title="">worker</var>, and run the following
1888     steps asynchronously.</li>
1889    
1890     <!-- (this is done by the "run a worker" algorithm)
1891     <li><p>Enable <var title="">inside port</var>'s <span>port message
1892     queue</span>.</p></li>
1893     -->
1894    
1895     <li><p>Enable <var title="">outside port</var>'s <span>port message
1896     queue</span>.</li>
1897    
1898     <li>
1899    
1900     <p>Let <var title="">docs</var> be the <a href=#list-of-relevant-document-objects-to-add>list of relevant
1901     <code>Document</code> objects to add</a> given the <span title="script's global object">global object</span> of the <span title=concept-script>script</span> that invoked the
1902     constructor.</p>
1903    
1904     </li>
1905    
1906     <li>
1907    
1908     <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
1909     <var title="">worker global scope</var>'s list of <span>the
1910     worker's <code>Document</code>s</span></a> the
1911     <code>Document</code> objects in <var title="">docs</var>.</p>
1912    
1913     </li>
1914    
1915     <li>
1916    
1917     <p>If the <span title="script's global object">global object</span>
1918     of the <span title=concept-script>script</span> that invoked the
1919     constructor is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object (i.e. we
1920     are creating a nested worker), add <var title="">worker global
1921     scope</var> to the list of <a href="#the-worker's-workers">the worker's workers</a> of the
1922     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object that is the <span title="script's global object">global object</span> of the <span title=concept-script>script</span> that invoked the
1923     constructor.</p>
1924    
1925     </li>
1926    
1927     <li>
1928    
1929     <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
1930     URL</span>, with the <span>script's browsing context</span> of the
1931     script that invoked the method as the <var title="">owner browsing
1932 wakaba 1.193 context</var>, with the <span>script's document</span> of the
1933     script that invoked the method as the <var title="">owner
1934     document</var>, with the <span>origin</span> of the <span>entry
1935 wakaba 1.190 script</span> as the <var title="">owner origin</var>, and with
1936     <var title="">worker global scope</var> as the global scope.</p>
1937    
1938     </li>
1939    
1940     </ol><p>This constructor must be visible when the <span>script's global
1941     object</span> is either a <code>Window</code> object or an object
1942     implementing the <code><a href=#workerutils>WorkerUtils</a></code> interface.</p>
1943    
1944    
1945     <h4 id=shared-workers-and-the-sharedworker-interface><span class=secno>4.7.3 </span>Shared workers and the <code><a href=#sharedworker>SharedWorker</a></code> interface</h4>
1946    
1947     <pre class=idl>[<a href=#dom-sharedworker title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in optional DOMString name)]
1948     interface <dfn id=sharedworker>SharedWorker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1949     readonly attribute <span>MessagePort</span> <a href=#dom-sharedworker-port title=dom-SharedWorker-port>port</a>;
1950     };</pre>
1951    
1952     <p>The <dfn id=dom-sharedworker-port title=dom-SharedWorker-port><code>port</code></dfn>
1953     attribute must return the value it was assigned by the object's
1954     constructor. It represents the <code>MessagePort</code> for
1955     communicating with the shared worker.</p>
1956    
1957     <p>When the <dfn id=dom-sharedworker title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>, <var title="">name</var>)</code></dfn>
1958     constructor is invoked, the user agent must run the following
1959     steps:</p>
1960    
1961     <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
1962    
1963     <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1964     exception.</li>
1965    
1966     <li><p>Otherwise, let <var title="">scriptURL</var> be the
1967     resulting <span>absolute URL</span>.</li>
1968    
1969     <li><p>Let <var title="">name</var> be the value of the second
1970     argument, or the empty string if the second argument was
1971     omitted.</li>
1972    
1973     <li>
1974    
1975     <p>If the <span>origin</span> of <var title="">scriptURL</var> is
1976     not the <span title="same origin">same</span> as the origin of the
1977     <span>entry script</span>, then throw a <code>SECURITY_ERR</code>
1978     exception.</p>
1979    
1980     <p class=note>Thus, scripts must be external files with the same
1981     scheme as the original page: you can't load a script from a <code title="">data:</code> URL or <code title="">javascript:</code>
1982     URL, and a <code>https:</code> page couldn't start workers using
1983     scripts with <code>http:</code> URLs.</p>
1984    
1985     </li>
1986    
1987     <li>
1988    
1989     <p>Let <var title="">docs</var> be the <a href=#list-of-relevant-document-objects-to-add>list of relevant
1990     <code>Document</code> objects to add</a> given the <span title="script's global object">global object</span> of the <span title=concept-script>script</span> that invoked the
1991     constructor.</p>
1992    
1993     </li>
1994    
1995     <li>
1996    
1997     <p>Execute the following substeps atomically:</p>
1998    
1999     <ol><li><p>Create a new <code><a href=#sharedworker>SharedWorker</a></code> object, which will
2000     shortly be associated with a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
2001     object. Let this <code><a href=#sharedworker>SharedWorker</a></code> object be <var title="">worker</var>.</li>
2002    
2003     <li><p><span>Create a new <code>MessagePort</code> object</span>
2004     owned by the <span title="script's global object">global
2005     object</span> of the script that invoked the method. Let this be
2006     the <var title="">outside port</var>.</li>
2007    
2008     <li><p>Assign <var title="">outside port</var> to the <code title=dom-SharedWorker-port><a href=#dom-sharedworker-port>port</a></code> attribute of <var title="">worker</var>.</li>
2009    
2010     <li><p>Let <var title="">worker global scope</var> be
2011     null.</li>
2012    
2013     <li><p>If <var title="">name</var> is not the empty string and
2014     there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object whose
2015     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag
2016     is false, whose <code title=dom-WorkerGlobalScope-name>name</code> attribute is
2017     exactly equal to <var title="">name</var>, and whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
2018     represents an <span>absolute URL</span> with the <span>same
2019     origin</span> as <var title="">scriptURL</var>, then let <var title="">worker global scope</var> be that
2020     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object.</li>
2021    
2022     <li><p>Otherwise, if <var title="">name</var> is the empty string
2023     and there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object
2024     whose <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a>
2025     flag is false, and whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
2026 wakaba 1.197 represents an <span>absolute URL</span> that is exactly equal to
2027     <var title="">scriptURL</var>, then let <var title="">worker
2028     global scope</var> be that <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
2029     object.</li>
2030 wakaba 1.190
2031     <li>
2032    
2033     <p>If <var title="">worker global scope</var> is not null, then
2034     run these steps:</p>
2035    
2036     <ol><li><p>If <var title="">worker global scope</var>'s <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code>
2037     attribute represents an <span>absolute URL</span> that is not
2038     exactly equal to <var title="">scriptURL</var>, then throw a
2039     <code>URL_MISMATCH_ERR</code> exception and abort all these
2040     steps.</li>
2041    
2042     <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
2043    
2044     <li><p><span>Create a new <code>MessagePort</code>
2045     object</span> owned by <var title="">worker global
2046     scope</var>. Let this be the <var title="">inside
2047     port</var>.</li>
2048    
2049     <li><p><span>Entangle</span> <var title="">outside port</var>
2050     and <var title="">inside port</var>.</li>
2051    
2052     <li><p>Return <var title="">worker</var> and perform the next
2053     step asynchronously.</li>
2054    
2055     <li><p>Create an event that uses the <code>MessageEvent</code>
2056     interface, with the name <code title=event-connect>connect</code>, which does not bubble, is
2057     not cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value
2058     is the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose
2059     value is an array containing only the newly created port, and
2060     <span>queue a task</span> to dispatch the event at <var title="">worker global scope</var>.</li>
2061    
2062     <li>
2063    
2064     <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
2065     <var title="">worker global scope</var>'s list of <span>the
2066     worker's <code>Document</code>s</span></a> the
2067     <code>Document</code> objects in <var title="">docs</var>.</p>
2068    
2069     </li>
2070    
2071     <li>
2072    
2073     <p>If the <span title="script's global object">global
2074     object</span> of the <span title=concept-script>script</span>
2075     that invoked the constructor is a
2076     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, add <var title="">worker global scope</var> to the list of <a href="#the-worker's-workers">the
2077     worker's workers</a> of the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
2078     object that is the <span title="script's global object">global
2079     object</span> of the <span title=concept-script>script</span>
2080     that invoked the constructor.</p>
2081    
2082     </li>
2083    
2084     <li><p>Abort all these steps.</li>
2085    
2086     </ol></li>
2087    
2088     <li><p>Create a new <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
2089     object. Let <var title="">worker global scope</var> be this new
2090     object.</li>
2091    
2092     <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
2093    
2094     <li><p>Set the <code title=dom-SharedWorkerGlobalScope-name><a href=#dom-sharedworkerglobalscope-name>name</a></code> attribute of
2095     <var title="">worker global scope</var> to <var title="">name</var>.</li>
2096    
2097     <li><p><span>Create a new <code>MessagePort</code> object</span>
2098     owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
2099    
2100     <li><p><span>Entangle</span> <var title="">outside port</var> and
2101     <var title="">inside port</var>.</li>
2102    
2103     </ol></li>
2104    
2105     <li><p>Return <var title="">worker</var> and perform the remaining
2106     steps asynchronously.</li>
2107    
2108     <li><p>Create an event that uses the <code>MessageEvent</code>
2109     interface, with the name <code title=event-connect>connect</code>, which does not bubble, is not
2110     cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value is
2111     the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose value
2112     is an array containing only the newly created port, and <span>queue
2113     a task</span> to dispatch the event at <var title="">worker global
2114     scope</var>.</li>
2115    
2116     <li>
2117    
2118     <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
2119     <var title="">worker global scope</var>'s list of <span>the
2120     worker's <code>Document</code>s</span></a> the
2121     <code>Document</code> objects in <var title="">docs</var>.</p>
2122    
2123     </li>
2124    
2125     <li>
2126    
2127     <p>If the <span title="script's global object">global object</span>
2128     of the <span title=concept-script>script</span> that invoked the
2129     constructor is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, add <var title="">worker global scope</var> to the list of <a href="#the-worker's-workers">the
2130     worker's workers</a> of the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
2131     object that is the <span title="script's global object">global
2132     object</span> of the <span title=concept-script>script</span>
2133     that invoked the constructor.</p>
2134    
2135     </li>
2136    
2137     <li>
2138    
2139     <p><a href=#run-a-worker>Run a worker</a> for <var title="">scriptURL</var>,
2140     with the <span>script's browsing context</span> of the script that
2141     invoked the method as the <var title="">owner browsing
2142 wakaba 1.193 context</var>, with the <span>script's document</span> of the
2143     script that invoked the method as the <var title="">owner
2144     document</var>, with the <span>origin</span> of the <span>entry
2145 wakaba 1.190 script</span> as the <var title="">owner origin</var>, and with
2146     <var title="">worker global scope</var> as the global scope.</p>
2147    
2148     </li>
2149    
2150     </ol><p>This constructor must be visible when the <span>script's global
2151     object</span> is either a <code>Window</code> object or an object
2152     implementing the <code><a href=#workerutils>WorkerUtils</a></code> interface.</p>
2153    
2154     <p>The <span>task source</span> for the tasks mentioned above is the
2155     <span>DOM manipulation task source</span>.</p>
2156    
2157    
2158    
2159     <h2 id=apis-available-to-workers><span class=secno>5 </span>APIs available to workers</h2>
2160    
2161     <pre class=idl>[Supplemental, NoInterfaceObject]
2162     interface <dfn id=workerutils>WorkerUtils</dfn> {
2163     void <a href=#dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts>importScripts</a>(in DOMString... urls);
2164     readonly attribute <a href=#workernavigator>WorkerNavigator</a> <a href=#dom-worker-navigator title=dom-worker-navigator>navigator</a>;
2165     };
2166     <a href=#workerutils>WorkerUtils</a> implements <span>WindowTimers</span>;</pre>
2167    
2168     <p>The DOM APIs (<code>Node</code> objects, <code>Document</code>
2169     objects, etc) are not available to workers in this version of this
2170     specification.</p>
2171    
2172    
2173     <h3 id=importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</h3>
2174    
2175     <p>When a script invokes the <dfn id=dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts><code>importScripts(<var title="">urls</var>)</code></dfn> method on a
2176     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
2177     following steps:</p>
2178    
2179     <ol><li><p>If there are no arguments, return without doing
2180     anything. Abort these steps.</li>
2181    
2182     <li><p><span title="resolve a url">Resolve</span> each
2183     argument.</li>
2184    
2185     <li><p>If any fail, throw a <code>SYNTAX_ERR</code>
2186     exception.</li>
2187    
2188     <!--
2189     <li><p>If any of the resulting <span title="absolute URL">absolute
2190     URLs</span> have an <span>origin</span> that is not the <span
2191     title="same origin">same</span> as the origin of the script that
2192     invoked the method, then throw a <code>SECURITY_ERR</code>
2193     exception.</p></li>
2194     -->
2195    
2196     <li>
2197    
2198     <p>Attempt to <span>fetch</span> each resource identified by the
2199     resulting <span title="absolute URL">absolute URLs</span>, from
2200     the <span>entry script</span>'s <span>origin</span>.</p> <!-- not
2201     http-origin privacy sensitive -->
2202    
2203     </li>
2204    
2205     <li>
2206    
2207     <p>For each argument in turn, in the order given, starting with
2208     the first one, run these substeps:</p>
2209    
2210     <ol><li>
2211    
2212     <p>Wait for the fetching attempt for the corresponding resource
2213     to complete.</p>
2214    
2215     <p>If the fetching attempt failed, throw a
2216     <code>NETWORK_ERR</code> exception and abort all these
2217     steps.</p>
2218    
2219     <p>If the attempt succeeds, then convert the script resource to
2220     Unicode by assuming it was encoded as UTF-8, to obtain its <var title="">source</var>.</p>
2221    
2222     <p>Let <var title="">language</var> be JavaScript.</p>
2223    
2224     <p class=note>As with the worker's script, the script here is
2225     always assumed to be JavaScript, regardless of the MIME
2226     type.</p>
2227    
2228     </li>
2229    
2230     <li>
2231    
2232     <p><span>Create a script</span>, using <var title="">source</var> as the script source and <var title="">language</var> as the scripting language, using the
2233     same global object, browsing context, URL character encoding,
2234     base URL, and script group as the <span title=concept-script>script</span> that was created by the
2235     worker's <a href=#run-a-worker>run a worker</a> algorithm.</p>
2236    
2237     <p>Let the newly created <span title=concept-script>script</span> run until it either
2238     returns, fails to parse, fails to catch an exception, or gets
2239     prematurely aborted by the "<a href=#kill-a-worker>kill a worker</a>" or
2240     "<a href=#terminate-a-worker>terminate a worker</a>" algorithms defined above.</p>
2241    
2242     <p>If it failed to parse, then throw an ECMAScript
2243     <code>SyntaxError</code> exception and abort all these
2244     steps. <a href=#refsECMA262>[ECMA262]</a></p>
2245    
2246     <p>If an exception was raised or if the script was prematurely
2247     aborted, then abort all these steps, letting the exception or
2248     aborting continue to be processed by the script that called the
2249     <code title=dom-WorkerGlobalScope-importScripts><a href=#dom-workerglobalscope-importscripts>importScripts()</a></code>
2250     method.</p>
2251    
2252     <p>If the "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a
2253     worker</a>" algorithms abort the script then abort all these
2254     steps.</p>
2255    
2256     </li>
2257    
2258     </ol></li>
2259    
2260     </ol><h3 id=the-workernavigator-object><span class=secno>5.2 </span>The <code><a href=#workernavigator>WorkerNavigator</a></code> object</h3>
2261    
2262     <p>The <dfn id=dom-worker-navigator title=dom-worker-navigator><code>navigator</code></dfn> attribute
2263     of the <code><a href=#workerutils>WorkerUtils</a></code> interface must return an instance of
2264     the <code><a href=#workernavigator>WorkerNavigator</a></code> interface, which represents the
2265     identity and state of the user agent (the client):</p>
2266    
2267     <pre class=idl>interface <dfn id=workernavigator>WorkerNavigator</dfn> {};
2268     <a href=#workernavigator>WorkerNavigator</a> implements <span>NavigatorID</span>;
2269     <a href=#workernavigator>WorkerNavigator</a> implements <span>NavigatorOnLine</span>;</pre>
2270    
2271     <p>Objects implementing the <code><a href=#workernavigator>WorkerNavigator</a></code> interface
2272     also implement the <code>NavigatorID</code> and
2273     <code>NavigatorOnLine</code> interfaces.
2274    
2275     <a href=#refsHTML>[HTML]</a>
2276    
2277     </p>
2278    
2279     <p>This <code><a href=#workernavigator>WorkerNavigator</a></code> interface must not exist if the
2280     interface's <span>relevant namespace object</span> is a
2281     <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
2282    
2283    
2284    
2285     <h3 id=apis-defined-in-other-specifications><span class=secno>5.3 </span>APIs defined in other specifications</h3>
2286    
2287     <p>The <code title=dom-opendatabase>openDatabase()</code> and
2288     <code title=dom-opendatabase-sync>openDatabaseSync()</code>
2289     methods are defined in the Web SQL Database specification. <a href=#refsWEBSQL>[WEBSQL]</a></p>
2290    
2291    
2292    
2293     <h3 id=interface-objects-and-constructors><span class=secno>5.4 </span>Interface objects and constructors</h3>
2294    
2295     <p>There must be no interface objects and constructors available in
2296     the global scope of scripts whose <span>script's global
2297     object</span> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object except for
2298     the following:</p>
2299    
2300     <ul><li><p><code>XMLHttpRequest</code> and all interface objects and
2301     constructors defined by the XMLHttpRequest specifications, except
2302     that the <span>document response entity body</span> must always be
2303     null. The <span><code>XMLHttpRequest</code> base URL</span> is the
2304     <span>script's base URL</span>; the
2305     <span><code>XMLHttpRequest</code> origin</span> is the script's
2306     <span>origin</span>. <a href=#refsXHR>[XHR]</a></li>
2307    
2308     <li><p>The interface objects and constructors defined by this
2309     specification.</li>
2310    
2311     <li><p>Constructors defined by specifications that explicitly say
2312     that they should be visible when the <span>script's global
2313     object</span> is a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>, a
2314     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>, or an object implementing the
2315     <code><a href=#workerutils>WorkerUtils</a></code> interface; the interfaces of any objects
2316     with such constructors; and the interfaces of any objects made
2317     accessible through APIs exposed by those constructors or made
2318     accessible through interfaces to be implemented by any objects that
2319     are themselves accessible to scripts whose <span>script's global
2320     object</span> implements the <code><a href=#workerutils>WorkerUtils</a></code>
2321     interface.</li>
2322    
2323     </ul><p class=note>These requirements do not override the requirements
2324     defined by the Web IDL specification, in particular concerning the
2325     visibility of interfaces annotated with the <code title="">[NoInterfaceObject]</code> extended attribute.</p>
2326    
2327    
2328     <h3 id=worker-locations><span class=secno>5.5 </span>Worker locations</h3>
2329    
2330     <pre class=idl>interface <dfn id=workerlocation>WorkerLocation</dfn> {
2331     readonly attribute DOMString <a href=#dom-workerlocation-href title=dom-WorkerLocation-href>href</a>;
2332     readonly attribute DOMString <a href=#dom-workerlocation-protocol title=dom-WorkerLocation-protocol>protocol</a>;
2333     readonly attribute DOMString <a href=#dom-workerlocation-host title=dom-WorkerLocation-host>host</a>;
2334     readonly attribute DOMString <a href=#dom-workerlocation-hostname title=dom-WorkerLocation-hostname>hostname</a>;
2335     readonly attribute DOMString <a href=#dom-workerlocation-port title=dom-WorkerLocation-port>port</a>;
2336     readonly attribute DOMString <a href=#dom-workerlocation-pathname title=dom-WorkerLocation-pathname>pathname</a>;
2337     readonly attribute DOMString <a href=#dom-workerlocation-search title=dom-WorkerLocation-search>search</a>;
2338     readonly attribute DOMString <a href=#dom-workerlocation-hash title=dom-WorkerLocation-hash>hash</a>;
2339     };</pre>
2340    
2341     <p>A <code><a href=#workerlocation>WorkerLocation</a></code> object represents an <span>absolute
2342     URL</span> set at its creation.</p>
2343    
2344     <p>The <dfn id=dom-workerlocation-href title=dom-WorkerLocation-href><code>href</code></dfn>
2345     attribute must return the <span>absolute URL</span> that the object
2346     represents.</p>
2347    
2348     <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface also has the complement
2349     of <span>URL decomposition IDL attributes</span>, <dfn id=dom-workerlocation-protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
2350     <dfn id=dom-workerlocation-host title=dom-WorkerLocation-host><code>host</code></dfn>, <dfn id=dom-workerlocation-port title=dom-WorkerLocation-port><code>port</code></dfn>, <dfn id=dom-workerlocation-hostname title=dom-WorkerLocation-hostname><code>hostname</code></dfn>,
2351     <dfn id=dom-workerlocation-pathname title=dom-WorkerLocation-pathname><code>pathname</code></dfn>,
2352     <dfn id=dom-workerlocation-search title=dom-WorkerLocation-search><code>search</code></dfn>,
2353     and <dfn id=dom-workerlocation-hash title=dom-WorkerLocation-hash><code>hash</code></dfn>. These must
2354     follow the rules given for URL decomposition IDL attributes, with the
2355     <span title=concept-uda-input>input</span> being the
2356     <span>absolute URL</span> that the object represents (same as the
2357     <code title=dom-WorkerLocation-href><a href=#dom-workerlocation-href>href</a></code> attribute), and
2358     the <span title=concept-uda-setter>common setter action</span>
2359     being a no-op, since the attributes are defined to be readonly.
2360    
2361     <a href=#refsHTML>[HTML]</a>
2362    
2363     </p>
2364    
2365     <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface must not exist if the
2366     interface's <span>relevant namespace object</span> is a
2367     <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
2368    
2369    
2370    
2371     <h2 class=no-num id=references>References</h2><!--REFS-->
2372    
2373     <p>All references are normative unless marked "Non-normative".</p>
2374    
2375 wakaba 1.204 <!-- Dates are only included for standards older than the Web, because the newer ones keep changing. -->
2376 wakaba 1.190
2377     <dl><dt id=refsDOMCORE>[DOMCORE]</dt>
2378     <dd><cite><a href=http://www.w3.org/TR/DOM-Level-3-Core/>Document
2379     Object Model (DOM) Level 3 Core Specification</a></cite>, A. Le
2380     Hors, P. Le Hegaret, L. Wood, G. Nicol, J. Robie, M. Champion,
2381     S. Byrnes. W3C.</dd>
2382     <!--
2383     <dd><cite><a href="http://simon.html5.org/specs/web-dom-core">Web
2384     DOM Core</a></cite>, S. Pieters. W3C.</dd>
2385     -->
2386    
2387     <dt id=refsDOMEVENTS>[DOMEVENTS]</dt>
2388     <!--
2389     <dd><cite><a
2390     href="http://www.w3.org/TR/DOM-Level-3-Events/">Document Object
2391     Model (DOM) Level 3 Events Specification</a></cite>,
2392     B. H&ouml;hrmann, P. Le Hegaret, T. Pixley. W3C.</dd>
2393     -->
2394     <dd><cite><a href=http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html>Document
2395     Object Model (DOM) Level 3 Events Specification</a></cite>,
2396     D. Schepers. W3C.</dd>
2397    
2398     <dt id=refsECMA262>[ECMA262]</dt>
2399     <dd><cite><a href=http://www.ecma-international.org/publications/standards/Ecma-262.htm>ECMAScript
2400     Language Specification</a></cite>. ECMA.</dd>
2401    
2402     <dt id=refsHTML>[HTML]</dt>
2403     <dd><cite><a href=http://www.whatwg.org/specs/web-apps/current-work/>HTML</a></cite>,
2404     I. Hickson. WHATWG.</dd>
2405    
2406     <dt id=refsRFC2119>[RFC2119]</dt>
2407     <dd><cite><a href=http://www.ietf.org/rfc/rfc2119.txt>Key words for use in
2408     RFCs to Indicate Requirement Levels</a></cite>, S. Bradner. IETF.</dd>
2409    
2410     <dt id=refsWEBIDL>[WEBIDL]</dt>
2411     <!--
2412     <dd><cite><a href="http://www.w3.org/TR/WebIDL/">Web
2413     IDL</a></cite>, C. McCormack. W3C.</dd>
2414     -->
2415     <dd><cite><a href=http://dev.w3.org/2006/webapi/WebIDL/>Web
2416     IDL</a></cite>, C. McCormack. W3C.</dd>
2417 wakaba 1.192
2418     <dt id=refsWEBSQL>[WEBSQL]</dt>
2419     <dd><cite><a href=http://dev.w3.org/html5/webdatabase/>Web SQL
2420     Database</a></cite>, I. Hickson. W3C.</dd>
2421 wakaba 1.190
2422     <dt id=refsXHR>[XHR]</dt>
2423     <!--
2424     <dd><cite><a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest
2425     Object</a></cite>, A. van Kesteren. W3C.</dd>
2426     -->
2427     <dd><cite><a href=http://dev.w3.org/2006/webapi/XMLHttpRequest-2/><code>XMLHttpRequest</code></a></cite>,
2428     A. van Kesteren. W3C.</dd>
2429    
2430     </dl><h2 class=no-num id=acknowledgements>Acknowledgements</h2> <!-- ACKS -->
2431    
2432     <p>Thanks to
2433    
2434     Aaron Boodman,
2435     &#1040;&#1083;&#1077;&#1082;&#1089;&#1077;&#1081; &#1055;&#1088;&#1086;&#1089;&#1082;&#1091;&#1088;&#1103;&#1082;&#1086;&#1074; (Alexey Proskuryakov),
2436     Anne van Kesteren,
2437     Ben Turner,
2438     Dmitry Titov,
2439     Drew Wilson,
2440     Jeremy Orlow,
2441     Jonas Sicking,
2442     Justin James,
2443     Kevin Hakanson,
2444     Maciej Stachowiak,
2445     Michael Nordman,
2446     Mike Smith,
2447    
2448     and
2449    
2450     Philip Taylor
2451    
2452     for their useful and substantial comments.</p>
2453    
2454     <p>Huge thanks to the whole Gears team, who pioneered this
2455     technology and whose experience has been a huge influence on this
2456     specification.</p>
2457    
2458    

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24