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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24