Annotation of html5/workers/Overview.html, revision 1.70

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

Webmaster