/[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.201 - (hide annotations) (download) (as text)
Tue Apr 13 06:21:36 2010 UTC (15 years, 11 months ago) by wakaba
Branch: MAIN
Changes since 1.200: +7 -1 lines
File MIME type: text/html
make

1 wakaba 1.190 <!DOCTYPE html><html lang=en-US-x-hixie><meta charset=ascii><title>Web Workers</title><link href=/style/specification rel=stylesheet><link href=/images/icon rel=icon><body class=cfc>
2    
3     <header class=head><p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG src=/images/logo></a></p>
4     <hgroup><h1>Web Workers</h1>
5 wakaba 1.201 <h2 class="no-num no-toc">Draft Recommendation &mdash; 12 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     <li><p>Disentangle all the ports in the list of <a href="#the-worker's-ports">the worker's
1226     ports</a>.</li>
1227    
1228     </ol><p>The following are the <span>event handlers</span> (and their
1229     corresponding <span title="event handler event type">event handler
1230     event types</span>) that must be supported, as IDL attributes, by
1231     objects implementing the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
1232     interface:</p>
1233    
1234     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1235     <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>
1236     </table><hr><p>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface must not exist if
1237     the interface's <span>relevant namespace object</span> is a
1238     <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
1239    
1240    
1241    
1242     <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>
1243    
1244     <pre class=idl>[Supplemental, NoInterfaceObject]
1245     interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1246     void <a href=#dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in any message, in optional <span>MessagePortArray</span> ports);<!--
1247     <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
1248     attribute <span>Function</span> <a href=#handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
1249     };</pre>
1250    
1251     <p><code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects act as if they
1252     had an implicit <code>MessagePort</code> associated with them. This
1253     port is part of a channel that is set up when the worker is created,
1254     but it is not exposed. This object must never be garbage collected
1255     before the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1256    
1257     <p>All messages received by that port must immediately be retargeted
1258     at the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1259    
1260     <p>The <dfn id=dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
1261     and <dfn
1262     title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
1263     method<!--s (startConversation)--> on
1264     <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects must act as if, when
1265     invoked, it<!--/they (startConversation)--> immediately invoked the
1266     method of the same name on the port, with the same arguments, and
1267     returned the same return value.</p>
1268    
1269     <p>The following are the <span>event handlers</span> (and their
1270     corresponding <span title="event handler event type">event handler
1271     event types</span>) that must be supported, as IDL attributes, by
1272     objects implementing the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1273     interface:</p>
1274    
1275     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1276     <tbody><tr><td><dfn id=handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
1277     </table><p>For the purposes of the <span>application cache</span> networking
1278     model, a dedicated worker is an extension of the <span>cache
1279     host</span> from which it was created.</p>
1280    
1281    
1282    
1283     <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>
1284    
1285     <pre class=idl>[Supplemental, NoInterfaceObject]
1286     interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1287     readonly attribute DOMString <a href=#dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name>name</a>;
1288     readonly attribute <span>ApplicationCache</span> <span title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</span>;
1289     attribute <span>Function</span> <a href=#handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect>onconnect</a>;
1290     };</pre>
1291    
1292     <p>Shared workers receive message ports through <code title=event-WorkerGlobalScope-connect>connect</code> events on
1293     their global object for each connection.</p>
1294    
1295     <p>The <dfn id=dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name><code>name</code></dfn>
1296     attribute must return the value it was assigned when the
1297     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object was created by the
1298     "<a href=#run-a-worker>run a worker</a>" algorithm. Its value represents the name
1299     that can be used to obtain a reference to the worker using the
1300     <code><a href=#sharedworker>SharedWorker</a></code> constructor.</p>
1301    
1302     <p>The following are the <span>event handlers</span> (and their
1303     corresponding <span title="event handler event type">event handler
1304     event types</span>) that must be supported, as IDL attributes, by
1305     objects implementing the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1306     interface:</p>
1307    
1308     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1309     <tbody><tr><td><dfn id=handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect><code>onconnect</code></dfn> <td> <code title=event-connect>connect</code>
1310     </table><p>For the purposes of the <span>application cache</span> networking
1311     model, a shared worker is its own <span>cache host</span>. The
1312     <a href=#run-a-worker>run a worker</a> algorithm takes care of associating the
1313     worker with an <span>application cache</span>.</p>
1314    
1315     <p class=note>The <code title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</code>
1316     attribute returns the <code>ApplicationCache</code> object for the
1317     worker.</p><!-- normative conf criteria is in the appcache section
1318     -->
1319    
1320    
1321     <h3 id=origins-of-workers><span class=secno>4.2 </span>Origins of workers</h3>
1322    
1323     <p>Both the <span>origin</span> and <span>effective script
1324     origin</span> of scripts running in workers are the
1325     <span>origin</span> of the <span>absolute URL</span> given in that
1326     the worker's <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
1327     represents.</p>
1328    
1329    
1330    
1331     <h3 id=the-event-loop><span class=secno>4.3 </span>The event loop</h3>
1332    
1333     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an <span>event
1334     loop</span> distinct from those defined for <span title="unit of
1335     related similar-origin browsing contexts">units of related
1336     similar-origin browsing contexts</span>. This <span>event
1337     loop</span> has no associated <span>browsing context</span>, and its
1338     <span title="task queue">task queues</span> only have events,
1339     callbacks, and networking activity as <span title=concept-task>tasks</span>. The processing model of these
1340     <span title="event loop">event loops</span> is defined below in the
1341     <a href=#run-a-worker>run a worker</a> algorithm.</p>
1342    
1343     <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
1344     initially be false, but which can get set to true by the algorithms
1345     in the processing model section below.</p>
1346    
1347     <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
1348     true, the <span>event loop</span>'s <span title="task queue">task
1349     queues</span> must discard any further <span title=concept-task>tasks</span> that would be added to them (tasks
1350     already on the queue are unaffected except where otherwise
1351     specified). Effectively, once the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is true,
1352     timers stop firing, notifications for all pending asynchronous
1353     operations are dropped, etc.</p>
1354    
1355    
1356    
1357     <h3 id="the-worker's-lifetime"><span class=secno>4.4 </span>The worker's lifetime</h3>
1358    
1359     <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
1360     <code>MessagePort</code> objects.</p>
1361    
1362     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var title="">worker global
1363     scope</var> has a list of <dfn id="the-worker's-ports">the worker's ports</dfn>, which
1364     consists of all the <code>MessagePort</code> objects that are
1365     entangled with another port and that have one (but only one) port
1366     owned by <var title="">worker global scope</var>. This list includes
1367     <!--all the <code>MessagePort</code> objects that are in events
1368     pending in the <span>event loop</span>, as well as (commented out
1369     because in practice it makes no difference either way as far as I
1370     can tell, and it would be hard to strictly implement since these
1371     ports might not yet be across the thread boundary)--> the implicit
1372     <code>MessagePort</code> in the case of <a href=#dedicatedworkerglobalscope title=DedicatedWorkerGlobalScope>dedicated workers</a>.</p>
1373    
1374     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> also has a list of <dfn id="the-worker's-workers">the
1375     worker's workers</dfn>. Initially this list is empty; it is
1376     populated when the worker creates or obtains further workers.</p>
1377    
1378     <p>Finally, each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> also has a list of
1379     <dfn id="the-worker's-documents">the worker's <code>Document</code>s</dfn>. Initially this list
1380     is empty; it is populated when the worker is created.</p>
1381    
1382     <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
1383     worker's <code>Document</code>s</dfn>, the user agent must, for each
1384     worker in the list of <a href="#the-worker's-workers">the worker's workers</a> whose list
1385     of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> does not contain
1386     <var title="">d</var>, <a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's
1387     documents">add <var title="">d</var> to <var title="">q</var>'s
1388     <code>WorkerGlobalScope</code> owner's list of <span>the worker's
1389     <code>Document</code>s</span></a>.</p> <!-- suggestions welcome
1390     on making this sentence into understandable English -->
1391    
1392     <p>Whenever a <code>Document</code> object is <span title="discard a
1393     Document">discarded</span>, it must be removed from the list of
1394     <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> of each worker
1395     whose list contains that <code>Document</code>.</p>
1396    
1397     <p>Given a <span>script's global object</span> <var title="">o</var>
1398     when creating or obtaining a worker, the <dfn id=list-of-relevant-document-objects-to-add>list of relevant
1399     <code>Document</code> objects to add</dfn> depends on the type of
1400     <var title="">o</var>. If <var title="">o</var> is a
1401     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object (i.e. if we are creating a
1402     nested worker), then the relevant <code>Document</code>s are the
1403     <code>Document</code>s that are in <var title="">o</var>'s own list
1404     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
1405     <code>Document</code> is just the <code>Document</code> that is the
1406     <span>active document</span> of the <code>Window</code> object <var title="">o</var>.</p>
1407    
1408     <hr><p>A worker is said to be a <dfn id=permissible-worker>permissible worker</dfn> if its
1409     list of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> is not
1410     empty.</p>
1411    
1412     <p>A worker is said to be a <dfn id=protected-worker>protected worker</dfn> if it is a
1413     <a href=#permissible-worker>permissible worker</a> and either it has outstanding
1414     timers, database transactions, or network connections, or its list
1415     of <a href="#the-worker's-ports">the worker's ports</a> is not empty, or its
1416     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> is actually a
1417     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
1418     shared worker).</p>
1419    
1420     <p>A worker is said to be an <dfn id=active-needed-worker>active needed worker</dfn> if any
1421     of the <code>Document</code> objects in <a href="#the-worker's-documents">the worker's
1422     <code>Document</code>s</a> are <span>fully active</span>.</p>
1423    
1424     <p>A worker is said to be a <dfn id=suspendable-worker>suspendable worker</dfn> if it is
1425     not an <a href=#active-needed-worker>active needed worker</a> but it is a
1426     <a href=#permissible-worker>permissible worker</a>.</p>
1427    
1428    
1429     <h3 id=processing-model><span class=secno>4.5 </span>Processing model</h3>
1430    
1431     <p>When a user agent is to <dfn id=run-a-worker>run a worker</dfn> for a script with
1432 wakaba 1.193 <span>URL</span> <var title="">url</var>, a <span>browsing
1433     context</span> <var title="">owner browsing context</var>, a
1434     <code>Document</code> <var title="">owner document</var>, an
1435     <span>origin</span> <var title="">owner origin</var>, and with
1436     global scope <var title="">worker global scope</var>, it must run
1437     the following steps:</p>
1438 wakaba 1.190
1439     <ol><li>
1440    
1441     <p>Create a completely separate and parallel execution environment
1442     (i.e. a separate thread or process or equivalent construct), and
1443     run the rest of these steps asynchronously in that context.</p>
1444    
1445     </li>
1446    
1447     <li><p>If <var title="">worker global scope</var> is actually a
1448     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
1449     shared worker), and there are any <span title="relevant application
1450     cache">relevant application caches</span> that are identified by a
1451     manifest URL with the <span>same origin</span> as <var title="">url</var> and that have <var title="">url</var> as one of
1452     their entries, <em>not</em> excluding entries marked as <span title=concept-appcache-foreign>foreign</span>, then associate the
1453     <var title="">worker global scope</var> with the <span title=concept-appcache-selection>most appropriate application
1454     cache</span> of those that match.</li>
1455    
1456     <li>
1457    
1458     <p>Attempt to <span>fetch</span> the resource identified by <var title="">url</var>, from the <var title="">owner origin</var>.</p>
1459     <!-- not http-origin privacy sensitive -->
1460    
1461     <p>If the attempt fails, or if the attempt involves any redirects
1462     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
1463     origin</span> as the original <var title="">url</var>), then for
1464     each <code><a href=#worker>Worker</a></code> or <code><a href=#sharedworker>SharedWorker</a></code> object
1465     associated with <var title="">worker global scope</var>,
1466     <span>queue a task</span> to <span>fire a simple event</span>
1467     named <code title=event-error>error</code> at that
1468     object. Abort these steps.</p>
1469    
1470     <p>If the attempt succeeds, then convert the script resource to
1471     Unicode by assuming it was encoded as UTF-8, to obtain its <var title="">source</var>.</p>
1472    
1473     <p>Let <var title="">language</var> be JavaScript.</p>
1474    
1475     <p class=note>As with <code>script</code> elements, the MIME
1476     type of the script is ignored. Unlike with <code>script</code>
1477     elements, there is no way to override the type. It's always
1478     assumed to be JavaScript.</p>
1479    
1480     </li>
1481    
1482     <li>
1483    
1484     <p>A new <span title=concept-script>script</span> is now
1485     created, as follows.</p>
1486    
1487     <p>Create a new <span>script execution environment</span>
1488     set up as appropriate for the scripting language <var title="">language</var>.</p>
1489    
1490     <p>Parse/compile/initialize <var title="">source</var> using that
1491     <span>script execution environment</span>, as appropriate for <var title="">language</var>, and thus obtain a <span>list of code
1492     entry-points</span>; set the <i>initial code entry-point</i> to
1493     the entry-point for any executable code to be immediately run.</p>
1494    
1495     <p>Set the <span>script's global object</span> to <var title="">worker global scope</var>.</p>
1496    
1497     <p>Set the <span>script's browsing context</span> to <var title="">owner browsing context</var>.</p>
1498    
1499 wakaba 1.193 <p>Set the <span>script's document</span> to <var title="">owner
1500     document</var>.</p>
1501    
1502 wakaba 1.190 <p>Set the <span>script's URL character encoding</span> to
1503     UTF-8. (This is just used for encoding non-ASCII characters in the
1504     query component of URLs.)</p>
1505    
1506     <p>Set the <span>script's base URL</span> to <var title="">url</var>.</p>
1507    
1508     </li>
1509    
1510     <li>
1511    
1512     <p><strong>Closing orphan workers</strong>: Start monitoring the
1513     worker such that no sooner than it stops being either a
1514     <a href=#protected-worker>protected worker</a> or a <a href=#suspendable-worker>suspendable
1515     worker</a>, and no later than it stops being a
1516     <a href=#permissible-worker>permissible worker</a>, <var title="">worker global
1517     scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
1518     to true<!-- v2-onclose and <span title="queue a task">a task is
1519     queued</span> to <span>fire a simple event</span> named <code
1520     title="event-close">close</code> at <var title="">worker global
1521     scope</var>-->.</p>
1522    
1523     </li>
1524    
1525     <li>
1526    
1527     <p><strong>Suspending workers</strong>: Start monitoring the
1528     worker, such that whenever <var title="">worker global
1529     scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is false
1530     and the worker is a <a href=#suspendable-worker>suspendable worker</a>, the user
1531     agent suspends execution of script in that worker until such time
1532     as either the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag switches
1533     to true or the worker stops being a <a href=#suspendable-worker>suspendable
1534     worker</a>.</p>
1535    
1536     </li>
1537    
1538     <li>
1539    
1540     <p><span title="jump to a code entry-point">Jump</span> to the
1541     <span title=concept-script>script</span>'s <i>initial code
1542     entry-point</i>, and let that run until it either returns, fails
1543     to catch an exception, or gets prematurely aborted by the
1544     "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>"
1545     algorithms defined below.</p>
1546    
1547     <!-- v2-onclose
1548     <p class="note">If the script gets aborted by the "<span>kill a
1549     worker</span>" algorithm, then that same algorithm will cause
1550     there to only be a single <span title="concept-task">task</span>
1551     in the <span>event loop</span> at the next step, namely the task
1552     for the <code title="message-close">close</code> event. The
1553     "<span>terminate a worker</span>" algorithm removes all the
1554     events.</p>
1555     -->
1556    
1557     </li>
1558    
1559     <li><p>If <var title="">worker global scope</var> is actually a
1560     <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is
1561     a dedicated worker), then enable the <span>port message
1562     queue</span> of the worker's implicit port.</li>
1563    
1564     <li>
1565    
1566     <p><i title="">Event loop</i>: Wait until either there is a <span title=concept-task>task</span> in one of the <span>event
1567     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
1568     to true.</p>
1569    
1570     </li>
1571    
1572     <li>
1573    
1574     <p>Run the oldest task on one of the <span>event loop</span>'s
1575     <span title="task queue">task queues</span>, if any. The user
1576     agent may pick any <span>task queue</span>.</p>
1577    
1578     <p class=note>The handling of events or the execution of
1579     callbacks might get prematurely aborted by the "<a href=#kill-a-worker>kill a
1580     worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>" algorithms
1581     defined below.</p>
1582    
1583     </li>
1584    
1585     <li>
1586    
1587     <p>Remove the task run in the previous step, if any, from its
1588     <span>task queue</span>.</p>
1589    
1590     </li>
1591    
1592     <li>
1593    
1594     <p>If there are any more events in the <span>event loop</span>'s
1595     <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
1596     to false, then jump back to the step above labeled <i>event
1597     loop</i>.</p>
1598    
1599     </li>
1600    
1601     <li>
1602    
1603     <p>If there are any outstanding transactions that have callbacks
1604     that involve <span title=concept-script>scripts</span> whose
1605     <span title="script's global object">global object</span> is the
1606     <var title="">worker global scope</var>, roll them back (without
1607     invoking any of the callbacks).</p>
1608    
1609     </li>
1610    
1611     <li>
1612    
1613     <p>Empty the <var title="">worker global scope</var>'s <span>list
1614     of active timeouts</span> and its <span>list of active
1615     intervals</span>.</p>
1616    
1617     </li>
1618    
1619     <!-- v2-onclose
1620     <li>
1621    
1622     <p>For each <code>Worker</code> or <code>SharedWorker</code>
1623     object associated with <var title="">worker global scope</var>,
1624     <span>queue a task</span> to <span>fire a simple event</span>
1625     named <code title="event-close">close</code> at that object.</p>
1626    
1627     </li>
1628     -->
1629     </ol><hr><p>When a user agent is to <dfn id=kill-a-worker>kill a worker</dfn> it must
1630     run the following steps in parallel with the worker's main loop (the
1631     "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1632    
1633     <ol><!-- v2-onclose
1634     <li><p>If the worker's <code>WorkerGlobalScope</code> object's
1635     <span title="dom-WorkerGlobalScope-closing">closing</span> flag is
1636     false, <span>queue a task</span> to <span>fire a simple
1637     event</span> named <code title="event-close">close</code> at the
1638     worker's <code>WorkerGlobalScope</code> object.</p></li>
1639     --><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
1640     true.</li>
1641    
1642     <!-- v2-onclose
1643     <li><p>Wait a user-agent-defined amount of time. If the "<span>run
1644     a worker</span>" processing model defined above immediately starts
1645     running event listeners registered for the <code
1646     title="event-close">close</code> event, this time should not be
1647     zero &mdash; the idea is that the <code
1648     title="event-close">close</code> event can be used to clean up
1649     when shutting down unexpectedly.</p></li>
1650     -->
1651    
1652     <li><p>If there are any <span title=concept-task>tasks</span>
1653     queued in the <span>event loop</span>'s <span title="task
1654     queue">task queues</span><!-- v2-onclose other than the <code
1655     title="event-close">close</code> event that this algorithm just
1656     added-->, discard them without processing them.</li>
1657    
1658     <!-- v2-onclose
1659     <li><p>If the <code title="event-close">close</code> event that
1660     this algorithm just queued hasn't yet been dispatched, then abort
1661     the script currently running in the worker.</p></li>
1662     -->
1663    
1664     <li><p>Wait a user-agent-defined amount of time.</li>
1665    
1666     <li><p>Abort the script currently running in the worker<!--
1667     v2-onclose (if any script is running, then it will be a handler for
1668     the <code title="event-close">close</code> event)-->.</li>
1669    
1670     </ol><p>User agents may invoke the "<a href=#kill-a-worker>kill a worker</a>"
1671     processing model on a worker at any time, e.g. in response to user
1672     requests, in response to CPU quota management, or when a worker
1673     stops being an <a href=#active-needed-worker>active needed worker</a> if the worker
1674     continues executing even after its <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag was
1675     set to true.</p>
1676    
1677     <hr><p>When a user agent is to <dfn id=terminate-a-worker>terminate a worker</dfn> it must run
1678     the following steps in parallel with the worker's main loop (the
1679     "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1680    
1681     <ol><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1682     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1683     true.</li>
1684    
1685     <li><p>If there are any <span title=concept-task>tasks</span>
1686     queued in the <span>event loop</span>'s <span title="task
1687     queue">task queues</span>, discard them without processing
1688     them.</li>
1689    
1690     <li><p>Abort the script currently running in the worker.</li>
1691    
1692     <li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is
1693     actually a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the
1694     worker is a dedicated worker), then empty the <span>port message
1695     queue</span> of the port that the worker's implicit port is
1696     entangled with.</li>
1697    
1698     </ol><hr><p>The <span>task source</span> for the tasks mentioned above is the
1699     <span>DOM manipulation task source</span>.</p>
1700    
1701    
1702     <h3 id=runtime-script-errors><span class=secno>4.6 </span>Runtime script errors</h3>
1703    
1704     <p>Whenever an uncaught runtime script error occurs in one of the
1705     worker's scripts, if the error did not occur while handling a
1706     previous script error, the user agent must <span>report the
1707     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>
1708     attribute.
1709    
1710     <a href=#refsHTML>[HTML]</a>
1711    
1712     </p>
1713    
1714     <p>For shared workers, if the error is still <i title=concept-error-nothandled>not handled</i> afterwards, or if
1715     the error occurred while handling a previous script error, the error
1716     may be reported to the user.
1717    
1718     <a href=#refsHTML>[HTML]</a>
1719    
1720     </p>
1721    
1722     <p>For dedicated workers, if the error is still <i title=concept-error-nothandled>not handled</i> afterwards, or if
1723     the error occurred while handling a previous script error, the user
1724     agent must <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
1725     event</a> at the <code><a href=#worker>Worker</a></code> object associated with the
1726     worker.</p>
1727    
1728     <p>When the user agent is to <dfn id=fire-a-worker-error-event>fire a worker error event</dfn> at
1729     a <code><a href=#worker>Worker</a></code> object, it must dispatch an event that uses
1730     the <code><a href=#errorevent>ErrorEvent</a></code> interface, with the name <code title=event-error>error</code>, that doesn't bubble and is
1731     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
1732     appropriately. The default action of this event depends on whether
1733     the <code><a href=#worker>Worker</a></code> object is itself in a worker. If it is, and
1734     that worker is also a dedicated worker, then the user agent must
1735     again <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
1736     event</a> at the <code><a href=#worker>Worker</a></code> object associated with
1737     <em>that</em> worker. Otherwise, then the error may be reported
1738     to the user.</p>
1739    
1740     <p>The <span>task source</span> for the tasks mentioned above is the
1741     <span>DOM manipulation task source</span>.</p>
1742    
1743 wakaba 1.194 <hr><pre class=idl>interface <dfn id=errorevent>ErrorEvent</dfn> : <span>Event</span> {
1744 wakaba 1.190 readonly attribute DOMString <a href=#dom-errorevent-message title=dom-ErrorEvent-message>message</a>;
1745     readonly attribute DOMString <a href=#dom-errorevent-filename title=dom-ErrorEvent-filename>filename</a>;
1746     readonly attribute unsigned long <a href=#dom-errorevent-lineno title=dom-ErrorEvent-lineno>lineno</a>;
1747     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);
1748     };</pre>
1749    
1750     <p>The <dfn id=dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent><code>initErrorEvent()</code></dfn>
1751     method must initialize the event in a manner analogous to the
1752     similarly-named method in the DOM Events interfaces. <a href=#refsDOMEVENTS>[DOMEVENTS]</a></p>
1753    
1754     <p>The <dfn id=dom-errorevent-message title=dom-ErrorEvent-message><code>message</code></dfn>
1755     attribute represents the error message.</p>
1756    
1757     <p>The <dfn id=dom-errorevent-filename title=dom-ErrorEvent-filename><code>filename</code></dfn>
1758     attribute represents the <span>absolute URL</span> of the script in
1759     which the error originally occurred.</p>
1760    
1761     <p>The <dfn id=dom-errorevent-lineno title=dom-ErrorEvent-lineno><code>lineno</code></dfn>
1762     attribute represents the line number where the error occurred in the
1763     script.</p>
1764    
1765    
1766    
1767     <h3 id=creating-workers><span class=secno>4.7 </span>Creating workers</h3>
1768    
1769     <h4 id=the-abstractworker-abstract-interface><span class=secno>4.7.1 </span>The <code><a href=#abstractworker>AbstractWorker</a></code> abstract interface</h4>
1770    
1771     <pre class=idl>[Supplemental, NoInterfaceObject]
1772     interface <dfn id=abstractworker>AbstractWorker</dfn> {
1773     attribute <span>Function</span> <a href=#handler-abstractworker-onerror title=handler-AbstractWorker-onerror>onerror</a>;
1774     <!-- v2-onclose attribute <span>Function</span> <span title="handler-AbstractWorker-onclose">onclose</span>; -->
1775     };
1776     <a href=#abstractworker>AbstractWorker</a> implements <span>EventTarget</span>;</pre>
1777    
1778     <p>The following are the <span>event handlers</span> (and their
1779     corresponding <span title="event handler event type">event handler
1780     event types</span>) that must be supported, as IDL attributes, by
1781     objects implementing the <code><a href=#abstractworker>AbstractWorker</a></code> interface:</p>
1782    
1783     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1784     <tbody><tr><td><dfn id=handler-abstractworker-onerror title=handler-AbstractWorker-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
1785     <!-- v2-onclose <tr><td><dfn title="handler-AbstractWorker-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> -->
1786     </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>
1787    
1788     <pre class=idl>[<a href=#dom-worker title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
1789     interface <dfn id=worker>Worker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1790     void <a href=#dom-worker-terminate title=dom-Worker-terminate>terminate</a>();
1791    
1792     void <a href=#dom-worker-postmessage title=dom-Worker-postMessage>postMessage</a>(in any message, in optional <span>MessagePortArray</span> ports);<!--
1793     <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
1794     attribute <span>Function</span> <a href=#handler-worker-onmessage title=handler-Worker-onmessage>onmessage</a>;
1795     };</pre>
1796    
1797     <p>The <dfn id=dom-worker-terminate title=dom-Worker-terminate><code>terminate()</code></dfn> method,
1798     when invoked, must cause the "<a href=#terminate-a-worker>terminate a worker</a>"
1799     algorithm to be run on the worker with with the object is
1800     associated.</p>
1801    
1802     <p><code><a href=#worker>Worker</a></code> objects act as if they had an implicit
1803     <code>MessagePort</code> associated with them. This port is part of
1804     a channel that is set up when the worker is created, but it is not
1805     exposed. This object must never be garbage collected before the
1806     <code><a href=#worker>Worker</a></code> object.</p>
1807    
1808     <p>All messages received by that port must immediately be retargeted
1809     at the <code><a href=#worker>Worker</a></code> object.</p>
1810    
1811     <p>The <dfn id=dom-worker-postmessage title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
1812     and <dfn
1813     title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
1814     method<!--s (startConversation)--> on <code><a href=#worker>Worker</a></code> objects
1815     must act as if, when invoked, it<!--/they (startConversation)-->
1816     immediately invoked the method of the same name on the port, with
1817     the same arguments, and returned the same return value.</p>
1818    
1819     <p>The following are the <span>event handlers</span> (and their
1820     corresponding <span title="event handler event type">event handler
1821     event types</span>) that must be supported, as IDL attributes, by
1822     objects implementing the <code><a href=#worker>Worker</a></code> interface:</p>
1823    
1824     <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
1825     <tbody><tr><td><dfn id=handler-worker-onmessage title=handler-Worker-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
1826     </table><hr><p>When the <dfn id=dom-worker title=dom-Worker><code>Worker(<var title="">scriptURL</var>)</code></dfn> constructor is invoked, the
1827     user agent must run the following steps:</p>
1828    
1829     <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument relative to the <span>entry
1830     script</span>'s <span title="script's base URL">base URL</span>,
1831     when the method is invoked.</li>
1832    
1833     <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1834     exception.</li>
1835    
1836     <li>
1837    
1838     <p>If the <span>origin</span> of the resulting <span>absolute
1839     URL</span> is not the <span title="same origin">same</span> as the
1840     origin of the <span>entry script</span>, then throw a
1841     <code>SECURITY_ERR</code> exception.</p>
1842    
1843     <p class=note>Thus, scripts must be external files with the same
1844     scheme as the original page: you can't load a script from a <code title="">data:</code> URL or <code title="">javascript:</code>
1845     URL, and a <code>https:</code> page couldn't start workers using
1846     scripts with <code>http:</code> URLs.</p>
1847    
1848     </li>
1849    
1850     <li><p>Create a new <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1851     object. Let <var title="">worker global scope</var> be this new
1852     object.</li>
1853    
1854     <li><p>Create a new <code><a href=#worker>Worker</a></code> object, associated with
1855     <var title="">worker global scope</var>. Let <var title="">worker</var> be this new object.</li>
1856    
1857     <li><p><span>Create a new <code>MessagePort</code> object</span>
1858     owned by the <span title="script's global object">global
1859     object</span> of the <span title=concept-script>script</span> that
1860     invoked the constructor. Let this be the <var title="">outside
1861     port</var>.</li>
1862    
1863     <li><p>Associate the <var title="">outside port</var> with <var title="">worker</var>.</li>
1864    
1865     <li><p><span>Create a new <code>MessagePort</code> object</span>
1866     owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
1867    
1868     <li><p>Associate <var title="">inside port</var> with <var title="">worker global scope</var>.</li>
1869    
1870     <li><p><span>Entangle</span> <var title="">outside port</var> and
1871     <var title="">inside port</var>.</li>
1872    
1873     <li><p>Return <var title="">worker</var>, and run the following
1874     steps asynchronously.</li>
1875    
1876     <!-- (this is done by the "run a worker" algorithm)
1877     <li><p>Enable <var title="">inside port</var>'s <span>port message
1878     queue</span>.</p></li>
1879     -->
1880    
1881     <li><p>Enable <var title="">outside port</var>'s <span>port message
1882     queue</span>.</li>
1883    
1884     <li>
1885    
1886     <p>Let <var title="">docs</var> be the <a href=#list-of-relevant-document-objects-to-add>list of relevant
1887     <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
1888     constructor.</p>
1889    
1890     </li>
1891    
1892     <li>
1893    
1894     <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
1895     <var title="">worker global scope</var>'s list of <span>the
1896     worker's <code>Document</code>s</span></a> the
1897     <code>Document</code> objects in <var title="">docs</var>.</p>
1898    
1899     </li>
1900    
1901     <li>
1902    
1903     <p>If the <span title="script's global object">global object</span>
1904     of the <span title=concept-script>script</span> that invoked the
1905     constructor is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object (i.e. we
1906     are creating a nested worker), add <var title="">worker global
1907     scope</var> to the list of <a href="#the-worker's-workers">the worker's workers</a> of the
1908     <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
1909     constructor.</p>
1910    
1911     </li>
1912    
1913     <li>
1914    
1915     <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
1916     URL</span>, with the <span>script's browsing context</span> of the
1917     script that invoked the method as the <var title="">owner browsing
1918 wakaba 1.193 context</var>, with the <span>script's document</span> of the
1919     script that invoked the method as the <var title="">owner
1920     document</var>, with the <span>origin</span> of the <span>entry
1921 wakaba 1.190 script</span> as the <var title="">owner origin</var>, and with
1922     <var title="">worker global scope</var> as the global scope.</p>
1923    
1924     </li>
1925    
1926     </ol><p>This constructor must be visible when the <span>script's global
1927     object</span> is either a <code>Window</code> object or an object
1928     implementing the <code><a href=#workerutils>WorkerUtils</a></code> interface.</p>
1929    
1930    
1931     <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>
1932    
1933     <pre class=idl>[<a href=#dom-sharedworker title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in optional DOMString name)]
1934     interface <dfn id=sharedworker>SharedWorker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1935     readonly attribute <span>MessagePort</span> <a href=#dom-sharedworker-port title=dom-SharedWorker-port>port</a>;
1936     };</pre>
1937    
1938     <p>The <dfn id=dom-sharedworker-port title=dom-SharedWorker-port><code>port</code></dfn>
1939     attribute must return the value it was assigned by the object's
1940     constructor. It represents the <code>MessagePort</code> for
1941     communicating with the shared worker.</p>
1942    
1943     <p>When the <dfn id=dom-sharedworker title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>, <var title="">name</var>)</code></dfn>
1944     constructor is invoked, the user agent must run the following
1945     steps:</p>
1946    
1947     <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
1948    
1949     <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1950     exception.</li>
1951    
1952     <li><p>Otherwise, let <var title="">scriptURL</var> be the
1953     resulting <span>absolute URL</span>.</li>
1954    
1955     <li><p>Let <var title="">name</var> be the value of the second
1956     argument, or the empty string if the second argument was
1957     omitted.</li>
1958    
1959     <li>
1960    
1961     <p>If the <span>origin</span> of <var title="">scriptURL</var> is
1962     not the <span title="same origin">same</span> as the origin of the
1963     <span>entry script</span>, then throw a <code>SECURITY_ERR</code>
1964     exception.</p>
1965    
1966     <p class=note>Thus, scripts must be external files with the same
1967     scheme as the original page: you can't load a script from a <code title="">data:</code> URL or <code title="">javascript:</code>
1968     URL, and a <code>https:</code> page couldn't start workers using
1969     scripts with <code>http:</code> URLs.</p>
1970    
1971     </li>
1972    
1973     <li>
1974    
1975     <p>Let <var title="">docs</var> be the <a href=#list-of-relevant-document-objects-to-add>list of relevant
1976     <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
1977     constructor.</p>
1978    
1979     </li>
1980    
1981     <li>
1982    
1983     <p>Execute the following substeps atomically:</p>
1984    
1985     <ol><li><p>Create a new <code><a href=#sharedworker>SharedWorker</a></code> object, which will
1986     shortly be associated with a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1987     object. Let this <code><a href=#sharedworker>SharedWorker</a></code> object be <var title="">worker</var>.</li>
1988    
1989     <li><p><span>Create a new <code>MessagePort</code> object</span>
1990     owned by the <span title="script's global object">global
1991     object</span> of the script that invoked the method. Let this be
1992     the <var title="">outside port</var>.</li>
1993    
1994     <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>
1995    
1996     <li><p>Let <var title="">worker global scope</var> be
1997     null.</li>
1998    
1999     <li><p>If <var title="">name</var> is not the empty string and
2000     there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object whose
2001     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag
2002     is false, whose <code title=dom-WorkerGlobalScope-name>name</code> attribute is
2003     exactly equal to <var title="">name</var>, and whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
2004     represents an <span>absolute URL</span> with the <span>same
2005     origin</span> as <var title="">scriptURL</var>, then let <var title="">worker global scope</var> be that
2006     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object.</li>
2007    
2008     <li><p>Otherwise, if <var title="">name</var> is the empty string
2009     and there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object
2010     whose <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a>
2011     flag is false, and whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
2012 wakaba 1.197 represents an <span>absolute URL</span> that is exactly equal to
2013     <var title="">scriptURL</var>, then let <var title="">worker
2014     global scope</var> be that <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
2015     object.</li>
2016 wakaba 1.190
2017     <li>
2018    
2019     <p>If <var title="">worker global scope</var> is not null, then
2020     run these steps:</p>
2021    
2022     <ol><li><p>If <var title="">worker global scope</var>'s <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code>
2023     attribute represents an <span>absolute URL</span> that is not
2024     exactly equal to <var title="">scriptURL</var>, then throw a
2025     <code>URL_MISMATCH_ERR</code> exception and abort all these
2026     steps.</li>
2027    
2028     <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
2029    
2030     <li><p><span>Create a new <code>MessagePort</code>
2031     object</span> owned by <var title="">worker global
2032     scope</var>. Let this be the <var title="">inside
2033     port</var>.</li>
2034    
2035     <li><p><span>Entangle</span> <var title="">outside port</var>
2036     and <var title="">inside port</var>.</li>
2037    
2038     <li><p>Return <var title="">worker</var> and perform the next
2039     step asynchronously.</li>
2040    
2041     <li><p>Create an event that uses the <code>MessageEvent</code>
2042     interface, with the name <code title=event-connect>connect</code>, which does not bubble, is
2043     not cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value
2044     is the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose
2045     value is an array containing only the newly created port, and
2046     <span>queue a task</span> to dispatch the event at <var title="">worker global scope</var>.</li>
2047    
2048     <li>
2049    
2050     <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
2051     <var title="">worker global scope</var>'s list of <span>the
2052     worker's <code>Document</code>s</span></a> the
2053     <code>Document</code> objects in <var title="">docs</var>.</p>
2054    
2055     </li>
2056    
2057     <li>
2058    
2059     <p>If the <span title="script's global object">global
2060     object</span> of the <span title=concept-script>script</span>
2061     that invoked the constructor is a
2062     <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
2063     worker's workers</a> of the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
2064     object that is the <span title="script's global object">global
2065     object</span> of the <span title=concept-script>script</span>
2066     that invoked the constructor.</p>
2067    
2068     </li>
2069    
2070     <li><p>Abort all these steps.</li>
2071    
2072     </ol></li>
2073    
2074     <li><p>Create a new <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
2075     object. Let <var title="">worker global scope</var> be this new
2076     object.</li>
2077    
2078     <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
2079    
2080     <li><p>Set the <code title=dom-SharedWorkerGlobalScope-name><a href=#dom-sharedworkerglobalscope-name>name</a></code> attribute of
2081     <var title="">worker global scope</var> to <var title="">name</var>.</li>
2082    
2083     <li><p><span>Create a new <code>MessagePort</code> object</span>
2084     owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
2085    
2086     <li><p><span>Entangle</span> <var title="">outside port</var> and
2087     <var title="">inside port</var>.</li>
2088    
2089     </ol></li>
2090    
2091     <li><p>Return <var title="">worker</var> and perform the remaining
2092     steps asynchronously.</li>
2093    
2094     <li><p>Create an event that uses the <code>MessageEvent</code>
2095     interface, with the name <code title=event-connect>connect</code>, which does not bubble, is not
2096     cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value is
2097     the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose value
2098     is an array containing only the newly created port, and <span>queue
2099     a task</span> to dispatch the event at <var title="">worker global
2100     scope</var>.</li>
2101    
2102     <li>
2103    
2104     <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
2105     <var title="">worker global scope</var>'s list of <span>the
2106     worker's <code>Document</code>s</span></a> the
2107     <code>Document</code> objects in <var title="">docs</var>.</p>
2108    
2109     </li>
2110    
2111     <li>
2112    
2113     <p>If the <span title="script's global object">global object</span>
2114     of the <span title=concept-script>script</span> that invoked the
2115     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
2116     worker's workers</a> of the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
2117     object that is the <span title="script's global object">global
2118     object</span> of the <span title=concept-script>script</span>
2119     that invoked the constructor.</p>
2120    
2121     </li>
2122    
2123     <li>
2124    
2125     <p><a href=#run-a-worker>Run a worker</a> for <var title="">scriptURL</var>,
2126     with the <span>script's browsing context</span> of the script that
2127     invoked the method as the <var title="">owner browsing
2128 wakaba 1.193 context</var>, with the <span>script's document</span> of the
2129     script that invoked the method as the <var title="">owner
2130     document</var>, with the <span>origin</span> of the <span>entry
2131 wakaba 1.190 script</span> as the <var title="">owner origin</var>, and with
2132     <var title="">worker global scope</var> as the global scope.</p>
2133    
2134     </li>
2135    
2136     </ol><p>This constructor must be visible when the <span>script's global
2137     object</span> is either a <code>Window</code> object or an object
2138     implementing the <code><a href=#workerutils>WorkerUtils</a></code> interface.</p>
2139    
2140     <p>The <span>task source</span> for the tasks mentioned above is the
2141     <span>DOM manipulation task source</span>.</p>
2142    
2143    
2144    
2145     <h2 id=apis-available-to-workers><span class=secno>5 </span>APIs available to workers</h2>
2146    
2147     <pre class=idl>[Supplemental, NoInterfaceObject]
2148     interface <dfn id=workerutils>WorkerUtils</dfn> {
2149     void <a href=#dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts>importScripts</a>(in DOMString... urls);
2150     readonly attribute <a href=#workernavigator>WorkerNavigator</a> <a href=#dom-worker-navigator title=dom-worker-navigator>navigator</a>;
2151     };
2152     <a href=#workerutils>WorkerUtils</a> implements <span>WindowTimers</span>;</pre>
2153    
2154     <p>The DOM APIs (<code>Node</code> objects, <code>Document</code>
2155     objects, etc) are not available to workers in this version of this
2156     specification.</p>
2157    
2158    
2159     <h3 id=importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</h3>
2160    
2161     <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
2162     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
2163     following steps:</p>
2164    
2165     <ol><li><p>If there are no arguments, return without doing
2166     anything. Abort these steps.</li>
2167    
2168     <li><p><span title="resolve a url">Resolve</span> each
2169     argument.</li>
2170    
2171     <li><p>If any fail, throw a <code>SYNTAX_ERR</code>
2172     exception.</li>
2173    
2174     <!--
2175     <li><p>If any of the resulting <span title="absolute URL">absolute
2176     URLs</span> have an <span>origin</span> that is not the <span
2177     title="same origin">same</span> as the origin of the script that
2178     invoked the method, then throw a <code>SECURITY_ERR</code>
2179     exception.</p></li>
2180     -->
2181    
2182     <li>
2183    
2184     <p>Attempt to <span>fetch</span> each resource identified by the
2185     resulting <span title="absolute URL">absolute URLs</span>, from
2186     the <span>entry script</span>'s <span>origin</span>.</p> <!-- not
2187     http-origin privacy sensitive -->
2188    
2189     </li>
2190    
2191     <li>
2192    
2193     <p>For each argument in turn, in the order given, starting with
2194     the first one, run these substeps:</p>
2195    
2196     <ol><li>
2197    
2198     <p>Wait for the fetching attempt for the corresponding resource
2199     to complete.</p>
2200    
2201     <p>If the fetching attempt failed, throw a
2202     <code>NETWORK_ERR</code> exception and abort all these
2203     steps.</p>
2204    
2205     <p>If the attempt succeeds, then convert the script resource to
2206     Unicode by assuming it was encoded as UTF-8, to obtain its <var title="">source</var>.</p>
2207    
2208     <p>Let <var title="">language</var> be JavaScript.</p>
2209    
2210     <p class=note>As with the worker's script, the script here is
2211     always assumed to be JavaScript, regardless of the MIME
2212     type.</p>
2213    
2214     </li>
2215    
2216     <li>
2217    
2218     <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
2219     same global object, browsing context, URL character encoding,
2220     base URL, and script group as the <span title=concept-script>script</span> that was created by the
2221     worker's <a href=#run-a-worker>run a worker</a> algorithm.</p>
2222    
2223     <p>Let the newly created <span title=concept-script>script</span> run until it either
2224     returns, fails to parse, fails to catch an exception, or gets
2225     prematurely aborted by the "<a href=#kill-a-worker>kill a worker</a>" or
2226     "<a href=#terminate-a-worker>terminate a worker</a>" algorithms defined above.</p>
2227    
2228     <p>If it failed to parse, then throw an ECMAScript
2229     <code>SyntaxError</code> exception and abort all these
2230     steps. <a href=#refsECMA262>[ECMA262]</a></p>
2231    
2232     <p>If an exception was raised or if the script was prematurely
2233     aborted, then abort all these steps, letting the exception or
2234     aborting continue to be processed by the script that called the
2235     <code title=dom-WorkerGlobalScope-importScripts><a href=#dom-workerglobalscope-importscripts>importScripts()</a></code>
2236     method.</p>
2237    
2238     <p>If the "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a
2239     worker</a>" algorithms abort the script then abort all these
2240     steps.</p>
2241    
2242     </li>
2243    
2244     </ol></li>
2245    
2246     </ol><h3 id=the-workernavigator-object><span class=secno>5.2 </span>The <code><a href=#workernavigator>WorkerNavigator</a></code> object</h3>
2247    
2248     <p>The <dfn id=dom-worker-navigator title=dom-worker-navigator><code>navigator</code></dfn> attribute
2249     of the <code><a href=#workerutils>WorkerUtils</a></code> interface must return an instance of
2250     the <code><a href=#workernavigator>WorkerNavigator</a></code> interface, which represents the
2251     identity and state of the user agent (the client):</p>
2252    
2253     <pre class=idl>interface <dfn id=workernavigator>WorkerNavigator</dfn> {};
2254     <a href=#workernavigator>WorkerNavigator</a> implements <span>NavigatorID</span>;
2255     <a href=#workernavigator>WorkerNavigator</a> implements <span>NavigatorOnLine</span>;</pre>
2256    
2257     <p>Objects implementing the <code><a href=#workernavigator>WorkerNavigator</a></code> interface
2258     also implement the <code>NavigatorID</code> and
2259     <code>NavigatorOnLine</code> interfaces.
2260    
2261     <a href=#refsHTML>[HTML]</a>
2262    
2263     </p>
2264    
2265     <p>This <code><a href=#workernavigator>WorkerNavigator</a></code> interface must not exist if the
2266     interface's <span>relevant namespace object</span> is a
2267     <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
2268    
2269    
2270    
2271     <h3 id=apis-defined-in-other-specifications><span class=secno>5.3 </span>APIs defined in other specifications</h3>
2272    
2273     <p>The <code title=dom-opendatabase>openDatabase()</code> and
2274     <code title=dom-opendatabase-sync>openDatabaseSync()</code>
2275     methods are defined in the Web SQL Database specification. <a href=#refsWEBSQL>[WEBSQL]</a></p>
2276    
2277    
2278    
2279     <h3 id=interface-objects-and-constructors><span class=secno>5.4 </span>Interface objects and constructors</h3>
2280    
2281     <p>There must be no interface objects and constructors available in
2282     the global scope of scripts whose <span>script's global
2283     object</span> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object except for
2284     the following:</p>
2285    
2286     <ul><li><p><code>XMLHttpRequest</code> and all interface objects and
2287     constructors defined by the XMLHttpRequest specifications, except
2288     that the <span>document response entity body</span> must always be
2289     null. The <span><code>XMLHttpRequest</code> base URL</span> is the
2290     <span>script's base URL</span>; the
2291     <span><code>XMLHttpRequest</code> origin</span> is the script's
2292     <span>origin</span>. <a href=#refsXHR>[XHR]</a></li>
2293    
2294     <li><p>The interface objects and constructors defined by this
2295     specification.</li>
2296    
2297     <li><p>Constructors defined by specifications that explicitly say
2298     that they should be visible when the <span>script's global
2299     object</span> is a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>, a
2300     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>, or an object implementing the
2301     <code><a href=#workerutils>WorkerUtils</a></code> interface; the interfaces of any objects
2302     with such constructors; and the interfaces of any objects made
2303     accessible through APIs exposed by those constructors or made
2304     accessible through interfaces to be implemented by any objects that
2305     are themselves accessible to scripts whose <span>script's global
2306     object</span> implements the <code><a href=#workerutils>WorkerUtils</a></code>
2307     interface.</li>
2308    
2309     </ul><p class=note>These requirements do not override the requirements
2310     defined by the Web IDL specification, in particular concerning the
2311     visibility of interfaces annotated with the <code title="">[NoInterfaceObject]</code> extended attribute.</p>
2312    
2313    
2314     <h3 id=worker-locations><span class=secno>5.5 </span>Worker locations</h3>
2315    
2316     <pre class=idl>interface <dfn id=workerlocation>WorkerLocation</dfn> {
2317     readonly attribute DOMString <a href=#dom-workerlocation-href title=dom-WorkerLocation-href>href</a>;
2318     readonly attribute DOMString <a href=#dom-workerlocation-protocol title=dom-WorkerLocation-protocol>protocol</a>;
2319     readonly attribute DOMString <a href=#dom-workerlocation-host title=dom-WorkerLocation-host>host</a>;
2320     readonly attribute DOMString <a href=#dom-workerlocation-hostname title=dom-WorkerLocation-hostname>hostname</a>;
2321     readonly attribute DOMString <a href=#dom-workerlocation-port title=dom-WorkerLocation-port>port</a>;
2322     readonly attribute DOMString <a href=#dom-workerlocation-pathname title=dom-WorkerLocation-pathname>pathname</a>;
2323     readonly attribute DOMString <a href=#dom-workerlocation-search title=dom-WorkerLocation-search>search</a>;
2324     readonly attribute DOMString <a href=#dom-workerlocation-hash title=dom-WorkerLocation-hash>hash</a>;
2325     };</pre>
2326    
2327     <p>A <code><a href=#workerlocation>WorkerLocation</a></code> object represents an <span>absolute
2328     URL</span> set at its creation.</p>
2329    
2330     <p>The <dfn id=dom-workerlocation-href title=dom-WorkerLocation-href><code>href</code></dfn>
2331     attribute must return the <span>absolute URL</span> that the object
2332     represents.</p>
2333    
2334     <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface also has the complement
2335     of <span>URL decomposition IDL attributes</span>, <dfn id=dom-workerlocation-protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
2336     <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>,
2337     <dfn id=dom-workerlocation-pathname title=dom-WorkerLocation-pathname><code>pathname</code></dfn>,
2338     <dfn id=dom-workerlocation-search title=dom-WorkerLocation-search><code>search</code></dfn>,
2339     and <dfn id=dom-workerlocation-hash title=dom-WorkerLocation-hash><code>hash</code></dfn>. These must
2340     follow the rules given for URL decomposition IDL attributes, with the
2341     <span title=concept-uda-input>input</span> being the
2342     <span>absolute URL</span> that the object represents (same as the
2343     <code title=dom-WorkerLocation-href><a href=#dom-workerlocation-href>href</a></code> attribute), and
2344     the <span title=concept-uda-setter>common setter action</span>
2345     being a no-op, since the attributes are defined to be readonly.
2346    
2347     <a href=#refsHTML>[HTML]</a>
2348    
2349     </p>
2350    
2351     <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface must not exist if the
2352     interface's <span>relevant namespace object</span> is a
2353     <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
2354    
2355    
2356    
2357     <h2 class=no-num id=references>References</h2><!--REFS-->
2358    
2359     <p>All references are normative unless marked "Non-normative".</p>
2360    
2361     <!-- Dates are only included for standards older than the Web,
2362     because the newer ones keep changing. -->
2363    
2364     <dl><dt id=refsDOMCORE>[DOMCORE]</dt>
2365     <dd><cite><a href=http://www.w3.org/TR/DOM-Level-3-Core/>Document
2366     Object Model (DOM) Level 3 Core Specification</a></cite>, A. Le
2367     Hors, P. Le Hegaret, L. Wood, G. Nicol, J. Robie, M. Champion,
2368     S. Byrnes. W3C.</dd>
2369     <!--
2370     <dd><cite><a href="http://simon.html5.org/specs/web-dom-core">Web
2371     DOM Core</a></cite>, S. Pieters. W3C.</dd>
2372     -->
2373    
2374     <dt id=refsDOMEVENTS>[DOMEVENTS]</dt>
2375     <!--
2376     <dd><cite><a
2377     href="http://www.w3.org/TR/DOM-Level-3-Events/">Document Object
2378     Model (DOM) Level 3 Events Specification</a></cite>,
2379     B. H&ouml;hrmann, P. Le Hegaret, T. Pixley. W3C.</dd>
2380     -->
2381     <dd><cite><a href=http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html>Document
2382     Object Model (DOM) Level 3 Events Specification</a></cite>,
2383     D. Schepers. W3C.</dd>
2384    
2385     <dt id=refsECMA262>[ECMA262]</dt>
2386     <dd><cite><a href=http://www.ecma-international.org/publications/standards/Ecma-262.htm>ECMAScript
2387     Language Specification</a></cite>. ECMA.</dd>
2388    
2389     <dt id=refsHTML>[HTML]</dt>
2390     <dd><cite><a href=http://www.whatwg.org/specs/web-apps/current-work/>HTML</a></cite>,
2391     I. Hickson. WHATWG.</dd>
2392    
2393     <dt id=refsRFC2119>[RFC2119]</dt>
2394     <dd><cite><a href=http://www.ietf.org/rfc/rfc2119.txt>Key words for use in
2395     RFCs to Indicate Requirement Levels</a></cite>, S. Bradner. IETF.</dd>
2396    
2397     <dt id=refsWEBIDL>[WEBIDL]</dt>
2398     <!--
2399     <dd><cite><a href="http://www.w3.org/TR/WebIDL/">Web
2400     IDL</a></cite>, C. McCormack. W3C.</dd>
2401     -->
2402     <dd><cite><a href=http://dev.w3.org/2006/webapi/WebIDL/>Web
2403     IDL</a></cite>, C. McCormack. W3C.</dd>
2404 wakaba 1.192
2405     <dt id=refsWEBSQL>[WEBSQL]</dt>
2406     <dd><cite><a href=http://dev.w3.org/html5/webdatabase/>Web SQL
2407     Database</a></cite>, I. Hickson. W3C.</dd>
2408 wakaba 1.190
2409     <dt id=refsXHR>[XHR]</dt>
2410     <!--
2411     <dd><cite><a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest
2412     Object</a></cite>, A. van Kesteren. W3C.</dd>
2413     -->
2414     <dd><cite><a href=http://dev.w3.org/2006/webapi/XMLHttpRequest-2/><code>XMLHttpRequest</code></a></cite>,
2415     A. van Kesteren. W3C.</dd>
2416    
2417     </dl><h2 class=no-num id=acknowledgements>Acknowledgements</h2> <!-- ACKS -->
2418    
2419     <p>Thanks to
2420    
2421     Aaron Boodman,
2422     &#1040;&#1083;&#1077;&#1082;&#1089;&#1077;&#1081; &#1055;&#1088;&#1086;&#1089;&#1082;&#1091;&#1088;&#1103;&#1082;&#1086;&#1074; (Alexey Proskuryakov),
2423     Anne van Kesteren,
2424     Ben Turner,
2425     Dmitry Titov,
2426     Drew Wilson,
2427     Jeremy Orlow,
2428     Jonas Sicking,
2429     Justin James,
2430     Kevin Hakanson,
2431     Maciej Stachowiak,
2432     Michael Nordman,
2433     Mike Smith,
2434    
2435     and
2436    
2437     Philip Taylor
2438    
2439     for their useful and substantial comments.</p>
2440    
2441     <p>Huge thanks to the whole Gears team, who pioneered this
2442     technology and whose experience has been a huge influence on this
2443     specification.</p>
2444    
2445    

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24