Annotation of html5/workers/Overview.html, revision 1.68
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
1281: implicit port in used for dedicated workers), run the following
1282: substeps:</p>
1283:
1284: <ol>
1285: <li>
1286: <p>Unentangle the two ports.
1287:
1288: <li>
1.68 ! ihickson 1289: <p><span>Queue a task</span> on the <span>event loop</span> handling
! 1290: events for the other <code>MessagePort</code> (the one whose owner is
! 1291: not the <code><a
1.50 ihickson 1292: href="#workerglobalscope">WorkerGlobalScope</a></code> object on which
1293: the <code title=dom-WorkerGlobalScope-close><a
1.68 ! ihickson 1294: href="#close">close()</a></code> method was called) to <span>fire a
! 1295: simple event</span> called <code title=event-close>close</code> at
! 1296: that other <code>MessagePort</code> object.
1.50 ihickson 1297: </ol>
1298: </ol>
1.4 ihickson 1299:
1.9 ihickson 1300: <p>The following are the <span>event handler DOM attributes</span> that
1301: must be supported by objects implementing the <code><a
1.26 ihickson 1302: href="#workerglobalscope">WorkerGlobalScope</a></code> interface:
1.9 ihickson 1303:
1304: <dl>
1.50 ihickson 1305: <dt><dfn id=onclose
1306: title=handler-WorkerGlobalScope-onclose><code>onclose</code></dfn>
1.9 ihickson 1307:
1308: <dd>
1.50 ihickson 1309: <p>Must be invoked whenever a <code title=event-close>close</code> event
1310: is targeted at or bubbles through the <code><a
1.26 ihickson 1311: href="#workerglobalscope">WorkerGlobalScope</a></code> object.
1.50 ihickson 1312: </dl>
1313:
1314: <h4 id=dedicated><span class=secno>2.1.2 </span>Dedicated workers and the
1315: <code><a
1316: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1317: interface</h4>
1318:
1319: <pre
1320: class=idl>[NoInterfaceObject] interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href="#workerglobalscope">WorkerGlobalScope</a> {
1.51 ihickson 1321: void <a href="#postmessage" title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in DOMString message);
1.64 ihickson 1322: void <a href="#postmessage" title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in DOMString message, in <span>MessagePort</span> messagePort);<!--
1323: <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in DOMString message);-->
1.50 ihickson 1324: attribute <span>EventListener</span> <a href="#onmessage" title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
1325: };</pre>
1.9 ihickson 1326:
1.50 ihickson 1327: <p><code><a
1328: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1329: objects act as if they had an implicit <code>MessagePort</code> associated
1330: with them. This port is part of a channel that is set up when the worker
1331: is created, but it is not exposed. This object must never be garbage
1332: collected before the <code><a
1333: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1334: object.
1335:
1336: <p>All messages received by that port must immediately be retargetted at
1337: the <code><a
1338: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1339: object.
1340:
1341: <p>The <dfn id=postmessage
1.64 ihickson 1342: title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
1343: and <dfn
1344: title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
1345: method<!--s (startConversation)--> on <code><a
1.50 ihickson 1346: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1.64 ihickson 1347: objects must act as if, when invoked, it<!--/they (startConversation)-->
1348: immediately invoked the method of the same name on the port, with the same
1349: arguments, and returned the same return value.
1.50 ihickson 1350:
1351: <p>The following are the <span>event handler DOM attributes</span> that
1352: must be supported by objects implementing the <code><a
1353: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1354: interface:
1355:
1356: <dl>
1357: <dt><dfn id=onmessage
1358: title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn>
1.9 ihickson 1359:
1360: <dd>
1.50 ihickson 1361: <p>Must be invoked whenever a <code
1362: title=event-DedicatedWorkerGlobalScope-message>message</code> event is
1363: targeted at or bubbles through the <code><a
1364: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1365: object.
1.9 ihickson 1366: </dl>
1367:
1.50 ihickson 1368: <h4 id=shared0><span class=secno>2.1.3 </span>Shared workers and the
1369: <code><a
1370: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1371: inteface</h4>
1372:
1373: <pre
1374: class=idl>[NoInterfaceObject] interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href="#workerglobalscope">WorkerGlobalScope</a> {
1375: readonly attribute DOMString <a href="#name" title=dom-SharedWorkerGlobalScope-name>name</a>;
1376: attribute <span>EventListener</span> <a href="#onconnect" title=handler-SharedWorkerGlobalScope-onconnect>onconnect</a>;
1377: };</pre>
1378:
1379: <p>Shared workers receive message ports through <code
1380: title=event-WorkerGlobalScope-connect>connect</code> events on their
1381: global object for each connection.
1382:
1383: <p>The <dfn id=name
1384: title=dom-SharedWorkerGlobalScope-name><code>name</code></dfn> attribute
1385: must return the value it was assigned when the <code><a
1386: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code> object
1387: was created by the "<a href="#run-a">run a worker</a>" algorithm. Its
1388: value represents the name that can be used to obtain a reference to the
1389: worker using the <code><a href="#sharedworker">SharedWorker</a></code>
1390: constructor.
1391:
1392: <p>The following are the <span>event handler DOM attributes</span> that
1393: must be supported by objects implementing the <code><a
1394: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1395: interface:
1396:
1397: <dl>
1398: <dt><dfn id=onconnect
1399: title=handler-SharedWorkerGlobalScope-onconnect><code>onconnect</code></dfn>
1400:
1401: <dd>
1402: <p>Must be invoked whenever a <code
1403: title=event-SharedWorkerGlobalScope-connect>connect</code> event is
1404: targeted at or bubbles through the <code><a
1405: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1406: object.
1407: </dl>
1.30 ihickson 1408:
1.15 ihickson 1409: <h3 id=base-urls><span class=secno>2.2 </span>Base URLs and origins of
1410: workers</h3>
1411:
1.25 ihickson 1412: <p>Both the <span>origin</span> and <span>effective script origin</span> of
1413: scripts running in workers are the <span>origin</span> of the
1.68 ! ihickson 1414: <span>absolute URL</span> given in that the worker's <code
1.34 ihickson 1415: title=dom-WorkerGlobalScope-location><a
1416: href="#location">location</a></code> attribute represents.
1.15 ihickson 1417:
1.68 ! ihickson 1418: <h3 id=the-event><span class=secno>2.3 </span>The event loop</h3>
1.4 ihickson 1419:
1.26 ihickson 1420: <p>Each <code><a href="#workerglobalscope">WorkerGlobalScope</a></code>
1.68 ! ihickson 1421: object is asssociated with a <span>event loop</span>. This <span>event
! 1422: loop</span> has no associated <span>browsing context</span>, and its <span
! 1423: title="task queue">task queues</span> only have events, callbacks, and
! 1424: networking activity as <span title=concept-task>tasks</span>. The
! 1425: processing model of these <span title="event loop">event loops</span> is
! 1426: defined below in the <a href="#run-a">run a worker</a> algorithm.
1.8 ihickson 1427:
1.50 ihickson 1428: <p>Each <code><a href="#workerglobalscope">WorkerGlobalScope</a></code>
1429: object also has a <dfn id=closing
1430: title=dom-WorkerGlobalScope-closing>closing</dfn> flag, which must
1431: initially be false, but which can get set to true by the algorithms in the
1432: processing model section below.
1433:
1.26 ihickson 1434: <p>Once the <code><a
1.50 ihickson 1435: href="#workerglobalscope">WorkerGlobalScope</a></code>'s <a
1436: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag is
1.68 ! ihickson 1437: set to true, the <span>event loop</span>'s <span title="task queue">task
! 1438: queues</span> must discard any further <span
! 1439: title=concept-task>tasks</span> that would be added to them (tasks already
! 1440: on the queue are unaffected unless otherwise specified). Effectively, once
! 1441: the <a href="#closing" title=dom-WorkerGlobalScope-closing>closing</a>
! 1442: flag is true, timers stop firing, notifications for all pending
! 1443: asynchronous operations are dropped, etc.
1.8 ihickson 1444:
1.15 ihickson 1445: <h3 id=the-workers><span class=secno>2.4 </span>The worker's ports</h3>
1.9 ihickson 1446:
1447: <p>Workers communicate with other workers and with <span title="browsing
1448: context">browsing contexts</span> through <span title="channel
1449: messaging">message channels</span> and their <code>MessagePort</code>
1450: objects.
1451:
1.26 ihickson 1452: <p>Each <code><a href="#workerglobalscope">WorkerGlobalScope</a></code>
1.50 ihickson 1453: <var title="">worker global scope</var> has a list of <dfn
1454: id=the-workers0>the worker's ports</dfn>, which consists of all the
1455: <code>MessagePort</code> objects that are entangled with another port and
1456: that have one (but only one) port owned by <var title="">worker global
1.65 ihickson 1457: scope</var>. This list includes
1458: <!--all the <code>MessagePort</code> objects that are in events
1.68 ! ihickson 1459: pending in the <span>event loop</span>, as well as (commented out
! 1460: because in practice it makes no difference either way as far as I
! 1461: can tell, and it would be hard to strictly implement since these
1.65 ihickson 1462: ports might not yet be across the thread boundary)-->
1463: the implicit <code>MessagePort</code> in the case of <a
1.50 ihickson 1464: href="#dedicatedworkerglobalscope"
1465: title=DedicatedWorkerGlobalScope>dedicated workers</a>.
1.9 ihickson 1466:
1.17 ihickson 1467: <hr>
1468:
1.38 ihickson 1469: <p>A worker is said to be a <dfn id=permissible>permissible worker</dfn> if
1470: either:
1471:
1472: <ul>
1473: <li>at some point past or present a <code>MessagePort</code> owned by the
1474: worker was entangled with a <code>MessagePort</code> <var
1475: title="">p</var> whose owner is a <code>Window</code> object whose
1476: <span>active document</span> is the <code>Document</code> that was that
1477: <span>browsing context</span>'s <span>active document</span> when <var
1478: title="">p</var> was created, and that <code>Document</code> is
1479: <span>fully active</span>, or
1480:
1481: <li>at some point past or present a <code>MessagePort</code> owned by the
1482: worker was entangled with a <code>MessagePort</code> owned by another
1483: worker that is currently a <a href="#permissible">permissible worker</a>.
1484: </ul>
1485:
1486: <hr>
1487:
1488: <p>A worker is said to be a <dfn id=protected>protected worker</dfn> if
1489: either:
1490:
1491: <ul>
1492: <li>it has outstanding timers, database transactions, or network
1.60 ihickson 1493: connections, and is a <a href="#permissible">permissible worker</a>, or
1.38 ihickson 1494:
1495: <li>there is a <a href="#protected">protected worker</a> that at some
1496: point past or present owned a <code>MessagePort</code> that was entangled
1497: with a <code>MessagePort</code> owned by this worker.
1498: </ul>
1499:
1500: <hr>
1.17 ihickson 1501:
1.38 ihickson 1502: <p>A worker is said to be an <dfn id=active>active needed worker</dfn> if
1503: either:
1.17 ihickson 1504:
1505: <ul>
1.38 ihickson 1506: <li>the worker is a <a href="#protected">protected worker</a>, or
1507:
1508: <li>at least one of the <a href="#the-workers0">the worker's ports</a> is
1509: entangled with a <code>MessagePort</code> <var title="">p</var> whose
1510: owner is a <code>Window</code> object whose <span>active document</span>
1511: is the <code>Document</code> that was that <span>browsing
1512: context</span>'s <span>active document</span> when that
1513: <code>MessagePort</code> <var title="">p</var> was created, and that
1514: <code>Document</code> is <span>fully active</span>, 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 an <a href="#active">active needed worker</a>.
1.17 ihickson 1520: </ul>
1521:
1522: <hr>
1523:
1.38 ihickson 1524: <p>A worker is said to be a <dfn id=suspendable>suspendable worker</dfn> if
1525: it is not an <a href="#active">active needed worker</a> but either:
1.17 ihickson 1526:
1527: <ul>
1.38 ihickson 1528: <li>at least one of the <a href="#the-workers0">the worker's ports</a> has
1529: an entangled <code>MessagePort</code> owned by a <code>Window</code>
1530: object, or
1.17 ihickson 1531:
1532: <li>at least one of the <a href="#the-workers0">the worker's ports</a> has
1.26 ihickson 1533: an entangled <code>MessagePort</code> owned by a <code><a
1534: href="#workerglobalscope">WorkerGlobalScope</a></code> object that is
1.38 ihickson 1535: itself a <span>needed worker</span>.
1.17 ihickson 1536: </ul>
1537:
1.15 ihickson 1538: <h3 id=processing><span class=secno>2.5 </span>Processing model</h3>
1.4 ihickson 1539:
1.50 ihickson 1540: <p>When a user agent is to <dfn id=run-a>run a worker</dfn> for a script
1541: with <span>URL</span> <var title="">url</var>, a browsing context <var
1.68 ! ihickson 1542: title="">owner browsing context</var>, and with global scope <var
! 1543: title="">worker global scope</var>, it must run the following steps:
1.4 ihickson 1544:
1545: <ol>
1546: <li>
1.52 ihickson 1547: <p>Create a completely separate and parallel execution environment (i.e.
1548: a separate thread or process or equivalent construct), and run the rest
1549: of these steps asychronously in that context.</p>
1550:
1551: <li>
1.68 ! ihickson 1552: <p>Attempt to <span>fetch</span> the resource identified by <var
! 1553: title="">url</var>.</p>
1.7 ihickson 1554:
1.68 ! ihickson 1555: <p>If the attempt fails, then for each <code><a
! 1556: href="#worker1">Worker</a></code> or <code><a
! 1557: href="#sharedworker">SharedWorker</a></code> object associated with <var
! 1558: title="">worker global scope</var>, <span>queue a task</span> to
! 1559: <span>fire a simple event</span> called <code
! 1560: title=event-error>error</code> at that object. Abort these steps.</p>
! 1561:
! 1562: <p>If the attempt succeeds, then let <var title="">source</var> be the
! 1563: text of the resource that was obtained.</p>
! 1564: <!-- XXX do we need
! 1565: to define character encoding decoding here? -->
! 1566: <p>Let <var title="">language</var> be JavaScript.</p>
1.7 ihickson 1567:
1568: <p class=note>As with <code>script</code> elements, the MIME type of the
1569: script is ignored. Unlike with <code>script</code> elements, there is no
1570: way to override the type. It's always assumed to be JavaScript.</p>
1571: <!-- XXX people will complain about
1572: this. I guess we might want to examine the MIME type... -->
1573:
1574:
1575: <li>
1.68 ! ihickson 1576: <p>A new <span title=concept-script>script</span> is now created, as
! 1577: follows.</p>
! 1578:
! 1579: <p>Create a new <span>script execution environment</span> set up as
! 1580: appropriate for the scripting language <var title="">language</var>.</p>
1.34 ihickson 1581:
1.68 ! ihickson 1582: <p>Parse/compile/initialize <var title="">source</var> using that
! 1583: <span>script execution environment</span>, as appropriate for <var
! 1584: title="">language</var>, and thus obtain a <span>list of code
! 1585: entry-points</span>; set the <i>initial code entry-point</i> to the
! 1586: entry-point for any executable code to be immediately run.</p>
! 1587:
! 1588: <p>Set the <span>script's global object</span> to <var title="">worker
1.50 ihickson 1589: global scope</var>.</p>
1.4 ihickson 1590:
1.68 ! ihickson 1591: <p>Set the <span>script's browsing context</span> to <var title="">owner
! 1592: browsing context</var>.</p>
! 1593:
! 1594: <p>Set the <span>script's character encoding</span> to UTF-8. (This is
! 1595: just used for encoding non-ASCII characters in the query component of
! 1596: URLs.)</p>
! 1597:
! 1598: <p>Set the <span>script's base URL</span> to <var title="">url</var>.</p>
1.4 ihickson 1599:
1.68 ! ihickson 1600: <p>Create a new <span>script group</span> and add the <span
! 1601: title=concept-script>script</span> to it.</p>
1.4 ihickson 1602:
1603: <li>
1.50 ihickson 1604: <p><strong>Closing orphan workers</strong>: Start monitoring the worker
1605: such that as soon as it stops being either an <a href="#active">active
1606: needed worker</a> or a <a href="#suspendable">suspendable worker</a>,
1.68 ! ihickson 1607: <var title="">worker global scope</var>'s <a href="#closing"
1.50 ihickson 1608: title=dom-WorkerGlobalScope-closing>closing</a> flag is set to true and
1.68 ! ihickson 1609: <span title="queue a task">a task is queued</span> to <span>fire a
! 1610: simple event</span> called <code title=event-close>close</code> at <var
! 1611: title="">worker global scope</var>.</p>
1.9 ihickson 1612:
1613: <li>
1.50 ihickson 1614: <p><strong>Suspending workers</strong>: Start monitoring the worker, such
1.68 ! ihickson 1615: that whenever <var title="">worker global scope</var>'s <a
1.50 ihickson 1616: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag is
1617: false and the worker is a <a href="#suspendable">suspendable worker</a>,
1618: the user agent suspends execution of script in that worker until such
1619: time as either the <a href="#closing"
1620: title=dom-WorkerGlobalScope-closing>closing</a> flag switches to true or
1621: the worker stops being a <a href="#suspendable">suspendable worker</a>.</p>
1.7 ihickson 1622:
1623: <li>
1.68 ! ihickson 1624:
! 1625: <li>
! 1626: <p><span title="jump to a code entry-point">Jump</span> to the <span
! 1627: title=concept-script>script</span>'s <i>initial code entry-point</i>,
! 1628: and let that run until it either returns, fails to catch an exception,
! 1629: or gets prematurely aborted by the "<a href="#kill-a">kill a worker</a>"
! 1630: or "<a href="#terminate">terminate a worker</a>" algorithms defined
! 1631: below.</p>
1.7 ihickson 1632:
1633: <p class=note>If the script gets aborted by the "<a href="#kill-a">kill a
1634: worker</a>" algorithm, then that same algorithm will cause there to only
1.68 ! ihickson 1635: be a single <span title=concept-task>task</span> in the <span>event
! 1636: loop</span> at the next step, namely the task for the <code
! 1637: title=message-close>close</code> event. The "<a
! 1638: href="#terminate">terminate a worker</a>" algorithm removes all the
1.50 ihickson 1639: events.</p>
1.4 ihickson 1640:
1641: <li>
1.68 ! ihickson 1642: <p><i title="">Event loop</i>: Wait until either there is a <span
! 1643: title=concept-task>task</span> in one of the <span>event loop</span>'s
! 1644: <span title="task queue">task queues</span> or <var title="">worker
! 1645: global scope</var>'s <a href="#closing"
! 1646: title=dom-WorkerGlobalScope-closing>closing</a> flag is set to true.</p>
! 1647:
! 1648: <li>
! 1649: <p>Run the oldest task on one of the <span>event loop</span>'s <span
! 1650: title="task queue">task queues</span>, if any. The user agent may pick
! 1651: any <span>task queue</span>.</p>
! 1652:
! 1653: <p class=note>The handling of events or the execution of callbacks might
! 1654: get prematurely aborted by the "<a href="#kill-a">kill a worker</a>" or
! 1655: "<a href="#terminate">terminate a worker</a>" algorithms defined below.</p>
1.4 ihickson 1656:
1657: <li>
1.68 ! ihickson 1658: <p>Remove the task run in the previous step, if any, from its <span>task
! 1659: queue</span>.</p>
1.4 ihickson 1660:
1661: <li>
1.68 ! ihickson 1662: <p>If there are any more events in the <span>event loop</span>'s <span
! 1663: title="task queue">task queues</span> or if <var title="">worker global
! 1664: scope</var>'s <a href="#closing"
! 1665: title=dom-WorkerGlobalScope-closing>closing</a> flag is set to false,
! 1666: then jump back to the step above labeled <i>event loop</i>.</p>
1.4 ihickson 1667:
1668: <li>
1.68 ! ihickson 1669: <p>Freeze the <span>script group</span>.</p>
! 1670:
! 1671: <p class=note>This kills timers, database transactions, etc.</p>
1.43 ihickson 1672:
1673: <li>
1.68 ! ihickson 1674: <p>For each <code><a href="#worker1">Worker</a></code> or <code><a
! 1675: href="#sharedworker">SharedWorker</a></code> object associated with <var
! 1676: title="">worker global scope</var>, <span>queue a task</span> to
! 1677: <span>fire a simple event</span> called <code
! 1678: title=event-close>close</code> at that object.</p>
1.4 ihickson 1679: </ol>
1680:
1681: <hr>
1682:
1.50 ihickson 1683: <p>When a user agent is to <dfn id=kill-a>kill a worker</dfn> it must run
1.4 ihickson 1684: the following steps in parallel with the worker's main loop (the "<a
1685: href="#run-a">run a worker</a>" processing model defined above):
1686:
1687: <ol>
1688: <li>
1.68 ! ihickson 1689: <p><span>Queue a task</span> to <span>fire a simple event</span> called
! 1690: <code title=event-close>close</code> at the worker's <code><a
! 1691: href="#workerglobalscope">WorkerGlobalScope</a></code> object.
1.28 ihickson 1692: </li>
1.68 ! ihickson 1693: <!-- XXX
! 1694: shouldn't add one if closing is already true, assuming close has
! 1695: already been added to the queue (?) -->
1.4 ihickson 1696:
1697: <li>
1.26 ihickson 1698: <p>Set the worker's <code><a
1.50 ihickson 1699: href="#workerglobalscope">WorkerGlobalScope</a></code> object's <a
1700: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag to
1701: true.
1.8 ihickson 1702:
1703: <li>
1704: <p>Wait a user-agent-defined amount of time. If the "<a href="#run-a">run
1705: a worker</a>" processing model defined above immediately starts running
1.50 ihickson 1706: event listeners registered for the <code title=event-close>close</code>
1707: event, this time should not be zero — the idea is that the <code
1708: title=event-close>close</code> event can be used to clean up when
1709: shutting down unexpectedly.
1.4 ihickson 1710:
1711: <li>
1.68 ! ihickson 1712: <p>If there are any <span title=concept-task>tasks</span> queued in the
! 1713: <span>event loop</span>'s <span title="task queue">task queues</span>
1.50 ihickson 1714: other than the <code title=event-close>close</code> event that this
1.68 ! ihickson 1715: algorithm just added, discard them without processing them.
1.4 ihickson 1716:
1717: <li>
1.50 ihickson 1718: <p>If the <code title=event-close>close</code> event that this algorithm
1.68 ! ihickson 1719: just queued hasn't yet been dispatched, then abort the script currently
1.50 ihickson 1720: running in the worker.
1.4 ihickson 1721:
1722: <li>
1723: <p>Wait a user-agent-defined amount of time.
1724:
1725: <li>
1726: <p>Abort the script currently running in the worker (if any script is
1727: running, then it will be a handler for the <code
1.50 ihickson 1728: title=event-close>close</code> event).
1.4 ihickson 1729: </ol>
1730:
1.19 ihickson 1731: <p>User agents may invoke the "<a href="#kill-a">kill a worker</a>"
1732: processing model on a worker at any time, e.g. in response to user
1733: requests, in response to CPU quota management, or when a worker stops
1.38 ihickson 1734: being an <a href="#active">active needed worker</a> if the worker
1.50 ihickson 1735: continues executing even after its <a href="#closing"
1736: title=dom-WorkerGlobalScope-closing>closing</a> flag was set to true.
1.19 ihickson 1737:
1.8 ihickson 1738: <hr>
1739:
1.50 ihickson 1740: <p>When a user agent is to <dfn id=terminate>terminate a worker</dfn> it
1741: must run the following steps in parallel with the worker's main loop (the
1742: "<a href="#run-a">run a worker</a>" processing model defined above):
1.8 ihickson 1743:
1744: <ol>
1745: <li>
1.50 ihickson 1746: <p>Set the worker's <code><a
1.26 ihickson 1747: href="#workerglobalscope">WorkerGlobalScope</a></code> object's <a
1.50 ihickson 1748: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag to
1749: true.
1.8 ihickson 1750:
1751: <li>
1.68 ! ihickson 1752: <p>If there are any <span title=concept-task>tasks</span> queued in the
! 1753: <span>event loop</span>'s <span title="task queue">task queues</span>,
! 1754: discard them without processing them.
1.8 ihickson 1755:
1756: <li>
1.50 ihickson 1757: <p>Abort the script currently running in the worker.
1.8 ihickson 1758: </ol>
1759:
1.15 ihickson 1760: <h3 id=creating><span class=secno>2.6 </span>Creating workers</h3>
1.5 ihickson 1761:
1.50 ihickson 1762: <h4 id=the-abstractworker><span class=secno>2.6.1 </span>The <code><a
1763: href="#abstractworker">AbstractWorker</a></code> abstract interface</h4>
1764:
1.5 ihickson 1765: <pre
1.50 ihickson 1766: class=idl>[NoInterfaceObject] interface <dfn id=abstractworker>AbstractWorker</dfn> {
1767: attribute <span>EventListener</span> <a href="#onerror" title=handler-AbstractWorker-onerror>onerror</a>;
1768: attribute <span>EventListener</span> <a href="#onclose0" title=handler-AbstractWorker-onclose>onclose</a>;
1769: };</pre>
1770:
1.60 ihickson 1771: <p>Objects implementing the <code><a
1772: href="#abstractworker">AbstractWorker</a></code> interface must also
1773: implement the <code>EventTarget</code> interface.
1774:
1.50 ihickson 1775: <p>The following are the <span>event handler DOM attributes</span> that
1776: must be supported by objects implementing the <code><a
1777: href="#abstractworker">AbstractWorker</a></code> interface:
1778:
1779: <dl>
1780: <dt><dfn id=onerror
1781: title=handler-AbstractWorker-onerror><code>onerror</code></dfn>
1782:
1783: <dd>
1784: <p>Must be invoked whenever an <code title=event-error>error</code> event
1785: is targeted at or bubbles through the <code><a
1786: href="#abstractworker">AbstractWorker</a></code> object.
1787:
1788: <dt><dfn id=onclose0
1789: title=handler-AbstractWorker-onclose><code>onclose</code></dfn>
1790:
1791: <dd>
1792: <p>Must be invoked whenever an <code title=event-close>close</code> event
1793: is targeted at or bubbles through the <code><a
1794: href="#abstractworker">AbstractWorker</a></code> object.
1795: </dl>
1.43 ihickson 1796:
1.50 ihickson 1797: <h4 id=dedicated0><span class=secno>2.6.2 </span>Dedicated workers and the
1798: <code><a href="#worker1">Worker</a></code> interface</h4>
1.43 ihickson 1799:
1.50 ihickson 1800: <pre class=idl>[NoInterfaceObject,
1801: <a href="#worker2" title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
1802: interface <dfn id=worker1>Worker</dfn> : <a href="#abstractworker">AbstractWorker</a> {
1.56 ihickson 1803: void <a href="#terminate0" title=dom-Worker-terminate>terminate</a>();
1.50 ihickson 1804:
1.51 ihickson 1805: void <a href="#postmessage0" title=dom-Worker-postMessage>postMessage</a>(in DOMString message);
1.64 ihickson 1806: void <a href="#postmessage0" title=dom-Worker-postMessage>postMessage</a>(in DOMString message, in <span>MessagePort</span> messagePort);<!--
1807: <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in DOMString message);-->
1.50 ihickson 1808: attribute <span>EventListener</span> <a href="#onmessage0" title=handler-Worker-onmessage>onmessage</a>;
1.5 ihickson 1809: };</pre>
1810:
1.56 ihickson 1811: <p>The <dfn id=terminate0
1812: title=dom-Worker-terminate><code>terminate()</code></dfn> method, when
1813: invoked, must cause the "<a href="#terminate">terminate a worker</a>"
1814: algorithm to be run on the worker with with the object is associated.
1.50 ihickson 1815:
1816: <p><code><a href="#worker1">Worker</a></code> objects act as if they had an
1817: implicit <code>MessagePort</code> associated with them. This port is part
1818: of a channel that is set up when the worker is created, but it is not
1819: exposed. This object must never be garbage collected before the <code><a
1820: href="#worker1">Worker</a></code> object.
1821:
1822: <p>All messages received by that port must immediately be retargetted at
1823: the <code><a href="#worker1">Worker</a></code> object.
1824:
1825: <p>The <dfn id=postmessage0
1.64 ihickson 1826: title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
1827: and <dfn
1828: title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
1829: method<!--s (startConversation)--> on <code><a
1830: href="#worker1">Worker</a></code> objects must act as if, when invoked,
1831: it<!--/they (startConversation)--> immediately invoked the method of the
1832: same name on the port, with the same arguments, and returned the same
1833: return value.
1.50 ihickson 1834:
1835: <p>The following are the <span>event handler DOM attributes</span> that
1836: must be supported by objects implementing the <code><a
1837: href="#worker1">Worker</a></code> interface:
1838:
1839: <dl>
1840: <dt><dfn id=onmessage0
1841: title=handler-Worker-onmessage><code>onmessage</code></dfn>
1842:
1843: <dd>
1844: <p>Must be invoked whenever a <code
1845: title=event-Worker-message>message</code> event is targeted at or
1846: bubbles through the <code><a href="#worker1">Worker</a></code> object.
1847: </dl>
1.5 ihickson 1848:
1.9 ihickson 1849: <hr>
1850:
1.50 ihickson 1851: <p>When the <dfn id=worker2 title=dom-Worker><code>Worker(<var
1852: title="">scriptURL</var>)</code></dfn> constructor is invoked, the user
1853: agent must run the following steps:
1.9 ihickson 1854:
1855: <ol>
1856: <li>
1857: <p><span title="resolve a url">Resolve</span> the <var
1858: title="">scriptURL</var> argument.
1859:
1860: <li>
1861: <p>If this fails, throw a <code>SYNTAX_ERR</code> exception.
1862:
1863: <li>
1864: <p>If the <span>origin</span> of the resulting <span>absolute URL</span>
1865: is not the <span title="same origin">same</span> as the origin of the
1.50 ihickson 1866: script that invoked the constructor, then throw a <span>security
1.9 ihickson 1867: exception</span>.
1868:
1869: <li>
1.50 ihickson 1870: <p><span>Create a new <code><a
1871: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1.68 ! ihickson 1872: object</span>. Let <var title="">worker global scope</var> be this new
! 1873: object.
1.50 ihickson 1874:
1875: <li>
1876: <p>Create a new <code><a href="#worker1">Worker</a></code> object,
1.68 ! ihickson 1877: associated with <var title="">worker global scope</var>. Let <var
! 1878: title="">worker</var> be this new object.
1.9 ihickson 1879:
1880: <li>
1.50 ihickson 1881: <p><span>Create a <code>MessagePort</code> object</span> owned by the
1882: <span>script execution context</span> of the script that invoked the
1883: method. Let this be the <var title="">outside port</var>.
1884:
1885: <li>
1886: <p>Associate the <var title="">outside port</var> with <var
1887: title="">worker</var>.
1888:
1889: <li>
1.68 ! ihickson 1890: <p><span>Create a <code>MessagePort</code> object</span> owned by <var
! 1891: title="">worker global scope</var>. Let <var title="">inside port</var>
! 1892: be this new object.
1.50 ihickson 1893:
1894: <li>
1.68 ! ihickson 1895: <p>Associate <var title="">inside port</var> with <var title="">worker
! 1896: global scope</var>.
1.50 ihickson 1897:
1898: <li>
1899: <p><span>Entangle</span> <var title="">outside port</var> and <var
1900: title="">inside port</var>.
1901:
1902: <li>
1903: <p>Return <var title="">worker</var>, and run the following steps
1904: asynchronously.
1905:
1906: <li>
1907: <p>Open <var title="">inside port</var>'s <span>port message
1908: queue</span>.
1909:
1910: <li>
1.51 ihickson 1911: <p>Open <var title="">outside port</var>'s <span>port message
1912: queue</span>.
1913:
1914: <li>
1.68 ! ihickson 1915: <p><a href="#run-a">Run a worker</a> for the resulting <span>absolute
! 1916: URL</span>, with the <span>script browsing context</span> of the script
! 1917: that invoked the method as the <var title="">owner browsing
! 1918: context</var>, and with <var title="">worker global scope</var> as the
! 1919: global scope.</p>
1.9 ihickson 1920: </ol>
1921:
1.50 ihickson 1922: <h4 id=shared1><span class=secno>2.6.3 </span>Shared workers and the
1923: <code><a href="#sharedworker">SharedWorker</a></code> interface</h4>
1.9 ihickson 1924:
1.50 ihickson 1925: <pre class=idl>[NoInterfaceObject,
1926: <a href="#sharedworker0" title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in DOMString name)]
1927: interface <dfn id=sharedworker>SharedWorker</dfn> : <a href="#abstractworker">AbstractWorker</a> {
1928: readonly attribute <code>MessagePort</code> <a href="#port" title=dom-SharedWorker-port>port</a>;
1929: };</pre>
1930:
1931: <p>The <dfn id=port title=dom-SharedWorker-port><code>port</code></dfn>
1932: attribute must return the value it was assigned by the object's
1933: constructor. It represents the <code>MessagePort</code> for communicating
1934: with the shared worker.
1935:
1936: <p>When the <dfn id=sharedworker0
1937: title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>,
1938: <var title="">name</var>)</code></dfn> constructor is invoked, the user
1939: agent must run the following steps:
1.9 ihickson 1940:
1941: <ol>
1942: <li>
1943: <p><span title="resolve a url">Resolve</span> the <var
1944: title="">scriptURL</var> argument.
1.4 ihickson 1945:
1.9 ihickson 1946: <li>
1947: <p>If this fails, throw a <code>SYNTAX_ERR</code> exception.
1948:
1949: <li>
1950: <p>If the <span>origin</span> of the resulting <span>absolute URL</span>
1951: is not the <span title="same origin">same</span> as the origin of the
1.50 ihickson 1952: script that invoked the constructor, then throw a <span>security
1.9 ihickson 1953: exception</span>.
1954:
1955: <li>
1.50 ihickson 1956: <p>Execute the following substeps atomically:</p>
1.9 ihickson 1957:
1958: <ol>
1959: <li>
1.50 ihickson 1960: <p>Create a new <code><a href="#sharedworker">SharedWorker</a></code>
1961: object, which will shortly be associated with a <code><a
1962: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1963: object. Let this <code><a href="#sharedworker">SharedWorker</a></code>
1964: object be <var title="">worker</var>.
1.9 ihickson 1965:
1966: <li>
1.50 ihickson 1967: <p><span>Create a <code>MessagePort</code> object</span> owned by the
1968: <span>script execution context</span> of the script that invoked the
1969: method. Let this be the <var title="">outside port</var>.
1.9 ihickson 1970:
1971: <li>
1.50 ihickson 1972: <p>Assign <var title="">outside port</var> to the <code
1973: title=dom-SharedWorker-port><a href="#port">port</a></code> attribute
1974: of <var title="">worker</var>.
1.43 ihickson 1975:
1976: <li>
1.50 ihickson 1977: <p>If there exists a <code><a
1978: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1979: object whose <a href="#closing"
1980: title=dom-WorkerGlobalScope-closing>closing</a> flag is false, whose
1981: <code title=dom-WorkerGlobalScope-name>name</code> attribute is
1982: exactly equal to the <var title="">name</var> argument, and whose
1983: <code title=dom-WorkerGlobalScope-location><a
1984: href="#location">location</a></code> attribute represents an
1985: <span>absolute URL</span> that has the <span>same origin</span> as the
1986: resulting <span>absolute URL</span>, then run these substeps:</p>
1987:
1988: <ol>
1989: <li>
1990: <p>Let <var title="">worker global scope</var> be that <code><a
1991: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1992: object.
1993:
1994: <li>
1995: <p>If <var title="">worker global scope</var>'s <code
1996: title=dom-WorkerGlobalScope-location><a
1997: href="#location">location</a></code> attribute represents an
1998: <span>absolute URL</span> that is not exactly equal to the resulting
1999: <span>absolute URL</span>, then throw a
2000: <code>URL_MISMATCH_ERR</code> exception and abort all these steps.
2001: <span class=big-issue>code 21</span>
2002:
2003: <li>
2004: <p>Associate <var title="">worker</var> with <var title="">worker
2005: global scope</var>.
2006:
2007: <li>
1.68 ! ihickson 2008: <p><span>Create a <code>MessagePort</code> object</span> owned by
1.50 ihickson 2009: <var title="">worker global scope</var>. Let this be the <var
2010: title="">inside port</var>.
2011:
2012: <li>
2013: <p><span>Entangle</span> <var title="">outside port</var> and <var
2014: title="">inside port</var>.
2015:
2016: <li>
2017: <p>Return <var title="">worker</var> and perform the next step
2018: asynchronously.
2019:
2020: <li>
2021: <p>Create an event that uses the <code>MessageEvent</code> interface,
2022: with the name <code title=event-connect>connect</code>, which does
2023: not bubble, is cancelable, has no default action, has a <code
2024: title=dom-MessageEvent-data>data</code> attribute whose value is the
2025: empty string and has a <code
2026: title=dom-MessageEvent-messagePort>messagePort</code> attribute
1.68 ! ihickson 2027: whose value is the newly created port, and <span>queue a task</span>
! 2028: to dispatch the event at <var title="">worker global scope</var>.
1.50 ihickson 2029:
2030: <li>
2031: <p>Abort all these steps.
2032: </ol>
1.9 ihickson 2033:
2034: <li>
1.50 ihickson 2035: <p><span>Create a new <code><a
2036: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1.68 ! ihickson 2037: object</span>. Let <var title="">worker global scope</var> be this new
! 2038: object.
1.9 ihickson 2039:
1.50 ihickson 2040: <li>
2041: <p>Associate <var title="">worker</var> with <var title="">worker
2042: global scope</var>.
1.9 ihickson 2043:
1.50 ihickson 2044: <li>
2045: <p>Set the <code title=dom-SharedWorkerGlobalScope-name><a
2046: href="#name">name</a></code> attribute of <var title="">worker global
1.68 ! ihickson 2047: scope</var> to <var title="">name</var>.
1.9 ihickson 2048:
1.50 ihickson 2049: <li>
1.68 ! ihickson 2050: <p><span>Create a <code>MessagePort</code> object</span> owned by <var
! 2051: title="">worker global scope</var>. Let <var title="">inside
! 2052: port</var> be this new object.
1.9 ihickson 2053:
1.50 ihickson 2054: <li>
2055: <p><span>Entangle</span> <var title="">outside port</var> and <var
2056: title="">inside port</var>.
2057: </ol>
1.9 ihickson 2058:
2059: <li>
1.50 ihickson 2060: <p>Return <var title="">worker</var> and perform the next step
2061: asynchronously.
1.9 ihickson 2062:
2063: <li>
2064: <p>Create an event that uses the <code>MessageEvent</code> interface,
1.20 ihickson 2065: with the name <code title=event-connect>connect</code>, which does not
1.9 ihickson 2066: bubble, is cancelable, has no default action, has a <code
2067: title=dom-MessageEvent-data>data</code> attribute whose value is the
2068: empty string and has a <code
2069: title=dom-MessageEvent-messagePort>messagePort</code> attribute whose
1.68 ! ihickson 2070: value is the newly created port, and <span>queue a task</span> to
! 2071: dispatch the event at <var title="">worker global scope</var>.
1.28 ihickson 2072:
2073: <li>
1.68 ! ihickson 2074: <p><a href="#run-a">Run a worker</a> for the resulting <span>absolute
! 2075: URL</span>, with the <span>script browsing context</span> of the script
! 2076: that invoked the method as the <var title="">owner browsing
! 2077: context</var>, and with <var title="">worker global scope</var> as the
! 2078: global scope.</p>
1.9 ihickson 2079: </ol>
1.7 ihickson 2080:
1.12 ihickson 2081: <h2 id=apis-available><span class=secno>3. </span>APIs available to workers</h2>
2082:
1.26 ihickson 2083: <pre
2084: class=idl>[NoInterfaceObject] interface <dfn id=workerutils>WorkerUtils</dfn> {
1.46 ihickson 2085: void <a href="#importscripts" title=dom-WorkerGlobalScope-importScripts>importScripts</a>([Variadic] in DOMString urls);
1.26 ihickson 2086: readonly attribute <span>Storage</span> <a href="#localstorage" title=dom-localStorage>localStorage</a>;
1.61 ihickson 2087: readonly attribute <a href="#navigator0">Navigator</a> <a href="#navigator" title=dom-navigator>navigator</a>;
1.26 ihickson 2088: <span>Database</span> <a href="#opendatabase" title=dom-opendatabase>openDatabase</a>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
2089: void <a href="#shownotification" title=dom-showNotification>showNotification</a>(in DOMString title, in DOMString subtitle, in DOMString description);
2090: void <a href="#shownotification" title=dom-showNotification>showNotification</a>(in DOMString title, in DOMString subtitle, in DOMString description, in VoidCallback onclick);
2091: };</pre>
1.18 ihickson 2092:
1.12 ihickson 2093: <p>Objects that implement the <code><a
1.42 ihickson 2094: href="#workerglobalscope">WorkerGlobalScope</a></code> interface must also
2095: implement the <code><a href="#workerutils">WorkerUtils</a></code>
2096: interface.
1.12 ihickson 2097:
1.62 ihickson 2098: <p>Objects that implement the <code><a
2099: href="#workerutils">WorkerUtils</a></code> interface must also implement
2100: the <code>WindowTimers</code> interface. (This interface provides the
2101: <code title="">setTimeout()</code> method and its friends.)
2102:
1.61 ihickson 2103: <p class=big-issue>Need to define a sync database API.</p>
1.18 ihickson 2104: <!-- XXX ApplicationCache -->
2105: <!-- XXX a way to set cookies on the URL for the script -->
1.24 ihickson 2106: <!-- XXX debugging: void log(in DOMString s); // log to console -->
2107: <!-- XXX debugging: onerror -->
1.13 ihickson 2108:
1.18 ihickson 2109: <hr>
1.13 ihickson 2110:
1.18 ihickson 2111: <p>The DOM APIs (<code>Node</code> objects, <code>Document</code> objects,
2112: etc) are not available to workers in this version of this specification.
1.13 ihickson 2113:
1.26 ihickson 2114: <h3 id=importing><span class=secno>3.1 </span>Importing scripts and
2115: libraries</h3>
2116:
1.45 ihickson 2117: <p>When a script invokes the <dfn id=importscripts
2118: title=dom-WorkerGlobalScope-importScripts><code>importScripts(<var
2119: title="">urls</var>)</code></dfn> method on a <code><a
1.26 ihickson 2120: href="#workerglobalscope">WorkerGlobalScope</a></code> object, the user
2121: agent must run the following steps:
2122:
2123: <ol>
2124: <li>
1.46 ihickson 2125: <p>If there are no arguments, return without doing anything. Abort these
2126: steps.
2127:
2128: <li>
1.45 ihickson 2129: <p><span title="resolve a url">Resolve</span> each argument.
1.26 ihickson 2130:
2131: <li>
1.45 ihickson 2132: <p>If any fail, throw a <code>SYNTAX_ERR</code> exception.
1.60 ihickson 2133: </li>
1.67 ihickson 2134: <!--
2135: <li><p>If any of the resulting <span title="absolute URL">absolute
2136: URLs</span> have an <span>origin</span> that is not the <span
2137: title="same origin">same</span> as the origin of the script that
2138: invoked the method, then throw a <span>security
2139: exception</span>.</p></li>
2140: -->
1.26 ihickson 2141:
2142: <li>
1.45 ihickson 2143: <p>Attempt to <span>fetch</span> each resource identified by the
2144: resulting <span title="absolute URLs">absolute URL</span>.</p>
1.26 ihickson 2145:
2146: <li>
1.45 ihickson 2147: <p>For each argument in turn, in the order given, starting with the first
2148: one, run these substeps:</p>
1.26 ihickson 2149:
1.45 ihickson 2150: <ol>
2151: <li>
2152: <p>Wait for the fetching attempt for the corresponding resource to
2153: complete.</p>
1.26 ihickson 2154:
1.46 ihickson 2155: <p>If the fetching attempt failed, throw a <code>NETWORK_ERR</code>
1.68 ! ihickson 2156: exception and abort all these steps.</p>
1.26 ihickson 2157:
1.45 ihickson 2158: <p>If the fetching attempt succeeded, then let <var
1.68 ! ihickson 2159: title="">source</var> be the text of the resource that was obtained,
! 2160: and let <var title="">language</var> be JavaScript.</p>
1.26 ihickson 2161:
1.45 ihickson 2162: <p class=note>As with the worker's script, the script here is always
2163: assumed to be JavaScript, regardless of the MIME type.</p>
2164: <!-- XXX -->
1.26 ihickson 2165:
1.45 ihickson 2166: <li>
1.68 ! ihickson 2167: <p><span>Create a script</span>, using <var title="">source</var> as
! 2168: the script source and <var title="">language</var> as the scripting
! 2169: language, using the same global object, browsing context, character
! 2170: encoding, base URL, and script group as the <span
! 2171: title=concept-script>script</span> that was created by the worker's <a
! 2172: href="#run-a">run a worker</a> algorithm.</p>
! 2173:
! 2174: <p>Let the newly created <span title=concept-script>script</span> run
! 2175: until it either returns, fails to parse, fails to catch an exception,
! 2176: or gets prematurely aborted by the "<a href="#kill-a">kill a
! 2177: worker</a>" or "<a href="#terminate">terminate a worker</a>"
! 2178: algorithms defined above.</p>
1.60 ihickson 2179:
2180: <p>If it failed to parse, then throw a
2181: <code>SyntaxError</code><!-- XXX ref? --> exception and abort all
2182: these steps.</p>
1.45 ihickson 2183:
2184: <p>If an exception was raised or if the script was prematurely aborted,
2185: then abort all these steps, letting the exception or aborting continue
2186: to be processed by the script that called the <code
2187: title=dom-WorkerGlobalScope-importScripts><a
2188: href="#importscripts">importScripts()</a></code> method.</p>
2189:
1.50 ihickson 2190: <p>If the "<a href="#kill-a">kill a worker</a>" or "<a
1.59 ihickson 2191: href="#terminate">terminate a worker</a>" algorithms abort the script
1.50 ihickson 2192: then abort all these steps.</p>
1.45 ihickson 2193: </ol>
1.26 ihickson 2194: </ol>
2195:
1.61 ihickson 2196: <h3 id=the-navigator><span class=secno>3.2 </span>The <code><a
2197: href="#navigator0">Navigator</a></code> object</h3>
2198:
2199: <p>The <dfn id=navigator title=dom-navigator><code>navigator</code></dfn>
2200: attribute of the <code><a href="#workerutils">WorkerUtils</a></code>
2201: interface must return an instance of the <code><a
2202: href="#navigator0">Navigator</a></code> interface, which represents the
2203: identity and state of the user agent (the client):
2204:
2205: <pre
2206: class=idl>[NoInterfaceObject] interface <dfn id=navigator0>Navigator</dfn> {
2207: // objects implementing this interface also implement the interfaces listed below
2208: };</pre>
2209:
2210: <p>Objects implementing the <code><a
2211: href="#navigator0">Navigator</a></code> interface must also implement the
2212: <span>NavigatorID</span> and <span>NavigatorOnLine</span> interfaces
2213: specified in the HTML5 specification. <a href="#refsHTML5">[HTML5]</a>
2214:
2215: <p class=note>The <code><a href="#navigator0">Navigator</a></code>
2216: interface defined in this specification is different than the one defined
2217: in the HTML5 specification.
2218:
2219: <h3 id=apis-defined><span class=secno>3.3 </span>APIs defined in other
1.26 ihickson 2220: specifications</h3>
2221:
1.27 ihickson 2222: <p>The <dfn id=localstorage
1.26 ihickson 2223: title=dom-localStorage><code>localStorage</code></dfn>, <dfn
2224: id=opendatabase title=dom-opendatabase><code>openDatabase()</code></dfn>
2225: must act as defined for the APIs with the same names on the
2226: <code>Window</code> object in the HTML5 specification, with the exception
2227: that where the API would use the <span>origin</span> of the <span>active
2228: document</span> of the <span>browsing context</span> of the
2229: <code>Window</code> object on which the method was supposedly invoked, it
2230: must instead use the <span>origin</span> of the script that invoked the
2231: method. <a href="#refsHTML5">[HTML5]</a>
2232:
2233: <p>The <dfn id=shownotification
2234: title=dom-showNotification><code>showNotification()</code></dfn> methods
2235: must act as defined for the APIs with the same names on the
2236: <code>Window</code> object in the HTML5 specification. <a
2237: href="#refsHTML5">[HTML5]</a>
2238:
1.61 ihickson 2239: <h3 id=interface><span class=secno>3.4 </span>Interface objects and
1.26 ihickson 2240: constructors</h3>
2241:
2242: <p>There must be no interface objects and constructors available in the
2243: global scope of scripts whose <span>script execution context</span> is a
2244: <code><a href="#workerglobalscope">WorkerGlobalScope</a></code> object
2245: except for the following:
2246:
2247: <ul>
2248: <li>
2249: <p><code>XMLHttpRequest</code> and all interface objects and constructors
2250: defined by the XMLHttpRequest specifications, except that the
2251: <span>document response entity body</span> must always be null. <a
2252: href="#refsXHR">[XHR]</a>
2253:
2254: <li>
2255: <p>The <code>WebSocket</code> interface object and constructor.
2256:
2257: <li>
2258: <p>The <code>MessageChannel</code> interface object and constructor.
1.63 ihickson 2259:
2260: <li>
2261: <p>The <code title=dom-Worker><a href="#worker2">Worker()</a></code> and
2262: <code title=dom-SharedWorker><a href="#sharedworker0">SharedWorker(<var
2263: title="">url</var>)</a></code> constructors.
1.26 ihickson 2264: </ul>
2265:
1.61 ihickson 2266: <h3 id=worker0><span class=secno>3.5 </span>Worker locations</h3>
1.34 ihickson 2267:
2268: <pre
2269: class=idl>[NoInterfaceObject] interface <dfn id=workerlocation>WorkerLocation</dfn> {
2270: readonly attribute DOMString <a href="#href" title=dom-WorkerLocation-href>href</a>;
2271: readonly attribute DOMString <a href="#protocol" title=dom-WorkerLocation-protocol>protocol</a>;
2272: readonly attribute DOMString <a href="#host" title=dom-WorkerLocation-host>host</a>;
2273: readonly attribute DOMString <a href="#hostname" title=dom-WorkerLocation-hostname>hostname</a>;
1.50 ihickson 2274: readonly attribute DOMString <a href="#port0" title=dom-WorkerLocation-port>port</a>;
1.34 ihickson 2275: readonly attribute DOMString <a href="#pathname" title=dom-WorkerLocation-pathname>pathname</a>;
2276: readonly attribute DOMString <a href="#search" title=dom-WorkerLocation-search>search</a>;
2277: readonly attribute DOMString <a href="#hash" title=dom-WorkerLocation-hash>hash</a>;
2278: };</pre>
2279:
2280: <p>A <code><a href="#workerlocation">WorkerLocation</a></code> object
2281: represents an <span>absolute URL</span> set at its creation.
2282:
2283: <p>The <dfn id=href title=dom-WorkerLocation-href><code>href</code></dfn>
2284: attribute must return the <span>absolute URL</span> that the object
2285: represents.
2286:
2287: <p>The <code><a href="#workerlocation">WorkerLocation</a></code> interface
2288: also has the complement of <span>URL decomposition attributes</span>, <dfn
2289: id=protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
2290: <dfn id=host title=dom-WorkerLocation-host><code>host</code></dfn>, <dfn
1.50 ihickson 2291: id=port0 title=dom-WorkerLocation-port><code>port</code></dfn>, <dfn
1.34 ihickson 2292: id=hostname title=dom-WorkerLocation-hostname><code>hostname</code></dfn>,
2293: <dfn id=pathname
2294: title=dom-WorkerLocation-pathname><code>pathname</code></dfn>, <dfn
2295: id=search title=dom-WorkerLocation-search><code>search</code></dfn>, and
2296: <dfn id=hash title=dom-WorkerLocation-hash><code>hash</code></dfn>. These
2297: must follow the rules given for URL decomposition attributes, with the
2298: <span title=concept-uda-input>input</span> being the <span>absolute
2299: URL</span> that the object represents (same as the <code
2300: title=dom-WorkerLocation-href><a href="#href">href</a></code> attribute),
2301: and the <span title=concept-uda-setter>common setter action</span> being a
2302: no-op, since the attributes are defined to be readonly. <a
2303: href="#refsHTML5">[HTML5]</a>
2304:
1.1 ihickson 2305: <h2 class=no-num id=references>References</h2>
2306:
2307: <p class=big-issue>This section will be written in a future
2308: draft.<!--XXX-->
2309:
2310: <h2 class=no-num id=acknowledgements>Acknowledgements</h2>
2311: <!-- ACKS -->
2312:
1.62 ihickson 2313: <p>Thanks to Aaron Boodman, Dmitry Titov, Jonas Sicking, Justin James,
2314: Kevin Hakanson, Maciej Stachowiak, Michael Nordman, Mike Smith, and Philip
2315: Taylor for their useful and substantial comments.
1.4 ihickson 2316:
2317: <p>Huge thanks to the whole Gears team, who pioneered this technology and
2318: whose experience has been a huge influence on this specification.
Webmaster