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