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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24