/[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.70 - (hide annotations) (download) (as text)
Mon May 25 06:20:16 2009 UTC (16 years, 10 months ago) by wakaba
Branch: MAIN
Changes since 1.69: +1 -1 lines
File MIME type: text/html
make

1 wakaba 1.59 <!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 wakaba 1.70 <h2 class="no-num no-toc" id=draft-recommendation-&mdash;-date:-01-jan-1901>Draft Recommendation &mdash; 25 May 2009</h2>
6 wakaba 1.59 <p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
7     <p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
8     <dl><dt>This version:</dt>
9     <dd><a href=http://www.whatwg.org/specs/web-workers/current-work/>http://whatwg.org/ww</a></dd>
10     <dt>Version history:</dt>
11     <dd>Twitter messages (non-editorial changes only): <a href=http://twitter.com/WHATWG>http://twitter.com/WHATWG</a></dd>
12     <dd>Commit-Watchers mailing list: <a href=http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org>http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org</a></dd>
13     <dd>Interactive Web interface: <a href=http://html5.org/tools/web-workers-tracker>http://html5.org/tools/web-workers-tracker</a></dd>
14     <dd>Subversion interface: <a href=http://svn.whatwg.org/webworkers/>http://svn.whatwg.org/webworkers/</a></dd>
15     <dt>Issues:</dt>
16     <dd>To send feedback: <a href=http://www.whatwg.org/mailing-list>whatwg@whatwg.org</a></dd>
17     <dd>To view and vote on feedback: <a href=http://www.whatwg.org/issues/>http://www.whatwg.org/issues/</a></dd>
18     <dt>Editor:</dt>
19     <dd>Ian Hickson, Google, ian@hixie.ch</dd>
20     </dl><p class=copyright>&copy; Copyright 2004-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:whatwg@whatwg.org>whatwg@whatwg.org</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 unoptimized 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 wakaba 1.69 &lt;body onload="search('')"&gt;
269 wakaba 1.59 &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 wakaba 1.69 &lt;p&gt;&lt;label&gt;Search: &lt;input type="text" autofocus oninput="search(this.value)"&gt;&lt;/label&gt;&lt;/p&gt;
279 wakaba 1.59 &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     <p>The term "JavaScript" is used to refer to ECMA262, rather than
1035     the official term ECMAScript, since the term JavaScript is more
1036     widely known. <a href=#refsECMA262>[ECMA262]</a></p>
1037    
1038    
1039     <h2 id=infrastructure><span class=secno>4 </span>Infrastructure</h2>
1040    
1041     <p>There are two kinds of workers; dedicated workers, and shared
1042     workers. Dedicated workers, once created, and are linked to their
1043     creator; but message ports can be used to communicate from a
1044     dedicated worker to multiple other browsing contexts or
1045     workers. Shared workers, on the other hand, are named, and once
1046     created any script running in the same <span>origin</span> can
1047     obtain a reference to that worker and communicate with it.</p>
1048    
1049    
1050     <h3 id=the-global-scope><span class=secno>4.1 </span>The global scope</h3>
1051    
1052     <p>The global scope is the "inside" of a worker.</p>
1053    
1054     <h4 id=the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> abstract interface</h4>
1055    
1056     <pre class=idl>interface <dfn id=workerglobalscope>WorkerGlobalScope</dfn> {
1057     readonly attribute <a href=#workerglobalscope>WorkerGlobalScope</a> <a href=#dom-workerglobalscope-self title=dom-WorkerGlobalScope-self>self</a>;
1058     readonly attribute <a href=#workerlocation>WorkerLocation</a> <a href=#dom-workerglobalscope-location title=dom-WorkerGlobalScope-location>location</a>;
1059     // also implements everything on <a href=#workerutils>WorkerUtils</a>
1060    
1061     void <a href=#dom-workerglobalscope-close title=dom-WorkerGlobalScope-close>close</a>();
1062     attribute <span>EventListener</span> <a href=#handler-workerglobalscope-onclose title=handler-WorkerGlobalScope-onclose>onclose</a>;
1063     attribute <span>EventListener</span> <a href=#handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror>onerror</a>;
1064     };</pre>
1065    
1066     <p>Objects implementing the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface
1067     must also implement the <code>EventTarget</code> interface.</p>
1068    
1069     <p>The <dfn id=dom-workerglobalscope-self title=dom-WorkerGlobalScope-self><code>self</code></dfn> attribute
1070     must return the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object itself.</p>
1071    
1072     <p>The <dfn id=dom-workerglobalscope-location title=dom-WorkerGlobalScope-location><code>location</code></dfn>
1073     attribute must return the <code><a href=#workerlocation>WorkerLocation</a></code> object created
1074     for the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object when the worker was
1075     created. It represents the <span>absolute URL</span> of the script
1076     that was used to initialize the worker.</p>
1077    
1078     <hr><p>When a script invokes the <dfn id=dom-workerglobalscope-close title=dom-WorkerGlobalScope-close><code>close()</code></dfn> method on
1079     a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
1080     following steps:</p>
1081    
1082     <ol><li><p><span>Queue a task</span> to <span>fire a simple
1083     event</span> called <code title=event-close>close</code> at the
1084     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</li>
1085    
1086     <li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1087     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1088     true.</li>
1089    
1090     <li><p>For each <code>MessagePort</code> object that is entangled
1091     with another port and that has one (but only one) port whose owner
1092     is the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object on which the method
1093     was invoked (this would include, for instance, the implicit port in
1094     used for dedicated workers), disentangle the two ports.</li>
1095    
1096     </ol><p>The following are the <span>event handler attributes</span> (and their corresponding <span title="event handler event type">event handler event types</span>)
1097     that must be supported, as DOM attributes, by objects implementing
1098     the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface:</p>
1099    
1100     <table><thead><tr><th><span title="event handler attributes">event handler attribute</span> <th><span>Event handler event type</span>
1101     <tbody><tr><td><dfn id=handler-workerglobalscope-onclose title=handler-WorkerGlobalScope-onclose><code>onclose</code></dfn> <td> <code title=event-close>close</code>
1102     <tr><td><dfn id=handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
1103     </table><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>
1104    
1105     <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1106     <pre class=idl>[NoInterfaceObject, XXX] interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1107     void <a href=#dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in any message, [Optional] in <span>MessagePortArray</span> ports);<!--
1108     <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
1109     attribute <span>EventListener</span> <a href=#handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
1110     };</pre>
1111    
1112     <p><code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects act as if they
1113     had an implicit <code>MessagePort</code> associated with them. This
1114     port is part of a channel that is set up when the worker is created,
1115     but it is not exposed. This object must never be garbage collected
1116     before the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1117    
1118     <p>All messages received by that port must immediately be retargeted
1119     at the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
1120    
1121     <p>The <dfn id=dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
1122     and <dfn
1123     title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
1124     method<!--s (startConversation)--> on
1125     <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects must act as if, when
1126     invoked, it<!--/they (startConversation)--> immediately invoked the
1127     method of the same name on the port, with the same arguments, and
1128     returned the same return value.</p>
1129    
1130     <p>The following are the <span>event handler attributes</span> (and their corresponding <span title="event handler event type">event handler event types</span>)
1131     that must be supported, as DOM attributes, by objects implementing
1132     the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> interface:</p>
1133    
1134     <table><thead><tr><th><span title="event handler attributes">event handler attribute</span> <th><span>Event handler event type</span>
1135     <tbody><tr><td><dfn id=handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
1136     </table><p>For the purposes of the <span>offline application cache</span>
1137     networking model, a dedicated worker is an extension of the
1138     <span>cache host</span> from which it was created.</p>
1139    
1140    
1141    
1142     <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>
1143    
1144     <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1145     <pre class=idl>[NoInterfaceObject, XXX] interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
1146     readonly attribute DOMString <a href=#dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name>name</a>;
1147     readonly attribute <span>ApplicationCache</span> <a href=#dom-sharedworkerglobalscope-applicationcache title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</a>;
1148     attribute <span>EventListener</span> <a href=#handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect>onconnect</a>;
1149     };</pre>
1150    
1151     <p>Shared workers receive message ports through <code title=event-WorkerGlobalScope-connect>connect</code> events on
1152     their global object for each connection.</p>
1153    
1154     <p>The <dfn id=dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name><code>name</code></dfn>
1155     attribute must return the value it was assigned when the
1156     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object was created by the
1157     "<a href=#run-a-worker>run a worker</a>" algorithm. Its value represents the name
1158     that can be used to obtain a reference to the worker using the
1159     <code><a href=#sharedworker>SharedWorker</a></code> constructor.</p>
1160    
1161     <p>The following are the <span>event handler attributes</span> (and their corresponding <span title="event handler event type">event handler event types</span>)
1162     that must be supported, as DOM attributes, by objects implementing
1163     the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> interface:</p>
1164    
1165     <table><thead><tr><th><span title="event handler attributes">event handler attribute</span> <th><span>Event handler event type</span>
1166     <tbody><tr><td><dfn id=handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect><code>onconnect</code></dfn> <td> <code title=event-connect>connect</code>
1167     </table><p>For the purposes of the <span>offline application cache</span>
1168     networking model, a shared worker is its own <span>cache
1169     host</span>. The <a href=#run-a-worker>run a worker</a> algorithm takes care of
1170     associating the worker with an <span>application cache</span>.</p>
1171    
1172     <p class=note>The <dfn id=dom-sharedworkerglobalscope-applicationcache title=dom-SharedWorkerGlobalScope-applicationCache><code>applicationCache</code></dfn>
1173     returns the <code>ApplicationCache</code> object for the
1174     worker.</p><!-- normative conf criteria is in the appcache section
1175     -->
1176    
1177    
1178     <h3 id=base-urls-and-origins-of-workers><span class=secno>4.2 </span>Base URLs and origins of workers</h3>
1179    
1180     <p>Both the <span>origin</span> and <span>effective script
1181     origin</span> of scripts running in workers are the
1182     <span>origin</span> of the <span>absolute URL</span> given in that
1183     the worker's <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
1184     represents.</p>
1185    
1186    
1187     <h3 id=decoding-scripts><span class=secno>4.3 </span>Decoding scripts</h3>
1188    
1189     <p>When a user agent is to <dfn id=decode-a-script-resource>decode a script resource</dfn> to
1190     obtain its source in Unicode, it must run the following steps:</p>
1191    
1192     <ol><li>
1193    
1194     <p>Let <var title="">character encoding</var> be <i title="">unknown</i>.</p>
1195    
1196     </li>
1197    
1198     <li>
1199    
1200     <p>For each of the rows in the following table, starting with the
1201     first one and going down, if the resource has as many or more
1202     bytes available than the number of bytes in the first column, and
1203     the first bytes of the resource match the bytes given in the first
1204     column, then let <var title="">character encoding</var> be the
1205     encoding given in the cell in the second column of that row:</p>
1206    
1207     <!-- this table is present in several forms in this file; keep them in sync -->
1208     <table><thead><tr><th>Bytes in Hexadecimal
1209     <th>Encoding
1210     <tbody><!-- nobody uses this
1211     <tr>
1212     <td>00 00 FE FF
1213     <td>UTF-32BE
1214     <tr>
1215     <td>FF FE 00 00
1216     <td>UTF-32LE
1217     --><tr><td>FE FF
1218     <td>UTF-16BE
1219     <tr><td>FF FE
1220     <td>UTF-16LE
1221     <tr><td>EF BB BF
1222     <td>UTF-8
1223     <!-- nobody uses this
1224     <tr>
1225     <td>DD 73 66 73
1226     <td>UTF-EBCDIC
1227     -->
1228     </table><p class=note>This step looks for Unicode Byte Order Marks
1229     (BOMs).</p>
1230    
1231     </li>
1232    
1233     <li>
1234    
1235     <p>If <var title="">character encoding</var> is still <i title="">unknown</i>, apply the <span>algorithm for extracting an
1236     encoding from a Content-Type</span> to the resource's <span title=Content-Type>Content Type metadata</span>; if this returns
1237     an encoding, and the user agent supports that encoding, then let
1238     <var title="">character encoding</var> be that encoding.</p>
1239    
1240     </li>
1241    
1242     <li>
1243    
1244     <p>If <var title="">character encoding</var> is still <i title="">unknown</i>, then let <var title="">character
1245     encoding</var> be UTF-8.</p>
1246    
1247     </li>
1248    
1249     <li>
1250    
1251     <p>Convert the resource to Unicode using the character encoding
1252     given by <var title="">character encoding</var>.</p>
1253    
1254     <p>Return the text that is so obtained.</p>
1255    
1256     </li>
1257    
1258     </ol><h3 id=the-event-loop><span class=secno>4.4 </span>The event loop</h3>
1259    
1260     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is asssociated with a
1261     <span>event loop</span>. This <span>event loop</span> has no
1262     associated <span>browsing context</span>, and its <span title="task
1263     queue">task queues</span> only have events, callbacks, and
1264     networking activity as <span title=concept-task>tasks</span>. The
1265     processing model of these <span title="event loop">event
1266     loops</span> is defined below in the <a href=#run-a-worker>run a worker</a>
1267     algorithm.</p>
1268    
1269     <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
1270     initially be false, but which can get set to true by the algorithms
1271     in the processing model section below.</p>
1272    
1273     <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
1274     true, the <span>event loop</span>'s <span title="task queue">task
1275     queues</span> must discard any further <span title=concept-task>tasks</span> that would be added to them (tasks
1276     already on the queue are unaffected unless otherwise
1277     specified). Effectively, once the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is true,
1278     timers stop firing, notifications for all pending asynchronous
1279     operations are dropped, etc.</p>
1280    
1281    
1282     <h3 id="the-worker's-ports"><span class=secno>4.5 </span>The worker's ports</h3>
1283    
1284     <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
1285     <code>MessagePort</code> objects.</p>
1286    
1287     <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var title="">worker global
1288     scope</var> has a list of <dfn id="the-worker's-ports-0">the worker's ports</dfn>, which
1289     consists of all the <code>MessagePort</code> objects that are
1290     entangled with another port and that have one (but only one) port
1291     owned by <var title="">worker global scope</var>. This list includes
1292     <!--all the <code>MessagePort</code> objects that are in events
1293     pending in the <span>event loop</span>, as well as (commented out
1294     because in practice it makes no difference either way as far as I
1295     can tell, and it would be hard to strictly implement since these
1296     ports might not yet be across the thread boundary)--> the implicit
1297     <code>MessagePort</code> in the case of <a href=#dedicatedworkerglobalscope title=DedicatedWorkerGlobalScope>dedicated workers</a>.</p>
1298    
1299     <hr><p>A worker is said to be a <dfn id=permissible-worker>permissible worker</dfn> if
1300     either:</p>
1301    
1302     <ul><li>at some point past or present a <code>MessagePort</code> owned
1303     by the worker was entangled with a <code>MessagePort</code> <var title="">p</var> whose owner is a <code>Window</code> object whose
1304     <span>active document</span> is the <code>Document</code> that was
1305     that <span>browsing context</span>'s <span>active document</span>
1306     when <var title="">p</var> was created, and that
1307     <code>Document</code> is <span>fully active</span>, or</li>
1308    
1309     <li>at some point past or present a <code>MessagePort</code> owned
1310     by the worker was entangled with a <code>MessagePort</code> owned
1311     by another worker that is currently a <a href=#permissible-worker>permissible
1312     worker</a>.</li>
1313    
1314     </ul><hr><p>A worker is said to be a <dfn id=protected-worker>protected worker</dfn> if
1315     either:</p>
1316    
1317     <ul><li>it has outstanding timers, database transactions, or network
1318     connections, and is a <a href=#permissible-worker>permissible worker</a>, or</li>
1319    
1320     <li>there is a <a href=#protected-worker>protected worker</a> that at some point
1321     past or present owned a <code>MessagePort</code> that was entangled
1322     with a <code>MessagePort</code> owned by this worker.</li>
1323    
1324     </ul><hr><p>A worker is said to be an <dfn id=active-needed-worker>active needed worker</dfn> if either:
1325    
1326     <ul><li>the worker is a <a href=#protected-worker>protected worker</a>, or</li>
1327    
1328     <li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> is
1329     entangled with a <code>MessagePort</code> <var title="">p</var>
1330     whose owner is a <code>Window</code> object whose <span>active
1331     document</span> is the <code>Document</code> that was that
1332     <span>browsing context</span>'s <span>active document</span> when
1333     that <code>MessagePort</code> <var title="">p</var> was created,
1334     and that <code>Document</code> is <span>fully active</span>,
1335     or</li>
1336    
1337     <li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> has an
1338     entangled <code>MessagePort</code> owned by a
1339     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object that is itself an
1340     <a href=#active-needed-worker>active needed worker</a>.</li>
1341    
1342     </ul><hr><p>A worker is said to be a <dfn id=suspendable-worker>suspendable worker</dfn> if it is
1343     not an <a href=#active-needed-worker>active needed worker</a> but either:</p>
1344    
1345     <ul><li>at least one of the <a href="#the-worker's-ports-0">the worker's ports</a> has an
1346     entangled <code>MessagePort</code> owned by a <code>Window</code>
1347     object, 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 a <span>needed
1352     worker</span>.</li>
1353    
1354     </ul><h3 id=processing-model><span class=secno>4.6 </span>Processing model</h3>
1355    
1356     <p>When a user agent is to <dfn id=run-a-worker>run a worker</dfn> for a script with
1357     <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
1358     steps:</p>
1359    
1360     <ol><li>
1361    
1362     <p>Create a completely separate and parallel execution environment
1363     (i.e. a separate thread or process or equivalent construct), and
1364     run the rest of these steps asynchronously in that context.</p>
1365    
1366     </li>
1367    
1368     <li><p>If <var title="">worker global scope</var> is actually a
1369     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
1370     shared worker), and there are any <span title="relevant application
1371     cache">relevant application caches</span> that are identified by a
1372     manifest URL with the <span>same origin</span> as <var title="">url</var> and that have <var title="">url</var> as one of
1373     their entries, <em>not</em> excluding entries marked as <span title=concept-appcache-foreign>foreign</span>, then associate the
1374     <var title="">worker global scope</var> with the <span title=concept-appcache-selection>most appropriate application
1375     cache</span> of those that match.</li>
1376    
1377     <li>
1378    
1379     <p>Attempt to <span>fetch</span> the resource identified by <var title="">url</var>.</p>
1380    
1381     <p>If the attempt fails, then for each <code><a href=#worker>Worker</a></code> or
1382     <code><a href=#sharedworker>SharedWorker</a></code> object associated with <var title="">worker global scope</var>, <span>queue a task</span> to
1383     <span>fire a simple event</span> called <code title=event-error>error</code> at that object. Abort these
1384     steps.</p>
1385    
1386     <p>If the attempt succeeds, then <a href=#decode-a-script-resource title="decode a script
1387     resource">decode the script resource</a> to obtain its <var title="">source</var>.</p>
1388    
1389     <p>Let <var title="">language</var> be JavaScript.</p>
1390    
1391     <p class=note>As with <code>script</code> elements, the MIME
1392     type of the script is ignored. Unlike with <code>script</code>
1393     elements, there is no way to override the type. It's always
1394     assumed to be JavaScript.</p> <!-- XXX people will complain about
1395     this. I guess we might want to examine the MIME type... -->
1396    
1397     </li>
1398    
1399     <li>
1400    
1401     <p>A new <span title=concept-script>script</span> is now
1402     created, as follows.</p>
1403    
1404     <p>Create a new <span>script execution environment</span>
1405     set up as appropriate for the scripting language <var title="">language</var>.</p>
1406    
1407     <p>Parse/compile/initialize <var title="">source</var> using that
1408     <span>script execution environment</span>, as appropriate for <var title="">language</var>, and thus obtain a <span>list of code
1409     entry-points</span>; set the <i>initial code entry-point</i> to
1410     the entry-point for any executable code to be immediately run.</p>
1411    
1412     <p>Set the <span>script's global object</span> to <var title="">worker global scope</var>.</p>
1413    
1414     <p>Set the <span>script's browsing context</span> to <var title="">owner browsing context</var>.</p>
1415    
1416     <p>Set the <span>script's URL character encoding</span> to
1417     UTF-8. (This is just used for encoding non-ASCII characters in the
1418     query component of URLs.)</p>
1419    
1420     <p>Set the <span>script's base URL</span> to <var title="">url</var>.</p>
1421    
1422     <p>Create a new <span>script group</span> and add the <span title=concept-script>script</span> to it.</p>
1423    
1424     </li>
1425    
1426     <li>
1427    
1428     <p><strong>Closing orphan workers</strong>: Start monitoring the
1429     worker such that as soon as it stops being either an <a href=#active-needed-worker>active
1430     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
1431     to true and <span title="queue a task">a task is queued</span> to
1432     <span>fire a simple event</span> called <code title=event-close>close</code> at <var title="">worker global
1433     scope</var>.</p>
1434    
1435     </li>
1436    
1437     <li>
1438    
1439     <p><strong>Suspending workers</strong>: Start monitoring the
1440     worker, such that whenever <var title="">worker global
1441     scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is false
1442     and the worker is a <a href=#suspendable-worker>suspendable worker</a>, the user
1443     agent suspends execution of script in that worker until such time
1444     as either the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag switches
1445     to true or the worker stops being a <a href=#suspendable-worker>suspendable
1446     worker</a>.</p>
1447    
1448     </li>
1449    
1450     <li>
1451    
1452     <p><span title="jump to a code entry-point">Jump</span> to the
1453     <span title=concept-script>script</span>'s <i>initial code
1454     entry-point</i>, and let that run until it either returns, fails
1455     to catch an exception, or gets prematurely aborted by the
1456     "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>"
1457     algorithms defined below.</p>
1458    
1459     <p class=note>If the script gets aborted by the "<a href=#kill-a-worker>kill a
1460     worker</a>" algorithm, then that same algorithm will cause
1461     there to only be a single <span title=concept-task>task</span>
1462     in the <span>event loop</span> at the next step, namely the task
1463     for the <code title=message-close>close</code> event. The
1464     "<a href=#terminate-a-worker>terminate a worker</a>" algorithm removes all the
1465     events.</p>
1466    
1467     </li>
1468    
1469     <li><p>If <var title="">worker global scope</var> is actually a
1470     <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is
1471     a dedicated worker), then open the <span>port message queue</span>
1472     of the worker's implicit port.</li>
1473    
1474     <li>
1475    
1476     <p><i title="">Event loop</i>: Wait until either there is a <span title=concept-task>task</span> in one of the <span>event
1477     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
1478     to true.</p>
1479    
1480     </li>
1481    
1482     <li>
1483    
1484     <p>Run the oldest task on one of the <span>event loop</span>'s
1485     <span title="task queue">task queues</span>, if any. The user
1486     agent may pick any <span>task queue</span>.</p>
1487    
1488     <p class=note>The handling of events or the execution of
1489     callbacks might get prematurely aborted by the "<a href=#kill-a-worker>kill a
1490     worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>" algorithms
1491     defined below.</p>
1492    
1493     </li>
1494    
1495     <li>
1496    
1497     <p>Remove the task run in the previous step, if any, from its
1498     <span>task queue</span>.</p>
1499    
1500     </li>
1501    
1502     <li>
1503    
1504     <p>If there are any more events in the <span>event loop</span>'s
1505     <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
1506     to false, then jump back to the step above labeled <i>event
1507     loop</i>.</p>
1508    
1509     </li>
1510    
1511     <li>
1512    
1513     <p>Freeze the <span>script group</span>.</p>
1514    
1515     <p class=note>This kills timers, database transactions, etc.</p>
1516    
1517     </li>
1518    
1519     <li>
1520    
1521     <p>For each <code><a href=#worker>Worker</a></code> or <code><a href=#sharedworker>SharedWorker</a></code>
1522     object associated with <var title="">worker global scope</var>,
1523     <span>queue a task</span> to <span>fire a simple event</span>
1524     called <code title=event-close>close</code> at that object.</p>
1525    
1526     </li>
1527    
1528     </ol><hr><p>When a user agent is to <dfn id=kill-a-worker>kill a worker</dfn> it must
1529     run the following steps in parallel with the worker's main loop (the
1530     "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1531    
1532     <ol><li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1533     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is
1534     false, <span>queue a task</span> to <span>fire a simple
1535     event</span> called <code title=event-close>close</code> at the
1536     worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</li>
1537    
1538     <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
1539     true.</li>
1540    
1541     <li><p>Wait a user-agent-defined amount of time. If the "<a href=#run-a-worker>run
1542     a worker</a>" processing model defined above immediately starts
1543     running event listeners registered for the <code title=event-close>close</code> event, this time should not be
1544     zero &mdash; the idea is that the <code title=event-close>close</code> event can be used to clean up
1545     when shutting down unexpectedly.</li>
1546    
1547     <li><p>If there are any <span title=concept-task>tasks</span>
1548     queued in the <span>event loop</span>'s <span title="task
1549     queue">task queues</span> other than the <code title=event-close>close</code> event that this algorithm just
1550     added, discard them without processing them.</li>
1551    
1552     <li><p>If the <code title=event-close>close</code> event that
1553     this algorithm just queued hasn't yet been dispatched, then abort
1554     the script currently running in the worker.</li>
1555    
1556     <li><p>Wait a user-agent-defined amount of time.</li>
1557    
1558     <li><p>Abort the script currently running in the worker (if any
1559     script is running, then it will be a handler for the <code title=event-close>close</code> event).</li>
1560    
1561     </ol><p>User agents may invoke the "<a href=#kill-a-worker>kill a worker</a>"
1562     processing model on a worker at any time, e.g. in response to user
1563     requests, in response to CPU quota management, or when a worker
1564     stops being an <a href=#active-needed-worker>active needed worker</a> if the worker
1565     continues executing even after its <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag was
1566     set to true.</p>
1567    
1568     <hr><p>When a user agent is to <dfn id=terminate-a-worker>terminate a worker</dfn> it must run
1569     the following steps in parallel with the worker's main loop (the
1570     "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
1571    
1572     <ol><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
1573     <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
1574     true.</li>
1575    
1576     <li><p>If there are any <span title=concept-task>tasks</span>
1577     queued in the <span>event loop</span>'s <span title="task
1578     queue">task queues</span>, discard them without processing
1579     them.</li>
1580    
1581     <li><p>Abort the script currently running in the worker.</li>
1582    
1583     <li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is
1584     actually a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the
1585     worker is a dedicated worker), then empty the <span>port message
1586     queue</span> of the port that the worker's implicit port is
1587     entangled with.</li>
1588    
1589     </ol><h3 id=runtime-script-errors><span class=secno>4.7 </span>Runtime script errors</h3>
1590    
1591     <p>Whenever a runtime script error occurs in one of the worker's
1592     scripts, if the error did not occur while handling a previous script
1593     error, the user agent must <span>queue a task</span> to <span>fire a
1594     simple event</span> called <code title=event-error>error</code> at
1595     the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</p>
1596    
1597     <p>For shared workers, if the error is still <i title="">not
1598     handled</i> afterwards, or if the error occured while handling a
1599     previous script error, the error should be reported to the user.</p>
1600    
1601     <p>For dedicated workers, if the error is still <i title="">not
1602     handled</i> afterwards, or if the error occured while handling a
1603     previous script error, the user agent must further <span>queue a
1604     task</span> to <a href=#fire-a-worker-error-event>fire a worker error event</a> at the
1605     <code><a href=#worker>Worker</a></code> object associated with the worker.</p>
1606    
1607     <p>When the user agent is to <dfn id=fire-a-worker-error-event>fire a worker error event</dfn> at
1608     a <code><a href=#worker>Worker</a></code> object, it must dispatch an event that uses
1609     the <code><a href=#errorevent>ErrorEvent</a></code> interface, with the name <code title=event-error>error</code>, that doesn't bubble and is
1610     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
1611     appropriately. The default action of this event depends on whether
1612     the <code><a href=#worker>Worker</a></code> object is itself in a worker. If it is, and
1613     that worker is also a dedicated worker, then the user agent must
1614     again <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
1615     event</a> at the <code><a href=#worker>Worker</a></code> object associated with
1616     <em>that</em> worker. Otherwise, then the error should be reported
1617     to the user.</p>
1618    
1619     <hr><pre class=idl>interface <dfn id=errorevent>ErrorEvent</dfn> : Event {
1620     readonly attribute DOMObject <a href=#dom-errorevent-message title=dom-ErrorEvent-message>message</a>;
1621     readonly attribute DOMObject <a href=#dom-errorevent-filename title=dom-ErrorEvent-filename>filename</a>;
1622     readonly attribute unsigned long <a href=#dom-errorevent-lineno title=dom-ErrorEvent-lineno>lineno</a>;
1623     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);
1624     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);
1625     };</pre>
1626    
1627     <p>The <dfn id=dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent><code>initErrorEvent()</code></dfn>
1628     and <dfn id=dom-errorevent-initerroreventns title=dom-ErrorEvent-initErrorEventNS><code>initErrorEventNS()</code></dfn>
1629     methods must initialize the event in a manner analogous to the
1630     similarly-named methods in the DOM3 Events interfaces. <a href=#refsDOM3EVENTS>[DOM3EVENTS]</a></p>
1631    
1632     <p>The <dfn id=dom-errorevent-message title=dom-ErrorEvent-message><code>message</code></dfn>
1633     attribute represents the error message.</p>
1634    
1635     <p>The <dfn id=dom-errorevent-filename title=dom-ErrorEvent-filename><code>filename</code></dfn>
1636     attribute represents the <span>absolute URL</span> of the script in
1637     which the error originally occured.</p>
1638    
1639     <p>The <dfn id=dom-errorevent-lineno title=dom-ErrorEvent-lineno><code>lineno</code></dfn>
1640     attribute represents the line number where the error occured in the
1641     script.</p>
1642    
1643    
1644    
1645     <h3 id=creating-workers><span class=secno>4.8 </span>Creating workers</h3>
1646    
1647     <h4 id=the-abstractworker-abstract-interface><span class=secno>4.8.1 </span>The <code><a href=#abstractworker>AbstractWorker</a></code> abstract interface</h4>
1648    
1649     <pre class=idl>interface <dfn id=abstractworker>AbstractWorker</dfn> {
1650     attribute <span>EventListener</span> <a href=#handler-abstractworker-onerror title=handler-AbstractWorker-onerror>onerror</a>;
1651     attribute <span>EventListener</span> <a href=#handler-abstractworker-onclose title=handler-AbstractWorker-onclose>onclose</a>;
1652     };</pre>
1653    
1654     <p>Objects implementing the <code><a href=#abstractworker>AbstractWorker</a></code> interface
1655     must also implement the <code>EventTarget</code> interface.</p>
1656    
1657     <p>The following are the <span>event handler attributes</span> (and their corresponding <span title="event handler event type">event handler event types</span>)
1658     that must be supported, as DOM attributes, by objects implementing
1659     the <code><a href=#abstractworker>AbstractWorker</a></code> interface:</p>
1660    
1661     <table><thead><tr><th><span title="event handler attributes">event handler attribute</span> <th><span>Event handler event type</span>
1662     <tbody><tr><td><dfn id=handler-abstractworker-onerror title=handler-AbstractWorker-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
1663     <tr><td><dfn id=handler-abstractworker-onclose title=handler-AbstractWorker-onclose><code>onclose</code></dfn> <td> <code title=event-close>close</code>
1664     </table><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>
1665    
1666     <pre class=idl>[<a href=#dom-worker title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
1667     interface <dfn id=worker>Worker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1668     void <a href=#dom-worker-terminate title=dom-Worker-terminate>terminate</a>();
1669    
1670     void <a href=#dom-worker-postmessage title=dom-Worker-postMessage>postMessage</a>(in any message, [Optional] in <span>MessagePortArray</span> ports);<!--
1671     <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
1672     attribute <span>EventListener</span> <a href=#handler-worker-onmessage title=handler-Worker-onmessage>onmessage</a>;
1673     };</pre>
1674    
1675     <p>The <dfn id=dom-worker-terminate title=dom-Worker-terminate><code>terminate()</code></dfn> method,
1676     when invoked, must cause the "<a href=#terminate-a-worker>terminate a worker</a>"
1677     algorithm to be run on the worker with with the object is
1678     associated.</p>
1679    
1680     <p><code><a href=#worker>Worker</a></code> objects act as if they had an implicit
1681     <code>MessagePort</code> associated with them. This port is part of
1682     a channel that is set up when the worker is created, but it is not
1683     exposed. This object must never be garbage collected before the
1684     <code><a href=#worker>Worker</a></code> object.</p>
1685    
1686     <p>All messages received by that port must immediately be retargeted
1687     at the <code><a href=#worker>Worker</a></code> object.</p>
1688    
1689     <p>The <dfn id=dom-worker-postmessage title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
1690     and <dfn
1691     title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
1692     method<!--s (startConversation)--> on <code><a href=#worker>Worker</a></code> objects
1693     must act as if, when invoked, it<!--/they (startConversation)-->
1694     immediately invoked the method of the same name on the port, with
1695     the same arguments, and returned the same return value.</p>
1696    
1697     <p>The following are the <span>event handler attributes</span> (and their corresponding <span title="event handler event type">event handler event types</span>)
1698     that must be supported, as DOM attributes, by objects implementing
1699     the <code><a href=#worker>Worker</a></code> interface:</p>
1700    
1701     <table><thead><tr><th><span title="event handler attributes">event handler attribute</span> <th><span>Event handler event type</span>
1702     <tbody><tr><td><dfn id=handler-worker-onmessage title=handler-Worker-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
1703     </table><hr><p>When the <dfn id=dom-worker title=dom-Worker><code>Worker(<var title="">scriptURL</var>)</code></dfn> constructor is invoked, the
1704     user agent must run the following steps:</p>
1705    
1706     <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
1707    
1708     <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1709     exception.</li>
1710    
1711     <li><p>If the <span>origin</span> of the resulting <span>absolute
1712     URL</span> is not the <span title="same origin">same</span> as the
1713     origin of the script that invoked the constructor, then throw a
1714     <span>security exception</span>.</li>
1715    
1716     <li><p><span>Create a new <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
1717     object</span>. Let <var title="">worker global scope</var> be this
1718     new object.</li>
1719    
1720     <li><p>Create a new <code><a href=#worker>Worker</a></code> object, associated with
1721     <var title="">worker global scope</var>. Let <var title="">worker</var> be this new object.</li>
1722    
1723     <li><p><span>Create a <code>MessagePort</code> object</span> owned
1724     by the <span>script execution context</span> of the script that
1725     invoked the method. Let this be the <var title="">outside
1726     port</var>.</li>
1727    
1728     <li><p>Associate the <var title="">outside port</var> with <var title="">worker</var>.</li>
1729    
1730     <li><p><span>Create a <code>MessagePort</code> object</span> owned
1731     by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
1732    
1733     <li><p>Associate <var title="">inside port</var> with <var title="">worker global scope</var>.</li>
1734    
1735     <li><p><span>Entangle</span> <var title="">outside port</var> and
1736     <var title="">inside port</var>.</li>
1737    
1738     <li><p>Return <var title="">worker</var>, and run the following
1739     steps asynchronously.</li>
1740    
1741     <li><p>Open <var title="">inside port</var>'s <span>port message
1742     queue</span>.</li>
1743    
1744     <li><p>Open <var title="">outside port</var>'s <span>port message
1745     queue</span>.</li>
1746    
1747     <li>
1748    
1749     <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
1750     URL</span>, with the <span>script browsing context</span> of the
1751     script that invoked the method as the <var title="">owner browsing
1752     context</var>, and with <var title="">worker global scope</var> as
1753     the global scope.</p>
1754    
1755     </li>
1756    
1757     </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>
1758    
1759     <pre class=idl>[<a href=#dom-sharedworker title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in DOMString name)]
1760     interface <dfn id=sharedworker>SharedWorker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
1761     readonly attribute <span>MessagePort</span> <a href=#dom-sharedworker-port title=dom-SharedWorker-port>port</a>;
1762     };</pre>
1763    
1764     <p>The <dfn id=dom-sharedworker-port title=dom-SharedWorker-port><code>port</code></dfn>
1765     attribute must return the value it was assigned by the object's
1766     constructor. It represents the <code>MessagePort</code> for
1767     communicating with the shared worker.</p>
1768    
1769     <p>When the <dfn id=dom-sharedworker title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>, <var title="">name</var>)</code></dfn>
1770     constructor is invoked, the user agent must run the following
1771     steps:</p>
1772    
1773     <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
1774    
1775     <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
1776     exception.</li>
1777    
1778     <li><p>If the <span>origin</span> of the resulting <span>absolute
1779     URL</span> is not the <span title="same origin">same</span> as the
1780     origin of the script that invoked the constructor, then throw a
1781     <span>security exception</span>.</li>
1782    
1783     <li>
1784    
1785     <p>Execute the following substeps atomically:</p>
1786    
1787     <ol><li><p>Create a new <code><a href=#sharedworker>SharedWorker</a></code> object, which will
1788     shortly be associated with a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1789     object. Let this <code><a href=#sharedworker>SharedWorker</a></code> object be <var title="">worker</var>.</li>
1790    
1791     <li><p><span>Create a <code>MessagePort</code> object</span> owned
1792     by the <span>script execution context</span> of the script that
1793     invoked the method. Let this be the <var title="">outside
1794     port</var>.</li>
1795    
1796     <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>
1797    
1798     <li>
1799    
1800     <p>If there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object
1801     whose <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a>
1802     flag is false, whose <code title=dom-WorkerGlobalScope-name>name</code> attribute is
1803     exactly equal to the <var title="">name</var> argument, and
1804     whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
1805     represents an <span>absolute URL</span> that has the <span>same
1806     origin</span> as the resulting <span>absolute URL</span>, then
1807     run these substeps:</p>
1808    
1809     <ol><li><p>Let <var title="">worker global scope</var> be that
1810     <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object.</li>
1811    
1812     <li><p>If <var title="">worker global scope</var>'s <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code>
1813     attribute represents an <span>absolute URL</span> that is not
1814     exactly equal to the resulting <span>absolute URL</span>, then
1815     throw a <code>URL_MISMATCH_ERR</code> exception and abort all
1816     these steps. <span class=XXX>code 21</span></li>
1817    
1818     <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
1819    
1820     <li><p><span>Create a <code>MessagePort</code> object</span>
1821     owned by <var title="">worker global scope</var>. Let this
1822     be the <var title="">inside port</var>.</li>
1823    
1824     <li><p><span>Entangle</span> <var title="">outside port</var>
1825     and <var title="">inside port</var>.</li>
1826    
1827     <li><p>Return <var title="">worker</var> and perform the next
1828     step asynchronously.</li>
1829    
1830     <li><p>Create an event that uses the <code>MessageEvent</code>
1831     interface, with the name <code title=event-connect>connect</code>, which does not bubble, is
1832     not cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value
1833     is the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose
1834     value is an array containing only the newly created port, and
1835     <span>queue a task</span> to dispatch the event at <var title="">worker global scope</var>.</li>
1836    
1837     <li><p>Abort all these steps.</li>
1838    
1839     </ol></li>
1840    
1841     <li><p><span>Create a new <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
1842     object</span>. Let <var title="">worker global scope</var> be
1843     this new object.</li>
1844    
1845     <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
1846    
1847     <li><p>Set the <code title=dom-SharedWorkerGlobalScope-name><a href=#dom-sharedworkerglobalscope-name>name</a></code> attribute of
1848     <var title="">worker global scope</var> to <var title="">name</var>.</li>
1849    
1850     <li><p><span>Create a <code>MessagePort</code> object</span>
1851     owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
1852    
1853     <li><p><span>Entangle</span> <var title="">outside port</var> and
1854     <var title="">inside port</var>.</li>
1855    
1856     </ol></li>
1857    
1858     <li><p>Return <var title="">worker</var> and perform the next step
1859     asynchronously.</li>
1860    
1861     <li><p>Create an event that uses the <code>MessageEvent</code>
1862     interface, with the name <code title=event-connect>connect</code>, which does not bubble, is not
1863     cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value is
1864     the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose value
1865     is an array containing only the newly created port, and <span>queue
1866     a task</span> to dispatch the event at <var title="">worker global
1867     scope</var>.</li>
1868    
1869     <li>
1870    
1871     <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
1872     URL</span>, with the <span>script browsing context</span> of the
1873     script that invoked the method as the <var title="">owner browsing
1874     context</var>, and with <var title="">worker global scope</var> as
1875     the global scope.</p>
1876    
1877     </li>
1878    
1879     </ol><h2 id=apis-available-to-workers><span class=secno>5 </span>APIs available to workers</h2>
1880    
1881     <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1882     <pre class=idl>[NoInterfaceObject, ImplementedOn=WorkerGlobalScope, XXX] interface <dfn id=workerutils>WorkerUtils</dfn> {
1883     void <a href=#dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts>importScripts</a>([Variadic] in DOMString urls);
1884     readonly attribute <a href=#worker-navigator title=worker-Navigator>Navigator</a> <a href=#dom-worker-navigator title=dom-worker-navigator>navigator</a>;
1885     <span>Database</span> <span title=dom-opendatabase>openDatabase</span>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
1886     <span>DatabaseSync</span> <span title=dom-opendatabase-sync>openDatabaseSync</span>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
1887     };</pre>
1888    
1889     <p>Objects that implement the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
1890     interface must also implement the <code><a href=#workerutils>WorkerUtils</a></code>
1891     interface.</p>
1892    
1893     <p>Objects that implement the <code><a href=#workerutils>WorkerUtils</a></code> interface
1894     must also implement the <code>WindowTimers</code> interface. (This
1895     interface provides the <code title="">setTimeout()</code> method and
1896     its friends.)</p><!-- XXX ref -->
1897    
1898     <!-- XXX ApplicationCache -->
1899    
1900     <!-- XXX debugging: void log(in DOMString s); // log to console -->
1901    
1902     <hr><p>The DOM APIs (<code>Node</code> objects, <code>Document</code>
1903     objects, etc) are not available to workers in this version of this
1904     specification.</p>
1905    
1906    
1907     <h3 id=importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</h3>
1908    
1909     <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
1910     <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
1911     following steps:</p>
1912    
1913     <ol><li><p>If there are no arguments, return without doing
1914     anything. Abort these steps.</li>
1915    
1916     <li><p><span title="resolve a url">Resolve</span> each
1917     argument.</li>
1918    
1919     <li><p>If any fail, throw a <code>SYNTAX_ERR</code>
1920     exception.</li>
1921    
1922     <!--
1923     <li><p>If any of the resulting <span title="absolute URL">absolute
1924     URLs</span> have an <span>origin</span> that is not the <span
1925     title="same origin">same</span> as the origin of the script that
1926     invoked the method, then throw a <span>security
1927     exception</span>.</p></li>
1928     -->
1929    
1930     <li>
1931    
1932     <p>Attempt to <span>fetch</span> each resource identified by the
1933     resulting <span title="absolute URLs">absolute URL</span>.</p>
1934    
1935     </li>
1936    
1937     <li>
1938    
1939     <p>For each argument in turn, in the order given, starting with
1940     the first one, run these substeps:</p>
1941    
1942     <ol><li>
1943    
1944     <p>Wait for the fetching attempt for the corresponding resource
1945     to complete.</p>
1946    
1947     <p>If the fetching attempt failed, throw a
1948     <code>NETWORK_ERR</code> exception and abort all these
1949     steps.</p>
1950    
1951     <p>If the attempt succeeds, then <a href=#decode-a-script-resource title="decode a script
1952     resource">decode the script resource</a> to obtain its <var title="">source</var>.</p>
1953    
1954     <p>Let <var title="">language</var> be JavaScript.</p>
1955    
1956     <p class=note>As with the worker's script, the script here is
1957     always assumed to be JavaScript, regardless of the MIME
1958     type.</p> <!-- XXX -->
1959    
1960     </li>
1961    
1962     <li>
1963    
1964     <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
1965     same global object, browsing context, character encoding, base
1966     URL, and script group as the <span title=concept-script>script</span> that was created by the
1967     worker's <a href=#run-a-worker>run a worker</a> algorithm.</p>
1968    
1969     <p>Let the newly created <span title=concept-script>script</span> run until it either
1970     returns, fails to parse, fails to catch an exception, or gets
1971     prematurely aborted by the "<a href=#kill-a-worker>kill a worker</a>" or
1972     "<a href=#terminate-a-worker>terminate a worker</a>" algorithms defined above.</p>
1973    
1974     <p>If it failed to parse, then throw a
1975     <code>SyntaxError</code><!-- XXX ref? --> exception and abort
1976     all these steps.</p>
1977    
1978     <p>If an exception was raised or if the script was prematurely
1979     aborted, then abort all these steps, letting the exception or
1980     aborting continue to be processed by the script that called the
1981     <code title=dom-WorkerGlobalScope-importScripts><a href=#dom-workerglobalscope-importscripts>importScripts()</a></code>
1982     method.</p>
1983    
1984     <p>If the "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a
1985     worker</a>" algorithms abort the script then abort all these
1986     steps.</p>
1987    
1988     </li>
1989    
1990     </ol></li>
1991    
1992     </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>
1993    
1994     <p>The <dfn id=dom-worker-navigator title=dom-worker-navigator><code>navigator</code></dfn> attribute
1995     of the <code><a href=#workerutils>WorkerUtils</a></code> interface must return an instance of
1996     the <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code> interface, which
1997     represents the identity and state of the user agent (the
1998     client):</p>
1999    
2000     <pre class=idl>interface <dfn id=worker-navigator title=worker-Navigator>Navigator</dfn> {
2001     // objects implementing this interface also implement the interfaces listed below
2002     };</pre>
2003    
2004     <p>Objects implementing the <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code> interface must also
2005     implement the <span>NavigatorID</span> and
2006     <span>NavigatorOnLine</span> interfaces specified in the HTML5
2007     specification. <a href=#refsHTML5>[HTML5]</a></p>
2008    
2009     <p class=note>The <code title=worker-Navigator><a href=#worker-navigator>Navigator</a></code>
2010     interface defined in this specification is different than the one
2011     defined in the HTML5 specification.</p>
2012    
2013    
2014    
2015     <h3 id=apis-defined-in-other-specifications><span class=secno>5.3 </span>APIs defined in other specifications</h3>
2016    
2017     <p>The <code title=dom-opendatabase>openDatabase()</code> and
2018     <code title=dom-opendatabase-sync>openDatabaseSync()</code>
2019     methods are defined in the Web Storage specification. <a href=#refsWEBSTORAGE>[WEBSTORAGE]</a></p>
2020    
2021    
2022    
2023     <h3 id=interface-objects-and-constructors><span class=secno>5.4 </span>Interface objects and constructors</h3>
2024    
2025     <p>There must be no interface objects and constructors available in
2026     the global scope of scripts whose <span>script execution
2027     context</span> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object except for
2028     the following:</p>
2029    
2030     <ul><li><p><code>XMLHttpRequest</code> and all interface objects and
2031     constructors defined by the XMLHttpRequest specifications, except
2032     that the <span>document response entity body</span> must always be
2033     null. <a href=#refsXHR>[XHR]</a></li>
2034    
2035     <li><p>The <code>WebSocket</code> interface object and
2036     constructor. <a href=#refsWEBSOCKET>[WEBSOCKET]</a></li>
2037    
2038     <li><p>The <code>EventSource</code> interface object and
2039     constructor. <a href=#refsEVENTSOURCE>[EVENTSOURCE]</a></li>
2040    
2041     <li><p>The <code>MessageChannel</code> interface object and
2042     constructor. <a href=#refsHTML5>[HTML5]</a></li>
2043    
2044     <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>
2045    
2046     </ul><h3 id=worker-locations><span class=secno>5.5 </span>Worker locations</h3>
2047    
2048     <pre class=idl>interface <dfn id=workerlocation>WorkerLocation</dfn> {
2049     readonly attribute DOMString <a href=#dom-workerlocation-href title=dom-WorkerLocation-href>href</a>;
2050     readonly attribute DOMString <a href=#dom-workerlocation-protocol title=dom-WorkerLocation-protocol>protocol</a>;
2051     readonly attribute DOMString <a href=#dom-workerlocation-host title=dom-WorkerLocation-host>host</a>;
2052     readonly attribute DOMString <a href=#dom-workerlocation-hostname title=dom-WorkerLocation-hostname>hostname</a>;
2053     readonly attribute DOMString <a href=#dom-workerlocation-port title=dom-WorkerLocation-port>port</a>;
2054     readonly attribute DOMString <a href=#dom-workerlocation-pathname title=dom-WorkerLocation-pathname>pathname</a>;
2055     readonly attribute DOMString <a href=#dom-workerlocation-search title=dom-WorkerLocation-search>search</a>;
2056     readonly attribute DOMString <a href=#dom-workerlocation-hash title=dom-WorkerLocation-hash>hash</a>;
2057     };</pre>
2058    
2059     <p>A <code><a href=#workerlocation>WorkerLocation</a></code> object represents an <span>absolute
2060     URL</span> set at its creation.</p>
2061    
2062     <p>The <dfn id=dom-workerlocation-href title=dom-WorkerLocation-href><code>href</code></dfn>
2063     attribute must return the <span>absolute URL</span> that the object
2064     represents.</p>
2065    
2066     <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface also has the complement
2067     of <span>URL decomposition attributes</span>, <dfn id=dom-workerlocation-protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
2068     <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>,
2069     <dfn id=dom-workerlocation-pathname title=dom-WorkerLocation-pathname><code>pathname</code></dfn>,
2070     <dfn id=dom-workerlocation-search title=dom-WorkerLocation-search><code>search</code></dfn>,
2071     and <dfn id=dom-workerlocation-hash title=dom-WorkerLocation-hash><code>hash</code></dfn>. These must
2072     follow the rules given for URL decomposition attributes, with the
2073     <span title=concept-uda-input>input</span> being the
2074     <span>absolute URL</span> that the object represents (same as the
2075     <code title=dom-WorkerLocation-href><a href=#dom-workerlocation-href>href</a></code> attribute), and
2076     the <span title=concept-uda-setter>common setter action</span>
2077     being a no-op, since the attributes are defined to be readonly. <a href=#refsHTML5>[HTML5]</a></p>
2078    
2079    
2080    
2081    
2082     <h2 class=no-num id=references>References</h2>
2083    
2084     <p class=big-issue>This section will be written in a future
2085     draft.<!--XXX--></p>
2086    
2087    
2088     <h2 class=no-num id=acknowledgements>Acknowledgements</h2> <!-- ACKS -->
2089    
2090     <p>Thanks to
2091    
2092     Aaron Boodman,
2093     &#1040;&#1083;&#1077;&#1082;&#1089;&#1077;&#1081; &#1055;&#1088;&#1086;&#1089;&#1082;&#1091;&#1088;&#1103;&#1082;&#1086;&#1074; (Alexey Proskuryakov),
2094     Anne van Kesteren,
2095     Ben Turner,
2096     Dmitry Titov,
2097     Drew Wilson,
2098     Jeremy Orlow,
2099     Jonas Sicking,
2100     Justin James,
2101     Kevin Hakanson,
2102     Maciej Stachowiak,
2103     Michael Nordman,
2104     Mike Smith,
2105    
2106     and
2107    
2108     Philip Taylor
2109    
2110     for their useful and substantial comments.</p>
2111    
2112     <p>Huge thanks to the whole Gears team, who pioneered this
2113     technology and whose experience has been a huge influence on this
2114     specification.</p>
2115    
2116    

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24