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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24