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

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

Webmaster