Annotation of html5/workers/Overview.html, revision 1.77
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.77 ! ihickson 19: Draft <!--ZZZ-->14 January 2009</h2>
1.1 ihickson 20:
21: <dl><!-- ZZZ: update the month/day
22: <dt>This Version:</dt>
1.77 ! ihickson 23: <dd><a href="http://www.w3.org/TR/2009/WD-workers-20090101/">http://www.w3.org/TR/2009/WD-workers-20090101/</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.77 ! ihickson 145: specification is the 14 January 2009 <!--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>
1.77 ! ihickson 180: <li><a href="#introduction"><span class=secno>1 </span>Introduction</a>
1.1 ihickson 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.77 ! ihickson 215: <li><a href="#infrastructure"><span class=secno>2
1.12 ihickson 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.74 ihickson 243: <ul class=toc>
244: <li><a href="#runtime"><span class=secno>2.5.1 </span>Runtime script
245: errors</a>
246: </ul>
1.12 ihickson 247:
1.15 ihickson 248: <li><a href="#creating"><span class=secno>2.6 </span>Creating
1.12 ihickson 249: workers</a>
1.50 ihickson 250: <ul class=toc>
251: <li><a href="#the-abstractworker"><span class=secno>2.6.1 </span>The
252: <code>AbstractWorker</code> abstract interface</a>
253:
254: <li><a href="#dedicated0"><span class=secno>2.6.2 </span>Dedicated
255: workers and the <code>Worker</code> interface</a>
256:
257: <li><a href="#shared1"><span class=secno>2.6.3 </span>Shared workers
258: and the <code>SharedWorker</code> interface</a>
259: </ul>
1.1 ihickson 260: </ul>
261:
1.77 ! ihickson 262: <li><a href="#apis-available"><span class=secno>3 </span>APIs available to
! 263: workers</a>
1.26 ihickson 264: <ul class=toc>
265: <li><a href="#importing"><span class=secno>3.1 </span>Importing scripts
266: and libraries</a>
267:
1.61 ihickson 268: <li><a href="#the-navigator"><span class=secno>3.2 </span>The
269: <code>Navigator</code> object</a>
270:
271: <li><a href="#apis-defined"><span class=secno>3.3 </span>APIs defined in
1.26 ihickson 272: other specifications</a>
273:
1.61 ihickson 274: <li><a href="#interface"><span class=secno>3.4 </span>Interface objects
1.26 ihickson 275: and constructors</a>
1.34 ihickson 276:
1.61 ihickson 277: <li><a href="#worker0"><span class=secno>3.5 </span>Worker locations</a>
1.34 ihickson 278:
1.26 ihickson 279: </ul>
1.4 ihickson 280:
1.1 ihickson 281: <li class=no-num><a href="#references">References</a>
282:
283: <li class=no-num><a href="#acknowledgements">Acknowledgements</a>
284: </ul>
285: <!--end-toc-->
286:
287: <hr>
288:
1.77 ! ihickson 289: <h2 id=introduction><span class=secno>1 </span>Introduction</h2>
1.1 ihickson 290:
1.55 ihickson 291: <h3 id=scope><span class=secno>1.1 </span>Scope</h3>
292:
293: <p><em>This section is non-normative.</em>
294:
295: <p>This specification defines an API for running scripts in the background
296: independently of any user interface scripts.
297:
298: <p>This allows for long-running scripts that are not interrupted by scripts
299: that respond to clicks or other user interactions, and allows long tasks
300: to be executed without yielding to keep the page responsive.
301:
302: <p>Workers (as these background scripts are called herein) are relatively
303: heavy-weight, and are not intended to be used in large numbers. For
304: example, it would be inappropriate to launch one worker for each pixel of
305: a four megapixel image. The examples below show some appropriate uses of
306: workers.
307:
308: <p>Generally, workers are expected to be long-lived, have a high start-up
309: performance cost, and a high per-instance memory cost.
310:
311: <h3 id=tutorial><span class=secno>1.2 </span>Tutorial</h3>
1.1 ihickson 312:
313: <p><em>This section is non-normative.</em>
314:
1.29 ihickson 315: <p>There are a variety of uses that workers can be put to. The following
316: subsections show various examples of this use.
317:
1.55 ihickson 318: <h4 id=a-background><span class=secno>1.2.1 </span>A background
1.32 ihickson 319: number-crunching worker</h4>
1.29 ihickson 320:
321: <p><em>This section is non-normative.</em>
322:
323: <p>The simplest use of workers is for performing a computationally
324: expensive task without interrupting the user interface.
325:
1.32 ihickson 326: <p>In this example, the main document spawns a worker to (naïvely)
1.29 ihickson 327: compute prime numbers, and progressively displays the most recently found
328: prime number.
329:
330: <p>The main page is as follows:
331:
332: <pre><!DOCTYPE HTML>
333: <html>
334: <head>
1.40 ihickson 335: <title>Worker example: One-core computation</title>
1.29 ihickson 336: </head>
337: <body>
338: <p>The highest prime number discovered so far is: <output id="result"></output></p>
339: <script>
1.50 ihickson 340: var worker = new Worker('worker.js');
341: worker.onmessage = function (event) {
1.54 ihickson 342: document.getElementById('result').textContent = event.data;
1.29 ihickson 343: };
344: </script>
345: </body>
346: </html></pre>
347:
1.50 ihickson 348: <p>The <code title=dom-Worker><a href="#worker2">Worker()</a></code>
349: constructor call creates a worker and returns a <code><a
350: href="#worker1">Worker</a></code> object representing that worker, which
351: is used to communicate with the worker. That object's <code
352: title=handler-Worker-onmessage><a href="#onmessage0">onmessage</a></code>
353: event handler attribute allows the code to receive messages from the
354: worker.
1.29 ihickson 355:
356: <p>The worker itself is as follows:
357:
358: <pre>var n = 1;
359: search: while (true) {
360: n += 1;
361: for (var i = 2; i <= Math.sqrt(n); i += 1)
362: if (n % i == 0)
363: continue search;
364: // found a prime!
1.50 ihickson 365: postMessage(n);
1.29 ihickson 366: }</pre>
367:
368: <p>The bulk of this code is simply an unoptimised search for a prime
369: number. To send a message back to the page, the <code
1.50 ihickson 370: title=dom-DedicatedWorkerGlobalScope-postMessage><a
371: href="#postmessage">postMessage()</a></code> method is used to post a
1.30 ihickson 372: message when a prime is found.
1.29 ihickson 373:
374: <p><a href="http://www.whatwg.org/demos/workers/primes/page.html">View this
375: example online</a>.
1.4 ihickson 376:
1.55 ihickson 377: <h4 id=a-worker><span class=secno>1.2.2 </span>A worker for updating a
1.31 ihickson 378: client-side database</h4>
379:
380: <p><em>This section is non-normative.</em>
381:
382: <p>In this example, the main document spawns a worker whose only task is to
383: listen for notifications from the server, and, when appropriate, either
384: add or remove data from the client-side database.
385:
386: <p>Since no communication occurs between the worker and the main page, the
387: main page can start the worker by just doing:
388:
389: <pre><script>
1.50 ihickson 390: new Worker('worker.js');
1.31 ihickson 391: </script></pre>
392:
393: <p>The worker itself is as follows:
394:
395: <pre>var server = new WebSocket('ws://whatwg.org/database');
1.42 ihickson 396: var database = openDatabase('demobase', '1.0', 'Demo Database', 10240);
1.31 ihickson 397: server.onmessage = function (event) {
398: // data is in the format "command key value"
1.54 ihickson 399: var data = event.data.split(' ');
1.31 ihickson 400: switch (data[0]) {
401: case '+':
402: database.transaction(function(tx) {
403: tx.executeSql('INSERT INTO pairs (key, value) VALUES (?, ?)', data[1], data[2]);
404: });
405: case '-':
406: database.transaction(function(tx) {
407: tx.executeSql('DELETE FROM pairs WHERE key=? AND value=?', data[1], data[2]);
408: });
409: }
410: };</pre>
411:
412: <p>This connects to the server using the <code>WebSocket</code> mechanism
413: and opens the local database (which, we presume, has been created
1.58 ihickson 414: earlier). The worker then just listens for messages from the server and
1.31 ihickson 415: acts on them as appropriate, forever (or until the main page is closed).
416:
417: <p><a
418: href="http://www.whatwg.org/demos/workers/database-updater/page.html">View
419: this example online</a>. (This example will not actually function, since
420: the server does not actually exist and the database is not created by this
421: sample code.)
422:
1.58 ihickson 423: <h4 id=worker><span class=secno>1.2.3 </span>Worker used for background I/O</h4>
1.33 ihickson 424:
425: <p><em>This section is non-normative.</em>
426:
427: <p>In this example, the main document uses two workers, one for fetching
428: stock updates for at regular intervals, and one for fetching performing
429: search queries that the user requests.
430:
431: <p>The main page is as follows:
432:
433: <pre><!DOCTYPE HTML>
434: <html>
435: <head>
436: <title>Worker example: Stock ticker</title>
437: <script>
438: // TICKER
439: var symbol = 'GOOG'; // default symbol to watch
1.50 ihickson 440: var ticker = new Worker('ticker.js');
1.33 ihickson 441:
442: // SEARCHER
1.50 ihickson 443: var searcher = new Worker('searcher.js');
1.33 ihickson 444: function search(query) {
1.50 ihickson 445: searcher.postMessage(query);
1.33 ihickson 446: }
447:
448: // SYMBOL SELECTION UI
449: function select(newSymbol) {
450: symbol = newSymbol;
1.50 ihickson 451: ticker.postMessage(symbol);
1.33 ihickson 452: }
453: </script>
454: </head>
455: <body>
456: <p><output id="symbol"></output> <output id="value"></output></p>
457: <script>
1.50 ihickson 458: ticker.onmessage = function (event) {
1.54 ihickson 459: var data = event.data.split(' ');
1.33 ihickson 460: document.getElementById('symbol').textContent = data[0];
461: document.getElementById('value').textContent = data[1];
462: };
1.50 ihickson 463: ticker.postMessage(symbol);
1.33 ihickson 464: </script>
465: <p><label>Search: <input type="text" oninput="search(this.value)"></label></p>
466: <ul id="results"></ul>
467: <script>
1.50 ihickson 468: searcher.onmessage = function (event) {
1.54 ihickson 469: var data = event.data.split(' ');
1.33 ihickson 470: var results = document.getElementById('results');
471: while (results.hasChildNodes()) // clear previous results
472: results.removeChild(results.firstChild);
473: for (var i = 0; i < data.length; i += 1) {
474: // add a list item with a button for each result
475: var li = document.createElement('li');
476: var button = document.createElement('button');
477: button.value = data[i];
478: button.type = 'button';
479: button.onclick = function () { select(this.value); };
480: button.textContent = data[i];
481: li.appendChild(button);
482: results.appendChild(li);
483: }
484: };
485: </script>
486: <p>(The data in this example is not real. Try searching for "Google" or "Apple".)</p>
487: </body>
488: </html></pre>
489:
490: <p>The two workers use a common library for performing the actual network
491: calls. This library is as follows:
492:
493: <pre>function get(url) {
1.50 ihickson 494: try {
495: var xhr = new XMLHttpRequest();
496: xhr.open('GET', url, false);
497: xhr.send();
498: return xhr.responseText;
499: } catch (e) {
500: return ''; // turn all errors into empty results
501: }
1.33 ihickson 502: }</pre>
503:
504: <p>The stock updater worker is as follows:
505:
1.45 ihickson 506: <pre>importScripts('io.js');
1.33 ihickson 507: var timer;
508: var symbol;
509: function update() {
1.50 ihickson 510: postMessage(symbol + ' ' + get('stock.cgi?' + symbol));
1.33 ihickson 511: timer = setTimeout(update, 10000);
512: }
1.50 ihickson 513: onmessage = function (event) {
1.33 ihickson 514: if (timer)
515: clearTimeout(timer);
1.54 ihickson 516: symbol = event.data;
1.33 ihickson 517: update();
518: };</pre>
519:
520: <p>The search query worker is as follows:
521:
1.45 ihickson 522: <pre>importScripts('io.js');
1.50 ihickson 523: onmessage = function (event) {
1.54 ihickson 524: postMessage(get('search.cgi?' + event.data));
1.33 ihickson 525: };</pre>
526:
1.36 ihickson 527: <p><a href="http://www.whatwg.org/demos/workers/stocks/page.html">View this
1.33 ihickson 528: example online</a>.
529:
1.55 ihickson 530: <h4 id=shared><span class=secno>1.2.4 </span>Shared workers</h4>
1.34 ihickson 531:
1.36 ihickson 532: <p><em>This section is non-normative.</em>
533:
534: <p>In this example, multiple windows (viewers) can be opened that are all
535: viewing the same map. All the windows share the same map information, with
536: a single worker coordinating all the viewers. Each viewer can move around
1.60 ihickson 537: independently, but if they set any data on the map, all the viewers are
1.36 ihickson 538: updated.
539:
540: <p>The main page isn't interesting, it merely provides a way to open the
541: viewers:
542:
543: <pre><!DOCTYPE HTML>
544: <html>
545: <head>
546: <title>Workers example: Multiviewer</title>
547: <script>
548: function openViewer() {
549: window.open('viewer.html');
550: }
551: </script>
552: </head>
553: <body>
554: <p><button type=button onclick="openViewer()">Open a new
555: viewer</button></p>
556: <p>Each viewer opens in a new window. You can have as many viewers
557: as you like, they all view the same data.</p>
558: </body>
559: </html></pre>
560:
561: <p>The viewer is more involved:
562:
563: <pre><!DOCTYPE HTML>
564: <html>
565: <head>
566: <title>Workers example: Multiviewer viewer</title>
567: <script>
1.50 ihickson 568: var worker = new SharedWorker('worker.js', 'core');
1.36 ihickson 569:
570: // CONFIGURATION
571: function configure(event) {
1.54 ihickson 572: if (event.data.substr(0, 4) != 'cfg ') return;
573: var name = event.data.substr(4).split(' ', 1);
1.36 ihickson 574: // update display to mention our name is name
575: document.getElementsByTagName('h1')[0].textContent += ' ' + name;
576: // no longer need this listener
1.43 ihickson 577: worker.port.removeEventListener('message', configure, false);
1.36 ihickson 578: }
1.53 ihickson 579: worker.port.addEventListener('message', configure, false);
1.36 ihickson 580:
581: // MAP
582: function paintMap(event) {
1.54 ihickson 583: if (event.data.substr(0, 4) != 'map ') return;
584: var data = event.data.substr(4).split(',');
1.36 ihickson 585: // display tiles data[0] .. data[8]
586: var canvas = document.getElementById('map');
587: var context = canvas.getContext('2d');
588: for (var y = 0; y < 3; y += 1) {
589: for (var x = 0; x < 3; x += 1) {
590: var tile = data[y * 3 + x];
591: if (tile == '0')
592: context.fillStyle = 'green';
593: else
594: context.fillStyle = 'maroon';
595: fillRect(x * 50, y * 50, 50, 50);
596: }
597: }
598: }
1.53 ihickson 599: worker.port.addEventListener('message', paintMap, false);
1.36 ihickson 600:
601: // PUBLIC CHAT
602: function updatePublicChat(event) {
1.54 ihickson 603: if (event.data.substr(0, 4) != 'txt ') return;
604: var name = event.data.substr(4).split(' ', 1);
605: var message = event.data.substr(4 + length(name) + 1);
1.36 ihickson 606: // display "<name> message" in public chat
607: var dialog = document.getElementById('public');
608: var dt = document.createElement('dt');
609: dt.textContent = name;
610: dialog.appendChild(dt);
611: var dd = document.createElement('dd');
612: dd.textContent = message;
613: dialog.appendChild(dd);
614: }
1.53 ihickson 615: worker.port.addEventListener('message', updatePublicChat, false);
1.36 ihickson 616:
617: // PRIVATE CHAT
618: function startPrivateChat(event) {
1.54 ihickson 619: if (event.data.substr(0, 4) != 'msg ') return;
620: var name = event.data.substr(4).split(' ', 1);
1.36 ihickson 621: var port = event.port;
622: // display a private chat UI
623: var ul = document.getElementById('private');
624: var li = document.createElement('li');
625: var h3 = document.createElement('h3');
626: h3.textContent = 'Private chat with ' + name;
627: li.appendChild(h3);
628: var dialog = document.createElement('dialog');
629: var addMessage = function(name, message) {
630: var dt = document.createElement('dt');
631: dt.textContent = name;
632: dialog.appendChild(dt);
633: var dd = document.createElement('dd');
634: dd.textContent = message;
635: dialog.appendChild(dd);
636: };
637: port.onmessage = function (event) {
1.54 ihickson 638: addMessage(name, event.data);
1.36 ihickson 639: };
640: li.appendChild(dialog);
641: var form = document.createElement('form');
642: var p = document.createElement('p');
643: var input = document.createElement('input');
644: input.size = 50;
645: p.appendChild(input);
646: p.appendChild(document.createTextNode(' '));
647: var button = document.createElement('button');
648: button.textContent = 'Post';
649: p.appendChild(button);
650: form.onsubmit = function () {
651: port.postMessage(input.value);
652: addMessage('me', input.value);
653: input.value = '';
654: return false;
655: };
656: form.appendChild(p);
657: li.appendChild(form);
658: }
1.53 ihickson 659: worker.port.addEventListener('message', startPrivateChat, false);
1.36 ihickson 660: </script>
661: </head>
1.50 ihickson 662: <body>
1.36 ihickson 663: <h1>Viewer</h1>
664: <h2>Map</h2>
665: <p><canvas id="map" height=150 width=150></canvas></p>
666: <p>
1.53 ihickson 667: <button type=button onclick="worker.port.postMessage('mov left')">Left</button>
668: <button type=button onclick="worker.port.postMessage('mov up')">Up</button>
669: <button type=button onclick="worker.port.postMessage('mov down')">Down</button>
670: <button type=button onclick="worker.port.postMessage('mov right')">Right</button>
671: <button type=button onclick="worker.port.postMessage('set 0')">Set 0</button>
672: <button type=button onclick="worker.port.postMessage('set 1')">Set 1</button>
1.36 ihickson 673: </p>
674: <h2>Public Chat</h2>
675: <dialog id="public"></dialog>
1.53 ihickson 676: <form onsubmit="worker.port.postMessage('txt ' + message.value); message.value = ''; return false;">
1.36 ihickson 677: <p>
678: <input type="text" name="message" size="50">
679: <button>Post</button>
680: </p>
681: </form>
682: <h2>Private Chat</h2>
683: <ul id="private"></ul>
684: </body>
1.43 ihickson 685: </html>
686: </pre>
1.36 ihickson 687:
688: <p>There are several key things worth noting about the way the viewer is
689: written.
690:
691: <p><strong>Multiple listeners</strong>. Instead of a single message
692: processing function, the code here attaches multiple event listeners, each
693: one performing a quick check to see if it is relevant for the message. In
694: this example it doesn't make much difference, but if multiple authors
695: wanted to collaborate using a single port to communicate with a worker, it
696: would allow for independent code instead of changes having to all be made
697: to a single event handling function.
698:
699: <p>Registering event listeners in this way also allows you to unregister
700: specific listeners when you are done with them, as is done with the <code
701: title="">configure()</code> method in this example.
702:
703: <p>Finally, the worker:
704:
705: <pre>
706: var nextName = 0;
707: function getNextName() {
708: // this could use more friendly names
709: // but for now just return a number
710: return nextName++;
711: }
712:
713: var map = [
714: [0, 0, 0, 0, 0, 0, 0],
715: [1, 1, 0, 1, 0, 1, 1],
716: [0, 1, 0, 1, 0, 0, 0],
717: [0, 1, 0, 1, 0, 1, 1],
718: [0, 0, 0, 1, 0, 0, 0],
719: [1, 0, 0, 1, 1, 1, 1],
720: [1, 1, 0, 1, 1, 0, 1],
721: ];
722:
723: function wrapX(x) {
724: if (x < 0) return wrapX(x + map[0].length);
725: if (x >= map[0].length) return wrapX(x - map[0].length);
726: return x;
727: }
728:
729: function wrapY(y) {
730: if (y < 0) return wrapY(y + map.length);
731: if (y >= map[0].length) return wrapY(y - map.length);
732: return y;
733: }
734:
1.50 ihickson 735: function sendMapData(callback) {
1.36 ihickson 736: var data = '';
737: for (var y = viewer.y-1; y <= viewer.y+1; y += 1) {
738: for (var x = viewer.x-1; x <= viewer.x+1; x += 1) {
739: if (data != '')
740: data += ',';
741: data += map[y][x];
742: }
743: }
1.50 ihickson 744: callback('map ' + data);
1.36 ihickson 745: }
746:
747: var viewers = {};
748: onconnect = function (event) {
749: event.port._name = getNextName();
750: event.port._data = { port: event.port, x: 0, y: 0, };
751: viewers[event.port._name] = event.port._data;
752: event.port.postMessage('cfg ' + name);
753: event.port.onmessage = getMessage;
1.50 ihickson 754: sendMapData(event.port.postMessage);
1.36 ihickson 755: };
756:
757: function getMessage(event) {
1.54 ihickson 758: switch (event.data.substr(0, 4)) {
1.36 ihickson 759: case 'mov ':
1.54 ihickson 760: var direction = event.data.substr(4);
1.36 ihickson 761: var dx = 0;
762: var dy = 0;
763: switch (direction) {
764: case 'up': dy = -1; break;
765: case 'down': dy = 1; break;
766: case 'left': dx = -1; break;
767: case 'right': dx = 1; break;
768: }
769: event.target._data.x = wrapX(event.target._data.x + dx);
770: event.target._data.y = wrapY(event.target._data.y + dy);
1.50 ihickson 771: sendMapData(event.target.postMessage);
1.36 ihickson 772: break;
773: case 'set ':
1.54 ihickson 774: var value = event.data.substr(4);
1.36 ihickson 775: map[event.target._data.y][event.target._data.x] = value;
776: for (var viewer in viewers)
1.50 ihickson 777: sendMapData(viewers[viewer].port.postMessage);
1.36 ihickson 778: break;
779: case 'txt ':
780: var name = event.target._name;
1.54 ihickson 781: var message = event.data.substr(4);
1.36 ihickson 782: for (var viewer in viewers)
783: viewers[viewer].port.postMessage('txt ' + name + ' ' + message);
784: break;
785: case 'msg ':
786: var party1 = event._data;
1.54 ihickson 787: var party2 = viewers[event.data.substr(4).split(' ', 1)];
1.36 ihickson 788: if (party2) {
789: var channel = new MessageChannel();
790: party1.port.postMessage('msg ' + party2.name, channel.port1);
791: party2.port.postMessage('msg ' + party1.name, channel.port2);
792: }
793: break;
794: }
795: }</pre>
796:
1.50 ihickson 797: <p><strong>Connecting to multiple pages</strong>. The script uses the <code
798: title=handler-SharedWorkerGlobalScope-onconnect><a
1.37 ihickson 799: href="#onconnect">onconnect</a></code> event listener to listen for
800: multiple connections.
1.36 ihickson 801:
802: <p><strong>Direct channels</strong>. When the worker receives a "msg"
803: message from one viewer naming another viewer, it sets up a direct
804: connection between the two, so that the two viewers can communicate
805: directly without the worker having to proxy all the messages.
806:
807: <p><a href="http://www.whatwg.org/demos/workers/multiviewer/page.html">View
808: this example online</a>.
1.34 ihickson 809:
1.55 ihickson 810: <h4 id=delegation><span class=secno>1.2.5 </span>Delegation</h4>
1.34 ihickson 811:
1.36 ihickson 812: <p><em>This section is non-normative.</em>
813:
1.40 ihickson 814: <p>With multicore CPUs becoming prevalent, one way to obtain better
815: performance is to split computationally expensive tasks amongst multiple
816: workers. In this example, a computationally expensive task that is to be
817: performed for every number from 1 to 10,000,000 is farmed out to ten
818: subworkers.
819:
820: <p>The main page is as follows, it just reports the result:
821:
822: <pre><!DOCTYPE HTML>
823: <html>
824: <head>
825: <title>Worker example: One-core computation</title>
826: </head>
827: <body>
828: <p>The highest prime number discovered so far is: <output id="result"></output></p>
829: <script>
1.50 ihickson 830: var worker = new Worker('worker.js');
831: worker.onmessage = function (event) {
1.54 ihickson 832: document.getElementById('result').textContent = event.data;
1.40 ihickson 833: };
834: </script>
835: </body>
836: </html></pre>
837:
838: <p>The worker itself is as follows:
839:
840: <pre>// settings
841: var num_workers = 10;
842: var items_per_worker = 1000000;
843:
844: // start the workers
845: var result = 0;
846: var pending_workers = num_workers;
847: for (var i = 0; i < num_workers; i += 1) {
1.50 ihickson 848: var worker = new Worker('core.js');
849: worker.postMessage(i * items_per_worker);
850: worker.postMessage((i+1) * items_per_worker);
851: worker.onmessage = storeResult;
1.40 ihickson 852: }
853:
854: // handle the results
855: function storeResult(event) {
1.54 ihickson 856: result += 1*event.data;
1.40 ihickson 857: pending_workers -= 1;
858: if (pending_workers <= 0)
1.50 ihickson 859: postMessage(result); // finished!
1.40 ihickson 860: }</pre>
861:
862: <p>It consists of a loop to start the subworkers, and then a handler that
863: waits for all the subworkers to respond.
864:
865: <p>The subworkers are implemented as follows:
866:
867: <pre>var start;
1.41 ihickson 868: onmessage = getStart;
1.40 ihickson 869: function getStart(event) {
1.54 ihickson 870: start = 1*event.data;
1.40 ihickson 871: onmessage = getEnd;
872: }
873:
874: var end;
875: function getEnd(event) {
1.54 ihickson 876: end = 1*event.data;
1.40 ihickson 877: onmessage = null;
1.66 ihickson 878: work();
1.40 ihickson 879: }
880:
1.66 ihickson 881: function work() {
1.40 ihickson 882: var result = 0;
883: for (var i = start; i < end; i += 1) {
884: // perform some complex calculation here
885: result += 1;
886: }
1.50 ihickson 887: postMessage(result);
888: close();
1.40 ihickson 889: }</pre>
890:
891: <p>They receive two numbers in two events, perform the computation for the
892: range of numbers thus specified, and then report the result back to the
893: parent.
894:
895: <p><a href="http://www.whatwg.org/demos/workers/multicore/page.html">View
896: this example online</a>.
1.34 ihickson 897:
1.55 ihickson 898: <h4 id=providing><span class=secno>1.2.6 </span>Providing libraries</h4>
1.49 ihickson 899:
900: <p><em>This section is non-normative.</em>
901:
902: <p>Suppose that a cryptography library is made available that provides
903: three tasks:
904:
905: <dl>
906: <dt>Generate a public/private key pair
907:
908: <dd>Takes a port, on which it will send two messages, first the public key
909: and then the private key.
910:
911: <dt>Given a plaintext and a public key, return the corresponding
912: cyphertext
913:
914: <dd>Takes a port, to which any number of messages can be sent, the first
915: giving the public key, and the remainder giving the plaintext, each of
916: which is encrypted and then sent on that same channel as the cyphertext.
917: The user can close the port when it is done encrypting content.
918:
919: <dt>Given a cyphertext and a private key, return the corresponding
920: plaintext
921:
922: <dd>Takes a port, to which any number of messages can be sent, the first
923: giving the private key, and the remainder giving the cyphertext, each of
924: which is decrypted and then sent on that same channel as the plaintext.
925: The user can close the port when it is done decrypting content.
926: </dl>
927:
928: <p>The library itself is as follows:
929:
930: <pre>function handleMessage(e) {
1.54 ihickson 931: if (e.data == "genkeys")
1.49 ihickson 932: genkeys(e.port);
1.54 ihickson 933: else if (e.data == "encrypt")
1.49 ihickson 934: encrypt(e.port);
1.54 ihickson 935: else if (e.data == "decrypt")
1.49 ihickson 936: decrypt(e.port);
937: }
938:
939: function genkeys(p) {
940: var keys = _generateKeyPair();
941: p.postMessage(keys[0]);
942: p.postMessage(keys[1]);
943: }
944:
945: function encrypt(p) {
946: var key, state = 0;
947: p.onmessage = function (e) {
948: if (state == 0) {
1.54 ihickson 949: key = e.data;
1.49 ihickson 950: state = 1;
951: } else {
1.54 ihickson 952: p.postMessage(_encrypt(key, e.data));
1.49 ihickson 953: }
954: };
955: }
956:
957: function decrypt(p) {
958: var key, state = 0;
959: p.onmessage = function (e) {
960: if (state == 0) {
1.54 ihickson 961: key = e.data;
1.49 ihickson 962: state = 1;
963: } else {
1.54 ihickson 964: p.postMessage(_decrypt(key, e.data));
1.49 ihickson 965: }
966: };
967: }
968:
1.50 ihickson 969: // support being used as a shared worker as well as a dedicated worker
970: if (this.onmessage) // dedicated worker
971: onmessage = handleMessage;
972: else // shared worker
973: onconnect = function (e) { e.port.onmessage = handleMessage; }
1.49 ihickson 974:
975:
976: // the "crypto" functions:
977:
978: function _generateKeyPair() {
979: return [Math.random(), Math.random()];
980: }
981:
982: function _encrypt(k, s) {
983: return 'encrypted-' + k + ' ' + s;
984: }
985:
986: function _decrypt(k, s) {
987: return s.substr(s.indexOf(' ')+1);
988: }</pre>
989:
990: <p>Note that the crypto functions here are just stubs and don't do real
991: cryptography.
992:
993: <p>This library could be used as follows:
994:
995: <pre><!DOCTYPE HTML>
996: <html>
997: <head>
998: <title>Worker example: Crypto library</title>
999: <script>
1.50 ihickson 1000: var crytoLib = new Worker('libcrypto-v1.js'); // or could use 'libcrypto-v2.js'
1.49 ihickson 1001: function getKeys() {
1002: var state = 0;
1.50 ihickson 1003: cryptoLib.startConversation("genkeys").onmessage = function (e) {
1.49 ihickson 1004: if (state == 0)
1.54 ihickson 1005: document.getElementById('public').value = e.data;
1.49 ihickson 1006: else if (state == 1)
1.54 ihickson 1007: document.getElementById('private').value = e.data;
1.49 ihickson 1008: state += 1;
1009: };
1010: }
1011: function enc() {
1.50 ihickson 1012: var port = cryptoLib.startConversation("encrypt");
1013: port.postMessage(document.getElementById('public').value);
1014: port.postMessage(document.getElementById('input').value);
1015: port.onmessage = function (e) {
1.54 ihickson 1016: document.getElementById('input').value = e.data;
1.50 ihickson 1017: port.close();
1.49 ihickson 1018: };
1019: }
1020: function dec() {
1.50 ihickson 1021: var port = cryptoLib.startConversation("decrypt");
1022: port.postMessage(document.getElementById('private').value);
1023: port.postMessage(document.getElementById('input').value);
1024: port.onmessage = function (e) {
1.54 ihickson 1025: document.getElementById('input').value = e.data;
1.50 ihickson 1026: port.close();
1.49 ihickson 1027: };
1028: }
1029: </script>
1030: <style>
1031: textarea { display: block; }
1032: </style>
1033: </head>
1034: <body onload="getKeys()">
1035: <fieldset>
1036: <legend>Keys</legend>
1.50 ihickson 1037: <p><label>Public Key: <textarea id="public"></textarea></label></p>
1038: <p><label>Private Key: <textarea id="private"></textarea></label></p>
1.49 ihickson 1039: </fieldset>
1.50 ihickson 1040: <p><label>Input: <textarea id="input"></textarea></label></p>
1.49 ihickson 1041: <p><button onclick="enc()">Encrypt</button> <button onclick="dec()">Decrypt</button></p>
1042: </body>
1043: </html></pre>
1044:
1045: <p>A later version of the API, though, might want to offload all the crypto
1046: work onto subworkers. This could be done as follows:
1047:
1048: <pre>function handleMessage(e) {
1.54 ihickson 1049: if (e.data == "genkeys")
1.49 ihickson 1050: genkeys(e.port);
1.54 ihickson 1051: else if (e.data == "encrypt")
1.49 ihickson 1052: encrypt(e.port);
1.54 ihickson 1053: else if (e.data == "decrypt")
1.49 ihickson 1054: decrypt(e.port);
1055: }
1056:
1057: function genkeys(p) {
1.50 ihickson 1058: var generator = new Worker('libcrypto-v2-generator.js');
1.49 ihickson 1059: generator.postMessage('', p);
1060: }
1061:
1062: function encrypt(p) {
1063: p.onmessage = function (e) {
1.54 ihickson 1064: var key = e.data;
1.50 ihickson 1065: var encryptor = new Worker('libcrypto-v2-encryptor.js');
1.49 ihickson 1066: encryptor.postMessage(key, p);
1067: };
1068: }
1069:
1070: function encrypt(p) {
1071: p.onmessage = function (e) {
1.54 ihickson 1072: var key = e.data;
1.50 ihickson 1073: var decryptor = new Worker('libcrypto-v2-decryptor.js');
1.49 ihickson 1074: decryptor.postMessage(key, p);
1075: };
1076: }
1077:
1.50 ihickson 1078: // support being used as a shared worker as well as a dedicated worker
1079: if (this.onmessage) // dedicated worker
1080: onmessage = handleMessage;
1081: else // shared worker
1082: onconnect = function (e) { e.port.onmessage = handleMessage; }
1.49 ihickson 1083: </pre>
1084:
1085: <p>The little subworkers would then be as follows.
1086:
1087: <p>For generating key pairs:
1088:
1.50 ihickson 1089: <pre>onmessage = function (e) {
1090: var k = _generateKeyPair();
1091: e.port.postMessage(k[0]);
1092: e.port.postMessage(k[1]);
1.49 ihickson 1093: close();
1094: }
1.50 ihickson 1095:
1096: function _generateKeyPair() {
1097: return [Math.random(), Math.random()];
1098: }</pre>
1.49 ihickson 1099:
1100: <p>For encrypting:
1101:
1.50 ihickson 1102: <pre>onmessage = function (e) {
1.54 ihickson 1103: var key = e.data;
1.49 ihickson 1104: e.port.onmessage = function (e) {
1.54 ihickson 1105: var s = e.data;
1.50 ihickson 1106: postMessage(_encrypt(key, s));
1.49 ihickson 1107: }
1.50 ihickson 1108: e.port.onclose = function (e) {
1.49 ihickson 1109: close();
1110: }
1.50 ihickson 1111: }
1112:
1113: function _encrypt(k, s) {
1114: return 'encrypted-' + k + ' ' + s;
1.49 ihickson 1115: }</pre>
1116:
1117: <p>For decrypting:
1118:
1.50 ihickson 1119: <pre>onmessage = function (e) {
1.54 ihickson 1120: var key = e.data;
1.49 ihickson 1121: e.port.onmessage = function (e) {
1.54 ihickson 1122: var s = e.data;
1.50 ihickson 1123: postMessage(_decrypt(key, s));
1.49 ihickson 1124: }
1.50 ihickson 1125: e.port.onclose = function (e) {
1.49 ihickson 1126: close();
1127: }
1.50 ihickson 1128: }
1129:
1130: function _decrypt(k, s) {
1131: return s.substr(s.indexOf(' ')+1);
1.49 ihickson 1132: }</pre>
1133:
1134: <p>Notice how the users of the API don't have to even know that this is
1135: happening — the API hasn't changed; the library can delegate to
1136: subworkers without changing its API, even though it is accepting data
1137: using message channels.
1138:
1139: <p><a href="http://www.whatwg.org/demos/workers/crypto/page.html">View this
1140: example online</a>.
1141:
1.55 ihickson 1142: <h3 id=conformance><span class=secno>1.3 </span>Conformance requirements</h3>
1.1 ihickson 1143:
1144: <p>All diagrams, examples, and notes in this specification are
1145: non-normative, as are all sections explicitly marked non-normative.
1146: Everything else in this specification is normative.
1147:
1148: <p>The key words "MUST", "MUST NOT", "REQUIRED", <!--"SHALL", "SHALL
1149: NOT",-->
1150: "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the
1151: normative parts of this document are to be interpreted as described in
1152: RFC2119. For readability, these words do not appear in all uppercase
1.68 ihickson 1153: letters in this specification. <a href="#refsRFC2119">[RFC2119]</a>
1.1 ihickson 1154:
1155: <p>Requirements phrased in the imperative as part of algorithms (such as
1156: "strip any leading space characters" or "return false and abort these
1157: steps") are to be interpreted with the meaning of the key word ("must",
1158: "should", "may", etc) used in introducing the algorithm.
1159:
1160: <p>Some conformance requirements are phrased as requirements on attributes,
1161: methods or objects. Such requirements are to be interpreted as
1162: requirements on user agents.
1163:
1164: <p>Conformance requirements phrased as algorithms or specific steps may be
1165: implemented in any manner, so long as the end result is equivalent. (In
1166: particular, the algorithms defined in this specification are intended to
1167: be easy to follow, and not intended to be performant.)
1168:
1169: <p>The only conformance class defined by this specification is user agents.
1170:
1171: <p>User agents may impose implementation-specific limits on otherwise
1172: unconstrained inputs, e.g. to prevent denial of service attacks, to guard
1173: against running out of memory, or to work around platform-specific
1174: limitations.
1175:
1.55 ihickson 1176: <h4 id=dependencies><span class=secno>1.3.1 </span>Dependencies</h4>
1.1 ihickson 1177:
1178: <p>This specification relies on several other underlying specifications.
1179:
1180: <dl>
1181: <dt>HTML5
1182:
1183: <dd>
1184: <p>Many fundamental concepts from HTML5 are used by this specification.
1185: <a href="#refsHTML5">[HTML5]</a></p>
1186:
1187: <dt>ECMAScript
1188:
1189: <dd>
1190: <p>This specification is intended to be used with JavaScript as the
1191: scripting language. <a href="#refsJS">[JS]</a></p>
1192:
1193: <dt>WebIDL
1194:
1195: <dd>
1196: <p>The IDL blocks in this specification use the semantics of the WebIDL
1197: specification. <a href="#refsWebIDL">[WebIDL]</a></p>
1198: </dl>
1199:
1.55 ihickson 1200: <h3 id=terminology><span class=secno>1.4 </span>Terminology</h3>
1.1 ihickson 1201:
1.4 ihickson 1202: <p>The construction "a <code title="">Foo</code> object", where <code
1203: title="">Foo</code> is actually an interface, is sometimes used instead of
1204: the more accurate "an object implementing the interface <code
1205: title="">Foo</code>".
1.1 ihickson 1206:
1207: <p>The term DOM is used to refer to the API set made available to scripts
1208: in Web applications, and does not necessarily imply the existence of an
1209: actual <code>Document</code> object or of any other <code>Node</code>
1210: objects as defined in the DOM Core specifications. <a
1211: href="#refsDOM3CORE">[DOM3CORE]</a>
1212:
1213: <p>A DOM attribute is said to be <em>getting</em> when its value is being
1214: retrieved (e.g. by author script), and is said to be <em>setting</em> when
1215: a new value is assigned to it.
1216:
1.77 ! ihickson 1217: <h2 id=infrastructure><span class=secno>2 </span>Infrastructure</h2>
1.4 ihickson 1218:
1.50 ihickson 1219: <p>There are two kinds of workers; dedicated workers, and shared workers.
1220: Dedicated workers, once created, and are linked to their creator; but
1221: message ports can be used to communicate from a dedicated worker to
1.60 ihickson 1222: multiple other browsing contexts or workers. Shared workers, on the other
1.50 ihickson 1223: hand, are named, and once created any script running in the same
1224: <span>origin</span> can obtain a reference to that worker and communicate
1225: with it.
1226:
1227: <h3 id=the-global><span class=secno>2.1 </span>The global scope</h3>
1228:
1229: <p>The global scope is the "inside" of a worker.
1230:
1231: <h4 id=the-workerglobalscope><span class=secno>2.1.1 </span>The <code><a
1232: href="#workerglobalscope">WorkerGlobalScope</a></code> abstract interface</h4>
1.4 ihickson 1233:
1234: <pre
1.77 ! ihickson 1235: class=idl>interface <dfn id=workerglobalscope>WorkerGlobalScope</dfn> {
1.26 ihickson 1236: readonly attribute <a href="#workerglobalscope">WorkerGlobalScope</a> <a href="#self" title=dom-WorkerGlobalScope-self>self</a>;
1.34 ihickson 1237: readonly attribute <a href="#workerlocation">WorkerLocation</a> <a href="#location" title=dom-WorkerGlobalScope-location>location</a>;
1.50 ihickson 1238: // also implements everything on <a href="#workerutils">WorkerUtils</a>
1239:
1.26 ihickson 1240: void <a href="#close" title=dom-WorkerGlobalScope-close>close</a>();
1.50 ihickson 1241: attribute <span>EventListener</span> <a href="#onclose" title=handler-WorkerGlobalScope-onclose>onclose</a>;
1.74 ihickson 1242: attribute <span>EventListener</span> <a href="#onerror" title=handler-WorkerGlobalScope-onerror>onerror</a>;
1.4 ihickson 1243: };</pre>
1244:
1.39 ihickson 1245: <p>Objects implementing the <code><a
1.60 ihickson 1246: href="#workerglobalscope">WorkerGlobalScope</a></code> interface must also
1247: implement the <code>EventTarget</code> interface.
1.39 ihickson 1248:
1.26 ihickson 1249: <p>The <dfn id=self
1250: title=dom-WorkerGlobalScope-self><code>self</code></dfn> attribute must
1251: return the <code><a href="#workerglobalscope">WorkerGlobalScope</a></code>
1252: object itself.
1.9 ihickson 1253:
1.34 ihickson 1254: <p>The <dfn id=location
1255: title=dom-WorkerGlobalScope-location><code>location</code></dfn> attribute
1256: must return the <code><a href="#workerlocation">WorkerLocation</a></code>
1257: object created for the <code><a
1258: href="#workerglobalscope">WorkerGlobalScope</a></code> object when the
1259: worker was created. It represents the <span>absolute URL</span> of the
1260: script that was used to initialize the worker.
1.26 ihickson 1261:
1.50 ihickson 1262: <hr>
1263:
1264: <p>When a script invokes the <dfn id=close
1265: title=dom-WorkerGlobalScope-close><code>close()</code></dfn> method on a
1266: <code><a href="#workerglobalscope">WorkerGlobalScope</a></code> object,
1267: the user agent must run the following steps:
1268:
1269: <ol>
1270: <li>
1.68 ihickson 1271: <p><span>Queue a task</span> to <span>fire a simple event</span> called
1272: <code title=event-close>close</code> at the <code><a
1273: href="#workerglobalscope">WorkerGlobalScope</a></code> object.
1.50 ihickson 1274:
1275: <li>
1276: <p>Set the worker's <code><a
1277: href="#workerglobalscope">WorkerGlobalScope</a></code> object's <a
1278: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag to
1279: true.
1280:
1281: <li>
1282: <p>For each <code>MessagePort</code> object that is entangled with
1283: another port and that has one (but only one) port whose owner is the
1284: <code><a href="#workerglobalscope">WorkerGlobalScope</a></code> object
1285: on which the method was invoked (this would include, for instance, the
1.69 ihickson 1286: implicit port in used for dedicated workers), unentangle the two ports.
1.50 ihickson 1287: </ol>
1.4 ihickson 1288:
1.9 ihickson 1289: <p>The following are the <span>event handler DOM attributes</span> that
1290: must be supported by objects implementing the <code><a
1.26 ihickson 1291: href="#workerglobalscope">WorkerGlobalScope</a></code> interface:
1.9 ihickson 1292:
1293: <dl>
1.50 ihickson 1294: <dt><dfn id=onclose
1295: title=handler-WorkerGlobalScope-onclose><code>onclose</code></dfn>
1.9 ihickson 1296:
1297: <dd>
1.50 ihickson 1298: <p>Must be invoked whenever a <code title=event-close>close</code> event
1299: is targeted at or bubbles through the <code><a
1.26 ihickson 1300: href="#workerglobalscope">WorkerGlobalScope</a></code> object.
1.74 ihickson 1301:
1302: <dt><dfn id=onerror
1303: title=handler-WorkerGlobalScope-onerror><code>onerror</code></dfn>
1304:
1305: <dd>
1306: <p>Must be invoked whenever an <code title=event-error>error</code> event
1307: is targeted at or bubbles through the element.</p>
1308:
1309: <p>The initial value of <code title=handler-WorkerGlobalScope-onerror><a
1310: href="#onerror">onerror</a></code> must be <code>undefined</code>.
1.50 ihickson 1311: </dl>
1312:
1313: <h4 id=dedicated><span class=secno>2.1.2 </span>Dedicated workers and the
1314: <code><a
1315: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1316: interface</h4>
1.77 ! ihickson 1317: <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1.50 ihickson 1318:
1319: <pre
1.77 ! ihickson 1320: class=idl>[NoInterfaceObject, XXX] interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href="#workerglobalscope">WorkerGlobalScope</a> {
! 1321: void <a href="#postmessage" title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in any message, [Optional] in <span>MessagePort</span> messagePort);<!--
! 1322: <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
1.50 ihickson 1323: attribute <span>EventListener</span> <a href="#onmessage" title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
1324: };</pre>
1.9 ihickson 1325:
1.50 ihickson 1326: <p><code><a
1327: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1328: objects act as if they had an implicit <code>MessagePort</code> associated
1329: with them. This port is part of a channel that is set up when the worker
1330: is created, but it is not exposed. This object must never be garbage
1331: collected before the <code><a
1332: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1333: object.
1334:
1335: <p>All messages received by that port must immediately be retargetted at
1336: the <code><a
1337: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1338: object.
1339:
1340: <p>The <dfn id=postmessage
1.64 ihickson 1341: title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
1342: and <dfn
1343: title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
1344: method<!--s (startConversation)--> on <code><a
1.50 ihickson 1345: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1.64 ihickson 1346: objects must act as if, when invoked, it<!--/they (startConversation)-->
1347: immediately invoked the method of the same name on the port, with the same
1348: arguments, and returned the same return value.
1.50 ihickson 1349:
1350: <p>The following are the <span>event handler DOM attributes</span> that
1351: must be supported by objects implementing the <code><a
1352: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1353: interface:
1354:
1355: <dl>
1356: <dt><dfn id=onmessage
1357: title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn>
1.9 ihickson 1358:
1359: <dd>
1.50 ihickson 1360: <p>Must be invoked whenever a <code
1361: title=event-DedicatedWorkerGlobalScope-message>message</code> event is
1362: targeted at or bubbles through the <code><a
1363: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1364: object.
1.9 ihickson 1365: </dl>
1366:
1.50 ihickson 1367: <h4 id=shared0><span class=secno>2.1.3 </span>Shared workers and the
1368: <code><a
1369: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1370: inteface</h4>
1.77 ! ihickson 1371: <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1.50 ihickson 1372:
1373: <pre
1.77 ! ihickson 1374: class=idl>[NoInterfaceObject, XXX] interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href="#workerglobalscope">WorkerGlobalScope</a> {
1.50 ihickson 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: <p><span title="jump to a code entry-point">Jump</span> to the <span
1625: title=concept-script>script</span>'s <i>initial code entry-point</i>,
1626: and let that run until it either returns, fails to catch an exception,
1627: or gets prematurely aborted by the "<a href="#kill-a">kill a worker</a>"
1628: or "<a href="#terminate">terminate a worker</a>" algorithms defined
1629: below.</p>
1.7 ihickson 1630:
1631: <p class=note>If the script gets aborted by the "<a href="#kill-a">kill a
1632: worker</a>" algorithm, then that same algorithm will cause there to only
1.68 ihickson 1633: be a single <span title=concept-task>task</span> in the <span>event
1634: loop</span> at the next step, namely the task for the <code
1635: title=message-close>close</code> event. The "<a
1636: href="#terminate">terminate a worker</a>" algorithm removes all the
1.50 ihickson 1637: events.</p>
1.4 ihickson 1638:
1639: <li>
1.68 ihickson 1640: <p><i title="">Event loop</i>: Wait until either there is a <span
1641: title=concept-task>task</span> in one of the <span>event loop</span>'s
1642: <span title="task queue">task queues</span> or <var title="">worker
1643: global scope</var>'s <a href="#closing"
1644: title=dom-WorkerGlobalScope-closing>closing</a> flag is set to true.</p>
1645:
1646: <li>
1647: <p>Run the oldest task on one of the <span>event loop</span>'s <span
1648: title="task queue">task queues</span>, if any. The user agent may pick
1649: any <span>task queue</span>.</p>
1650:
1651: <p class=note>The handling of events or the execution of callbacks might
1652: get prematurely aborted by the "<a href="#kill-a">kill a worker</a>" or
1653: "<a href="#terminate">terminate a worker</a>" algorithms defined below.</p>
1.4 ihickson 1654:
1655: <li>
1.68 ihickson 1656: <p>Remove the task run in the previous step, if any, from its <span>task
1657: queue</span>.</p>
1.4 ihickson 1658:
1659: <li>
1.68 ihickson 1660: <p>If there are any more events in the <span>event loop</span>'s <span
1661: title="task queue">task queues</span> or if <var title="">worker global
1662: scope</var>'s <a href="#closing"
1663: title=dom-WorkerGlobalScope-closing>closing</a> flag is set to false,
1664: then jump back to the step above labeled <i>event loop</i>.</p>
1.4 ihickson 1665:
1666: <li>
1.68 ihickson 1667: <p>Freeze the <span>script group</span>.</p>
1668:
1669: <p class=note>This kills timers, database transactions, etc.</p>
1.43 ihickson 1670:
1671: <li>
1.68 ihickson 1672: <p>For each <code><a href="#worker1">Worker</a></code> or <code><a
1673: href="#sharedworker">SharedWorker</a></code> object associated with <var
1674: title="">worker global scope</var>, <span>queue a task</span> to
1675: <span>fire a simple event</span> called <code
1676: title=event-close>close</code> at that object.</p>
1.4 ihickson 1677: </ol>
1678:
1679: <hr>
1680:
1.50 ihickson 1681: <p>When a user agent is to <dfn id=kill-a>kill a worker</dfn> it must run
1.4 ihickson 1682: the following steps in parallel with the worker's main loop (the "<a
1683: href="#run-a">run a worker</a>" processing model defined above):
1684:
1685: <ol>
1686: <li>
1.69 ihickson 1687: <p>If the worker's <code><a
1688: href="#workerglobalscope">WorkerGlobalScope</a></code> object's <a
1689: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag is
1690: false, <span>queue a task</span> to <span>fire a simple event</span>
1691: called <code title=event-close>close</code> at the worker's <code><a
1.68 ihickson 1692: href="#workerglobalscope">WorkerGlobalScope</a></code> object.
1.4 ihickson 1693:
1694: <li>
1.26 ihickson 1695: <p>Set the worker's <code><a
1.50 ihickson 1696: href="#workerglobalscope">WorkerGlobalScope</a></code> object's <a
1697: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag to
1698: true.
1.8 ihickson 1699:
1700: <li>
1701: <p>Wait a user-agent-defined amount of time. If the "<a href="#run-a">run
1702: a worker</a>" processing model defined above immediately starts running
1.50 ihickson 1703: event listeners registered for the <code title=event-close>close</code>
1704: event, this time should not be zero — the idea is that the <code
1705: title=event-close>close</code> event can be used to clean up when
1706: shutting down unexpectedly.
1.4 ihickson 1707:
1708: <li>
1.68 ihickson 1709: <p>If there are any <span title=concept-task>tasks</span> queued in the
1710: <span>event loop</span>'s <span title="task queue">task queues</span>
1.50 ihickson 1711: other than the <code title=event-close>close</code> event that this
1.68 ihickson 1712: algorithm just added, discard them without processing them.
1.4 ihickson 1713:
1714: <li>
1.50 ihickson 1715: <p>If the <code title=event-close>close</code> event that this algorithm
1.68 ihickson 1716: just queued hasn't yet been dispatched, then abort the script currently
1.50 ihickson 1717: running in the worker.
1.4 ihickson 1718:
1719: <li>
1720: <p>Wait a user-agent-defined amount of time.
1721:
1722: <li>
1723: <p>Abort the script currently running in the worker (if any script is
1724: running, then it will be a handler for the <code
1.50 ihickson 1725: title=event-close>close</code> event).
1.4 ihickson 1726: </ol>
1727:
1.19 ihickson 1728: <p>User agents may invoke the "<a href="#kill-a">kill a worker</a>"
1729: processing model on a worker at any time, e.g. in response to user
1730: requests, in response to CPU quota management, or when a worker stops
1.38 ihickson 1731: being an <a href="#active">active needed worker</a> if the worker
1.50 ihickson 1732: continues executing even after its <a href="#closing"
1733: title=dom-WorkerGlobalScope-closing>closing</a> flag was set to true.
1.19 ihickson 1734:
1.8 ihickson 1735: <hr>
1736:
1.50 ihickson 1737: <p>When a user agent is to <dfn id=terminate>terminate a worker</dfn> it
1738: must run the following steps in parallel with the worker's main loop (the
1739: "<a href="#run-a">run a worker</a>" processing model defined above):
1.8 ihickson 1740:
1741: <ol>
1742: <li>
1.50 ihickson 1743: <p>Set the worker's <code><a
1.26 ihickson 1744: href="#workerglobalscope">WorkerGlobalScope</a></code> object's <a
1.50 ihickson 1745: href="#closing" title=dom-WorkerGlobalScope-closing>closing</a> flag to
1746: true.
1.8 ihickson 1747:
1748: <li>
1.68 ihickson 1749: <p>If there are any <span title=concept-task>tasks</span> queued in the
1750: <span>event loop</span>'s <span title="task queue">task queues</span>,
1751: discard them without processing them.
1.8 ihickson 1752:
1753: <li>
1.50 ihickson 1754: <p>Abort the script currently running in the worker.
1.71 ihickson 1755:
1756: <li>
1757: <p>If the worker's <code><a
1758: href="#workerglobalscope">WorkerGlobalScope</a></code> object is
1759: actually a <code><a
1760: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1761: object (i.e. the worker is a dedicated worker), then empty the
1762: <span>port message queue</span> of the port that the worker's implicit
1763: port is entangled with.
1.8 ihickson 1764: </ol>
1765:
1.74 ihickson 1766: <h4 id=runtime><span class=secno>2.5.1 </span>Runtime script errors</h4>
1767:
1768: <p>Whenever a runtime script error occurs in one of the worker's scripts,
1769: the user agent must <span>report the error</span> using the <code
1770: title=handler-WorkerGlobalScope-onerror><a
1771: href="#onerror">onerror</a></code> <span title="event handler DOM
1772: attributes">event handler DOM attribute</span> of the <code><a
1773: href="#workerglobalscope">WorkerGlobalScope</a></code> object.
1774:
1775: <p>For shared workers, if the error is still <i title="">not handled</i>
1776: afterwards, the error should be reported to the user.
1777:
1778: <p>For dedicated workers, if the error is still <i title="">not handled</i>
1779: afterwards, <span>queue a task</span> to <a href="#fire-an">fire an error
1780: event</a> at the <code><a href="#worker1">Worker</a></code> object
1781: associated with the worker.
1782:
1783: <p>When the user agent is to <dfn id=fire-an>fire an error event</dfn> at a
1784: <code><a href="#worker1">Worker</a></code> object, it must dispatch an
1785: event that uses the <code><a href="#errorevent">ErrorEvent</a></code>
1786: interface, with the name <code title=event-error>error</code>, that
1787: doesn't bubble and is cancelable, with its <code
1788: title=dom-ErrorEvent-message><a href="#message">message</a></code>, <code
1789: title=dom-ErrorEvent-filename><a href="#filename">filename</a></code>, and
1.76 ihickson 1790: <code title=dom-ErrorEvent-lineno><a href="#lineno">lineno</a></code>
1791: attributes set appropriately. The default action of this event depends on
1792: whether the <code><a href="#worker1">Worker</a></code> object is itself in
1793: a worker. If it is, and that worker is also a dedicated worker, then the
1794: user agent must again <span>queue a task</span> to <a href="#fire-an">fire
1795: an error event</a> at the <code><a href="#worker1">Worker</a></code>
1796: object associated with <em>that</em> worker. Otherwise, then the error
1797: should be reported to the user.
1.74 ihickson 1798:
1799: <hr>
1800:
1801: <pre class=idl>interface <dfn id=errorevent>ErrorEvent</dfn> : Event {
1802: readonly attribute DOMObject <a href="#message" title=dom-ErrorEvent-message>message</a>;
1803: readonly attribute DOMObject <a href="#filename" title=dom-ErrorEvent-filename>filename</a>;
1.76 ihickson 1804: readonly attribute unsigned long <a href="#lineno" title=dom-ErrorEvent-lineno>lineno</a>;
1805: void <a href="#initerrorevent" title=dom-ErrorEvent-initErrorEvent>initErrorEvent</a>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMObject messageArg, in DOMObject filenameArg, in unsigned long linenoArg);
1806: void <a href="#initerroreventns" title=dom-ErrorEvent-initErrorEventNS>initErrorEventNS</a>(in DOMString namespaceURIArg, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMObject messageArg, in DOMObject filenameArg, in unsigned long linenoArg);
1.74 ihickson 1807: };</pre>
1808:
1809: <p>The <dfn id=initerrorevent
1810: title=dom-ErrorEvent-initErrorEvent><code>initErrorEvent()</code></dfn>
1811: and <dfn id=initerroreventns
1812: title=dom-ErrorEvent-initErrorEventNS><code>initErrorEventNS()</code></dfn>
1813: methods must initialize the event in a manner analogous to the
1814: similarly-named methods in the DOM3 Events interfaces. <a
1815: href="#refsDOM3EVENTS">[DOM3EVENTS]</a>
1816:
1817: <p>The <dfn id=message
1818: title=dom-ErrorEvent-message><code>message</code></dfn> attribute
1819: represents the error message.
1820:
1821: <p>The <dfn id=filename
1822: title=dom-ErrorEvent-filename><code>filename</code></dfn> attribute
1823: represents the <span>absolute URL</span> of the script in which the error
1824: originally occured.
1825:
1.76 ihickson 1826: <p>The <dfn id=lineno title=dom-ErrorEvent-lineno><code>lineno</code></dfn>
1.74 ihickson 1827: attribute represents the line number where the error occured in the
1828: script.
1829:
1.15 ihickson 1830: <h3 id=creating><span class=secno>2.6 </span>Creating workers</h3>
1.5 ihickson 1831:
1.50 ihickson 1832: <h4 id=the-abstractworker><span class=secno>2.6.1 </span>The <code><a
1833: href="#abstractworker">AbstractWorker</a></code> abstract interface</h4>
1834:
1.77 ! ihickson 1835: <pre class=idl>interface <dfn id=abstractworker>AbstractWorker</dfn> {
1.74 ihickson 1836: attribute <span>EventListener</span> <a href="#onerror0" title=handler-AbstractWorker-onerror>onerror</a>;
1.50 ihickson 1837: attribute <span>EventListener</span> <a href="#onclose0" title=handler-AbstractWorker-onclose>onclose</a>;
1838: };</pre>
1839:
1.60 ihickson 1840: <p>Objects implementing the <code><a
1841: href="#abstractworker">AbstractWorker</a></code> interface must also
1842: implement the <code>EventTarget</code> interface.
1843:
1.50 ihickson 1844: <p>The following are the <span>event handler DOM attributes</span> that
1845: must be supported by objects implementing the <code><a
1846: href="#abstractworker">AbstractWorker</a></code> interface:
1847:
1848: <dl>
1.74 ihickson 1849: <dt><dfn id=onerror0
1.50 ihickson 1850: title=handler-AbstractWorker-onerror><code>onerror</code></dfn>
1851:
1852: <dd>
1853: <p>Must be invoked whenever an <code title=event-error>error</code> event
1854: is targeted at or bubbles through the <code><a
1855: href="#abstractworker">AbstractWorker</a></code> object.
1856:
1857: <dt><dfn id=onclose0
1858: title=handler-AbstractWorker-onclose><code>onclose</code></dfn>
1859:
1860: <dd>
1861: <p>Must be invoked whenever an <code title=event-close>close</code> event
1862: is targeted at or bubbles through the <code><a
1863: href="#abstractworker">AbstractWorker</a></code> object.
1864: </dl>
1.43 ihickson 1865:
1.50 ihickson 1866: <h4 id=dedicated0><span class=secno>2.6.2 </span>Dedicated workers and the
1867: <code><a href="#worker1">Worker</a></code> interface</h4>
1.43 ihickson 1868:
1.77 ! ihickson 1869: <pre
! 1870: class=idl>[<a href="#worker2" title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
1.50 ihickson 1871: interface <dfn id=worker1>Worker</dfn> : <a href="#abstractworker">AbstractWorker</a> {
1.56 ihickson 1872: void <a href="#terminate0" title=dom-Worker-terminate>terminate</a>();
1.50 ihickson 1873:
1.77 ! ihickson 1874: void <a href="#postmessage0" title=dom-Worker-postMessage>postMessage</a>(in any message, [Optional] in <span>MessagePort</span> messagePort);<!--
! 1875: <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
1.50 ihickson 1876: attribute <span>EventListener</span> <a href="#onmessage0" title=handler-Worker-onmessage>onmessage</a>;
1.5 ihickson 1877: };</pre>
1878:
1.56 ihickson 1879: <p>The <dfn id=terminate0
1880: title=dom-Worker-terminate><code>terminate()</code></dfn> method, when
1881: invoked, must cause the "<a href="#terminate">terminate a worker</a>"
1882: algorithm to be run on the worker with with the object is associated.
1.50 ihickson 1883:
1884: <p><code><a href="#worker1">Worker</a></code> objects act as if they had an
1885: implicit <code>MessagePort</code> associated with them. This port is part
1886: of a channel that is set up when the worker is created, but it is not
1887: exposed. This object must never be garbage collected before the <code><a
1888: href="#worker1">Worker</a></code> object.
1889:
1890: <p>All messages received by that port must immediately be retargetted at
1891: the <code><a href="#worker1">Worker</a></code> object.
1892:
1893: <p>The <dfn id=postmessage0
1.64 ihickson 1894: title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
1895: and <dfn
1896: title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
1897: method<!--s (startConversation)--> on <code><a
1898: href="#worker1">Worker</a></code> objects must act as if, when invoked,
1899: it<!--/they (startConversation)--> immediately invoked the method of the
1900: same name on the port, with the same arguments, and returned the same
1901: return value.
1.50 ihickson 1902:
1903: <p>The following are the <span>event handler DOM attributes</span> that
1904: must be supported by objects implementing the <code><a
1905: href="#worker1">Worker</a></code> interface:
1906:
1907: <dl>
1908: <dt><dfn id=onmessage0
1909: title=handler-Worker-onmessage><code>onmessage</code></dfn>
1910:
1911: <dd>
1912: <p>Must be invoked whenever a <code
1913: title=event-Worker-message>message</code> event is targeted at or
1914: bubbles through the <code><a href="#worker1">Worker</a></code> object.
1915: </dl>
1.5 ihickson 1916:
1.9 ihickson 1917: <hr>
1918:
1.50 ihickson 1919: <p>When the <dfn id=worker2 title=dom-Worker><code>Worker(<var
1920: title="">scriptURL</var>)</code></dfn> constructor is invoked, the user
1921: agent must run the following steps:
1.9 ihickson 1922:
1923: <ol>
1924: <li>
1925: <p><span title="resolve a url">Resolve</span> the <var
1926: title="">scriptURL</var> argument.
1927:
1928: <li>
1929: <p>If this fails, throw a <code>SYNTAX_ERR</code> exception.
1930:
1931: <li>
1932: <p>If the <span>origin</span> of the resulting <span>absolute URL</span>
1933: is not the <span title="same origin">same</span> as the origin of the
1.50 ihickson 1934: script that invoked the constructor, then throw a <span>security
1.9 ihickson 1935: exception</span>.
1936:
1937: <li>
1.50 ihickson 1938: <p><span>Create a new <code><a
1939: href="#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</a></code>
1.68 ihickson 1940: object</span>. Let <var title="">worker global scope</var> be this new
1941: object.
1.50 ihickson 1942:
1943: <li>
1944: <p>Create a new <code><a href="#worker1">Worker</a></code> object,
1.68 ihickson 1945: associated with <var title="">worker global scope</var>. Let <var
1946: title="">worker</var> be this new object.
1.9 ihickson 1947:
1948: <li>
1.50 ihickson 1949: <p><span>Create a <code>MessagePort</code> object</span> owned by the
1950: <span>script execution context</span> of the script that invoked the
1951: method. Let this be the <var title="">outside port</var>.
1952:
1953: <li>
1954: <p>Associate the <var title="">outside port</var> with <var
1955: title="">worker</var>.
1956:
1957: <li>
1.68 ihickson 1958: <p><span>Create a <code>MessagePort</code> object</span> owned by <var
1959: title="">worker global scope</var>. Let <var title="">inside port</var>
1960: be this new object.
1.50 ihickson 1961:
1962: <li>
1.68 ihickson 1963: <p>Associate <var title="">inside port</var> with <var title="">worker
1964: global scope</var>.
1.50 ihickson 1965:
1966: <li>
1967: <p><span>Entangle</span> <var title="">outside port</var> and <var
1968: title="">inside port</var>.
1969:
1970: <li>
1971: <p>Return <var title="">worker</var>, and run the following steps
1972: asynchronously.
1973:
1974: <li>
1975: <p>Open <var title="">inside port</var>'s <span>port message
1976: queue</span>.
1977:
1978: <li>
1.51 ihickson 1979: <p>Open <var title="">outside port</var>'s <span>port message
1980: queue</span>.
1981:
1982: <li>
1.68 ihickson 1983: <p><a href="#run-a">Run a worker</a> for the resulting <span>absolute
1984: URL</span>, with the <span>script browsing context</span> of the script
1985: that invoked the method as the <var title="">owner browsing
1986: context</var>, and with <var title="">worker global scope</var> as the
1987: global scope.</p>
1.9 ihickson 1988: </ol>
1989:
1.50 ihickson 1990: <h4 id=shared1><span class=secno>2.6.3 </span>Shared workers and the
1991: <code><a href="#sharedworker">SharedWorker</a></code> interface</h4>
1.9 ihickson 1992:
1.77 ! ihickson 1993: <pre
! 1994: class=idl>[<a href="#sharedworker0" title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in DOMString name)]
1.50 ihickson 1995: interface <dfn id=sharedworker>SharedWorker</dfn> : <a href="#abstractworker">AbstractWorker</a> {
1996: readonly attribute <code>MessagePort</code> <a href="#port" title=dom-SharedWorker-port>port</a>;
1997: };</pre>
1998:
1999: <p>The <dfn id=port title=dom-SharedWorker-port><code>port</code></dfn>
2000: attribute must return the value it was assigned by the object's
2001: constructor. It represents the <code>MessagePort</code> for communicating
2002: with the shared worker.
2003:
2004: <p>When the <dfn id=sharedworker0
2005: title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>,
2006: <var title="">name</var>)</code></dfn> constructor is invoked, the user
2007: agent must run the following steps:
1.9 ihickson 2008:
2009: <ol>
2010: <li>
2011: <p><span title="resolve a url">Resolve</span> the <var
2012: title="">scriptURL</var> argument.
1.4 ihickson 2013:
1.9 ihickson 2014: <li>
2015: <p>If this fails, throw a <code>SYNTAX_ERR</code> exception.
2016:
2017: <li>
2018: <p>If the <span>origin</span> of the resulting <span>absolute URL</span>
2019: is not the <span title="same origin">same</span> as the origin of the
1.50 ihickson 2020: script that invoked the constructor, then throw a <span>security
1.9 ihickson 2021: exception</span>.
2022:
2023: <li>
1.50 ihickson 2024: <p>Execute the following substeps atomically:</p>
1.9 ihickson 2025:
2026: <ol>
2027: <li>
1.50 ihickson 2028: <p>Create a new <code><a href="#sharedworker">SharedWorker</a></code>
2029: object, which will shortly be associated with a <code><a
2030: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
2031: object. Let this <code><a href="#sharedworker">SharedWorker</a></code>
2032: object be <var title="">worker</var>.
1.9 ihickson 2033:
2034: <li>
1.50 ihickson 2035: <p><span>Create a <code>MessagePort</code> object</span> owned by the
2036: <span>script execution context</span> of the script that invoked the
2037: method. Let this be the <var title="">outside port</var>.
1.9 ihickson 2038:
2039: <li>
1.50 ihickson 2040: <p>Assign <var title="">outside port</var> to the <code
2041: title=dom-SharedWorker-port><a href="#port">port</a></code> attribute
2042: of <var title="">worker</var>.
1.43 ihickson 2043:
2044: <li>
1.50 ihickson 2045: <p>If there exists a <code><a
2046: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
2047: object whose <a href="#closing"
2048: title=dom-WorkerGlobalScope-closing>closing</a> flag is false, whose
2049: <code title=dom-WorkerGlobalScope-name>name</code> attribute is
2050: exactly equal to the <var title="">name</var> argument, and whose
2051: <code title=dom-WorkerGlobalScope-location><a
2052: href="#location">location</a></code> attribute represents an
2053: <span>absolute URL</span> that has the <span>same origin</span> as the
2054: resulting <span>absolute URL</span>, then run these substeps:</p>
2055:
2056: <ol>
2057: <li>
2058: <p>Let <var title="">worker global scope</var> be that <code><a
2059: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
2060: object.
2061:
2062: <li>
2063: <p>If <var title="">worker global scope</var>'s <code
2064: title=dom-WorkerGlobalScope-location><a
2065: href="#location">location</a></code> attribute represents an
2066: <span>absolute URL</span> that is not exactly equal to the resulting
2067: <span>absolute URL</span>, then throw a
2068: <code>URL_MISMATCH_ERR</code> exception and abort all these steps.
2069: <span class=big-issue>code 21</span>
2070:
2071: <li>
2072: <p>Associate <var title="">worker</var> with <var title="">worker
2073: global scope</var>.
2074:
2075: <li>
1.68 ihickson 2076: <p><span>Create a <code>MessagePort</code> object</span> owned by
1.50 ihickson 2077: <var title="">worker global scope</var>. Let this be the <var
2078: title="">inside port</var>.
2079:
2080: <li>
2081: <p><span>Entangle</span> <var title="">outside port</var> and <var
2082: title="">inside port</var>.
2083:
2084: <li>
2085: <p>Return <var title="">worker</var> and perform the next step
2086: asynchronously.
2087:
2088: <li>
2089: <p>Create an event that uses the <code>MessageEvent</code> interface,
2090: with the name <code title=event-connect>connect</code>, which does
2091: not bubble, is cancelable, has no default action, has a <code
2092: title=dom-MessageEvent-data>data</code> attribute whose value is the
2093: empty string and has a <code
2094: title=dom-MessageEvent-messagePort>messagePort</code> attribute
1.68 ihickson 2095: whose value is the newly created port, and <span>queue a task</span>
2096: to dispatch the event at <var title="">worker global scope</var>.
1.50 ihickson 2097:
2098: <li>
2099: <p>Abort all these steps.
2100: </ol>
1.9 ihickson 2101:
2102: <li>
1.50 ihickson 2103: <p><span>Create a new <code><a
2104: href="#sharedworkerglobalscope">SharedWorkerGlobalScope</a></code>
1.68 ihickson 2105: object</span>. Let <var title="">worker global scope</var> be this new
2106: object.
1.9 ihickson 2107:
1.50 ihickson 2108: <li>
2109: <p>Associate <var title="">worker</var> with <var title="">worker
2110: global scope</var>.
1.9 ihickson 2111:
1.50 ihickson 2112: <li>
2113: <p>Set the <code title=dom-SharedWorkerGlobalScope-name><a
2114: href="#name">name</a></code> attribute of <var title="">worker global
1.68 ihickson 2115: scope</var> to <var title="">name</var>.
1.9 ihickson 2116:
1.50 ihickson 2117: <li>
1.68 ihickson 2118: <p><span>Create a <code>MessagePort</code> object</span> owned by <var
2119: title="">worker global scope</var>. Let <var title="">inside
2120: port</var> be this new object.
1.9 ihickson 2121:
1.50 ihickson 2122: <li>
2123: <p><span>Entangle</span> <var title="">outside port</var> and <var
2124: title="">inside port</var>.
2125: </ol>
1.9 ihickson 2126:
2127: <li>
1.50 ihickson 2128: <p>Return <var title="">worker</var> and perform the next step
2129: asynchronously.
1.9 ihickson 2130:
2131: <li>
2132: <p>Create an event that uses the <code>MessageEvent</code> interface,
1.20 ihickson 2133: with the name <code title=event-connect>connect</code>, which does not
1.9 ihickson 2134: bubble, is cancelable, has no default action, has a <code
2135: title=dom-MessageEvent-data>data</code> attribute whose value is the
2136: empty string and has a <code
2137: title=dom-MessageEvent-messagePort>messagePort</code> attribute whose
1.68 ihickson 2138: value is the newly created port, and <span>queue a task</span> to
2139: dispatch the event at <var title="">worker global scope</var>.
1.28 ihickson 2140:
2141: <li>
1.68 ihickson 2142: <p><a href="#run-a">Run a worker</a> for the resulting <span>absolute
2143: URL</span>, with the <span>script browsing context</span> of the script
2144: that invoked the method as the <var title="">owner browsing
2145: context</var>, and with <var title="">worker global scope</var> as the
2146: global scope.</p>
1.9 ihickson 2147: </ol>
1.7 ihickson 2148:
1.77 ! ihickson 2149: <h2 id=apis-available><span class=secno>3 </span>APIs available to workers</h2>
! 2150: <!-- the XXX below is for collapsing this interface onto WorkerGlobalScope so it looks like just one interface - the inheritance is a spec fiction only -->
1.12 ihickson 2151:
1.26 ihickson 2152: <pre
1.77 ! ihickson 2153: class=idl>[NoInterfaceObject, ImplementedOn=WorkerGlobalScope, XXX] interface <dfn id=workerutils>WorkerUtils</dfn> {
1.46 ihickson 2154: void <a href="#importscripts" title=dom-WorkerGlobalScope-importScripts>importScripts</a>([Variadic] in DOMString urls);
1.26 ihickson 2155: readonly attribute <span>Storage</span> <a href="#localstorage" title=dom-localStorage>localStorage</a>;
1.61 ihickson 2156: readonly attribute <a href="#navigator0">Navigator</a> <a href="#navigator" title=dom-navigator>navigator</a>;
1.77 ! ihickson 2157: <span>Database</span> <a href="#opendatabase" title=dom-opendatabase>openDatabase</a>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);<!--
! 2158: void <span title="dom-showNotification">showNotification</span>(in DOMString title, in DOMString subtitle, in DOMString description, [Optional] in VoidCallback onclick); XXX-NOTIFY -->
1.26 ihickson 2159: };</pre>
1.18 ihickson 2160:
1.12 ihickson 2161: <p>Objects that implement the <code><a
1.42 ihickson 2162: href="#workerglobalscope">WorkerGlobalScope</a></code> interface must also
2163: implement the <code><a href="#workerutils">WorkerUtils</a></code>
2164: interface.
1.12 ihickson 2165:
1.62 ihickson 2166: <p>Objects that implement the <code><a
2167: href="#workerutils">WorkerUtils</a></code> interface must also implement
2168: the <code>WindowTimers</code> interface. (This interface provides the
2169: <code title="">setTimeout()</code> method and its friends.)
2170:
1.61 ihickson 2171: <p class=big-issue>Need to define a sync database API.</p>
1.18 ihickson 2172: <!-- XXX ApplicationCache -->
2173: <!-- XXX a way to set cookies on the URL for the script -->
1.24 ihickson 2174: <!-- XXX debugging: void log(in DOMString s); // log to console -->
2175: <!-- XXX debugging: onerror -->
1.13 ihickson 2176:
1.18 ihickson 2177: <hr>
1.13 ihickson 2178:
1.18 ihickson 2179: <p>The DOM APIs (<code>Node</code> objects, <code>Document</code> objects,
2180: etc) are not available to workers in this version of this specification.
1.13 ihickson 2181:
1.26 ihickson 2182: <h3 id=importing><span class=secno>3.1 </span>Importing scripts and
2183: libraries</h3>
2184:
1.45 ihickson 2185: <p>When a script invokes the <dfn id=importscripts
2186: title=dom-WorkerGlobalScope-importScripts><code>importScripts(<var
2187: title="">urls</var>)</code></dfn> method on a <code><a
1.26 ihickson 2188: href="#workerglobalscope">WorkerGlobalScope</a></code> object, the user
2189: agent must run the following steps:
2190:
2191: <ol>
2192: <li>
1.46 ihickson 2193: <p>If there are no arguments, return without doing anything. Abort these
2194: steps.
2195:
2196: <li>
1.45 ihickson 2197: <p><span title="resolve a url">Resolve</span> each argument.
1.26 ihickson 2198:
2199: <li>
1.45 ihickson 2200: <p>If any fail, throw a <code>SYNTAX_ERR</code> exception.
1.60 ihickson 2201: </li>
1.67 ihickson 2202: <!--
2203: <li><p>If any of the resulting <span title="absolute URL">absolute
2204: URLs</span> have an <span>origin</span> that is not the <span
2205: title="same origin">same</span> as the origin of the script that
2206: invoked the method, then throw a <span>security
2207: exception</span>.</p></li>
2208: -->
1.26 ihickson 2209:
2210: <li>
1.45 ihickson 2211: <p>Attempt to <span>fetch</span> each resource identified by the
2212: resulting <span title="absolute URLs">absolute URL</span>.</p>
1.26 ihickson 2213:
2214: <li>
1.45 ihickson 2215: <p>For each argument in turn, in the order given, starting with the first
2216: one, run these substeps:</p>
1.26 ihickson 2217:
1.45 ihickson 2218: <ol>
2219: <li>
2220: <p>Wait for the fetching attempt for the corresponding resource to
2221: complete.</p>
1.26 ihickson 2222:
1.46 ihickson 2223: <p>If the fetching attempt failed, throw a <code>NETWORK_ERR</code>
1.68 ihickson 2224: exception and abort all these steps.</p>
1.26 ihickson 2225:
1.45 ihickson 2226: <p>If the fetching attempt succeeded, then let <var
1.68 ihickson 2227: title="">source</var> be the text of the resource that was obtained,
2228: and let <var title="">language</var> be JavaScript.</p>
1.26 ihickson 2229:
1.45 ihickson 2230: <p class=note>As with the worker's script, the script here is always
2231: assumed to be JavaScript, regardless of the MIME type.</p>
2232: <!-- XXX -->
1.26 ihickson 2233:
1.45 ihickson 2234: <li>
1.68 ihickson 2235: <p><span>Create a script</span>, using <var title="">source</var> as
2236: the script source and <var title="">language</var> as the scripting
2237: language, using the same global object, browsing context, character
2238: encoding, base URL, and script group as the <span
2239: title=concept-script>script</span> that was created by the worker's <a
2240: href="#run-a">run a worker</a> algorithm.</p>
2241:
2242: <p>Let the newly created <span title=concept-script>script</span> run
2243: until it either returns, fails to parse, fails to catch an exception,
2244: or gets prematurely aborted by the "<a href="#kill-a">kill a
2245: worker</a>" or "<a href="#terminate">terminate a worker</a>"
2246: algorithms defined above.</p>
1.60 ihickson 2247:
2248: <p>If it failed to parse, then throw a
2249: <code>SyntaxError</code><!-- XXX ref? --> exception and abort all
2250: these steps.</p>
1.45 ihickson 2251:
2252: <p>If an exception was raised or if the script was prematurely aborted,
2253: then abort all these steps, letting the exception or aborting continue
2254: to be processed by the script that called the <code
2255: title=dom-WorkerGlobalScope-importScripts><a
2256: href="#importscripts">importScripts()</a></code> method.</p>
2257:
1.50 ihickson 2258: <p>If the "<a href="#kill-a">kill a worker</a>" or "<a
1.59 ihickson 2259: href="#terminate">terminate a worker</a>" algorithms abort the script
1.50 ihickson 2260: then abort all these steps.</p>
1.45 ihickson 2261: </ol>
1.26 ihickson 2262: </ol>
2263:
1.61 ihickson 2264: <h3 id=the-navigator><span class=secno>3.2 </span>The <code><a
2265: href="#navigator0">Navigator</a></code> object</h3>
2266:
2267: <p>The <dfn id=navigator title=dom-navigator><code>navigator</code></dfn>
2268: attribute of the <code><a href="#workerutils">WorkerUtils</a></code>
2269: interface must return an instance of the <code><a
2270: href="#navigator0">Navigator</a></code> interface, which represents the
2271: identity and state of the user agent (the client):
2272:
1.77 ! ihickson 2273: <pre class=idl>interface <dfn id=navigator0>Navigator</dfn> {
1.61 ihickson 2274: // objects implementing this interface also implement the interfaces listed below
2275: };</pre>
2276:
2277: <p>Objects implementing the <code><a
2278: href="#navigator0">Navigator</a></code> interface must also implement the
2279: <span>NavigatorID</span> and <span>NavigatorOnLine</span> interfaces
2280: specified in the HTML5 specification. <a href="#refsHTML5">[HTML5]</a>
2281:
2282: <p class=note>The <code><a href="#navigator0">Navigator</a></code>
2283: interface defined in this specification is different than the one defined
2284: in the HTML5 specification.
2285:
2286: <h3 id=apis-defined><span class=secno>3.3 </span>APIs defined in other
1.26 ihickson 2287: specifications</h3>
2288:
1.27 ihickson 2289: <p>The <dfn id=localstorage
1.26 ihickson 2290: title=dom-localStorage><code>localStorage</code></dfn>, <dfn
2291: id=opendatabase title=dom-opendatabase><code>openDatabase()</code></dfn>
2292: must act as defined for the APIs with the same names on the
2293: <code>Window</code> object in the HTML5 specification, with the exception
2294: that where the API would use the <span>origin</span> of the <span>active
2295: document</span> of the <span>browsing context</span> of the
2296: <code>Window</code> object on which the method was supposedly invoked, it
2297: must instead use the <span>origin</span> of the script that invoked the
2298: method. <a href="#refsHTML5">[HTML5]</a>
2299:
2300: <p>The <dfn id=shownotification
2301: title=dom-showNotification><code>showNotification()</code></dfn> methods
2302: must act as defined for the APIs with the same names on the
2303: <code>Window</code> object in the HTML5 specification. <a
2304: href="#refsHTML5">[HTML5]</a>
2305:
1.61 ihickson 2306: <h3 id=interface><span class=secno>3.4 </span>Interface objects and
1.26 ihickson 2307: constructors</h3>
2308:
2309: <p>There must be no interface objects and constructors available in the
2310: global scope of scripts whose <span>script execution context</span> is a
2311: <code><a href="#workerglobalscope">WorkerGlobalScope</a></code> object
2312: except for the following:
2313:
2314: <ul>
2315: <li>
2316: <p><code>XMLHttpRequest</code> and all interface objects and constructors
2317: defined by the XMLHttpRequest specifications, except that the
2318: <span>document response entity body</span> must always be null. <a
2319: href="#refsXHR">[XHR]</a>
2320:
2321: <li>
2322: <p>The <code>WebSocket</code> interface object and constructor.
2323:
2324: <li>
2325: <p>The <code>MessageChannel</code> interface object and constructor.
1.63 ihickson 2326:
2327: <li>
2328: <p>The <code title=dom-Worker><a href="#worker2">Worker()</a></code> and
2329: <code title=dom-SharedWorker><a href="#sharedworker0">SharedWorker(<var
2330: title="">url</var>)</a></code> constructors.
1.26 ihickson 2331: </ul>
2332:
1.61 ihickson 2333: <h3 id=worker0><span class=secno>3.5 </span>Worker locations</h3>
1.34 ihickson 2334:
1.77 ! ihickson 2335: <pre class=idl>interface <dfn id=workerlocation>WorkerLocation</dfn> {
1.34 ihickson 2336: readonly attribute DOMString <a href="#href" title=dom-WorkerLocation-href>href</a>;
2337: readonly attribute DOMString <a href="#protocol" title=dom-WorkerLocation-protocol>protocol</a>;
2338: readonly attribute DOMString <a href="#host" title=dom-WorkerLocation-host>host</a>;
2339: readonly attribute DOMString <a href="#hostname" title=dom-WorkerLocation-hostname>hostname</a>;
1.50 ihickson 2340: readonly attribute DOMString <a href="#port0" title=dom-WorkerLocation-port>port</a>;
1.34 ihickson 2341: readonly attribute DOMString <a href="#pathname" title=dom-WorkerLocation-pathname>pathname</a>;
2342: readonly attribute DOMString <a href="#search" title=dom-WorkerLocation-search>search</a>;
2343: readonly attribute DOMString <a href="#hash" title=dom-WorkerLocation-hash>hash</a>;
2344: };</pre>
2345:
2346: <p>A <code><a href="#workerlocation">WorkerLocation</a></code> object
2347: represents an <span>absolute URL</span> set at its creation.
2348:
2349: <p>The <dfn id=href title=dom-WorkerLocation-href><code>href</code></dfn>
2350: attribute must return the <span>absolute URL</span> that the object
2351: represents.
2352:
2353: <p>The <code><a href="#workerlocation">WorkerLocation</a></code> interface
2354: also has the complement of <span>URL decomposition attributes</span>, <dfn
2355: id=protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
2356: <dfn id=host title=dom-WorkerLocation-host><code>host</code></dfn>, <dfn
1.50 ihickson 2357: id=port0 title=dom-WorkerLocation-port><code>port</code></dfn>, <dfn
1.34 ihickson 2358: id=hostname title=dom-WorkerLocation-hostname><code>hostname</code></dfn>,
2359: <dfn id=pathname
2360: title=dom-WorkerLocation-pathname><code>pathname</code></dfn>, <dfn
2361: id=search title=dom-WorkerLocation-search><code>search</code></dfn>, and
2362: <dfn id=hash title=dom-WorkerLocation-hash><code>hash</code></dfn>. These
2363: must follow the rules given for URL decomposition attributes, with the
2364: <span title=concept-uda-input>input</span> being the <span>absolute
2365: URL</span> that the object represents (same as the <code
2366: title=dom-WorkerLocation-href><a href="#href">href</a></code> attribute),
2367: and the <span title=concept-uda-setter>common setter action</span> being a
2368: no-op, since the attributes are defined to be readonly. <a
2369: href="#refsHTML5">[HTML5]</a>
2370:
1.1 ihickson 2371: <h2 class=no-num id=references>References</h2>
2372:
2373: <p class=big-issue>This section will be written in a future
2374: draft.<!--XXX-->
2375:
2376: <h2 class=no-num id=acknowledgements>Acknowledgements</h2>
2377: <!-- ACKS -->
2378:
1.72 ihickson 2379: <p>Thanks to Aaron Boodman,
2380: Алексей
2381: Проскуряков
1.75 ihickson 2382: (Alexey Proskuryakov), Ben Turner, Dmitry Titov, Jonas Sicking, Justin
2383: James, Kevin Hakanson, Maciej Stachowiak, Michael Nordman, Mike Smith, and
2384: Philip Taylor for their useful and substantial comments.
1.4 ihickson 2385:
2386: <p>Huge thanks to the whole Gears team, who pioneered this technology and
2387: whose experience has been a huge influence on this specification.
Webmaster