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

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

Webmaster