/[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.30 - (show annotations) (download) (as text)
Sat Mar 28 06:17:44 2009 UTC (17 years, 3 months ago) by wakaba
Branch: MAIN
Changes since 1.29: +30 -3 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=draft>
2 <div class=head>
3 <p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG src=/images/logo></a></p>
4 <h1>Web Workers</h1>
5 <h2 class="no-num no-toc" id=draft-recommendation-&mdash;-date:-01-jan-1901>Draft Recommendation &mdash; 28 March 2009</h2>
6 <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>[email protected]</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, [email protected]</dd>
20 </dl><p class=copyright>&copy; Copyright 2004-2008 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 </div>
25
26 <hr><h2 class="no-num no-toc" id=abstract>Abstract</h2>
27
28 <p>This specification defines an API that allows Web application
29 authors to spawn background workers running scripts in parallel to
30 their main page. This allows for thread-like operation with
31 message-passing as the coordination mechanism.</p>
32
33
34 <h2 class="no-num no-toc" id=status>Status of this document</h2>
35
36 <p><strong>This is a work in progress!</strong> This document is
37 changing on a daily if not hourly basis in response to comments and
38 as a general part of its development process. Comments are very
39 welcome, please send them to <a href=mailto:[email protected]>[email protected]</a>. Thank
40 you.</p>
41
42 <p>The current focus is in developing a first draft proposal.</p>
43
44 <p>Implementors should be aware that this specification is not
45 stable. <strong>Implementors who are not taking part in the
46 discussions are likely to find the specification changing out from
47 under them in incompatible ways.</strong> Vendors interested in
48 implementing this specification before it eventually reaches the
49 call for implementations should join the <a href=/mailing-list>WHATWG mailing list</a> and take part in the
50 discussions.</p>
51
52 <p>This specification is also being produced by the <a href=http://www.w3.org/2008/webapps/>W3C Web Apps WG</a>. The two
53 specifications are identical from the table of contents onwards.</p>
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><span class=secno>1.2.4 </span>Shared workers</a></li>
68 <li><a href=#delegation><span class=secno>1.2.5 </span>Delegation</a></li>
69 <li><a href=#providing-libraries><span class=secno>1.2.6 </span>Providing libraries</a></ol></ol></li>
70 <li><a href=#conformance-requirements><span class=secno>2 </span>Conformance requirements</a>
71 <ol>
72 <li><a href=#dependencies><span class=secno>2.1 </span>Dependencies</a></ol></li>
73 <li><a href=#terminology><span class=secno>3 </span>Terminology</a></li>
74 <li><a href=#infrastructure><span class=secno>4 </span>Infrastructure</a>
75 <ol>
76 <li><a href=#the-global-scope><span class=secno>4.1 </span>The global scope</a>
77 <ol>
78 <li><a href=#the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code>WorkerGlobalScope</code> abstract interface</a></li>
79 <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>
80 <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>
81 <li><a href=#base-urls-and-origins-of-workers><span class=secno>4.2 </span>Base URLs and origins of workers</a></li>
82 <li><a href=#decoding-scripts><span class=secno>4.3 </span>Decoding scripts</a></li>
83 <li><a href=#the-event-loop><span class=secno>4.4 </span>The event loop</a></li>
84 <li><a href="#the-worker's-ports"><span class=secno>4.5 </span>The worker's ports</a></li>
85 <li><a href=#processing-model><span class=secno>4.6 </span>Processing model</a></li>
86 <li><a href=#runtime-script-errors><span class=secno>4.7 </span>Runtime script errors</a></li>
87 <li><a href=#creating-workers><span class=secno>4.8 </span>Creating workers</a>
88 <ol>
89 <li><a href=#the-abstractworker-abstract-interface><span class=secno>4.8.1 </span>The <code>AbstractWorker</code> abstract interface</a></li>
90 <li><a href=#dedicated-workers-and-the-worker-interface><span class=secno>4.8.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.8.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-navigator-object><span class=secno>5.2 </span>The <code title=worker-Navigator>Navigator</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><em>This section is non-normative.</em></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><em>This section is non-normative.</em></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><em>This section is non-normative.</em></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
166 attribute allows the code to receive messages from the worker.</p>
167
168 <p>The worker itself is as follows:</p>
169
170 <pre>var n = 1;
171 search: while (true) {
172 n += 1;
173 for (var i = 2; i &lt;= Math.sqrt(n); i += 1)
174 if (n % i == 0)
175 continue search;
176 // found a prime!
177 postMessage(n);
178 }</pre>
179
180 <p>The bulk of this code is simply an unoptimised search for a prime
181 number. To send a message back to the page, the <code title=dom-DedicatedWorkerGlobalScope-postMessage><a href=#dom-dedicatedworkerglobalscope-postmessage>postMessage()</a></code>
182 method is used to post a message when a prime is found.</p>
183
184 <p><a href=http://www.whatwg.org/demos/workers/primes/page.html>View this example online</a>.</p>
185
186
187
188 <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>
189
190 <p><em>This section is non-normative.</em></p>
191
192 <p>In this example, the main document spawns a worker whose only
193 task is to listen for notifications from the server, and, when
194 appropriate, either add or remove data from the client-side
195 database.</p>
196
197 <p>Since no communication occurs between the worker and the main
198 page, the main page can start the worker by just doing:</p>
199
200 <pre>&lt;script&gt;
201 new Worker('worker.js');
202 &lt;/script&gt;</pre>
203
204 <p>The worker itself is as follows:</p>
205
206 <pre>var server = new WebSocket('ws://whatwg.org/database');
207 var database = openDatabase('demobase', '1.0', 'Demo Database', 10240);
208 server.onmessage = function (event) {
209 // data is in the format "command key value"
210 var data = event.data.split(' ');
211 switch (data[0]) {
212 case '+':
213 database.transaction(function(tx) {
214 tx.executeSql('INSERT INTO pairs (key, value) VALUES (?, ?)', data[1], data[2]);
215 });
216 case '-':
217 database.transaction(function(tx) {
218 tx.executeSql('DELETE FROM pairs WHERE key=? AND value=?', data[1], data[2]);
219 });
220 }
221 };</pre>
222
223 <p>This connects to the server using the <code>WebSocket</code>
224 mechanism and opens the local database (which, we presume, has been
225 created earlier). The worker then just listens for messages from the
226 server and acts on them as appropriate, forever (or until the main
227 page is closed).</p>
228
229 <p><a href=http://www.whatwg.org/demos/workers/database-updater/page.html>View
230 this example online</a>. (This example will not actually function,
231 since the server does not actually exist and the database is not
232 created by this sample code.)</p>
233
234
235
236 <h4 id=worker-used-for-background-i/o><span class=secno>1.2.3 </span>Worker used for background I/O</h4>
237
238 <p><em>This section is non-normative.</em></p>
239
240 <p>In this example, the main document uses two workers, one for
241 fetching stock updates for at regular intervals, and one for
242 fetching performing search queries that the user requests.</p>
243
244 <p>The main page is as follows:</p>
245
246 <pre>&lt;!DOCTYPE HTML&gt;
247 &lt;html&gt;
248 &lt;head&gt;
249 &lt;title&gt;Worker example: Stock ticker&lt;/title&gt;
250 &lt;script&gt;
251 // TICKER
252 var symbol = 'GOOG'; // default symbol to watch
253 var ticker = new Worker('ticker.js');
254
255 // SEARCHER
256 var searcher = new Worker('searcher.js');
257 function search(query) {
258 searcher.postMessage(query);
259 }
260
261 // SYMBOL SELECTION UI
262 function select(newSymbol) {
263 symbol = newSymbol;
264 ticker.postMessage(symbol);
265 }
266 &lt;/script&gt;
267 &lt;/head&gt;
268 &lt;body&gt;
269 &lt;p&gt;&lt;output id="symbol"&gt;&lt;/output&gt; &lt;output id="value"&gt;&lt;/output&gt;&lt;/p&gt;
270 &lt;script&gt;
271 ticker.onmessage = function (event) {
272 var data = event.data.split(' ');
273 document.getElementById('symbol').textContent = data[0];
274 document.getElementById('value').textContent = data[1];
275 };
276 ticker.postMessage(symbol);
277 &lt;/script&gt;
278 &lt;p&gt;&lt;label&gt;Search: &lt;input type="text" oninput="search(this.value)"&gt;&lt;/label&gt;&lt;/p&gt;
279 &lt;ul id="results"&gt;&lt;/ul&gt;
280 &lt;script&gt;
281 searcher.onmessage = function (event) {
282 var data = event.data.split(' ');
283 var results = document.getElementById('results');
284 while (results.hasChildNodes()) // clear previous results
285 results.removeChild(results.firstChild);
286 for (var i = 0; i &lt; data.length; i += 1) {
287 // add a list item with a button for each result
288 var li = document.createElement('li');
289 var button = document.createElement('button');
290 button.value = data[i];
291 button.type = 'button';
292 button.onclick = function () { select(this.value); };
293 button.textContent = data[i];
294 li.appendChild(button);
295 results.appendChild(li);
296 }
297 };
298 &lt;/script&gt;
299 &lt;p&gt;(The data in this example is not real. Try searching for "Google" or "Apple".)&lt;/p&gt;
300 &lt;/body&gt;
301 &lt;/html&gt;</pre>
302
303 <p>The two workers use a common library for performing the actual
304 network calls. This library is as follows:</p>
305
306 <pre>function get(url) {
307 try {
308 var xhr = new XMLHttpRequest();
309 xhr.open('GET', url, false);
310 xhr.send();
311 return xhr.responseText;
312 } catch (e) {
313 return ''; // turn all errors into empty results
314 }
315 }</pre>
316
317 <p>The stock updater worker is as follows:</p>
318
319 <pre>importScripts('io.js');
320 var timer;
321 var symbol;
322 function update() {
323 postMessage(symbol + ' ' + get('stock.cgi?' + symbol));
324 timer = setTimeout(update, 10000);
325 }
326 onmessage = function (event) {
327 if (timer)
328 clearTimeout(timer);
329 symbol = event.data;
330 update();
331 };</pre>
332
333 <p>The search query worker is as follows:</p>
334
335 <pre>importScripts('io.js');
336 onmessage = function (event) {
337 postMessage(get('search.cgi?' + event.data));
338 };</pre>
339
340 <p><a href=http://www.whatwg.org/demos/workers/stocks/page.html>View this example online</a>.</p>
341
342
343 <h4 id=shared-workers><span class=secno>1.2.4 </span>Shared workers</h4>
344
345 <p><em>This section is non-normative.</em></p>
346
347 <p>In this example, multiple windows (viewers) can be opened that
348 are all viewing the same map. All the windows share the same map
349 information, with a single worker coordinating all the viewers. Each
350 viewer can move around independently, but if they set any data on
351 the map, all the viewers are updated.</p>
352
353 <p>The main page isn't interesting, it merely provides a way to open
354 the viewers:</p>
355
356 <pre>&lt;!DOCTYPE HTML&gt;
357 &lt;html&gt;
358 &lt;head&gt;
359 &lt;title&gt;Workers example: Multiviewer&lt;/title&gt;
360 &lt;script&gt;
361 function openViewer() {
362 window.open('viewer.html');
363 }
364 &lt;/script&gt;
365 &lt;/head&gt;
366 &lt;body&gt;
367 &lt;p&gt;&lt;button type=button onclick="openViewer()"&gt;Open a new
368 viewer&lt;/button&gt;&lt;/p&gt;
369 &lt;p&gt;Each viewer opens in a new window. You can have as many viewers
370 as you like, they all view the same data.&lt;/p&gt;
371 &lt;/body&gt;
372 &lt;/html&gt;</pre>
373
374 <p>The viewer is more involved:</p>
375
376 <pre>&lt;!DOCTYPE HTML&gt;
377 &lt;html&gt;
378 &lt;head&gt;
379 &lt;title&gt;Workers example: Multiviewer viewer&lt;/title&gt;
380 &lt;script&gt;
381 var worker = new SharedWorker('worker.js', 'core');
382
383 // CONFIGURATION
384 function configure(event) {
385 if (event.data.substr(0, 4) != 'cfg ') return;
386 var name = event.data.substr(4).split(' ', 1);
387 // update display to mention our name is name
388 document.getElementsByTagName('h1')[0].textContent += ' ' + name;
389 // no longer need this listener
390 worker.port.removeEventListener('message', configure, false);
391 }
392 worker.port.addEventListener('message', configure, false);
393
394 // MAP
395 function paintMap(event) {
396 if (event.data.substr(0, 4) != 'map ') return;
397 var data = event.data.substr(4).split(',');
398 // display tiles data[0] .. data[8]
399 var canvas = document.getElementById('map');
400 var context = canvas.getContext('2d');
401 for (var y = 0; y &lt; 3; y += 1) {
402 for (var x = 0; x &lt; 3; x += 1) {
403 var tile = data[y * 3 + x];
404 if (tile == '0')
405 context.fillStyle = 'green';
406 else
407 context.fillStyle = 'maroon';
408 fillRect(x * 50, y * 50, 50, 50);
409 }
410 }
411 }
412 worker.port.addEventListener('message', paintMap, false);
413
414 // PUBLIC CHAT
415 function updatePublicChat(event) {
416 if (event.data.substr(0, 4) != 'txt ') return;
417 var name = event.data.substr(4).split(' ', 1);
418 var message = event.data.substr(4 + length(name) + 1);
419 // display "&lt;name&gt; message" in public chat
420 var dialog = document.getElementById('public');
421 var dt = document.createElement('dt');
422 dt.textContent = name;
423 dialog.appendChild(dt);
424 var dd = document.createElement('dd');
425 dd.textContent = message;
426 dialog.appendChild(dd);
427 }
428 worker.port.addEventListener('message', updatePublicChat, false);
429
430 // PRIVATE CHAT
431 function startPrivateChat(event) {
432 if (event.data.substr(0, 4) != 'msg ') return;
433 var name = event.data.substr(4).split(' ', 1);
434 var port = event.ports[0];
435 // display a private chat UI
436 var ul = document.getElementById('private');
437 var li = document.createElement('li');
438 var h3 = document.createElement('h3');
439 h3.textContent = 'Private chat with ' + name;
440 li.appendChild(h3);
441 var dialog = document.createElement('dialog');
442 var addMessage = function(name, message) {
443 var dt = document.createElement('dt');
444 dt.textContent = name;
445 dialog.appendChild(dt);
446 var dd = document.createElement('dd');
447 dd.textContent = message;
448 dialog.appendChild(dd);
449 };
450 port.onmessage = function (event) {
451 addMessage(name, event.data);
452 };
453 li.appendChild(dialog);
454 var form = document.createElement('form');
455 var p = document.createElement('p');
456 var input = document.createElement('input');
457 input.size = 50;
458 p.appendChild(input);
459 p.appendChild(document.createTextNode(' '));
460 var button = document.createElement('button');
461 button.textContent = 'Post';
462 p.appendChild(button);
463 form.onsubmit = function () {
464 port.postMessage(input.value);
465 addMessage('me', input.value);
466 input.value = '';
467 return false;
468 };
469 form.appendChild(p);
470 li.appendChild(form);
471 }
472 worker.port.addEventListener('message', startPrivateChat, false);
473 &lt;/script&gt;
474 &lt;/head&gt;
475 &lt;body&gt;
476 &lt;h1&gt;Viewer&lt;/h1&gt;
477 &lt;h2&gt;Map&lt;/h2&gt;
478 &lt;p&gt;&lt;canvas id="map" height=150 width=150&gt;&lt;/canvas&gt;&lt;/p&gt;
479 &lt;p&gt;
480 &lt;button type=button onclick="worker.port.postMessage('mov left')"&gt;Left&lt;/button&gt;
481 &lt;button type=button onclick="worker.port.postMessage('mov up')"&gt;Up&lt;/button&gt;
482 &lt;button type=button onclick="worker.port.postMessage('mov down')"&gt;Down&lt;/button&gt;
483 &lt;button type=button onclick="worker.port.postMessage('mov right')"&gt;Right&lt;/button&gt;
484 &lt;button type=button onclick="worker.port.postMessage('set 0')"&gt;Set 0&lt;/button&gt;
485 &lt;button type=button onclick="worker.port.postMessage('set 1')"&gt;Set 1&lt;/button&gt;
486 &lt;/p&gt;
487 &lt;h2&gt;Public Chat&lt;/h2&gt;
488 &lt;dialog id="public"&gt;&lt;/dialog&gt;
489 &lt;form onsubmit="worker.port.postMessage('txt ' + message.value); message.value = ''; return false;"&gt;
490 &lt;p&gt;
491 &lt;input type="text" name="message" size="50"&gt;
492 &lt;button&gt;Post&lt;/button&gt;
493 &lt;/p&gt;
494 &lt;/form&gt;
495 &lt;h2&gt;Private Chat&lt;/h2&gt;
496 &lt;ul id="private"&gt;&lt;/ul&gt;
497 &lt;/body&gt;
498 &lt;/html&gt;
499 </pre>
500
501 <p>There are several key things worth noting about the way the
502 viewer is written.</p>
503
504 <p><strong>Multiple listeners</strong>. Instead of a single message
505 processing function, the code here attaches multiple event
506 listeners, each one performing a quick check to see if it is
507 relevant for the message. In this example it doesn't make much
508 difference, but if multiple authors wanted to collaborate using a
509 single port to communicate with a worker, it would allow for
510 independent code instead of changes having to all be made to a
511 single event handling function.</p>
512
513 <p>Registering event listeners in this way also allows you to
514 unregister specific listeners when you are done with them, as is
515 done with the <code title="">configure()</code> method in this
516 example.</p>
517
518 <p>Finally, the worker:</p>
519
520 <pre>
521 var nextName = 0;
522 function getNextName() {
523 // this could use more friendly names
524 // but for now just return a number
525 return nextName++;
526 }
527
528 var map = [
529 [0, 0, 0, 0, 0, 0, 0],
530 [1, 1, 0, 1, 0, 1, 1],
531 [0, 1, 0, 1, 0, 0, 0],
532 [0, 1, 0, 1, 0, 1, 1],
533 [0, 0, 0, 1, 0, 0, 0],
534 [1, 0, 0, 1, 1, 1, 1],
535 [1, 1, 0, 1, 1, 0, 1],
536 ];
537
538 function wrapX(x) {
539 if (x &lt; 0) return wrapX(x + map[0].length);
540 if (x &gt;= map[0].length) return wrapX(x - map[0].length);
541 return x;
542 }
543
544 function wrapY(y) {
545 if (y &lt; 0) return wrapY(y + map.length);
546 if (y &gt;= map[0].length) return wrapY(y - map.length);
547 return y;
548 }
549
550 function sendMapData(callback) {
551 var data = '';
552 for (var y = viewer.y-1; y &lt;= viewer.y+1; y += 1) {
553 for (var x = viewer.x-1; x &lt;= viewer.x+1; x += 1) {
554 if (data != '')
555 data += ',';
556 data += map[y][x];
557 }
558 }
559 callback('map ' + data);
560 }
561
562 var viewers = {};
563 onconnect = function (event) {
564 event.ports[0]._name = getNextName();
565 event.ports[0]._data = { port: event.port, x: 0, y: 0, };
566 viewers[event.ports[0]._name] = event.port._data;
567 event.ports[0].postMessage('cfg ' + name);
568 event.ports[0].onmessage = getMessage;
569 sendMapData(event.ports[0].postMessage);
570 };
571
572 function getMessage(event) {
573 switch (event.data.substr(0, 4)) {
574 case 'mov ':
575 var direction = event.data.substr(4);
576 var dx = 0;
577 var dy = 0;
578 switch (direction) {
579 case 'up': dy = -1; break;
580 case 'down': dy = 1; break;
581 case 'left': dx = -1; break;
582 case 'right': dx = 1; break;
583 }
584 event.target._data.x = wrapX(event.target._data.x + dx);
585 event.target._data.y = wrapY(event.target._data.y + dy);
586 sendMapData(event.target.postMessage);
587 break;
588 case 'set ':
589 var value = event.data.substr(4);
590 map[event.target._data.y][event.target._data.x] = value;
591 for (var viewer in viewers)
592 sendMapData(viewers[viewer].port.postMessage);
593 break;
594 case 'txt ':
595 var name = event.target._name;
596 var message = event.data.substr(4);
597 for (var viewer in viewers)
598 viewers[viewer].port.postMessage('txt ' + name + ' ' + message);
599 break;
600 case 'msg ':
601 var party1 = event._data;
602 var party2 = viewers[event.data.substr(4).split(' ', 1)];
603 if (party2) {
604 var channel = new MessageChannel();
605 party1.port.postMessage('msg ' + party2.name, [channel.port1]);
606 party2.port.postMessage('msg ' + party1.name, [channel.port2]);
607 }
608 break;
609 }
610 }</pre>
611
612 <p><strong>Connecting to multiple pages</strong>. The script uses
613 the <code title=handler-SharedWorkerGlobalScope-onconnect><a href=#handler-sharedworkerglobalscope-onconnect>onconnect</a></code>
614 event listener to listen for multiple connections.</p>
615
616 <p><strong>Direct channels</strong>. When the worker receives a
617 "msg" message from one viewer naming another viewer, it sets up a
618 direct connection between the two, so that the two viewers can
619 communicate directly without the worker having to proxy all the
620 messages.</p>
621
622 <p><a href=http://www.whatwg.org/demos/workers/multiviewer/page.html>View this example online</a>.</p>
623
624
625 <h4 id=delegation><span class=secno>1.2.5 </span>Delegation</h4>
626
627 <p><em>This section is non-normative.</em></p>
628
629 <p>With multicore CPUs becoming prevalent, one way to obtain better
630 performance is to split computationally expensive tasks amongst
631 multiple workers. In this example, a computationally expensive task
632 that is to be performed for every number from 1 to 10,000,000 is
633 farmed out to ten subworkers.</p>
634
635 <p>The main page is as follows, it just reports the result:</p>
636
637 <pre>&lt;!DOCTYPE HTML&gt;
638 &lt;html&gt;
639 &lt;head&gt;
640 &lt;title&gt;Worker example: One-core computation&lt;/title&gt;
641 &lt;/head&gt;
642 &lt;body&gt;
643 &lt;p&gt;The highest prime number discovered so far is: &lt;output id="result"&gt;&lt;/output&gt;&lt;/p&gt;
644 &lt;script&gt;
645 var worker = new Worker('worker.js');
646 worker.onmessage = function (event) {
647 document.getElementById('result').textContent = event.data;
648 };
649 &lt;/script&gt;
650 &lt;/body&gt;
651 &lt;/html&gt;</pre>
652
653 <p>The worker itself is as follows:</p>
654
655 <pre>// settings
656 var num_workers = 10;
657 var items_per_worker = 1000000;
658
659 // start the workers
660 var result = 0;
661 var pending_workers = num_workers;
662 for (var i = 0; i &lt; num_workers; i += 1) {
663 var worker = new Worker('core.js');
664 worker.postMessage(i * items_per_worker);
665 worker.postMessage((i+1) * items_per_worker);
666 worker.onmessage = storeResult;
667 }
668
669 // handle the results
670 function storeResult(event) {
671 result += 1*event.data;
672 pending_workers -= 1;
673 if (pending_workers &lt;= 0)
674 postMessage(result); // finished!
675 }</pre>
676
677 <p>It consists of a loop to start the subworkers, and then a handler
678 that waits for all the subworkers to respond.</p>
679
680 <p>The subworkers are implemented as follows:</p>
681
682 <pre>var start;
683 onmessage = getStart;
684 function getStart(event) {
685 start = 1*event.data;
686 onmessage = getEnd;
687 }
688
689 var end;
690 function getEnd(event) {
691 end = 1*event.data;
692 onmessage = null;
693 work();
694 }
695
696 function work() {
697 var result = 0;
698 for (var i = start; i &lt; end; i += 1) {
699 // perform some complex calculation here
700 result += 1;
701 }
702 postMessage(result);
703 close();
704 }</pre>
705
706 <p>They receive two numbers in two events, perform the computation
707 for the range of numbers thus specified, and then report the result
708 back to the parent.</p>
709
710 <p><a href=http://www.whatwg.org/demos/workers/multicore/page.html>View this example online</a>.</p>
711
712
713 <h4 id=providing-libraries><span class=secno>1.2.6 </span>Providing libraries</h4>
714
715 <p><em>This section is non-normative.</em></p>
716
717 <p>Suppose that a cryptography library is made available that
718 provides three tasks:</p>
719
720 <dl><dt>Generate a public/private key pair</dt>
721
722 <dd>Takes a port, on which it will send two messages, first the
723 public key and then the private key.</dd>
724
725 <dt>Given a plaintext and a public key, return the corresponding cyphertext</dt>
726
727 <dd>Takes a port, to which any number of messages can be sent, the
728 first giving the public key, and the remainder giving the
729 plaintext, each of which is encrypted and then sent on that same
730 channel as the cyphertext. The user can close the port when it is
731 done encrypting content.</dd>
732
733 <dt>Given a cyphertext and a private key, return the corresponding plaintext</dt>
734
735 <dd>Takes a port, to which any number of messages can be sent, the
736 first giving the private key, and the remainder giving the
737 cyphertext, each of which is decrypted and then sent on that same
738 channel as the plaintext. The user can close the port when it is
739 done decrypting content.</dd>
740
741 </dl><p>The library itself is as follows:</p>
742
743 <pre>function handleMessage(e) {
744 if (e.data == "genkeys")
745 genkeys(e.ports[0]);
746 else if (e.data == "encrypt")
747 encrypt(e.ports[0]);
748 else if (e.data == "decrypt")
749 decrypt(e.ports[0]);
750 }
751
752 function genkeys(p) {
753 var keys = _generateKeyPair();
754 p.postMessage(keys[0]);
755 p.postMessage(keys[1]);
756 }
757
758 function encrypt(p) {
759 var key, state = 0;
760 p.onmessage = function (e) {
761 if (state == 0) {
762 key = e.data;
763 state = 1;
764 } else {
765 p.postMessage(_encrypt(key, e.data));
766 }
767 };
768 }
769
770 function decrypt(p) {
771 var key, state = 0;
772 p.onmessage = function (e) {
773 if (state == 0) {
774 key = e.data;
775 state = 1;
776 } else {
777 p.postMessage(_decrypt(key, e.data));
778 }
779 };
780 }
781
782 // support being used as a shared worker as well as a dedicated worker
783 if (this.onmessage) // dedicated worker
784 onmessage = handleMessage;
785 else // shared worker
786 onconnect = function (e) { e.port.onmessage = handleMessage; }
787
788
789 // the "crypto" functions:
790
791 function _generateKeyPair() {
792 return [Math.random(), Math.random()];
793 }
794
795 function _encrypt(k, s) {
796 return 'encrypted-' + k + ' ' + s;
797 }
798
799 function _decrypt(k, s) {
800 return s.substr(s.indexOf(' ')+1);
801 }</pre>
802
803 <p>Note that the crypto functions here are just stubs and don't do
804 real cryptography.</p>
805
806 <p>This library could be used as follows:</p>
807
808 <pre>&lt;!DOCTYPE HTML&gt;
809 &lt;html&gt;
810 &lt;head&gt;
811 &lt;title&gt;Worker example: Crypto library&lt;/title&gt;
812 &lt;script&gt;
813 var crytoLib = new Worker('libcrypto-v1.js'); // or could use 'libcrypto-v2.js'
814 function getKeys() {
815 var state = 0;
816 cryptoLib.startConversation("genkeys").onmessage = function (e) {
817 if (state == 0)
818 document.getElementById('public').value = e.data;
819 else if (state == 1)
820 document.getElementById('private').value = e.data;
821 state += 1;
822 };
823 }
824 function enc() {
825 var port = cryptoLib.startConversation("encrypt");
826 port.postMessage(document.getElementById('public').value);
827 port.postMessage(document.getElementById('input').value);
828 port.onmessage = function (e) {
829 document.getElementById('input').value = e.data;
830 port.close();
831 };
832 }
833 function dec() {
834 var port = cryptoLib.startConversation("decrypt");
835 port.postMessage(document.getElementById('private').value);
836 port.postMessage(document.getElementById('input').value);
837 port.onmessage = function (e) {
838 document.getElementById('input').value = e.data;
839 port.close();
840 };
841 }
842 &lt;/script&gt;
843 &lt;style&gt;
844 textarea { display: block; }
845 &lt;/style&gt;
846 &lt;/head&gt;
847 &lt;body onload="getKeys()"&gt;
848 &lt;fieldset&gt;
849 &lt;legend&gt;Keys&lt;/legend&gt;
850 &lt;p&gt;&lt;label&gt;Public Key: &lt;textarea id="public"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
851 &lt;p&gt;&lt;label&gt;Private Key: &lt;textarea id="private"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
852 &lt;/fieldset&gt;
853 &lt;p&gt;&lt;label&gt;Input: &lt;textarea id="input"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
854 &lt;p&gt;&lt;button onclick="enc()"&gt;Encrypt&lt;/button&gt; &lt;button onclick="dec()"&gt;Decrypt&lt;/button&gt;&lt;/p&gt;
855 &lt;/body&gt;
856 &lt;/html&gt;</pre>
857
858 <p>A later version of the API, though, might want to offload all the
859 crypto work onto subworkers. This could be done as follows:</p>
860
861 <pre>function handleMessage(e) {
862 if (e.data == "genkeys")
863 genkeys(e.ports[0]);
864 else if (e.data == "encrypt")
865 encrypt(e.ports[0]);
866 else if (e.data == "decrypt")
867 decrypt(e.ports[0]);
868 }
869
870 function genkeys(p) {
871 var generator = new Worker('libcrypto-v2-generator.js');
872 generator.postMessage('', [p]);
873 }
874
875 function encrypt(p) {
876 p.onmessage = function (e) {
877 var key = e.data;
878 var encryptor = new Worker('libcrypto-v2-encryptor.js');
879 encryptor.postMessage(key, [p]);
880 };
881 }
882
883 function encrypt(p) {
884 p.onmessage = function (e) {
885 var key = e.data;
886 var decryptor = new Worker('libcrypto-v2-decryptor.js');
887 decryptor.postMessage(key, [p]);
888 };
889 }
890
891 // support being used as a shared worker as well as a dedicated worker
892 if (this.onmessage) // dedicated worker
893 onmessage = handleMessage;
894 else // shared worker
895 onconnect = function (e) { e.ports[0].onmessage = handleMessage };
896 </pre>
897
898 <p>The little subworkers would then be as follows.</p>
899
900 <p>For generating key pairs:</p>
901
902 <pre>onmessage = function (e) {
903 var k = _generateKeyPair();
904 e.ports[0].postMessage(k[0]);
905 e.ports[0].postMessage(k[1]);
906 close();
907 }
908
909 function _generateKeyPair() {
910 return [Math.random(), Math.random()];
911 }</pre>
912
913 <p>For encrypting:</p>
914
915 <pre>onmessage = function (e) {
916 var key = e.data;
917 e.ports[0].onmessage = function (e) {
918 var s = e.data;
919 postMessage(_encrypt(key, s));
920 }
921 e.ports[0].onclose = function (e) {
922 close();
923 }
924 }
925
926 function _encrypt(k, s) {
927 return 'encrypted-' + k + ' ' + s;
928 }</pre>
929
930 <p>For decrypting:</p>
931
932 <pre>onmessage = function (e) {
933 var key = e.data;
934 e.ports[0].onmessage = function (e) {
935 var s = e.data;
936 postMessage(_decrypt(key, s));
937 }
938 e.ports[0].onclose = function (e) {
939 close();
940 }
941 }
942
943 function _decrypt(k, s) {
944 return s.substr(s.indexOf(' ')+1);
945 }</pre>
946
947 <p>Notice how the users of the API don't have to even know that this
948 is happening &mdash; the API hasn't changed; the library can
949 delegate to subworkers without changing its API, even though it is
950 accepting data using message channels.</p>
951
952 <p><a href=http://www.whatwg.org/demos/workers/crypto/page.html>View this example online</a>.</p>
953
954
955
956
957 <h2 id=conformance-requirements><span class=secno>2 </span>Conformance requirements</h2>
958
959 <p>All diagrams, examples, and notes in this specification are
960 non-normative, as are all sections explicitly marked non-normative.
961 Everything else in this specification is normative.</p>
962
963 <p>The key words "MUST", "MUST NOT", "REQUIRED", <!--"SHALL", "SHALL
964 NOT",--> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
965 "OPTIONAL" in the normative parts of this document are to be
966 interpreted as described in RFC2119. For readability, these words do
967 not appear in all uppercase letters in this specification. <a href=#refsRFC2119>[RFC2119]</a></p>
968
969 <p>Requirements phrased in the imperative as part of algorithms
970 (such as "strip any leading space characters" or "return false and
971 abort these steps") are to be interpreted with the meaning of the
972 key word ("must", "should", "may", etc) used in introducing the
973 algorithm.</p>
974
975 <p>Some conformance requirements are phrased as requirements on
976 attributes, methods or objects. Such requirements are to be
977 interpreted as requirements on user agents.</p>
978
979 <p>Conformance requirements phrased as algorithms or specific steps
980 may be implemented in any manner, so long as the end result is
981 equivalent. (In particular, the algorithms defined in this
982 specification are intended to be easy to follow, and not intended to
983 be performant.)</p>
984
985 <p>The only conformance class defined by this specification is user
986 agents.</p>
987
988 <p>User agents may impose implementation-specific limits on
989 otherwise unconstrained inputs, e.g. to prevent denial of service
990 attacks, to guard against running out of memory, or to work around
991 platform-specific limitations.</p>
992
993
994 <h3 id=dependencies><span class=secno>2.1 </span>Dependencies</h3>
995
996 <p>This specification relies on several other underlying
997 specifications.</p>
998
999 <dl><dt>HTML5</dt>
1000
1001 <dd>
1002
1003 <p>Many fundamental concepts from HTML5 are used by this
1004 specification. <a href=#refsHTML5>[HTML5]</a></p>
1005
1006 </dd>
1007
1008 <dt>WebIDL</dt>
1009
1010 <dd>
1011
1012 <p>The IDL blocks in this specification use the semantics of the
1013 WebIDL specification. <a href=#refsWebIDL>[WebIDL]</a></p>
1014
1015 </dd>
1016
1017 </dl><h2 id=terminology><span class=secno>3 </span>Terminology</h2>
1018
1019 <p>The construction "a <code title="">Foo</code> object", where
1020 <code title="">Foo</code> is actually an interface, is sometimes
1021 used instead of the more accurate "an object implementing the
1022 interface <code title="">Foo</code>".</p>
1023
1024 <p>The term DOM is used to refer to the API set made available to
1025 scripts in Web applications, and does not necessarily imply the
1026 existence of an actual <code>Document</code> object or of any other
1027 <code>Node</code> objects as defined in the DOM Core
1028 specifications. <a href=#refsDOM3CORE>[DOM3CORE]</a></p>
1029
1030 <p>A DOM attribute is said to be <em>getting</em> when its value is
1031 being retrieved (e.g. by author script), and is said to be
1032 <em>setting</em> when a new value is assigned to it.</p>
1033
1034
1035
1036 <h2 id=infrastructure><span class=secno>4 </span>Infrastructure</h2>
1037
1038 <p>There are two kinds of workers; dedicated workers, and shared
1039 workers. Dedicated workers, once created, and are linked to their
1040 creator; but message ports can be used to communicate from a
1041 dedicated worker to multiple other browsing contexts or
1042 workers. Shared workers, on the other hand, are named, and once
1043 created any script running in the same <span>origin</span> can
1044 obtain a reference to that worker and communicate with it.</p>
1045
1046
1047 <h3 id=the-global-scope><span class=secno>4.1 </span>The global scope</h3>
1048
1049 <p>The global scope is the "inside" of a worker.</p>
1050
1051 <h4 id=the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> abstract interface</h4>
1052
1053 <pre class=idl>interface <dfn id=workerglobalscope>WorkerGlobalScope</dfn> {
1054 readonly attribute <a href=#workerglobalscope>WorkerGlobalScope</a> <a href=#dom-workerglobalscope-self title=dom-WorkerGlobalScope-self>self</a>;
1055 readonly attribute <a href=#workerlocation>WorkerLocation</a> <a href=#dom-workerglobalscope-location title=dom-WorkerGlobalScope-location>location</a>;
1056 // also implements everything on <a href=#workerutils>WorkerUtils</a>
1057
1058 void <a href=#dom-workerglobalscope-close title=dom-WorkerGlobalScope-close>close</a>();
1059 attribute <span>EventListener</span> <a href=#handler-workerglobalscope-onclose title=handler-WorkerGlobalScope-onclose>onclose</a>;
1060 attribute <span>EventListener</span> <a href=#handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror>onerror</a>;
1061 };</pre>
1062
1063 <p>Objects implementing the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface
1064 must also implement the <code>EventTarget</code> interface.</p>
1065
1066 <p>The <dfn id=dom-workerglobalscope-self title=dom-WorkerGlobalScope-self><code>self</code></dfn> attribute
1067 must return the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object itself.</p>
1068
1069 <p>The <dfn id=dom-workerglobalscope-location title=dom-WorkerGlobalScope-location><code>location</code></dfn>
1070 attribute must return the <code><a href=#workerlocation>WorkerLocation</a></code> object created
1071 for the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object when the worker was
1072 created. It represents the <span>absolute URL</span> of the script
1073 that was used to initialize the worker.</p>
1074
1075 <hr><p>When a script invokes the <dfn id=dom-workerglobalscope-close title=dom-WorkerGlobalScope-close><code>close()</code></dfn> method on
1076 a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
1077 following steps:</p>
1078
1079 <ol><li><p><span>Queue a task</span> to <span>fire a simple
1080 event</span> called <code title=event-close>close</code> at the
1081 <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</li>
1082
1083 <li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1084 <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1085 true.</li>
1086
1087 <li><p>For each <code>MessagePort</code> object that is entangled
1088 with another port and that has one (but only one) port whose owner
1089 is the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object on which the method
1090 was invoked (this would include, for instance, the implicit port in
1091 used for dedicated workers), unentangle the two ports.</li>
1092
1093 </ol><p>The following are the <span>event handler DOM attributes</span>
1094 that must be supported by objects implementing the
1095 <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface:</p>
1096
1097 <dl><dt><dfn id=handler-workerglobalscope-onclose title=handler-WorkerGlobalScope-onclose><code>onclose</code></dfn></dt>
1098
1099 <dd><p>Must be invoked whenever a <code title=event-close>close</code> event is targeted at or bubbles
1100 through the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</dd>
1101
1102
1103 <dt><dfn id=handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror><code>onerror</code></dfn></dt>
1104
1105 <dd><p>Must be invoked whenever an <code title=event-error>error</code> event is targeted at or bubbles
1106 through the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</dd>
1107
1108 </dl><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>
1109
1110 <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1111 <pre class=idl>[NoInterfaceObject, XXX] interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1112 void <a href=#dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in any message, [Optional] in <span>MessagePortArray</span> ports);<!--
1113 <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
1114 attribute <span>EventListener</span> <a href=#handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
1115 };</pre>
1116
1117 <p><code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects act as if they
1118 had an implicit <code>MessagePort</code> associated with them. This
1119 port is part of a channel that is set up when the worker is created,
1120 but it is not exposed. This object must never be garbage collected
1121 before the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1122
1123 <p>All messages received by that port must immediately be
1124 retargetted at the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1125 object.</p>
1126
1127 <p>The <dfn id=dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
1128 and <dfn
1129 title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
1130 method<!--s (startConversation)--> on
1131 <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects must act as if, when
1132 invoked, it<!--/they (startConversation)--> immediately invoked the
1133 method of the same name on the port, with the same arguments, and
1134 returned the same return value.</p>
1135
1136 <p>The following are the <span>event handler DOM attributes</span>
1137 that must be supported by objects implementing the
1138 <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> interface:</p>
1139
1140 <dl><dt><dfn id=handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn></dt>
1141
1142 <dd><p>Must be invoked whenever a <code title=event-DedicatedWorkerGlobalScope-message>message</code> event is targeted
1143 at or bubbles through the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</dd>
1144
1145 </dl><p>For the purposes of the <span>offline application cache</span>
1146 networking model, a dedicated worker is an extension of the
1147 <span>cache host</span> from which it was created.</p>
1148
1149
1150
1151 <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>
1152
1153 <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1154 <pre class=idl>[NoInterfaceObject, XXX] interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1155 readonly attribute DOMString <a href=#dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name>name</a>;
1156 readonly attribute <span>ApplicationCache</span> <a href=#dom-sharedworkerglobalscope-applicationcache title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</a>;
1157 attribute <span>EventListener</span> <a href=#handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect>onconnect</a>;
1158 };</pre>
1159
1160 <p>Shared workers receive message ports through <code title=event-WorkerGlobalScope-connect>connect</code> events on
1161 their global object for each connection.</p>
1162
1163 <p>The <dfn id=dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name><code>name</code></dfn>
1164 attribute must return the value it was assigned when the
1165 <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object was created by the
1166 "<a href=#run-a-worker>run a worker</a>" algorithm. Its value represents the name
1167 that can be used to obtain a reference to the worker using the
1168 <code><a href=#sharedworker>SharedWorker</a></code> constructor.</p>
1169
1170 <p>The following are the <span>event handler DOM attributes</span>
1171 that must be supported by objects implementing the
1172 <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> interface:</p>
1173
1174 <dl><dt><dfn id=handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect><code>onconnect</code></dfn></dt>
1175
1176 <dd><p>Must be invoked whenever a <code title=event-SharedWorkerGlobalScope-connect>connect</code> event is targeted
1177 at or bubbles through the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object.</dd>
1178
1179 </dl><p>For the purposes of the <span>offline application cache</span>
1180 networking model, a shared worker is its own <span>cache
1181 host</span>. The <a href=#run-a-worker>run a worker</a> algorithm takes care of
1182 associating the worker with an <span>application cache</span>.</p>
1183
1184 <p class=note>The <dfn id=dom-sharedworkerglobalscope-applicationcache title=dom-SharedWorkerGlobalScope-applicationCache><code>applicationCache</code></dfn>
1185 returns the <code>ApplicationCache</code> object for the
1186 worker.</p><!-- normative conf criteria is in the appcache section
1187 -->
1188
1189
1190 <h3 id=base-urls-and-origins-of-workers><span class=secno>4.2 </span>Base URLs and origins of workers</h3>
1191
1192 <p>Both the <span>origin</span> and <span>effective script
1193 origin</span> of scripts running in workers are the
1194 <span>origin</span> of the <span>absolute URL</span> given in that
1195 the worker's <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
1196 represents.</p>
1197
1198
1199 <h3 id=decoding-scripts><span class=secno>4.3 </span>Decoding scripts</h3>
1200
1201 <p>When a user agent is to <dfn id=decode-a-script-resource>decode a script resource</dfn> to
1202 obtain its source in Unicode, it must run the following steps:</p>
1203
1204 <ol><li>
1205
1206 <p>Let <var title="">character encoding</var> be <i title="">unknown</i>.</p>
1207
1208 </li>
1209
1210 <li>
1211
1212 <p>For each of the rows in the following table, starting with the
1213 first one and going down, if the resource has as many or more
1214 bytes available than the number of bytes in the first column, and
1215 the first bytes of the resource match the bytes given in the first
1216 column, then let <var title="">character encoding</var> be the
1217 encoding given in the cell in the second column of that row:</p>
1218
1219 <!-- this table is present in several forms in this file; keep them in sync -->
1220 <table><thead><tr><th>Bytes in Hexadecimal
1221 <th>Encoding
1222 <tbody><!-- nobody uses this
1223 <tr>
1224 <td>00 00 FE FF
1225 <td>UTF-32BE
1226 <tr>
1227 <td>FF FE 00 00
1228 <td>UTF-32LE
1229 --><tr><td>FE FF
1230 <td>UTF-16BE
1231 <tr><td>FF FE
1232 <td>UTF-16LE
1233 <tr><td>EF BB BF
1234 <td>UTF-8
1235 <!-- nobody uses this
1236 <tr>
1237 <td>DD 73 66 73
1238 <td>UTF-EBCDIC
1239 -->
1240 </table><p class=note>This step looks for Unicode Byte Order Marks
1241 (BOMs).</p>
1242
1243 </li>
1244
1245 <li>
1246
1247 <p>If <var title="">character encoding</var> is still <i title="">unknown</i>, apply the <span>algorithm for extracting an
1248 encoding from a Content-Type</span> to the resource's <span title=Content-Type>Content Type metadata</span>; if this returns
1249 an encoding, and the user agent supports that encoding, then let
1250 <var title="">character encoding</var> be that encoding.</p>
1251
1252 </li>
1253
1254 <li>
1255
1256 <p>If <var title="">character encoding</var> is still <i title="">unknown</i>, then let <var title="">character
1257 encoding</var> be UTF-8.</p>
1258
1259 </li>
1260
1261 <li>
1262
1263 <p>Convert the resource to Unicode using the character encoding
1264 given by <var title="">character encoding</var>.</p>
1265
1266 <p>Return the text that is so obtained.</p>
1267
1268 </li>
1269
1270 </ol><h3 id=the-event-loop><span class=secno>4.4 </span>The event loop</h3>
1271
1272 <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is asssociated with a
1273 <span>event loop</span>. This <span>event loop</span> has no
1274 associated <span>browsing context</span>, and its <span title="task
1275 queue">task queues</span> only have events, callbacks, and
1276 networking activity as <span title=concept-task>tasks</span>. The
1277 processing model of these <span title="event loop">event
1278 loops</span> is defined below in the <a href=#run-a-worker>run a worker</a>
1279 algorithm.</p>
1280
1281 <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
1282 initially be false, but which can get set to true by the algorithms
1283 in the processing model section below.</p>
1284
1285 <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
1286 true, the <span>event loop</span>'s <span title="task queue">task
1287 queues</span> must discard any further <span title=concept-task>tasks</span> that would be added to them (tasks
1288 already on the queue are unaffected unless otherwise
1289 specified). Effectively, once the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is true,
1290 timers stop firing, notifications for all pending asynchronous
1291 operations are dropped, etc.</p>
1292
1293
1294 <h3 id="the-worker's-ports"><span class=secno>4.5 </span>The worker's ports</h3>
1295
1296 <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
1297 <code>MessagePort</code> objects.</p>
1298
1299 <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var title="">worker global
1300 scope</var> has a list of <dfn id="the-worker's-ports-0">the worker's ports</dfn>, which
1301 consists of all the <code>MessagePort</code> objects that are
1302 entangled with another port and that have one (but only one) port
1303 owned by <var title="">worker global scope</var>. This list includes
1304 <!--all the <code>MessagePort</code> objects that are in events
1305 pending in the <span>event loop</span>, as well as (commented out
1306 because in practice it makes no difference either way as far as I
1307 can tell, and it would be hard to strictly implement since these
1308 ports might not yet be across the thread boundary)--> the implicit
1309 <code>MessagePort</code> in the case of <a href=#dedicatedworkerglobalscope title=DedicatedWorkerGlobalScope>dedicated workers</a>.</p>
1310
1311 <hr><p>A worker is said to be a <dfn id=permissible-worker>permissible worker</dfn> if
1312 either:</p>
1313
1314 <ul><li>at some point past or present a <code>MessagePort</code> owned
1315 by the worker was entangled with a <code>MessagePort</code> <var title="">p</var> whose owner is a <code>Window</code> object whose
1316 <span>active document</span> is the <code>Document</code> that was
1317 that <span>browsing context</span>'s <span>active document</span>
1318 when <var title="">p</var> was created, and that
1319 <code>Document</code> is <span>fully active</span>, or</li>
1320
1321 <li>at some point past or present a <code>MessagePort</code> owned
1322 by the worker was entangled with a <code>MessagePort</code> owned
1323 by another worker that is currently a <a href=#permissible-worker>permissible
1324 worker</a>.</li>
1325
1326 </ul><hr><p>A worker is said to be a <dfn id=protected-worker>protected worker</dfn> if
1327 either:</p>
1328
1329 <ul><li>it has outstanding timers, database transactions, or network
1330 connections, and is a <a href=#permissible-worker>permissible worker</a>, or</li>
1331
1332 <li>there is a <a href=#protected-worker>protected worker</a> that at some point
1333 past or present owned a <code>MessagePort</code> that was entangled
1334 with a <code>MessagePort</code> owned by this worker.</li>
1335
1336 </ul><hr><p>A worker is said to be an <dfn id=active-needed-worker>active needed worker</dfn> if either:
1337
1338 <ul><li>the worker is a <a href=#protected-worker>protected worker</a>, or</li>
1339
1340 <li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> is
1341 entangled with a <code>MessagePort</code> <var title="">p</var>
1342 whose owner is a <code>Window</code> object whose <span>active
1343 document</span> is the <code>Document</code> that was that
1344 <span>browsing context</span>'s <span>active document</span> when
1345 that <code>MessagePort</code> <var title="">p</var> was created,
1346 and that <code>Document</code> is <span>fully active</span>,
1347 or</li>
1348
1349 <li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> has an
1350 entangled <code>MessagePort</code> owned by a
1351 <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object that is itself an
1352 <a href=#active-needed-worker>active needed worker</a>.</li>
1353
1354 </ul><hr><p>A worker is said to be a <dfn id=suspendable-worker>suspendable worker</dfn> if it is
1355 not an <a href=#active-needed-worker>active needed worker</a> but either:</p>
1356
1357 <ul><li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> has an
1358 entangled <code>MessagePort</code> owned by a <code>Window</code>
1359 object, or</li>
1360
1361 <li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> has an
1362 entangled <code>MessagePort</code> owned by a
1363 <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object that is itself a <span>needed
1364 worker</span>.</li>
1365
1366 </ul><h3 id=processing-model><span class=secno>4.6 </span>Processing model</h3>
1367
1368 <p>When a user agent is to <dfn id=run-a-worker>run a worker</dfn> for a script with
1369 <span>URL</span> <var title="">url</var>, a browsing context <var title="">owner browsing context</var>, and with global scope <var title="">worker global scope</var>, it must run the following
1370 steps:</p>
1371
1372 <ol><li>
1373
1374 <p>Create a completely separate and parallel execution environment
1375 (i.e. a separate thread or process or equivalent construct), and
1376 run the rest of these steps asychronously in that context.</p>
1377
1378 </li>
1379
1380 <li><p>If <var title="">worker global scope</var> is actually a
1381 <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
1382 shared worker), and there are any <span title="relevant application
1383 cache">relevant application caches</span> that are identified by a
1384 manifest URL with the <span>same origin</span> as <var title="">url</var> and that have <var title="">url</var> as one of
1385 their entries, <em>not</em> excluding entries marked as <span title=concept-appcache-foreign>foreign</span>, then associate the
1386 <var title="">worker global scope</var> with the <span title=concept-appcache-selection>most appropriate application
1387 cache</span> of those that match.</li>
1388
1389 <li>
1390
1391 <p>Attempt to <span>fetch</span> the resource identified by <var title="">url</var>.</p>
1392
1393 <p>If the attempt fails, then for each <code><a href=#worker>Worker</a></code> or
1394 <code><a href=#sharedworker>SharedWorker</a></code> object associated with <var title="">worker global scope</var>, <span>queue a task</span> to
1395 <span>fire a simple event</span> called <code title=event-error>error</code> at that object. Abort these
1396 steps.</p>
1397
1398 <p>If the attempt succeeds, then <a href=#decode-a-script-resource title="decode a script
1399 resource">decode the script resource</a> to obtain its <var title="">source</var>.</p>
1400
1401 <p>Let <var title="">language</var> be JavaScript.</p>
1402
1403 <p class=note>As with <code>script</code> elements, the MIME
1404 type of the script is ignored. Unlike with <code>script</code>
1405 elements, there is no way to override the type. It's always
1406 assumed to be JavaScript.</p> <!-- XXX people will complain about
1407 this. I guess we might want to examine the MIME type... -->
1408
1409 </li>
1410
1411 <li>
1412
1413 <p>A new <span title=concept-script>script</span> is now
1414 created, as follows.</p>
1415
1416 <p>Create a new <span>script execution environment</span>
1417 set up as appropriate for the scripting language <var title="">language</var>.</p>
1418
1419 <p>Parse/compile/initialize <var title="">source</var> using that
1420 <span>script execution environment</span>, as appropriate for <var title="">language</var>, and thus obtain a <span>list of code
1421 entry-points</span>; set the <i>initial code entry-point</i> to
1422 the entry-point for any executable code to be immediately run.</p>
1423
1424 <p>Set the <span>script's global object</span> to <var title="">worker global scope</var>.</p>
1425
1426 <p>Set the <span>script's browsing context</span> to <var title="">owner browsing context</var>.</p>
1427
1428 <p>Set the <span>script's URL character encoding</span> to
1429 UTF-8. (This is just used for encoding non-ASCII characters in the
1430 query component of URLs.)</p>
1431
1432 <p>Set the <span>script's base URL</span> to <var title="">url</var>.</p>
1433
1434 <p>Create a new <span>script group</span> and add the <span title=concept-script>script</span> to it.</p>
1435
1436 </li>
1437
1438 <li>
1439
1440 <p><strong>Closing orphan workers</strong>: Start monitoring the
1441 worker such that as soon as it stops being either an <a href=#active-needed-worker>active
1442 needed worker</a> or a <a href=#suspendable-worker>suspendable worker</a>, <var title="">worker global scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
1443 to true and <span title="queue a task">a task is queued</span> to
1444 <span>fire a simple event</span> called <code title=event-close>close</code> at <var title="">worker global
1445 scope</var>.</p>
1446
1447 </li>
1448
1449 <li>
1450
1451 <p><strong>Suspending workers</strong>: Start monitoring the
1452 worker, such that whenever <var title="">worker global
1453 scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is false
1454 and the worker is a <a href=#suspendable-worker>suspendable worker</a>, the user
1455 agent suspends execution of script in that worker until such time
1456 as either the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag switches
1457 to true or the worker stops being a <a href=#suspendable-worker>suspendable
1458 worker</a>.</p>
1459
1460 </li>
1461
1462 <li>
1463
1464 <p><span title="jump to a code entry-point">Jump</span> to the
1465 <span title=concept-script>script</span>'s <i>initial code
1466 entry-point</i>, and let that run until it either returns, fails
1467 to catch an exception, or gets prematurely aborted by the
1468 "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>"
1469 algorithms defined below.</p>
1470
1471 <p class=note>If the script gets aborted by the "<a href=#kill-a-worker>kill a
1472 worker</a>" algorithm, then that same algorithm will cause
1473 there to only be a single <span title=concept-task>task</span>
1474 in the <span>event loop</span> at the next step, namely the task
1475 for the <code title=message-close>close</code> event. The
1476 "<a href=#terminate-a-worker>terminate a worker</a>" algorithm removes all the
1477 events.</p>
1478
1479 </li>
1480
1481 <li><p>If <var title="">worker global scope</var> is actually a
1482 <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is
1483 a dedicated worker), then open the <span>port message queue</span>
1484 of the worker's implicit port.</li>
1485
1486 <li>
1487
1488 <p><i title="">Event loop</i>: Wait until either there is a <span title=concept-task>task</span> in one of the <span>event
1489 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
1490 to true.</p>
1491
1492 </li>
1493
1494 <li>
1495
1496 <p>Run the oldest task on one of the <span>event loop</span>'s
1497 <span title="task queue">task queues</span>, if any. The user
1498 agent may pick any <span>task queue</span>.</p>
1499
1500 <p class=note>The handling of events or the execution of
1501 callbacks might get prematurely aborted by the "<a href=#kill-a-worker>kill a
1502 worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>" algorithms
1503 defined below.</p>
1504
1505 </li>
1506
1507 <li>
1508
1509 <p>Remove the task run in the previous step, if any, from its
1510 <span>task queue</span>.</p>
1511
1512 </li>
1513
1514 <li>
1515
1516 <p>If there are any more events in the <span>event loop</span>'s
1517 <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
1518 to false, then jump back to the step above labeled <i>event
1519 loop</i>.</p>
1520
1521 </li>
1522
1523 <li>
1524
1525 <p>Freeze the <span>script group</span>.</p>
1526
1527 <p class=note>This kills timers, database transactions, etc.</p>
1528
1529 </li>
1530
1531 <li>
1532
1533 <p>For each <code><a href=#worker>Worker</a></code> or <code><a href=#sharedworker>SharedWorker</a></code>
1534 object associated with <var title="">worker global scope</var>,
1535 <span>queue a task</span> to <span>fire a simple event</span>
1536 called <code title=event-close>close</code> at that object.</p>
1537
1538 </li>
1539
1540 </ol><hr><p>When a user agent is to <dfn id=kill-a-worker>kill a worker</dfn> it must
1541 run the following steps in parallel with the worker's main loop (the
1542 "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1543
1544 <ol><li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1545 <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is
1546 false, <span>queue a task</span> to <span>fire a simple
1547 event</span> called <code title=event-close>close</code> at the
1548 worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</li>
1549
1550 <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
1551 true.</li>
1552
1553 <li><p>Wait a user-agent-defined amount of time. If the "<a href=#run-a-worker>run
1554 a worker</a>" processing model defined above immediately starts
1555 running event listeners registered for the <code title=event-close>close</code> event, this time should not be
1556 zero &mdash; the idea is that the <code title=event-close>close</code> event can be used to clean up
1557 when shutting down unexpectedly.</li>
1558
1559 <li><p>If there are any <span title=concept-task>tasks</span>
1560 queued in the <span>event loop</span>'s <span title="task
1561 queue">task queues</span> other than the <code title=event-close>close</code> event that this algorithm just
1562 added, discard them without processing them.</li>
1563
1564 <li><p>If the <code title=event-close>close</code> event that
1565 this algorithm just queued hasn't yet been dispatched, then abort
1566 the script currently running in the worker.</li>
1567
1568 <li><p>Wait a user-agent-defined amount of time.</li>
1569
1570 <li><p>Abort the script currently running in the worker (if any
1571 script is running, then it will be a handler for the <code title=event-close>close</code> event).</li>
1572
1573 </ol><p>User agents may invoke the "<a href=#kill-a-worker>kill a worker</a>"
1574 processing model on a worker at any time, e.g. in response to user
1575 requests, in response to CPU quota management, or when a worker
1576 stops being an <a href=#active-needed-worker>active needed worker</a> if the worker
1577 continues executing even after its <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag was
1578 set to true.</p>
1579
1580 <hr><p>When a user agent is to <dfn id=terminate-a-worker>terminate a worker</dfn> it must run
1581 the following steps in parallel with the worker's main loop (the
1582 "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1583
1584 <ol><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1585 <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1586 true.</li>
1587
1588 <li><p>If there are any <span title=concept-task>tasks</span>
1589 queued in the <span>event loop</span>'s <span title="task
1590 queue">task queues</span>, discard them without processing
1591 them.</li>
1592
1593 <li><p>Abort the script currently running in the worker.</li>
1594
1595 <li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is
1596 actually a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the
1597 worker is a dedicated worker), then empty the <span>port message
1598 queue</span> of the port that the worker's implicit port is
1599 entangled with.</li>
1600
1601 </ol><h3 id=runtime-script-errors><span class=secno>4.7 </span>Runtime script errors</h3>
1602
1603 <p>Whenever a runtime script error occurs in one of the worker's
1604 scripts, if the error did not occur while handling a previous script
1605 error, the user agent must <span>queue a task</span> to <a href=#fire-an-error-event>fire
1606 an error event</a> at the the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
1607 object.</p>
1608
1609 <p>For shared workers, if the error is still <i title="">not
1610 handled</i> afterwards, or if the error occured while handling a
1611 previous script error, the error should be reported to the user.</p>
1612
1613 <p>For dedicated workers, if the error is still <i title="">not
1614 handled</i> afterwards, or if the error occured while handling a
1615 previous script error, the user agent must further <span>queue a
1616 task</span> to <a href=#fire-an-error-event>fire an error event</a> at the
1617 <code><a href=#worker>Worker</a></code> object associated with the worker.</p>
1618
1619 <p>When the user agent is to <dfn id=fire-an-error-event>fire an error event</dfn> at a
1620 <code><a href=#worker>Worker</a></code> object, it must dispatch an event that uses the
1621 <code><a href=#errorevent>ErrorEvent</a></code> interface, with the name <code title=event-error>error</code>, that doesn't bubble and is
1622 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
1623 appropriately. The default action of this event depends on whether
1624 the <code><a href=#worker>Worker</a></code> object is itself in a worker. If it is, and
1625 that worker is also a dedicated worker, then the user agent must
1626 again <span>queue a task</span> to <a href=#fire-an-error-event>fire an error event</a>
1627 at the <code><a href=#worker>Worker</a></code> object associated with <em>that</em>
1628 worker. Otherwise, then the error should be reported to the
1629 user.</p>
1630
1631 <hr><pre class=idl>interface <dfn id=errorevent>ErrorEvent</dfn> : Event {
1632 readonly attribute DOMObject <a href=#dom-errorevent-message title=dom-ErrorEvent-message>message</a>;
1633 readonly attribute DOMObject <a href=#dom-errorevent-filename title=dom-ErrorEvent-filename>filename</a>;
1634 readonly attribute unsigned long <a href=#dom-errorevent-lineno title=dom-ErrorEvent-lineno>lineno</a>;
1635 void <a href=#dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent>initErrorEvent</a>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMObject messageArg, in DOMObject filenameArg, in unsigned long linenoArg);
1636 void <a href=#dom-errorevent-initerroreventns title=dom-ErrorEvent-initErrorEventNS>initErrorEventNS</a>(in DOMString namespaceURIArg, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMObject messageArg, in DOMObject filenameArg, in unsigned long linenoArg);
1637 };</pre>
1638
1639 <p>The <dfn id=dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent><code>initErrorEvent()</code></dfn>
1640 and <dfn id=dom-errorevent-initerroreventns title=dom-ErrorEvent-initErrorEventNS><code>initErrorEventNS()</code></dfn>
1641 methods must initialize the event in a manner analogous to the
1642 similarly-named methods in the DOM3 Events interfaces. <a href=#refsDOM3EVENTS>[DOM3EVENTS]</a></p>
1643
1644 <p>The <dfn id=dom-errorevent-message title=dom-ErrorEvent-message><code>message</code></dfn>
1645 attribute represents the error message.</p>
1646
1647 <p>The <dfn id=dom-errorevent-filename title=dom-ErrorEvent-filename><code>filename</code></dfn>
1648 attribute represents the <span>absolute URL</span> of the script in
1649 which the error originally occured.</p>
1650
1651 <p>The <dfn id=dom-errorevent-lineno title=dom-ErrorEvent-lineno><code>lineno</code></dfn>
1652 attribute represents the line number where the error occured in the
1653 script.</p>
1654
1655
1656
1657 <h3 id=creating-workers><span class=secno>4.8 </span>Creating workers</h3>
1658
1659 <h4 id=the-abstractworker-abstract-interface><span class=secno>4.8.1 </span>The <code><a href=#abstractworker>AbstractWorker</a></code> abstract interface</h4>
1660
1661 <pre class=idl>interface <dfn id=abstractworker>AbstractWorker</dfn> {
1662 attribute <span>EventListener</span> <a href=#handler-abstractworker-onerror title=handler-AbstractWorker-onerror>onerror</a>;
1663 attribute <span>EventListener</span> <a href=#handler-abstractworker-onclose title=handler-AbstractWorker-onclose>onclose</a>;
1664 };</pre>
1665
1666 <p>Objects implementing the <code><a href=#abstractworker>AbstractWorker</a></code> interface
1667 must also implement the <code>EventTarget</code> interface.</p>
1668
1669 <p>The following are the <span>event handler DOM attributes</span>
1670 that must be supported by objects implementing the
1671 <code><a href=#abstractworker>AbstractWorker</a></code> interface:</p>
1672
1673 <dl><dt><dfn id=handler-abstractworker-onerror title=handler-AbstractWorker-onerror><code>onerror</code></dfn></dt>
1674
1675 <dd><p>Must be invoked whenever an <code title=event-error>error</code> event is targeted at or bubbles
1676 through the <code><a href=#abstractworker>AbstractWorker</a></code> object.</dd>
1677
1678 <dt><dfn id=handler-abstractworker-onclose title=handler-AbstractWorker-onclose><code>onclose</code></dfn></dt>
1679
1680 <dd><p>Must be invoked whenever an <code title=event-close>close</code> event is targeted at or bubbles
1681 through the <code><a href=#abstractworker>AbstractWorker</a></code> object.</dd>
1682
1683 </dl><h4 id=dedicated-workers-and-the-worker-interface><span class=secno>4.8.2 </span>Dedicated workers and the <code><a href=#worker>Worker</a></code> interface</h4>
1684
1685 <pre class=idl>[<a href=#dom-worker title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
1686 interface <dfn id=worker>Worker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1687 void <a href=#dom-worker-terminate title=dom-Worker-terminate>terminate</a>();
1688
1689 void <a href=#dom-worker-postmessage title=dom-Worker-postMessage>postMessage</a>(in any message, [Optional] in <span>MessagePortArray</span> ports);<!--
1690 <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
1691 attribute <span>EventListener</span> <a href=#handler-worker-onmessage title=handler-Worker-onmessage>onmessage</a>;
1692 };</pre>
1693
1694 <p>The <dfn id=dom-worker-terminate title=dom-Worker-terminate><code>terminate()</code></dfn> method,
1695 when invoked, must cause the "<a href=#terminate-a-worker>terminate a worker</a>"
1696 algorithm to be run on the worker with with the object is
1697 associated.</p>
1698
1699 <p><code><a href=#worker>Worker</a></code> objects act as if they had an implicit
1700 <code>MessagePort</code> associated with them. This port is part of
1701 a channel that is set up when the worker is created, but it is not
1702 exposed. This object must never be garbage collected before the
1703 <code><a href=#worker>Worker</a></code> object.</p>
1704
1705 <p>All messages received by that port must immediately be
1706 retargetted at the <code><a href=#worker>Worker</a></code> object.</p>
1707
1708 <p>The <dfn id=dom-worker-postmessage title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
1709 and <dfn
1710 title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
1711 method<!--s (startConversation)--> on <code><a href=#worker>Worker</a></code> objects
1712 must act as if, when invoked, it<!--/they (startConversation)-->
1713 immediately invoked the method of the same name on the port, with
1714 the same arguments, and returned the same return value.</p>
1715
1716 <p>The following are the <span>event handler DOM attributes</span>
1717 that must be supported by objects implementing the
1718 <code><a href=#worker>Worker</a></code> interface:</p>
1719
1720 <dl><dt><dfn id=handler-worker-onmessage title=handler-Worker-onmessage><code>onmessage</code></dfn></dt>
1721
1722 <dd><p>Must be invoked whenever a <code title=event-Worker-message>message</code> event is targeted
1723 at or bubbles through the <code><a href=#worker>Worker</a></code> object.</dd>
1724
1725 </dl><hr><p>When the <dfn id=dom-worker title=dom-Worker><code>Worker(<var title="">scriptURL</var>)</code></dfn> constructor is invoked, the
1726 user agent must run the following steps:</p>
1727
1728 <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
1729
1730 <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1731 exception.</li>
1732
1733 <li><p>If the <span>origin</span> of the resulting <span>absolute
1734 URL</span> is not the <span title="same origin">same</span> as the
1735 origin of the script that invoked the constructor, then throw a
1736 <span>security exception</span>.</li>
1737
1738 <li><p><span>Create a new <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1739 object</span>. Let <var title="">worker global scope</var> be this
1740 new object.</li>
1741
1742 <li><p>Create a new <code><a href=#worker>Worker</a></code> object, associated with
1743 <var title="">worker global scope</var>. Let <var title="">worker</var> be this new object.</li>
1744
1745 <li><p><span>Create a <code>MessagePort</code> object</span> owned
1746 by the <span>script execution context</span> of the script that
1747 invoked the method. Let this be the <var title="">outside
1748 port</var>.</li>
1749
1750 <li><p>Associate the <var title="">outside port</var> with <var title="">worker</var>.</li>
1751
1752 <li><p><span>Create a <code>MessagePort</code> object</span> owned
1753 by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
1754
1755 <li><p>Associate <var title="">inside port</var> with <var title="">worker global scope</var>.</li>
1756
1757 <li><p><span>Entangle</span> <var title="">outside port</var> and
1758 <var title="">inside port</var>.</li>
1759
1760 <li><p>Return <var title="">worker</var>, and run the following
1761 steps asynchronously.</li>
1762
1763 <li><p>Open <var title="">inside port</var>'s <span>port message
1764 queue</span>.</li>
1765
1766 <li><p>Open <var title="">outside port</var>'s <span>port message
1767 queue</span>.</li>
1768
1769 <li>
1770
1771 <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
1772 URL</span>, with the <span>script browsing context</span> of the
1773 script that invoked the method as the <var title="">owner browsing
1774 context</var>, and with <var title="">worker global scope</var> as
1775 the global scope.</p>
1776
1777 </li>
1778
1779 </ol><h4 id=shared-workers-and-the-sharedworker-interface><span class=secno>4.8.3 </span>Shared workers and the <code><a href=#sharedworker>SharedWorker</a></code> interface</h4>
1780
1781 <pre class=idl>[<a href=#dom-sharedworker title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in DOMString name)]
1782 interface <dfn id=sharedworker>SharedWorker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1783 readonly attribute <span>MessagePort</span> <a href=#dom-sharedworker-port title=dom-SharedWorker-port>port</a>;
1784 };</pre>
1785
1786 <p>The <dfn id=dom-sharedworker-port title=dom-SharedWorker-port><code>port</code></dfn>
1787 attribute must return the value it was assigned by the object's
1788 constructor. It represents the <code>MessagePort</code> for
1789 communicating with the shared worker.</p>
1790
1791 <p>When the <dfn id=dom-sharedworker title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>, <var title="">name</var>)</code></dfn>
1792 constructor is invoked, the user agent must run the following
1793 steps:</p>
1794
1795 <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
1796
1797 <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1798 exception.</li>
1799
1800 <li><p>If the <span>origin</span> of the resulting <span>absolute
1801 URL</span> is not the <span title="same origin">same</span> as the
1802 origin of the script that invoked the constructor, then throw a
1803 <span>security exception</span>.</li>
1804
1805 <li>
1806
1807 <p>Execute the following substeps atomically:</p>
1808
1809 <ol><li><p>Create a new <code><a href=#sharedworker>SharedWorker</a></code> object, which will
1810 shortly be associated with a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1811 object. Let this <code><a href=#sharedworker>SharedWorker</a></code> object be <var title="">worker</var>.</li>
1812
1813 <li><p><span>Create a <code>MessagePort</code> object</span> owned
1814 by the <span>script execution context</span> of the script that
1815 invoked the method. Let this be the <var title="">outside
1816 port</var>.</li>
1817
1818 <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>
1819
1820 <li>
1821
1822 <p>If there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object
1823 whose <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a>
1824 flag is false, whose <code title=dom-WorkerGlobalScope-name>name</code> attribute is
1825 exactly equal to the <var title="">name</var> argument, and
1826 whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
1827 represents an <span>absolute URL</span> that has the <span>same
1828 origin</span> as the resulting <span>absolute URL</span>, then
1829 run these substeps:</p>
1830
1831 <ol><li><p>Let <var title="">worker global scope</var> be that
1832 <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object.</li>
1833
1834 <li><p>If <var title="">worker global scope</var>'s <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code>
1835 attribute represents an <span>absolute URL</span> that is not
1836 exactly equal to the resulting <span>absolute URL</span>, then
1837 throw a <code>URL_MISMATCH_ERR</code> exception and abort all
1838 these steps. <span class=XXX>code 21</span></li>
1839
1840 <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
1841
1842 <li><p><span>Create a <code>MessagePort</code> object</span>
1843 owned by <var title="">worker global scope</var>. Let this
1844 be the <var title="">inside port</var>.</li>
1845
1846 <li><p><span>Entangle</span> <var title="">outside port</var>
1847 and <var title="">inside port</var>.</li>
1848
1849 <li><p>Return <var title="">worker</var> and perform the next
1850 step asynchronously.</li>
1851
1852 <li><p>Create an event that uses the <code>MessageEvent</code>
1853 interface, with the name <code title=event-connect>connect</code>, which does not bubble, is
1854 cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value
1855 is the empty string and has a <code title=dom-MessageEvent-ports>ports</code>
1856 attribute whose value is an array containing only the newly
1857 created port, and <span>queue a task</span> to dispatch the
1858 event at <var title="">worker global scope</var>.</li>
1859
1860 <li><p>Abort all these steps.</li>
1861
1862 </ol></li>
1863
1864 <li><p><span>Create a new <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1865 object</span>. Let <var title="">worker global scope</var> be
1866 this new object.</li>
1867
1868 <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
1869
1870 <li><p>Set the <code title=dom-SharedWorkerGlobalScope-name><a href=#dom-sharedworkerglobalscope-name>name</a></code> attribute of
1871 <var title="">worker global scope</var> to <var title="">name</var>.</li>
1872
1873 <li><p><span>Create a <code>MessagePort</code> object</span>
1874 owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
1875
1876 <li><p><span>Entangle</span> <var title="">outside port</var> and
1877 <var title="">inside port</var>.</li>
1878
1879 </ol></li>
1880
1881 <li><p>Return <var title="">worker</var> and perform the next step
1882 asynchronously.</li>
1883
1884 <li><p>Create an event that uses the <code>MessageEvent</code>
1885 interface, with the name <code title=event-connect>connect</code>, which does not bubble, is
1886 cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value is
1887 the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute
1888 whose value is an array containing only the newly created port, and
1889 <span>queue a task</span> to dispatch the event at <var title="">worker global scope</var>.</li>
1890
1891 <li>
1892
1893 <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
1894 URL</span>, with the <span>script browsing context</span> of the
1895 script that invoked the method as the <var title="">owner browsing
1896 context</var>, and with <var title="">worker global scope</var> as
1897 the global scope.</p>
1898
1899 </li>
1900
1901 </ol><h2 id=apis-available-to-workers><span class=secno>5 </span>APIs available to workers</h2>
1902
1903 <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1904 <pre class=idl>[NoInterfaceObject, ImplementedOn=WorkerGlobalScope, XXX] interface <dfn id=workerutils>WorkerUtils</dfn> {
1905 void <a href=#dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts>importScripts</a>([Variadic] in DOMString urls);
1906 readonly attribute <a href=#worker-navigator title=worker-Navigator>Navigator</a> <a href=#dom-worker-navigator title=dom-worker-navigator>navigator</a>;
1907 <span>Database</span> <a href=#dom-opendatabase title=dom-opendatabase>openDatabase</a>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
1908 };</pre>
1909
1910 <p>Objects that implement the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
1911 interface must also implement the <code><a href=#workerutils>WorkerUtils</a></code>
1912 interface.</p>
1913
1914 <p>Objects that implement the <code><a href=#workerutils>WorkerUtils</a></code> interface
1915 must also implement the <code>WindowTimers</code> interface. (This
1916 interface provides the <code title="">setTimeout()</code> method and
1917 its friends.)</p><!-- XXX ref -->
1918
1919 <p class=XXX>Need to define a sync database API.</p>
1920
1921 <!-- XXX ApplicationCache -->
1922
1923 <!-- XXX debugging: void log(in DOMString s); // log to console -->
1924
1925 <hr><p>The DOM APIs (<code>Node</code> objects, <code>Document</code>
1926 objects, etc) are not available to workers in this version of this
1927 specification.</p>
1928
1929
1930 <h3 id=importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</h3>
1931
1932 <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
1933 <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
1934 following steps:</p>
1935
1936 <ol><li><p>If there are no arguments, return without doing
1937 anything. Abort these steps.</li>
1938
1939 <li><p><span title="resolve a url">Resolve</span> each
1940 argument.</li>
1941
1942 <li><p>If any fail, throw a <code>SYNTAX_ERR</code>
1943 exception.</li>
1944
1945 <!--
1946 <li><p>If any of the resulting <span title="absolute URL">absolute
1947 URLs</span> have an <span>origin</span> that is not the <span
1948 title="same origin">same</span> as the origin of the script that
1949 invoked the method, then throw a <span>security
1950 exception</span>.</p></li>
1951 -->
1952
1953 <li>
1954
1955 <p>Attempt to <span>fetch</span> each resource identified by the
1956 resulting <span title="absolute URLs">absolute URL</span>.</p>
1957
1958 </li>
1959
1960 <li>
1961
1962 <p>For each argument in turn, in the order given, starting with
1963 the first one, run these substeps:</p>
1964
1965 <ol><li>
1966
1967 <p>Wait for the fetching attempt for the corresponding resource
1968 to complete.</p>
1969
1970 <p>If the fetching attempt failed, throw a
1971 <code>NETWORK_ERR</code> exception and abort all these
1972 steps.</p>
1973
1974 <p>If the attempt succeeds, then <a href=#decode-a-script-resource title="decode a script
1975 resource">decode the script resource</a> to obtain its <var title="">source</var>.</p>
1976
1977 <p>Let <var title="">language</var> be JavaScript.</p>
1978
1979 <p class=note>As with the worker's script, the script here is
1980 always assumed to be JavaScript, regardless of the MIME
1981 type.</p> <!-- XXX -->
1982
1983 </li>
1984
1985 <li>
1986
1987 <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
1988 same global object, browsing context, character encoding, base
1989 URL, and script group as the <span title=concept-script>script</span> that was created by the
1990 worker's <a href=#run-a-worker>run a worker</a> algorithm.</p>
1991
1992 <p>Let the newly created <span title=concept-script>script</span> run until it either
1993 returns, fails to parse, fails to catch an exception, or gets
1994 prematurely aborted by the "<a href=#kill-a-worker>kill a worker</a>" or
1995 "<a href=#terminate-a-worker>terminate a worker</a>" algorithms defined above.</p>
1996
1997 <p>If it failed to parse, then throw a
1998 <code>SyntaxError</code><!-- XXX ref? --> exception and abort
1999 all these steps.</p>
2000
2001 <p>If an exception was raised or if the script was prematurely
2002 aborted, then abort all these steps, letting the exception or
2003 aborting continue to be processed by the script that called the
2004 <code title=dom-WorkerGlobalScope-importScripts><a href=#dom-workerglobalscope-importscripts>importScripts()</a></code>
2005 method.</p>
2006
2007 <p>If the "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a
2008 worker</a>" algorithms abort the script then abort all these
2009 steps.</p>
2010
2011 </li>
2012
2013 </ol></li>
2014
2015 </ol><h3 id=the-navigator-object><span class=secno>5.2 </span>The <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code> object</h3>
2016
2017 <p>The <dfn id=dom-worker-navigator title=dom-worker-navigator><code>navigator</code></dfn> attribute
2018 of the <code><a href=#workerutils>WorkerUtils</a></code> interface must return an instance of
2019 the <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code> interface, which
2020 represents the identity and state of the user agent (the
2021 client):</p>
2022
2023 <pre class=idl>interface <dfn id=worker-navigator title=worker-Navigator>Navigator</dfn> {
2024 // objects implementing this interface also implement the interfaces listed below
2025 };</pre>
2026
2027 <p>Objects implementing the <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code> interface must also
2028 implement the <span>NavigatorID</span> and
2029 <span>NavigatorOnLine</span> interfaces specified in the HTML5
2030 specification. <a href=#refsHTML5>[HTML5]</a></p>
2031
2032 <p class=note>The <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code>
2033 interface defined in this specification is different than the one
2034 defined in the HTML5 specification.</p>
2035
2036
2037
2038 <h3 id=apis-defined-in-other-specifications><span class=secno>5.3 </span>APIs defined in other specifications</h3>
2039
2040 <p>The <dfn id=dom-opendatabase title=dom-opendatabase><code>openDatabase()</code></dfn> method
2041 must act as defined for the API of the same name defined in the Web
2042 Storage specification, with the exception that where the API would
2043 use the <span>origin</span> of the <span>active document</span> of
2044 the <span>browsing context</span> of the <code>Window</code> object
2045 on which the method was supposedly invoked, it must instead use the
2046 <span>origin</span> of the script that invoked the method. <a href=#refsWEBSTORAGE>[WEBSTORAGE]</a></p>
2047
2048
2049
2050 <h3 id=interface-objects-and-constructors><span class=secno>5.4 </span>Interface objects and constructors</h3>
2051
2052 <p>There must be no interface objects and constructors available in
2053 the global scope of scripts whose <span>script execution
2054 context</span> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object except for
2055 the following:</p>
2056
2057 <ul><li><p><code>XMLHttpRequest</code> and all interface objects and
2058 constructors defined by the XMLHttpRequest specifications, except
2059 that the <span>document response entity body</span> must always be
2060 null. <a href=#refsXHR>[XHR]</a></li>
2061
2062 <li><p>The <code>WebSocket</code> interface object and
2063 constructor. <a href=#refsWEBSOCKET>[WEBSOCKET]</a></li>
2064
2065 <li><p>The <code>MessageChannel</code> interface object and
2066 constructor. <a href=#refsHTML5>[HTML5]</a></li>
2067
2068 <li><p>The <code title=dom-Worker><a href=#dom-worker>Worker()</a></code> and <code title=dom-SharedWorker><a href=#dom-sharedworker>SharedWorker(<var title="">url</var>)</a></code> constructors.</li>
2069
2070 </ul><h3 id=worker-locations><span class=secno>5.5 </span>Worker locations</h3>
2071
2072 <pre class=idl>interface <dfn id=workerlocation>WorkerLocation</dfn> {
2073 readonly attribute DOMString <a href=#dom-workerlocation-href title=dom-WorkerLocation-href>href</a>;
2074 readonly attribute DOMString <a href=#dom-workerlocation-protocol title=dom-WorkerLocation-protocol>protocol</a>;
2075 readonly attribute DOMString <a href=#dom-workerlocation-host title=dom-WorkerLocation-host>host</a>;
2076 readonly attribute DOMString <a href=#dom-workerlocation-hostname title=dom-WorkerLocation-hostname>hostname</a>;
2077 readonly attribute DOMString <a href=#dom-workerlocation-port title=dom-WorkerLocation-port>port</a>;
2078 readonly attribute DOMString <a href=#dom-workerlocation-pathname title=dom-WorkerLocation-pathname>pathname</a>;
2079 readonly attribute DOMString <a href=#dom-workerlocation-search title=dom-WorkerLocation-search>search</a>;
2080 readonly attribute DOMString <a href=#dom-workerlocation-hash title=dom-WorkerLocation-hash>hash</a>;
2081 };</pre>
2082
2083 <p>A <code><a href=#workerlocation>WorkerLocation</a></code> object represents an <span>absolute
2084 URL</span> set at its creation.</p>
2085
2086 <p>The <dfn id=dom-workerlocation-href title=dom-WorkerLocation-href><code>href</code></dfn>
2087 attribute must return the <span>absolute URL</span> that the object
2088 represents.</p>
2089
2090 <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface also has the complement
2091 of <span>URL decomposition attributes</span>, <dfn id=dom-workerlocation-protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
2092 <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>,
2093 <dfn id=dom-workerlocation-pathname title=dom-WorkerLocation-pathname><code>pathname</code></dfn>,
2094 <dfn id=dom-workerlocation-search title=dom-WorkerLocation-search><code>search</code></dfn>,
2095 and <dfn id=dom-workerlocation-hash title=dom-WorkerLocation-hash><code>hash</code></dfn>. These must
2096 follow the rules given for URL decomposition attributes, with the
2097 <span title=concept-uda-input>input</span> being the
2098 <span>absolute URL</span> that the object represents (same as the
2099 <code title=dom-WorkerLocation-href><a href=#dom-workerlocation-href>href</a></code> attribute), and
2100 the <span title=concept-uda-setter>common setter action</span>
2101 being a no-op, since the attributes are defined to be readonly. <a href=#refsHTML5>[HTML5]</a></p>
2102
2103
2104
2105
2106 <h2 class=no-num id=references>References</h2>
2107
2108 <p class=big-issue>This section will be written in a future
2109 draft.<!--XXX--></p>
2110
2111
2112 <h2 class=no-num id=acknowledgements>Acknowledgements</h2> <!-- ACKS -->
2113
2114 <p>Thanks to
2115
2116 Aaron Boodman,
2117 &#1040;&#1083;&#1077;&#1082;&#1089;&#1077;&#1081; &#1055;&#1088;&#1086;&#1089;&#1082;&#1091;&#1088;&#1103;&#1082;&#1086;&#1074; (Alexey Proskuryakov),
2118 Anne van Kesteren,
2119 Ben Turner,
2120 Dmitry Titov,
2121 Drew Wilson,
2122 Jeremy Orlow,
2123 Jonas Sicking,
2124 Justin James,
2125 Kevin Hakanson,
2126 Maciej Stachowiak,
2127 Michael Nordman,
2128 Mike Smith,
2129
2130 and
2131
2132 Philip Taylor
2133
2134 for their useful and substantial comments.</p>
2135
2136 <p>Huge thanks to the whole Gears team, who pioneered this
2137 technology and whose experience has been a huge influence on this
2138 specification.</p>
2139
2140

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24