/[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.11 - (hide annotations) (download) (as text)
Fri Aug 15 06:19:33 2008 UTC (17 years, 7 months ago) by wakaba
Branch: MAIN
Changes since 1.10: +232 -3 lines
File MIME type: text/html
make

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24