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