| SVN | Bug | Comment | Time (UTC) |
| 2 | | Fix minor editorial mistakes. | 2008-07-09 11:00 |
| 3 | | Title fix. | 2008-07-09 11:07 |
| 4 | | First pass at requirements. | 2008-07-10 01:10 |
| 5 | | First draft of the 'inside workers' section. | 2008-07-16 01:39 |
| 6 | | accidentally checked in debugging style rules | 2008-07-16 01:40 |
| 7 | | WindowWorkerCreators IDL | 2008-07-16 01:46 |
| 8 | | Workers can be named. | 2008-07-16 01:52 |
| 9 | | Actually fetch the script. | 2008-07-16 08:06 |
| 10 | | window.close() for a worker | 2008-07-17 01:27 |
| 11 | | Finish the basic processing model of workers. | 2008-07-18 01:11 |
| 12 | | capitalise correctly | 2008-07-18 01:11 |
| 13 | | make a shorter url available | 2008-07-18 01:12 |
| 14 | | xrefs | 2008-07-18 01:14 |
| 15 | | Start talking about APIs in workers. | 2008-07-18 01:25 |
| 16 | | Add some APIs. | 2008-07-18 08:10 |
| 17 | | Define import(url). | 2008-07-18 08:43 |
| 18 | | define base URLs and origins for workers. | 2008-07-18 08:51 |
| 19 | | typo | 2008-07-18 08:52 |
| 20 | | note where we are referencing html5 | 2008-07-18 09:03 |
| 21 | | minor correction | 2008-07-18 09:06 |
| 22 | | Workers created by workers still need to stop if the original browsing context goes away. | 2008-07-18 09:27 |
| 23 | | minor correction | 2008-07-18 09:29 |
| 24 | | even more minor correction to fix the earlier one | 2008-07-18 09:30 |
| 25 | | Make more APIs accessible to workers. | 2008-07-18 09:48 |
| 26 | | Allow 'kill a worker' to be run whenever; change /window/ to /worker/ in the 'run a worker' steps; mention that other algorithms than 'kill' can set 'closing' to true. | 2008-07-18 10:07 |
| 27 | | s/attach/connect/ (credit: pt) | 2008-07-18 10:10 |
| 28 | | uh duh, i know my alphabet. honest. | 2008-07-18 10:11 |
| 29 | | Remove requirements. (they're all handled now) | 2008-07-18 10:14 |
| 30 | | promote one popular request to a red box | 2008-07-18 10:20 |
| 31 | | we'll need onerror too at some point | 2008-07-18 10:31 |
| 32 | | grammar tweak | 2008-08-05 23:54 |
| 33 | | Remove all mention of Windows from inside workers. Move all APIs to the 'utils' object. | 2008-08-06 01:10 |
| 34 | | Rename import() to importScript(). | 2008-08-06 02:10 |
| 35 | | Remove mention of MessagePort.active; add worker.port; fix the algorithms to work with the new HTML5 definitions. | 2008-08-06 08:50 |
| 36 | | First example. | 2008-08-06 09:32 |
| 37 | | Define 'port' and cause all references to it to cross-reference. | 2008-08-06 09:43 |
| 38 | | Another example. | 2008-08-06 10:08 |
| 39 | | Stop using the 't' word. | 2008-08-06 10:09 |
| 40 | | New example. | 2008-08-06 11:02 |
| 41 | | Change from URL to Location. also, add some placeholders for more tutorials. | 2008-08-06 11:21 |
| 42 | | typo | 2008-08-06 11:26 |
| 43 | | Add another example. | 2008-08-06 22:09 |
| 44 | | typo | 2008-08-06 22:12 |
| 45 | | Update the lifetime of workers to be less surprising. | 2008-08-06 22:48 |
| 46 | | Oops, wrong object implemented EventTarget | 2008-08-06 22:51 |
| 47 | | Another example. | 2008-08-07 02:30 |
| 48 | | oops, missing line | 2008-08-07 02:32 |
| 49 | | Fold 'utils' into the global scope. | 2008-08-08 02:37 |
| 50 | | Introduce a Worker object. | 2008-08-08 04:13 |
| 51 | | Fire unload when the worker shuts down normally. | 2008-08-08 05:05 |
| 52 | | Change importScript() to importScripts() and allow it to take any number of arguments. | 2008-08-08 05:26 |
| 53 | | Make importScripts() throw on network error. | 2008-08-08 05:50 |
| 54 | | Rename createNamedWorker to createSharedWorker. | 2008-08-08 05:58 |
| 55 | | Play musical chairs with Anne's exception codes. | 2008-08-10 22:46 |
| 56 | | Another example with delegation. | 2008-08-14 23:33 |
| 57 | | First draft of updating the spec to the proposal here: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/015853.html | 2008-08-27 07:07 |
| 58 | | Make postMessage() return void. (credit: js) | 2008-08-27 09:49 |
| 59 | | Make it blazingly clear where the thread begins. (credit: jj) | 2008-08-27 09:55 |
| 60 | | Woops, error in the example. (credit: js) | 2008-08-27 23:17 |
| 61 | | Fix the examples to use 'data' instead of 'message'. | 2008-11-12 19:28 |
| 62 | | Describe the expected use cases and performance characteristics of workers. (credit: jj) | 2008-11-12 23:10 |
| 63 | | Rename Worker.close() to Worker.terminate(). | 2008-11-12 23:36 |
| 64 | | Ack for previous checkin. | 2008-11-12 23:36 |
| 65 | | typos | 2008-11-12 23:38 |
| 66 | | Clarify that the closing flag doesn't empty the queue. (credit: js) | 2008-11-12 23:48 |
| 67 | | Make importScripts() fire SyntaxError on error; and minor editorial mistakes. | 2008-11-13 01:08 |
| 68 | | Define self.navigator for workers | 2008-11-13 01:25 |
| 69 | | Add setTimeout() to workers. (credit: dt) | 2008-11-13 01:39 |
| 70 | | Add the ability to create workers from workers. (credit: dt) | 2008-11-13 01:41 |
| 71 | | Remove startConversation() for now, as it is distracting in the worker discussions. May return in some form later. | 2008-11-13 01:45 |
| 72 | | Comment out the bit about queued ports for now. | 2008-11-18 03:02 |
| 73 | | Fix a bug in an example; update the draft to match recent W3C bureaucracy changes. | 2008-11-20 00:10 |
| 74 | | Make importScripts() allow cross-origin script loads. | 2008-11-26 23:33 |
| 75 | | Terminology update to match recent HTML5 changes. | 2008-12-16 00:52 |
| 76 | | Drop MessagePort.onclose. | 2008-12-16 01:34 |
| 77 | | typo | 2008-12-16 06:40 |
| 78 | | Empty the worker's outgoing queue of pending messages when terminate() is called. (credit: ap) | 2008-12-16 10:47 |
| 79 | | acks for recent checkins | 2008-12-16 20:15 |
| 80 | | typo | 2008-12-16 20:15 |
| 81 | | Reporting script errors. (credit: js) | 2008-12-23 21:07 |
| 82 | | another ack for previous checkin | 2008-12-23 21:07 |
| 83 | | fix typos | 2008-12-27 23:24 |
| 84 | | Drag the IDL of Workers into 2009. | 2009-01-14 09:10 |
| 85 | | markup consistency | 2009-01-14 09:11 |
| 86 | | ack for previous checkin(s) | 2009-01-14 09:11 |
| 87 | | Simplify error handling in workers. | 2009-01-21 01:48 |
| 88 | | Change the way the Web Workers spec is generated. | 2009-03-20 08:36 |
| 89 | | Integrate the specs together a bit more, fix some legacy issues. | 2009-03-20 08:52 |
| 90 | | Change the term 'script's character encoding' to be less confusing. | 2009-03-20 20:04 |
| 91 | | postMessage() methods that take MessagePort objects now take MessagePortArray objects. | 2009-03-20 21:09 |
| 94 | | Define how to determine the character encoding of worker scripts. | 2009-03-20 22:29 |
| 96 | | Rename attributes for form submission to avoid clashes with existing usage. | 2009-03-21 06:36 |
| 99 | | Fix some headers and text/plain cross-reference issues. | 2009-03-23 18:24 |
| 101 | | Remove localStorage from Workers for now. | 2009-03-23 23:57 |
| 102 | | Remove the commented-out notification API. | 2009-03-24 02:18 |
| 106 | | xref fixes for the merged spec | 2009-03-24 08:23 |
| 110 | | SVG in text/html: Second try, based on more recent feedback. | 2009-03-25 00:35 |
| 118 | | Implicitly open the port message queue of dedicated workers. (Before, they would never actually receive messages, oops...) | 2009-03-25 23:08 |
| 119 | | ack for last checkin | 2009-03-25 23:22 |
| 120 | | update refs for web workers, given the recent spec splits | 2009-03-25 23:57 |
| 121 | | Rename navigator.releaseLocks() to navigator.getStorageUpdates(); make the network layer's seting of cookies grab the lock. | 2009-03-26 00:42 |
| 124 | | tweak header levels; remove obsolete issue marker | 2009-03-27 00:13 |
| 125 | | this was a test and it should have not been submitted. | 2009-03-27 01:09 |
| 126 | | Define the interaction of the appcache feature and the workers feature. | 2009-03-28 01:24 |
| 127 | | Tighten up the definitions of event handler attributes. (bug 6490) | 2009-03-31 23:44 |
| 128 | | Refer to ECMAScript as JavaScript more consistently; add the various MIME types that JavaScript is sometimes known as. | 2009-04-02 00:49 |
| 129 | | Set the stage for a synchronous Database API. | 2009-04-02 21:32 |
| 130 | | Typos: round 1. | 2009-04-18 06:33 |
| 131 | | Typos: round 3. | 2009-04-19 00:17 |
| 132 | | Typos: round 4. | 2009-04-19 00:32 |
| 133 | | Typos: round 6. | 2009-04-19 20:56 |
| 134 | | W3C policy: fear of change, caution to the point of paralysis. Let's change the world, but without taking any risks! | 2009-04-22 22:21 |
| 135 | | pubrules fixes | 2009-04-23 05:17 |
| 136 | | Clean up event dispatch, with a particular emphasis on whether events get canceled or not. | 2009-04-26 22:11 |
| 137 | | Make EventSource available to workers, and add some notes to EventSource's definition that clarifies how to reduce the number of connections per server. (credit: jf) | 2009-04-26 23:29 |
| 138 | | whitespace issues | 2009-05-07 00:13 |
| 139 | | Fix up some Workers examples; remove extraneous <link rel=alternate> step in Atom export. (credit: sp) | 2009-05-23 09:09 |
| 140 | | Big changes to Workers and SharedWorkers to make their lifetime model easier. Move 'close' events to v2. Also, fix some omissions and xref problems that I ran across. | 2009-05-28 07:01 |
| 141 | | Only directly created nested workers inherit the lifetime requirements; ports on their own don't do it. | 2009-05-28 09:25 |
| 142 | | Allow workers to be GC'ed when they become useless. | 2009-05-28 21:29 |
| 143 | | To avoid confusion, use different words for workers closing and for ports being disabled. | 2009-06-03 19:28 |
| 144 | | remove XXX now that web dom core defines this | 2009-06-06 04:57 |
| 145 | | Vaguely clarify event loop mechanics for web workers. | 2009-06-11 21:40 |
| 146 | | Clarify behaviour in the face of redirects. | 2009-06-12 01:08 |
| 147 | | Revamp how the spec refers to 'HTML5', 'XHTML', etc. | 2009-06-12 23:09 |
| 148 | | spelling errors occurred | 2009-06-23 01:58 |
| 149 | | Workers have to define how to resolve the URL passed to the constructor, oops. | 2009-06-23 22:10 |
| 150 | | Use [Supplemental] instead of [XXX], in preparation for WebIDL defining [Supplemental]. Add all the DOM2 HTML obsolete stuff. Define <frame>. | 2009-06-24 11:56 |
| 151 | | Move openDatabase(), localStorage, and sessionStorage from HTML5 to Web Storage. Make it clearer where constructors are supposed to be visible. | 2009-06-26 08:43 |
| 152 | | markup error | 2009-06-26 09:08 |
| 153 | | Define the task source for web workers. | 2009-07-10 04:34 |
| 154 | | Fix use of <i>, <em>, punctuation. Add note to <em> section. | 2009-07-13 11:16 |
| 155 | | Split Web Storage into two: Web Storage and Web Database. | 2009-07-15 10:54 |
| 156 | | Clarify that only uncaught errors are reported. | 2009-07-16 01:04 |
| 157 | | Somehow these got missed when changing EventListener to Function a while back. | 2009-07-16 02:21 |
| 159 | | Make 'dependencies' its own top-level section, like in the other specs. | 2009-07-16 03:58 |
| 160 | | strings are DOMString, not DOMObject, duh | 2009-07-17 00:39 |
| 161 | | Actually I was wrong, the other specs do have this as a subsection. Oops. | 2009-07-17 23:05 |
| 162 | | Remove an obsolete note. | 2009-08-03 10:22 |
| 163 | | Update to latest Web IDL. | 2009-08-08 00:21 |
| 164 | | Clean up some references in preparation for actually having a references section. | 2009-08-08 08:20 |
| 165 | | Update references in all the specs I'm working on. | 2009-08-11 01:55 |
| 166 | | More reference cleanup | 2009-08-11 07:10 |
| 167 | | Yet more references fixes. | 2009-08-11 07:26 |
| 168 | | flush various formatting changes | 2009-08-14 23:08 |
| 169 | | First cut at ARIA integration. | 2009-08-22 01:11 |
| 170 | | Make SharedWorker's second argument optional. | 2009-08-25 23:25 |
| 171 | | Sync with XHR2. | 2009-08-29 00:43 |
| 172 | | Move to consistently referring to HTML versions as 'HTMLx' rather than having a space in there. | 2009-08-30 00:04 |
| 173 | | URL decomposition attributes are DOM attributes. | 2009-08-30 20:23 |
| 174 | | Rename DOM attributes to IDL attributes. | 2009-08-31 02:29 |
| 175 | | Make it possible to create a shared worker based only on the URL, not the name. | 2009-09-01 23:47 |
| 176 | | Update publication bits | 2009-09-08 22:02 |
| 177 | | clarify that data: and javascript: don't work as worker scripts | 2009-09-15 08:35 |
| 178 | | Warn about document.domain on shared hosting. | 2009-09-16 22:48 |
| 179 | | Update ws: and wss: registration. | 2009-09-17 10:12 |
| 180 | | More cleanup | 2009-09-18 07:57 |
| 181 | | miscellaneous cleanup | 2009-09-18 09:01 |
| 182 | | Move 'implements' requirements to IDL. | 2009-09-19 21:15 |
| 183 | 7448 | Clean up an orphan colon in author mode. | 2009-09-21 23:32 |
| 184 | | Oops, got the order of 'optional' and 'in' in teh wrong way around. | 2009-09-24 23:14 |
| 185 | | Change 'unless' to 'except where' in cases where that reduces ambiguity. | 2009-09-27 09:17 |
| 186 | 7599 | Synchronise with the latest Origin spec rules and semantics. | 2009-09-28 23:51 |
| 187 | 7625 | Rename 'event handler attributes' to 'event handlers' to reduce confusion with the actual attributes. | 2009-09-29 00:40 |
| 188 | | Split out the microdata vocabularies into their own specs | 2009-10-04 10:24 |
| 189 | | changed 'fire [an event] called /event/' to 'fire [an event] named /event/'. | 2009-10-04 11:42 |
| 190 | | Make a 'complete' spec of all the bits that WHATWG has worked on. | 2009-10-09 06:54 |
| 191 | | Use HTML5 in HTML5. | 2009-10-09 08:11 |
| 192 | | 'security exception' got defined more precisely a while ago | 2009-10-14 10:25 |
| 193 | | Constructors _are_ interface objects... oops. | 2009-10-14 10:27 |
| 194 | | typo in idl | 2009-10-14 10:28 |
| 195 | | xref errors found by complete.html | 2009-10-14 10:42 |
| 196 | | Drop support for anything but UTF-8 from Workers. | 2009-10-14 10:55 |
| 197 | | resync | 2009-10-17 08:59 |
| 198 | | Fix an example that would never have received its messages. | 2009-10-18 07:59 |
| 199 | 7752 | call the script's character encoding the URL character encoding. | 2009-10-18 10:49 |
| 200 | 7852 | Drop init*EventNS(), since DOM Events is dropping namespaced events. | 2009-10-20 10:37 |
| 201 | 7854 | xref | 2009-10-20 10:38 |
| 202 | 7947 | s/global scope/global object/ | 2009-10-21 09:38 |
| 203 | 7947 | s/script browsing context/script's browsing context/ | 2009-10-21 09:39 |
| 204 | 7960 | xref typo | 2009-10-21 10:11 |
| 205 | | correct examples | 2009-10-27 08:00 |
| 206 | | Prepare WHATWG drafts for CFC publication. | 2009-10-27 08:19 |
| 207 | | Minor clarifications | 2009-12-01 06:47 |
| 208 | | Rename Web Database to Web SQL Database. | 2009-12-01 06:51 |
| 209 | | Fix bogus references in complete.html. | 2009-12-01 07:13 |
| 210 | | Oops, wrong demo page. | 2009-12-01 07:22 |
| 211 | | Handle the case where a worker that is very slow to start up gets a message before it has an event loop. | 2009-12-01 09:36 |
| 212 | | Change the way that WebWorkers defines which interfaces are visible so that it doesn't have to continually be updated. | 2009-12-02 05:17 |
| 213 | | Make AbstractWorker disappear into the interfaces that inherit from it. | 2009-12-09 14:37 |
| 214 | | Prevent WorkerGlobalScope, Location, and WorkerNavigator from being visible on Window objects. | 2009-12-09 14:54 |
| 215 | | Rename Navigator to WorkerNavigator in Workers. | 2009-12-09 15:02 |
| 216 | | Full regen to get things back in sync. | 2009-12-11 16:15 |
| 217 | 8325 | Avoid requiring that the user be notified of something, since that's a UI issue. | 2010-01-05 08:11 |
| 218 | 8418 | s/first script/entry script/ for sanity. | 2010-01-06 03:36 |
| 219 | 8472 | Change to referencing CSSATTR instead of CSS for style=''. | 2010-01-06 07:46 |
| 220 | 8607 | Add an example for CDATA sections. | 2010-01-07 08:16 |
| 221 | 7542 | Splitting out the Microdata spec. | 2010-01-08 02:07 |
| 222 | | cleanup. This may introduce other problems; I'll clean them up too shortly. | 2010-01-08 06:49 |
| 223 | | more cleanup | 2010-01-08 08:20 |
| 224 | 8368 | split out communications section | 2010-01-08 09:22 |
| 225 | 8479 | Allow skipping sniffing steps. | 2010-01-10 11:03 |
| 226 | 8575 | Update references from ES3 to ES5. | 2010-01-11 06:48 |
| 227 | | Editorial changes to 2D and Microdata specs for FPWD. Clean-up of the references sections. Fix some problems caused by dropping language versioning at the WHATWG. | 2010-02-04 03:12 |
| 228 | 8691 | The annual restructuring to make things make sense again. | 2010-02-06 00:06 |
| 229 | | Fix the mess that was included in the last checkin. | 2010-02-11 10:03 |
| 230 | 8536 | Make it clear that disabling a feature should truly remove it, not just stub it out. | 2010-02-12 13:09 |
| 231 | 8857 | Fix up some references. | 2010-02-14 08:42 |
| 232 | | Make 'Referer' work correctly for scripts in shared workers. (For some definition of 'correctly' -- it uses the URL of the document that actually created the script. Arguably it should use the URL of the script itself. However, this doesn't change that, it just makes it not leak the URL of documents that that document's browsing context is navigated to.) | 2010-02-23 01:53 |
| 233 | | prepare to xref Event | 2010-02-23 11:24 |
| 234 | | Update all copyrights. | 2010-03-02 21:57 |
| 235 | | Fix some pubrules problems. (only affects the W3C variants of the specs) | 2010-03-03 23:55 |
| 236 | | objects aren't equal to urls, oops | 2010-03-24 22:26 |
| 237 | | Add more shared worker examples. | 2010-03-25 00:52 |
| 238 | | Fix the recently added examples. | 2010-03-25 07:56 |
| 239 | | I am incompetent at this editing thing. | 2010-03-25 08:18 |
| 240 | | spec gen updates | 2010-04-02 21:45 |
| 241 | 9383 | try to make things clearer and more consistent | 2010-04-03 02:45 |
| 242 | 9022 | updating header per chair request | 2010-04-04 06:34 |
| 243 | 9387 | add some worker demo links | 2010-04-12 08:04 |
| 244 | | regen with updated scripts (no changes expected other than dates) | 2010-04-14 20:00 |
| 245 | | Make self.close() in a worker not close the ports until after the worker has ended. | 2010-04-17 00:58 |
| 246 | | Make the worker event loop release the storage mutex. | 2010-04-17 01:05 |
| 247 | | regen | 2010-05-11 08:39 |
| 248 | | regen for build scripts | 2010-05-11 08:59 |
| 249 | | Remove the experimental timed tracks stuff from the W3C copy, by request of the chairs. | 2010-05-12 01:17 |
| 250 | | change how boilerplate is added and update some boilerplate text with the new mechanism | 2010-06-01 04:26 |
| 251 | | Captions - Stage 11.3: completed the external timed track download processing model, and did some more work on parsing WebSRT. Also: Update the 'fetch' algorithm to support doing same-origin enforcing, and made various parts of the spec use it; also made parts of the spec that acted like the algorith was sync actually invoke it that way. | 2010-06-25 19:22 |
| 252 | | Make a WebSRT-only view for Jonas. | 2010-07-23 08:06 |
| 253 | | A variety of minor fixes. | 2010-07-27 23:03 |
| 254 | | 404s | 2010-07-29 23:41 |
| 255 | | Some more references to UTF-8. | 2010-08-10 01:16 |
| 256 | 9552 | xref | 2010-08-23 22:41 |
| 257 | | give more images sizes | 2010-09-10 00:13 |
| 258 | 9663 | Tighten up UTF-8 error handling definitions | 2010-09-28 19:16 |
| 259 | 10411 | update ietf refs | 2010-10-12 06:35 |
| 260 | | remove unexpected damage in yesterday's checkin (no idea what happened - disk corruption?) | 2010-10-13 18:45 |
| 261 | | ref rfc2397 where appropriate | 2010-12-01 00:47 |
| 262 | | typo | 2010-12-07 02:52 |
| 263 | | Purge references to Web SQL Database. | 2011-01-01 06:34 |
| 264 | | update spec subheading | 2011-01-06 22:21 |
| 265 | | forced refresh | 2011-01-20 20:55 |
| 266 | | the word 'completely' was confusing the issue | 2011-02-07 21:41 |
| 267 | | Comment out an example that uses startConversation(), which isn't yet in the spec (it's commented out also). | 2011-02-07 22:16 |
| 268 | 11105 | Add a note about cases where scripts won't run. Also, update some references (unrelated to the bug below). | 2011-02-08 21:31 |
| 269 | 11817 | copyright date update | 2011-02-16 07:44 |
| 270 | | Completely revamp how peer-to-peer networking works (and some minor typo fixes in other parts of the spec). This is only a second draft, and therefore this feature will likely evolve a lot over the coming months. Detailed responses to feedback on the topic will be sent out soon. | 2011-03-14 10:20 |
| 271 | | full regen because the publishing pipeline seems to have gotten out of sync | 2011-04-12 00:10 |
| 272 | | pipeline update | 2011-04-13 22:10 |
| 273 | | remove pointless annotations | 2011-05-23 21:24 |
| 274 | | Fix WebIDL-related issues uncovered by the recent updates to the webidl checker | 2011-05-27 00:24 |
| 275 | | Update 'fire' and 'dispatch' terminology. | 2011-06-04 00:47 |
| 276 | | Expose handlers for online and offline events in workers | 2011-06-08 22:06 |
| 277 | | Add the atob/btoa methods to WorkerUtils | 2011-06-10 22:15 |
| 278 | 10640 | Update IDL to recent WebIDL changes, thanks to heycam. | 2011-06-13 23:39 |
Index: index
===================================================================
--- index (revision 1)
+++ index (revision 278)
@@ -1,259 +1,2456 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<!DOCTYPE html><html lang=en-US-x-hixie><meta charset=ascii><title>Web Workers</title><link href=/style/specification rel=stylesheet><link href=/images/icon rel=icon><body class=cfc>
-<html lang=en-US-x-hixie>
- <head>
- <title>HTML 5</title>
- <link href="/style/specification" rel=stylesheet>
- <link href="/images/icon" rel=icon>
+ <header class=head><p><a class=logo href=http://www.whatwg.org/><img alt=WHATWG height=101 src=/images/logo width=101></a></p>
+ <hgroup><h1>Web Workers</h1>
+ <h2 class="no-num no-toc">Living Standard — Last updated 13 June 2011</h2>
+ </hgroup><p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
+ <p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
+ <dl><dt>This version:</dt>
+ <dd><a href=http://www.whatwg.org/specs/web-workers/current-work/>http://whatwg.org/ww</a></dd>
+ <dt>Version history:</dt>
+ <dd>Twitter messages (non-editorial changes only): <a href=http://twitter.com/WHATWG>http://twitter.com/WHATWG</a></dd>
+ <dd>Commit-Watchers mailing list: <a href=http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org>http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org</a></dd>
+ <dd>Interactive Web interface: <a href=http://html5.org/tools/web-workers-tracker>http://html5.org/tools/web-workers-tracker</a></dd>
+ <dd>Subversion interface: <a href=http://svn.whatwg.org/webworkers/>http://svn.whatwg.org/webworkers/</a></dd>
+ <dt>Issues:</dt>
+ <dd>To send feedback: <a href=http://www.whatwg.org/mailing-list>whatwg@whatwg.org</a></dd>
+ <dd>To view and vote on feedback: <a href=http://www.whatwg.org/issues/>http://www.whatwg.org/issues/</a></dd>
+ <dt>Editor:</dt>
+ <dd>Ian Hickson, Google, ian@hixie.ch</dd>
+ </dl><p class=copyright>© Copyright 2004-2011 Apple Computer, Inc.,
+ Mozilla Foundation, and Opera Software ASA.</p>
+ <p class=copyright>You are granted a license to use, reproduce
+ and create derivative works of this document.</p>
+ </header><hr><h2 class="no-num no-toc" id=abstract>Abstract</h2>
- <body class=draft>
- <div class=head>
- <p><a class=logo href="http://www.whatwg.org/" rel=home><img alt=WHATWG
- src="/images/logo"></a></p>
+ <p>This specification defines an API that allows Web application
+ authors to spawn background workers running scripts in parallel to
+ their main page. This allows for thread-like operation with
+ message-passing as the coordination mechanism.</p>
- <h1 id=web-workers>Web Workers</h1>
- <h2 class="no-num no-toc" id=draft>Draft Recommendation — 9 July
- 2008</h2>
+ <h2 class="no-num no-toc" id=status>Status of this document</h2>
- <p>You can take part in this work. <a
- href="http://www.whatwg.org/mailing-list">Join the working group's
- discussion list.</a></p>
+ <p><strong>This is a work in progress!</strong> This document is
+ changing on a daily if not hourly basis in response to comments and
+ as a general part of its development process. Comments are very
+ welcome, please send them to <a href=mailto:whatwg@whatwg.org>whatwg@whatwg.org</a>. Thank
+ you.</p>
- <p><strong>Web designers!</strong> We have a <a
- href="http://blog.whatwg.org/faq/">FAQ</a>, a <a
- href="http://forums.whatwg.org/">forum</a>, and a <a
- href="http://www.whatwg.org/mailing-list#help">help mailing list</a> for
- you!</p>
+ <p>The current focus is in developing a first draft proposal.</p>
- <dl>
- <dt>This version:
+ <p>Implementors should be aware that this specification is not
+ stable. <strong>Implementors who are not taking part in the
+ discussions are likely to find the specification changing out from
+ under them in incompatible ways.</strong> Vendors interested in
+ implementing this specification before it eventually reaches the
+ call for implementations should join the <a href=/mailing-list>WHATWG mailing list</a> and take part in the
+ discussions.</p>
- <dd><a
- href="http://www.whatwg.org/specs/web-workers/current-work/">http://www.whatwg.org/specs/web-workers/current-work/</a>
+ <p>This specification is also being produced by the <a href=http://www.w3.org/2008/webapps/>W3C Web Applications WG</a>. The two
+ specifications are identical from the table of contents onwards.</p>
- <dt>Version history:
- <dd>Twitter messages (non-editorial changes only): <a
- href="http://twitter.com/WHATWG">http://twitter.com/WHATWG</a>
- <dd>Commit-Watchers mailing list: <a
- href="http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org">http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org</a>
+ <h2 class="no-num no-toc" id=contents>Table of contents</h2>
+
+<!--begin-toc-->
+<ol class=toc>
+ <li><a href=#introduction><span class=secno>1 </span>Introduction</a>
+ <ol>
+ <li><a href=#scope><span class=secno>1.1 </span>Scope</a></li>
+ <li><a href=#tutorial><span class=secno>1.2 </span>Tutorial</a>
+ <ol>
+ <li><a href=#a-background-number-crunching-worker><span class=secno>1.2.1 </span>A background number-crunching worker</a></li>
+ <li><a href=#a-worker-for-updating-a-client-side-database><span class=secno>1.2.2 </span>A worker for updating a client-side database</a></li>
+ <li><a href=#worker-used-for-background-i/o><span class=secno>1.2.3 </span>Worker used for background I/O</a></li>
+ <li><a href=#shared-workers-introduction><span class=secno>1.2.4 </span>Shared workers introduction</a></li>
+ <li><a href=#shared-state-using-a-shared-worker><span class=secno>1.2.5 </span>Shared state using a shared worker</a></li>
+ <li><a href=#delegation><span class=secno>1.2.6 </span>Delegation</a></ol></ol></li>
+ <li><a href=#conformance-requirements><span class=secno>2 </span>Conformance requirements</a>
+ <ol>
+ <li><a href=#dependencies><span class=secno>2.1 </span>Dependencies</a></ol></li>
+ <li><a href=#terminology><span class=secno>3 </span>Terminology</a></li>
+ <li><a href=#infrastructure><span class=secno>4 </span>Infrastructure</a>
+ <ol>
+ <li><a href=#the-global-scope><span class=secno>4.1 </span>The global scope</a>
+ <ol>
+ <li><a href=#the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code>WorkerGlobalScope</code> abstract interface</a></li>
+ <li><a href=#dedicated-workers-and-the-dedicatedworkerglobalscope-interface><span class=secno>4.1.2 </span>Dedicated workers and the <code>DedicatedWorkerGlobalScope</code> interface</a></li>
+ <li><a href=#shared-workers-and-the-sharedworkerglobalscope-interface><span class=secno>4.1.3 </span>Shared workers and the <code>SharedWorkerGlobalScope</code> interface</a></ol></li>
+ <li><a href=#origins-of-workers><span class=secno>4.2 </span>Origins of workers</a></li>
+ <li><a href=#the-event-loop><span class=secno>4.3 </span>The event loop</a></li>
+ <li><a href="#the-worker's-lifetime"><span class=secno>4.4 </span>The worker's lifetime</a></li>
+ <li><a href=#processing-model><span class=secno>4.5 </span>Processing model</a></li>
+ <li><a href=#runtime-script-errors><span class=secno>4.6 </span>Runtime script errors</a></li>
+ <li><a href=#creating-workers><span class=secno>4.7 </span>Creating workers</a>
+ <ol>
+ <li><a href=#the-abstractworker-abstract-interface><span class=secno>4.7.1 </span>The <code>AbstractWorker</code> abstract interface</a></li>
+ <li><a href=#dedicated-workers-and-the-worker-interface><span class=secno>4.7.2 </span>Dedicated workers and the <code>Worker</code> interface</a></li>
+ <li><a href=#shared-workers-and-the-sharedworker-interface><span class=secno>4.7.3 </span>Shared workers and the <code>SharedWorker</code> interface</a></ol></ol></li>
+ <li><a href=#apis-available-to-workers><span class=secno>5 </span>APIs available to workers</a>
+ <ol>
+ <li><a href=#importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</a></li>
+ <li><a href=#the-workernavigator-object><span class=secno>5.2 </span>The <code>WorkerNavigator</code> object</a></li>
+ <li><a href=#interface-objects-and-constructors><span class=secno>5.3 </span>Interface objects and constructors</a></li>
+ <li><a href=#worker-locations><span class=secno>5.4 </span>Worker locations</a></ol></li>
+ <li><a class=no-num href=#references>References</a></li>
+ <li><a class=no-num href=#acknowledgements>Acknowledgements</a></ol>
+<!--end-toc-->
+ <hr><h2 id=introduction><span class=secno>1 </span>Introduction</h2>
- <dd>Interactive Web interface: <a
- href="http://html5.org/tools/web-workers-tracker">http://html5.org/tools/web-workers-tracker</a>
+ <h3 id=scope><span class=secno>1.1 </span>Scope</h3>
- <dd>Subversion interface: <a
- href="http://svn.whatwg.org/webworkers/">http://svn.whatwg.org/webworkers/</a>
+ <p><i>This section is non-normative.</i></p>
- <dt>Issues:
+ <p>This specification defines an API for running scripts in the
+ background independently of any user interface scripts.</p>
- <dd>To send feedback: <a
- href="http://www.whatwg.org/mailing-list">whatwg@whatwg.org</a>
+ <p>This allows for long-running scripts that are not interrupted by
+ scripts that respond to clicks or other user interactions, and
+ allows long tasks to be executed without yielding to keep the page
+ responsive.</p>
- <dd>To view and vote on feedback: <a
- href="http://www.whatwg.org/issues/">http://www.whatwg.org/issues/</a>
+ <p>Workers (as these background scripts are called herein) are
+ relatively heavy-weight, and are not intended to be used in large
+ numbers. For example, it would be inappropriate to launch one worker
+ for each pixel of a four megapixel image. The examples below show
+ some appropriate uses of workers.</p>
- <dt>Editor:
+ <p>Generally, workers are expected to be long-lived, have a high
+ start-up performance cost, and a high per-instance memory cost.</p>
- <dd>Ian Hickson, Google, ian@hixie.ch
- </dl>
- <p class=copyright>© Copyright 2004-2008 Apple Computer, Inc.,
- Mozilla Foundation, and Opera Software ASA.</p>
+ <h3 id=tutorial><span class=secno>1.2 </span>Tutorial</h3>
- <p class=copyright>You are granted a license to use, reproduce and create
- derivative works of this document.</p>
- </div>
+ <p><i>This section is non-normative.</i></p>
- <hr>
+ <p>There are a variety of uses that workers can be put to. The
+ following subsections show various examples of this use.</p>
- <h2 class="no-num no-toc" id=abstract>Abstract</h2>
+ <h4 id=a-background-number-crunching-worker><span class=secno>1.2.1 </span>A background number-crunching worker</h4>
- <p>This specification evolves HTML and its related APIs to ease the
- authoring of Web-based applications. Additions include the context menus,
- a direct-mode graphics canvas, inline popup windows, and server-sent
- events. Heavy emphasis is placed on keeping the language backwards
- compatible with existing legacy user agents and on keeping user agents
- backwards compatible with existing legacy documents.
+ <p><i>This section is non-normative.</i></p>
- <h2 class="no-num no-toc" id=status>Status of this document</h2>
+ <p>The simplest use of workers is for performing a computationally
+ expensive task without interrupting the user interface.</p>
- <p><strong>This is a work in progress!</strong> This document is changing
- on a daily if not hourly basis in response to comments and as a general
- part of its development process. Comments are very welcome, please send
- them to <a href="mailto:whatwg@whatwg.org">whatwg@whatwg.org</a>. Thank
- you.
+ <p>In this example, the main document spawns a worker to
+ (naïvely) compute prime numbers, and progressively displays the
+ most recently found prime number.</p>
- <p>The current focus is in developing a first draft proposal.
+ <p>The main page is as follows:</p>
- <p>Implementors should be aware that this specification is not stable.
- <strong>Implementors who are not taking part in the discussions are likely
- to find the specification changing out from under them in incompatible
- ways.</strong> Vendors interested in implementing this specification
- before it eventually reaches the call for implementations should join the
- <a href="/mailing-list">WHATWG mailing list</a> and take part in the
- discussions.
+ <pre><!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Worker example: One-core computation</title>
+ </head>
+ <body>
+ <p>The highest prime number discovered so far is: <output id="result"></output></p>
+ <script>
+ var worker = new Worker('worker.js');
+ worker.onmessage = function (event) {
+ document.getElementById('result').textContent = event.data;
+ };
+ </script>
+ </body>
+</html></pre>
- <p>This specification is also being produced by the <a
- href="http://www.w3.org/html/wg">W3C HTML WG</a>. The two specifications
- are identical from the table of contents onwards.
+ <p>The <code title=dom-Worker><a href=#dom-worker>Worker()</a></code> constructor call
+ creates a worker and returns a <code><a href=#worker>Worker</a></code> object
+ representing that worker, which is used to communicate with the
+ worker. That object's <code title=handler-Worker-onmessage><a href=#handler-worker-onmessage>onmessage</a></code> event handler allows the code to receive messages from the worker.</p>
- <h2 class="no-num no-toc" id=contents>Table of contents</h2>
- <!--begin-toc-->
+ <p>The worker itself is as follows:</p>
- <ul class=toc>
- <li><a href="#introduction"><span class=secno>1. </span>Introduction</a>
- <ul class=toc>
- <li><a href="#background"><span class=secno>1.1 </span>Background</a>
+ <pre>var n = 1;
+search: while (true) {
+ n += 1;
+ for (var i = 2; i <= Math.sqrt(n); i += 1)
+ if (n % i == 0)
+ continue search;
+ // found a prime!
+ postMessage(n);
+}</pre>
- <li><a href="#scope"><span class=secno>1.2 </span>Scope</a>
+ <p>The bulk of this code is simply an unoptimized search for a prime
+ number. To send a message back to the page, the <code title=dom-DedicatedWorkerGlobalScope-send>send()</code>
+ method is used to post a message when a prime is found.</p>
- <li><a href="#relationships"><span class=secno>1.3 </span>Relationships
- to other specifications</a>
- <ul class=toc>
- <li><a href="#relationship"><span class=secno>1.3.1
- </span>Relationship to HTML5</a>
+ <p><a href=http://www.whatwg.org/demos/workers/primes/page.html>View this example online</a>.</p>
- <li><a href="#relationship0"><span class=secno>1.3.2
- </span>Relationship to ECMAScript</a>
- </ul>
- <li><a href="#conformance"><span class=secno>1.4 </span>Conformance
- requirements</a>
- <ul class=toc>
- <li><a href="#dependencies"><span class=secno>1.4.1
- </span>Dependencies</a>
- </ul>
- <li><a href="#terminology"><span class=secno>1.5 </span>Terminology</a>
- </ul>
+ <h4 id=a-worker-for-updating-a-client-side-database><span class=secno>1.2.2 </span>A worker for updating a client-side database</h4>
- <li class=no-num><a href="#references">References</a>
+ <p><i>This section is non-normative.</i></p>
- <li class=no-num><a href="#acknowledgements">Acknowledgements</a>
- </ul>
- <!--end-toc-->
+ <p>In this example, the main document spawns a worker whose only
+ task is to listen for notifications from the server, and, when
+ appropriate, either add or remove data from the client-side
+ database.</p>
- <hr>
+ <p>Since no communication occurs between the worker and the main
+ page, the main page can start the worker by just doing:</p>
- <h2 id=introduction><span class=secno>1. </span>Introduction</h2>
+ <pre><script>
+ new Worker('worker.js');
+</script></pre>
- <h3 id=background><span class=secno>1.1 </span>Background</h3>
+ <p>The worker itself is as follows:</p>
- <p><em>This section is non-normative.</em>
+ <pre>var server = new WebSocket('ws://whatwg.org/database');
+var database = openDatabase('demobase', '1.0', 'Demo Database', 10240);
+server.onmessage = function (event) {
+ // data is in the format "command key value"
+ var data = event.data.split(' ');
+ switch (data[0]) {
+ case '+':
+ database.transaction(function(tx) {
+ tx.executeSql('INSERT INTO pairs (key, value) VALUES (?, ?)', data[1], data[2]);
+ });
+ case '-':
+ database.transaction(function(tx) {
+ tx.executeSql('DELETE FROM pairs WHERE key=? AND value=?', data[1], data[2]);
+ });
+ }
+};</pre>
- <h3 id=scope><span class=secno>1.2 </span>Scope</h3>
+ <p>This connects to the server using the <code>WebSocket</code>
+ mechanism and opens the local database (which, we presume, has been
+ created earlier). The worker then just listens for messages from the
+ server and acts on them as appropriate, forever (or until the main
+ page is closed).</p>
- <p><em>This section is non-normative.</em>
+ <p><a href=http://www.whatwg.org/demos/workers/database-updater/page.html>View
+ this example online</a>. (This example will not actually function,
+ since the server does not actually exist and the database is not
+ created by this sample code.)</p>
- <h3 id=relationships><span class=secno>1.3 </span>Relationships to other
- specifications</h3>
- <h4 id=relationship><span class=secno>1.3.1 </span>Relationship to HTML5</h4>
- <p><em>This section is non-normative.</em>
+ <h4 id=worker-used-for-background-i/o><span class=secno>1.2.3 </span>Worker used for background I/O</h4>
- <h4 id=relationship0><span class=secno>1.3.2 </span>Relationship to
- ECMAScript</h4>
+ <p><i>This section is non-normative.</i></p>
- <p><em>This section is non-normative.</em>
+ <p>In this example, the main document uses two workers, one for
+ fetching stock updates for at regular intervals, and one for
+ fetching performing search queries that the user requests.</p>
- <h3 id=conformance><span class=secno>1.4 </span>Conformance requirements</h3>
+ <p>The main page is as follows:</p>
+ <pre><!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Worker example: Stock ticker</title>
+ <script>
+ // TICKER
+ var symbol = 'GOOG'; // default symbol to watch
+ var ticker = new Worker('ticker.js');
+
+ // SEARCHER
+ var searcher = new Worker('searcher.js');
+ function search(query) {
+ searcher.postMessage(query);
+ }
+
+ // SYMBOL SELECTION UI
+ function select(newSymbol) {
+ symbol = newSymbol;
+ ticker.postMessage(symbol);
+ }
+ </script>
+ </head>
+ <body onload="search('')">
+ <p><output id="symbol"></output> <output id="value"></output></p>
+ <script>
+ ticker.onmessage = function (event) {
+ var data = event.data.split(' ');
+ document.getElementById('symbol').textContent = data[0];
+ document.getElementById('value').textContent = data[1];
+ };
+ ticker.postMessage(symbol);
+ </script>
+ <p><label>Search: <input type="text" autofocus oninput="search(this.value)"></label></p>
+ <ul id="results"></ul>
+ <script>
+ searcher.onmessage = function (event) {
+ var data = event.data.split(' ');
+ var results = document.getElementById('results');
+ while (results.hasChildNodes()) // clear previous results
+ results.removeChild(results.firstChild);
+ for (var i = 0; i < data.length; i += 1) {
+ // add a list item with a button for each result
+ var li = document.createElement('li');
+ var button = document.createElement('button');
+ button.value = data[i];
+ button.type = 'button';
+ button.onclick = function () { select(this.value); };
+ button.textContent = data[i];
+ li.appendChild(button);
+ results.appendChild(li);
+ }
+ };
+ </script>
+ <p>(The data in this example is not real. Try searching for "Google" or "Apple".)</p>
+ </body>
+</html></pre>
+
+ <p>The two workers use a common library for performing the actual
+ network calls. This library is as follows:</p>
+
+ <pre>function get(url) {
+ try {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, false);
+ xhr.send();
+ return xhr.responseText;
+ } catch (e) {
+ return ''; // turn all errors into empty results
+ }
+}</pre>
+
+ <p>The stock updater worker is as follows:</p>
+
+ <pre>importScripts('io.js');
+var timer;
+var symbol;
+function update() {
+ postMessage(symbol + ' ' + get('stock.cgi?' + symbol));
+ timer = setTimeout(update, 10000);
+}
+onmessage = function (event) {
+ if (timer)
+ clearTimeout(timer);
+ symbol = event.data;
+ update();
+};</pre>
+
+ <p>The search query worker is as follows:</p>
+
+ <pre>importScripts('io.js');
+onmessage = function (event) {
+ postMessage(get('search.cgi?' + event.data));
+};</pre>
+
+ <p><a href=http://www.whatwg.org/demos/workers/stocks/page.html>View this example online</a>.</p>
+
+
+ <h4 id=shared-workers-introduction><span class=secno>1.2.4 </span>Shared workers introduction</h4>
+
+ <p><i>This section is non-normative.</i></p>
+
+ <p>This section introduces shared workers using a Hello World
+ example. Shared workers use slightly different APIs, since each
+ worker can have multiple connections.</p>
+
+ <p>This first example shows how you connect to a worker and how a
+ worker can send a message back to the page when it connects to
+ it. Received messages are displayed in a log.</p>
+
+ <p>Here is the HTML page:</p>
+
+ <pre><!DOCTYPE HTML>
+<title>Shared workers: demo 1</title>
+<pre id="log">Log:</pre>
+<script>
+ var worker = new SharedWorker('test.js');
+ var log = document.getElementById('log');
+ worker.port.onmessage = function(e) { // note: not worker.onmessage!
+ log.textContent += '\n' + e.data;
+ }
+</script>
+</pre>
+
+ <p>Here is the JavaScript worker:</p>
+
+ <pre>onconnect = function(e) {
+ var port = e.ports[0];
+ port.postMessage('Hello World!');
+}
+</pre>
+
+ <p><a href=http://www.whatwg.org/demos/workers/shared/001/test.html>View this example online</a>.</p>
+
+ <hr><p>This second example extends the first one by changing two things:
+ first, messages are received using <code title="">addEventListener()</code> instead of an <span title="event
+ handler IDL attributes">event handler IDL attribute</span>, and
+ second, a message is sent <em>to</em> the worker, causing the worker
+ to send another message in return. Received messages are again
+ displayed in a log.</p>
+
+ <p>Here is the HTML page:</p>
+
+ <pre><!DOCTYPE HTML>
+<title>Shared workers: demo 2</title>
+<pre id="log">Log:</pre>
+<script>
+ var worker = new SharedWorker('test.js');
+ var log = document.getElementById('log');
+ worker.port.addEventListener('message', function(e) {
+ log.textContent += '\n' + e.data;
+ }, false);
+ worker.port.start(); // note: need this when using addEventListener
+ worker.port.postMessage('ping');
+</script>
+</pre>
+
+ <p>Here is the JavaScript worker:</p>
+
+ <pre>onconnect = function(e) {
+ var port = e.ports[0];
+ port.postMessage('Hello World!');
+ port.onmessage = function(e) {
+ port.postMessage('pong'); // not e.ports[0].postMessage!
+ // e.target.postMessage('pong'); would work also
+ }
+}
+</pre>
+
+ <p><a href=http://www.whatwg.org/demos/workers/shared/002/test.html>View this example online</a>.</p>
+
+ <hr><p>Finally, the example is extended to show how two pages can
+ connect to the same worker; in this case, the second page is merely
+ in an <code>iframe</code> on the first page, but the same principle
+ would apply to an entirely separate page in a separate
+ <span>top-level browsing context</span>.</p>
+
+ <p>Here is the outer HTML page:</p>
+
+ <pre><!DOCTYPE HTML>
+<title>Shared workers: demo 3</title>
+<pre id="log">Log:</pre>
+<script>
+ var worker = new SharedWorker('test.js');
+ var log = document.getElementById('log');
+ worker.port.addEventListener('message', function(e) {
+ log.textContent += '\n' + e.data;
+ }, false);
+ worker.port.start();
+ worker.port.postMessage('ping');
+</script>
+<iframe src="inner.html"></iframe>
+</pre>
+
+ <p>Here is the inner HTML page:</p>
+
+ <pre><!DOCTYPE HTML>
+<title>Shared workers: demo 3 inner frame</title>
+<pre id=log>Inner log:</pre>
+<script>
+ var worker = new SharedWorker('test.js');
+ var log = document.getElementById('log');
+ worker.port.onmessage = function(e) {
+ log.textContent += '\n' + e.data;
+ }
+</script>
+</pre>
+
+ <p>Here is the JavaScript worker:</p>
+
+ <pre>var count = 0;
+onconnect = function(e) {
+ count += 1;
+ var port = e.ports[0];
+ port.postMessage('Hello World! You are connection #' + count);
+ port.onmessage = function(e) {
+ port.postMessage('pong');
+ }
+}
+</pre>
+
+ <p><a href=http://www.whatwg.org/demos/workers/shared/003/test.html>View this example online</a>.</p>
+
+
+ <h4 id=shared-state-using-a-shared-worker><span class=secno>1.2.5 </span>Shared state using a shared worker</h4>
+
+ <p><i>This section is non-normative.</i></p>
+
+ <p>In this example, multiple windows (viewers) can be opened that
+ are all viewing the same map. All the windows share the same map
+ information, with a single worker coordinating all the viewers. Each
+ viewer can move around independently, but if they set any data on
+ the map, all the viewers are updated.</p>
+
+ <p>The main page isn't interesting, it merely provides a way to open
+ the viewers:</p>
+
+ <pre><!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Workers example: Multiviewer</title>
+ <script>
+ function openViewer() {
+ window.open('viewer.html');
+ }
+ </script>
+ </head>
+ <body>
+ <p><button type=button onclick="openViewer()">Open a new
+ viewer</button></p>
+ <p>Each viewer opens in a new window. You can have as many viewers
+ as you like, they all view the same data.</p>
+ </body>
+</html></pre>
+
+ <p>The viewer is more involved:</p>
+
+ <pre><!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Workers example: Multiviewer viewer</title>
+ <script>
+ var worker = new SharedWorker('worker.js', 'core');
+
+ // CONFIGURATION
+ function configure(event) {
+ if (event.data.substr(0, 4) != 'cfg ') return;
+ var name = event.data.substr(4).split(' ', 1);
+ // update display to mention our name is name
+ document.getElementsByTagName('h1')[0].textContent += ' ' + name;
+ // no longer need this listener
+ worker.port.removeEventListener('message', configure, false);
+ }
+ worker.port.addEventListener('message', configure, false);
+
+ // MAP
+ function paintMap(event) {
+ if (event.data.substr(0, 4) != 'map ') return;
+ var data = event.data.substr(4).split(',');
+ // display tiles data[0] .. data[8]
+ var canvas = document.getElementById('map');
+ var context = canvas.getContext('2d');
+ for (var y = 0; y < 3; y += 1) {
+ for (var x = 0; x < 3; x += 1) {
+ var tile = data[y * 3 + x];
+ if (tile == '0')
+ context.fillStyle = 'green';
+ else
+ context.fillStyle = 'maroon';
+ fillRect(x * 50, y * 50, 50, 50);
+ }
+ }
+ }
+ worker.port.addEventListener('message', paintMap, false);
+
+ // PUBLIC CHAT
+ function updatePublicChat(event) {
+ if (event.data.substr(0, 4) != 'txt ') return;
+ var name = event.data.substr(4).split(' ', 1);
+ var message = event.data.substr(4 + length(name) + 1);
+ // display "<name> message" in public chat
+ var dialog = document.getElementById('public');
+ var dt = document.createElement('dt');
+ dt.textContent = name;
+ dialog.appendChild(dt);
+ var dd = document.createElement('dd');
+ dd.textContent = message;
+ dialog.appendChild(dd);
+ }
+ worker.port.addEventListener('message', updatePublicChat, false);
+
+ // PRIVATE CHAT
+ function startPrivateChat(event) {
+ if (event.data.substr(0, 4) != 'msg ') return;
+ var name = event.data.substr(4).split(' ', 1);
+ var port = event.ports[0];
+ // display a private chat UI
+ var ul = document.getElementById('private');
+ var li = document.createElement('li');
+ var h3 = document.createElement('h3');
+ h3.textContent = 'Private chat with ' + name;
+ li.appendChild(h3);
+ var dialog = document.createElement('dialog');
+ var addMessage = function(name, message) {
+ var dt = document.createElement('dt');
+ dt.textContent = name;
+ dialog.appendChild(dt);
+ var dd = document.createElement('dd');
+ dd.textContent = message;
+ dialog.appendChild(dd);
+ };
+ port.onmessage = function (event) {
+ addMessage(name, event.data);
+ };
+ li.appendChild(dialog);
+ var form = document.createElement('form');
+ var p = document.createElement('p');
+ var input = document.createElement('input');
+ input.size = 50;
+ p.appendChild(input);
+ p.appendChild(document.createTextNode(' '));
+ var button = document.createElement('button');
+ button.textContent = 'Post';
+ p.appendChild(button);
+ form.onsubmit = function () {
+ port.postMessage(input.value);
+ addMessage('me', input.value);
+ input.value = '';
+ return false;
+ };
+ form.appendChild(p);
+ li.appendChild(form);
+ }
+ worker.port.addEventListener('message', startPrivateChat, false);
+
+ worker.port.start();
+ </script>
+ </head>
+ <body>
+ <h1>Viewer</h1>
+ <h2>Map</h2>
+ <p><canvas id="map" height=150 width=150></canvas></p>
+ <p>
+ <button type=button onclick="worker.port.postMessage('mov left')">Left</button>
+ <button type=button onclick="worker.port.postMessage('mov up')">Up</button>
+ <button type=button onclick="worker.port.postMessage('mov down')">Down</button>
+ <button type=button onclick="worker.port.postMessage('mov right')">Right</button>
+ <button type=button onclick="worker.port.postMessage('set 0')">Set 0</button>
+ <button type=button onclick="worker.port.postMessage('set 1')">Set 1</button>
+ </p>
+ <h2>Public Chat</h2>
+ <dialog id="public"></dialog>
+ <form onsubmit="worker.port.postMessage('txt ' + message.value); message.value = ''; return false;">
+ <p>
+ <input type="text" name="message" size="50">
+ <button>Post</button>
+ </p>
+ </form>
+ <h2>Private Chat</h2>
+ <ul id="private"></ul>
+ </body>
+</html>
+</pre>
+
+ <p>There are several key things worth noting about the way the
+ viewer is written.</p>
+
+ <p><strong>Multiple listeners</strong>. Instead of a single message
+ processing function, the code here attaches multiple event
+ listeners, each one performing a quick check to see if it is
+ relevant for the message. In this example it doesn't make much
+ difference, but if multiple authors wanted to collaborate using a
+ single port to communicate with a worker, it would allow for
+ independent code instead of changes having to all be made to a
+ single event handling function.</p>
+
+ <p>Registering event listeners in this way also allows you to
+ unregister specific listeners when you are done with them, as is
+ done with the <code title="">configure()</code> method in this
+ example.</p>
+
+ <p>Finally, the worker:</p>
+
+ <pre>
+var nextName = 0;
+function getNextName() {
+ // this could use more friendly names
+ // but for now just return a number
+ return nextName++;
+}
+
+var map = [
+ [0, 0, 0, 0, 0, 0, 0],
+ [1, 1, 0, 1, 0, 1, 1],
+ [0, 1, 0, 1, 0, 0, 0],
+ [0, 1, 0, 1, 0, 1, 1],
+ [0, 0, 0, 1, 0, 0, 0],
+ [1, 0, 0, 1, 1, 1, 1],
+ [1, 1, 0, 1, 1, 0, 1],
+];
+
+function wrapX(x) {
+ if (x < 0) return wrapX(x + map[0].length);
+ if (x >= map[0].length) return wrapX(x - map[0].length);
+ return x;
+}
+
+function wrapY(y) {
+ if (y < 0) return wrapY(y + map.length);
+ if (y >= map[0].length) return wrapY(y - map.length);
+ return y;
+}
+
+function sendMapData(callback) {
+ var data = '';
+ for (var y = viewer.y-1; y <= viewer.y+1; y += 1) {
+ for (var x = viewer.x-1; x <= viewer.x+1; x += 1) {
+ if (data != '')
+ data += ',';
+ data += map[y][x];
+ }
+ }
+ callback('map ' + data);
+}
+
+var viewers = {};
+onconnect = function (event) {
+ event.ports[0]._name = getNextName();
+ event.ports[0]._data = { port: event.port, x: 0, y: 0, };
+ viewers[event.ports[0]._name] = event.port._data;
+ event.ports[0].postMessage('cfg ' + name);
+ event.ports[0].onmessage = getMessage;
+ sendMapData(event.ports[0].postMessage);
+};
+
+function getMessage(event) {
+ switch (event.data.substr(0, 4)) {
+ case 'mov ':
+ var direction = event.data.substr(4);
+ var dx = 0;
+ var dy = 0;
+ switch (direction) {
+ case 'up': dy = -1; break;
+ case 'down': dy = 1; break;
+ case 'left': dx = -1; break;
+ case 'right': dx = 1; break;
+ }
+ event.target._data.x = wrapX(event.target._data.x + dx);
+ event.target._data.y = wrapY(event.target._data.y + dy);
+ sendMapData(event.target.postMessage);
+ break;
+ case 'set ':
+ var value = event.data.substr(4);
+ map[event.target._data.y][event.target._data.x] = value;
+ for (var viewer in viewers)
+ sendMapData(viewers[viewer].port.postMessage);
+ break;
+ case 'txt ':
+ var name = event.target._name;
+ var message = event.data.substr(4);
+ for (var viewer in viewers)
+ viewers[viewer].port.postMessage('txt ' + name + ' ' + message);
+ break;
+ case 'msg ':
+ var party1 = event._data;
+ var party2 = viewers[event.data.substr(4).split(' ', 1)];
+ if (party2) {
+ var channel = new MessageChannel();
+ party1.port.postMessage('msg ' + party2.name, [channel.port1]);
+ party2.port.postMessage('msg ' + party1.name, [channel.port2]);
+ }
+ break;
+ }
+}</pre>
+
+ <p><strong>Connecting to multiple pages</strong>. The script uses
+ the <code title=handler-SharedWorkerGlobalScope-onconnect><a href=#handler-sharedworkerglobalscope-onconnect>onconnect</a></code>
+ event listener to listen for multiple connections.</p>
+
+ <p><strong>Direct channels</strong>. When the worker receives a
+ "msg" message from one viewer naming another viewer, it sets up a
+ direct connection between the two, so that the two viewers can
+ communicate directly without the worker having to proxy all the
+ messages.</p>
+
+ <p><a href=http://www.whatwg.org/demos/workers/multiviewer/page.html>View this example online</a>.</p>
+
+
+ <h4 id=delegation><span class=secno>1.2.6 </span>Delegation</h4>
+
+ <p><i>This section is non-normative.</i></p>
+
+ <p>With multicore CPUs becoming prevalent, one way to obtain better
+ performance is to split computationally expensive tasks amongst
+ multiple workers. In this example, a computationally expensive task
+ that is to be performed for every number from 1 to 10,000,000 is
+ farmed out to ten subworkers.</p>
+
+ <p>The main page is as follows, it just reports the result:</p>
+
+ <pre><!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Worker example: Multicore computation</title>
+ </head>
+ <body>
+ <p>Result: <output id="result"></output></p>
+ <script>
+ var worker = new Worker('worker.js');
+ worker.onmessage = function (event) {
+ document.getElementById('result').textContent = event.data;
+ };
+ </script>
+ </body>
+</html></pre>
+
+ <p>The worker itself is as follows:</p>
+
+ <pre>// settings
+var num_workers = 10;
+var items_per_worker = 1000000;
+
+// start the workers
+var result = 0;
+var pending_workers = num_workers;
+for (var i = 0; i < num_workers; i += 1) {
+ var worker = new Worker('core.js');
+ worker.postMessage(i * items_per_worker);
+ worker.postMessage((i+1) * items_per_worker);
+ worker.onmessage = storeResult;
+}
+
+// handle the results
+function storeResult(event) {
+ result += 1*event.data;
+ pending_workers -= 1;
+ if (pending_workers <= 0)
+ postMessage(result); // finished!
+}</pre>
+
+ <p>It consists of a loop to start the subworkers, and then a handler
+ that waits for all the subworkers to respond.</p>
+
+ <p>The subworkers are implemented as follows:</p>
+
+ <pre>var start;
+onmessage = getStart;
+function getStart(event) {
+ start = 1*event.data;
+ onmessage = getEnd;
+}
+
+var end;
+function getEnd(event) {
+ end = 1*event.data;
+ onmessage = null;
+ work();
+}
+
+function work() {
+ var result = 0;
+ for (var i = start; i < end; i += 1) {
+ // perform some complex calculation here
+ result += 1;
+ }
+ postMessage(result);
+ close();
+}</pre>
+
+ <p>They receive two numbers in two events, perform the computation
+ for the range of numbers thus specified, and then report the result
+ back to the parent.</p>
+
+ <p><a href=http://www.whatwg.org/demos/workers/multicore/page.html>View this example online</a>.</p>
+
+<!--(this uses startConversation, which is currently commented out)
+
+ <h4>Providing libraries</h4>
+
+ <!- -END dev-html- -><p><i>This section is non-normative.</i></p><!- -START dev-html- ->
+
+ <p>Suppose that a cryptography library is made available that
+ provides three tasks:</p>
+
+ <dl>
+
+ <dt>Generate a public/private key pair</dt>
+
+ <dd>Takes a port, on which it will send two messages, first the
+ public key and then the private key.</dd>
+
+ <dt>Given a plaintext and a public key, return the corresponding cyphertext</dt>
+
+ <dd>Takes a port, to which any number of messages can be sent, the
+ first giving the public key, and the remainder giving the
+ plaintext, each of which is encrypted and then sent on that same
+ channel as the cyphertext. The user can close the port when it is
+ done encrypting content.</dd>
+
+ <dt>Given a cyphertext and a private key, return the corresponding plaintext</dt>
+
+ <dd>Takes a port, to which any number of messages can be sent, the
+ first giving the private key, and the remainder giving the
+ cyphertext, each of which is decrypted and then sent on that same
+ channel as the plaintext. The user can close the port when it is
+ done decrypting content.</dd>
+
+ </dl>
+
+ <p>The library itself is as follows:</p>
+
+ <pre>function handleMessage(e) {
+ if (e.data == "genkeys")
+ genkeys(e.ports[0]);
+ else if (e.data == "encrypt")
+ encrypt(e.ports[0]);
+ else if (e.data == "decrypt")
+ decrypt(e.ports[0]);
+}
+
+function genkeys(p) {
+ var keys = _generateKeyPair();
+ p.postMessage(keys[0]);
+ p.postMessage(keys[1]);
+}
+
+function encrypt(p) {
+ var key, state = 0;
+ p.onmessage = function (e) {
+ if (state == 0) {
+ key = e.data;
+ state = 1;
+ } else {
+ p.postMessage(_encrypt(key, e.data));
+ }
+ };
+}
+
+function decrypt(p) {
+ var key, state = 0;
+ p.onmessage = function (e) {
+ if (state == 0) {
+ key = e.data;
+ state = 1;
+ } else {
+ p.postMessage(_decrypt(key, e.data));
+ }
+ };
+}
+
+// support being used as a shared worker as well as a dedicated worker
+if ('onmessage' in this) // dedicated worker
+ onmessage = handleMessage;
+else // shared worker
+ onconnect = function (e) { e.port.onmessage = handleMessage; }
+
+
+// the "crypto" functions:
+
+function _generateKeyPair() {
+ return [Math.random(), Math.random()];
+}
+
+function _encrypt(k, s) {
+ return 'encrypted-' + k + ' ' + s;
+}
+
+function _decrypt(k, s) {
+ return s.substr(s.indexOf(' ')+1);
+}</pre>
+
+ <p>Note that the crypto functions here are just stubs and don't do
+ real cryptography.</p>
+
+ <p>This library could be used as follows:</p>
+
+ <pre><!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Worker example: Crypto library</title>
+ <script>
+ var cryptoLib = new Worker('libcrypto-v1.js'); // or could use 'libcrypto-v2.js'
+ function getKeys() {
+ var state = 0;
+ cryptoLib.startConversation("genkeys").onmessage = function (e) {
+ if (state == 0)
+ document.getElementById('public').value = e.data;
+ else if (state == 1)
+ document.getElementById('private').value = e.data;
+ state += 1;
+ };
+ }
+ function enc() {
+ var port = cryptoLib.startConversation("encrypt");
+ port.postMessage(document.getElementById('public').value);
+ port.postMessage(document.getElementById('input').value);
+ port.onmessage = function (e) {
+ document.getElementById('input').value = e.data;
+ port.close();
+ };
+ }
+ function dec() {
+ var port = cryptoLib.startConversation("decrypt");
+ port.postMessage(document.getElementById('private').value);
+ port.postMessage(document.getElementById('input').value);
+ port.onmessage = function (e) {
+ document.getElementById('input').value = e.data;
+ port.close();
+ };
+ }
+ </script>
+ <style>
+ textarea { display: block; }
+ </style>
+ </head>
+ <body onload="getKeys()">
+ <fieldset>
+ <legend>Keys</legend>
+ <p><label>Public Key: <textarea id="public"></textarea></label></p>
+ <p><label>Private Key: <textarea id="private"></textarea></label></p>
+ </fieldset>
+ <p><label>Input: <textarea id="input"></textarea></label></p>
+ <p><button onclick="enc()">Encrypt</button> <button onclick="dec()">Decrypt</button></p>
+ </body>
+</html></pre>
+
+ <p>A later version of the API, though, might want to offload all the
+ crypto work onto subworkers. This could be done as follows:</p>
+
+ <pre>function handleMessage(e) {
+ if (e.data == "genkeys")
+ genkeys(e.ports[0]);
+ else if (e.data == "encrypt")
+ encrypt(e.ports[0]);
+ else if (e.data == "decrypt")
+ decrypt(e.ports[0]);
+}
+
+function genkeys(p) {
+ var generator = new Worker('libcrypto-v2-generator.js');
+ generator.postMessage('', [p]);
+}
+
+function encrypt(p) {
+ p.onmessage = function (e) {
+ var key = e.data;
+ var encryptor = new Worker('libcrypto-v2-encryptor.js');
+ encryptor.postMessage(key, [p]);
+ };
+}
+
+function encrypt(p) {
+ p.onmessage = function (e) {
+ var key = e.data;
+ var decryptor = new Worker('libcrypto-v2-decryptor.js');
+ decryptor.postMessage(key, [p]);
+ };
+}
+
+// support being used as a shared worker as well as a dedicated worker
+if ('onmessage' in this) // dedicated worker
+ onmessage = handleMessage;
+else // shared worker
+ onconnect = function (e) { e.ports[0].onmessage = handleMessage };
+</pre>
+
+ <p>The little subworkers would then be as follows.</p>
+
+ <p>For generating key pairs:</p>
+
+ <pre>onmessage = function (e) {
+ var k = _generateKeyPair();
+ e.ports[0].postMessage(k[0]);
+ e.ports[0].postMessage(k[1]);
+ close();
+}
+
+function _generateKeyPair() {
+ return [Math.random(), Math.random()];
+}</pre>
+
+ <p>For encrypting:</p>
+
+ <pre>onmessage = function (e) {
+ var key = e.data;
+ e.ports[0].onmessage = function (e) {
+ var s = e.data;
+ postMessage(_encrypt(key, s));
+ }
+}
+
+function _encrypt(k, s) {
+ return 'encrypted-' + k + ' ' + s;
+}</pre>
+
+ <p>For decrypting:</p>
+
+ <pre>onmessage = function (e) {
+ var key = e.data;
+ e.ports[0].onmessage = function (e) {
+ var s = e.data;
+ postMessage(_decrypt(key, s));
+ }
+}
+
+function _decrypt(k, s) {
+ return s.substr(s.indexOf(' ')+1);
+}</pre>
+
+ <p>Notice how the users of the API don't have to even know that this
+ is happening — the API hasn't changed; the library can
+ delegate to subworkers without changing its API, even though it is
+ accepting data using message channels.</p>
+
+ <p><a href="http://www.whatwg.org/demos/workers/crypto/page.html">View this example online</a>.</p>
+
+(end startConversation block) (beware nested comments)-->
+
+
+
+
+
+ <h2 id=conformance-requirements><span class=secno>2 </span>Conformance requirements</h2>
+
<p>All diagrams, examples, and notes in this specification are
- non-normative, as are all sections explicitly marked non-normative.
- Everything else in this specification is normative.
+ non-normative, as are all sections explicitly marked non-normative.
+ Everything else in this specification is normative.</p>
<p>The key words "MUST", "MUST NOT", "REQUIRED", <!--"SHALL", "SHALL
- NOT",-->
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the
- normative parts of this document are to be interpreted as described in
- RFC2119. For readability, these words do not appear in all uppercase
- letters in this specification. <a href="#refsRFC2119">[RFC2119]</a></p>
- <!-- XXX but they should be
- marked up -->
+ NOT",--> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
+ "OPTIONAL" in the normative parts of this document are to be
+ interpreted as described in RFC2119. For readability, these words do
+ not appear in all uppercase letters in this specification. <a href=#refsRFC2119>[RFC2119]</a></p>
- <p>Requirements phrased in the imperative as part of algorithms (such as
- "strip any leading space characters" or "return false and abort these
- steps") are to be interpreted with the meaning of the key word ("must",
- "should", "may", etc) used in introducing the algorithm.
+ <p>Requirements phrased in the imperative as part of algorithms
+ (such as "strip any leading space characters" or "return false and
+ abort these steps") are to be interpreted with the meaning of the
+ key word ("must", "should", "may", etc) used in introducing the
+ algorithm.</p>
- <p>Some conformance requirements are phrased as requirements on attributes,
- methods or objects. Such requirements are to be interpreted as
- requirements on user agents.
+ <p>Some conformance requirements are phrased as requirements on
+ attributes, methods or objects. Such requirements are to be
+ interpreted as requirements on user agents.</p>
- <p>Conformance requirements phrased as algorithms or specific steps may be
- implemented in any manner, so long as the end result is equivalent. (In
- particular, the algorithms defined in this specification are intended to
- be easy to follow, and not intended to be performant.)
+ <p>Conformance requirements phrased as algorithms or specific steps
+ may be implemented in any manner, so long as the end result is
+ equivalent. (In particular, the algorithms defined in this
+ specification are intended to be easy to follow, and not intended to
+ be performant.)</p>
- <p>The only conformance class defined by this specification is user agents.
+ <p>The only conformance class defined by this specification is user
+ agents.</p>
- <p>User agents may impose implementation-specific limits on otherwise
- unconstrained inputs, e.g. to prevent denial of service attacks, to guard
- against running out of memory, or to work around platform-specific
- limitations.
+ <p>User agents may impose implementation-specific limits on
+ otherwise unconstrained inputs, e.g. to prevent denial of service
+ attacks, to guard against running out of memory, or to work around
+ platform-specific limitations.</p>
- <h4 id=dependencies><span class=secno>1.4.1 </span>Dependencies</h4>
+ <p>When support for a feature is disabled (e.g. as an emergency
+ measure to mitigate a security problem, or to aid in development, or
+ for performance reasons), user agents must act as if they had no
+ support for the feature whatsoever, and as if the feature was not
+ mentioned in this specification. For example, if a particular
+ feature is accessed via an attribute in a Web IDL interface, the
+ attribute itself would be omitted from the objects that implement
+ that interface — leaving the attribute on the object but
+ making it return null or throw an exception is insufficient.</p>
- <p>This specification relies on several other underlying specifications.
- <dl>
- <dt>HTML5
+ <h3 id=dependencies><span class=secno>2.1 </span>Dependencies</h3>
- <dd>
- <p>Many fundamental concepts from HTML5 are used by this specification.
- <a href="#refsHTML5">[HTML5]</a></p>
+ <p>This specification relies on several other underlying
+ specifications.</p>
- <dt>ECMAScript
+ <dl><dt>HTML</dt>
<dd>
- <p>This specification is intended to be used with JavaScript as the
- scripting language. <a href="#refsJS">[JS]</a></p>
- <dt>WebIDL
+ <p>Many fundamental concepts from HTML are used by this
+ specification. <a href=#refsHTML>[HTML]</a></p>
+ </dd>
+
+ <dt>WebIDL</dt>
+
<dd>
- <p>The IDL blocks in this specification use the semantics of the WebIDL
- specification. <a href="#refsWebIDL">[WebIDL]</a></p>
- </dl>
- <h3 id=terminology><span class=secno>1.5 </span>Terminology</h3>
+ <p>The IDL blocks in this specification use the semantics of the
+ WebIDL specification. <a href=#refsWEBIDL>[WEBIDL]</a></p>
- <p>For simplicity, terms such as <em>shown</em>, <em>displayed</em>, and
- <em>visible</em> might sometimes be used when referring to the way a
- document is rendered to the user. These terms are not meant to imply a
- visual medium; they must be considered to apply to other media in
- equivalent ways.
+ </dd>
- <p>The construction "a <code>Foo</code> object", where <code>Foo</code> is
- actually an interface, is sometimes used instead of the more accurate "an
- object implementing the interface <code>Foo</code>".
+ </dl><h2 id=terminology><span class=secno>3 </span>Terminology</h2>
- <p>The term DOM is used to refer to the API set made available to scripts
- in Web applications, and does not necessarily imply the existence of an
- actual <code>Document</code> object or of any other <code>Node</code>
- objects as defined in the DOM Core specifications. <a
- href="#refsDOM3CORE">[DOM3CORE]</a>
+ <p>The construction "a <code title="">Foo</code> object", where
+ <code title="">Foo</code> is actually an interface, is sometimes
+ used instead of the more accurate "an object implementing the
+ interface <code title="">Foo</code>".</p>
- <p>A DOM attribute is said to be <em>getting</em> when its value is being
- retrieved (e.g. by author script), and is said to be <em>setting</em> when
- a new value is assigned to it.
+ <p>The term DOM is used to refer to the API set made available to
+ scripts in Web applications, and does not necessarily imply the
+ existence of an actual <code>Document</code> object or of any other
+ <code>Node</code> objects as defined in the DOM Core
+ specifications. <a href=#refsDOMCORE>[DOMCORE]</a></p>
- <p>If a DOM object is said to be <dfn id=live>live</dfn>, then that means
- that any attributes returning that object must always return the same
- object (not a new object each time), and the attributes and methods on
- that object must operate on the actual underlying data, not a snapshot of
- the data.
+ <p>An IDL attribute is said to be <em>getting</em> when its value is
+ being retrieved (e.g. by author script), and is said to be
+ <em>setting</em> when a new value is assigned to it.</p>
- <h2 class=no-num id=references>References</h2>
+
+ <p>The term "JavaScript" is used to refer to ECMA262, rather than
+ the official term ECMAScript, since the term JavaScript is more
+ widely known. <a href=#refsECMA262>[ECMA262]</a></p>
- <p class=big-issue>This section will be written in a future
- draft.<!--XXX-->
- <h2 class=no-num id=acknowledgements>Acknowledgements</h2>
- <!-- ACKS -->
- <p>Thanks to Maciej Stachowiak and Mike Smith for their useful and
- substantial comments.
+ <h2 id=infrastructure><span class=secno>4 </span>Infrastructure</h2>
+
+ <p>There are two kinds of workers; dedicated workers, and shared
+ workers. Dedicated workers, once created, and are linked to their
+ creator; but message ports can be used to communicate from a
+ dedicated worker to multiple other browsing contexts or
+ workers. Shared workers, on the other hand, are named, and once
+ created any script running in the same <span>origin</span> can
+ obtain a reference to that worker and communicate with it.</p>
+
+
+ <h3 id=the-global-scope><span class=secno>4.1 </span>The global scope</h3>
+
+ <p>The global scope is the "inside" of a worker.</p>
+
+ <h4 id=the-workerglobalscope-abstract-interface><span class=secno>4.1.1 </span>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> abstract interface</h4>
+
+ <pre class=idl>interface <dfn id=workerglobalscope>WorkerGlobalScope</dfn> {
+ readonly attribute <a href=#workerglobalscope>WorkerGlobalScope</a> <a href=#dom-workerglobalscope-self title=dom-WorkerGlobalScope-self>self</a>;
+ readonly attribute <a href=#workerlocation>WorkerLocation</a> <a href=#dom-workerglobalscope-location title=dom-WorkerGlobalScope-location>location</a>;
+
+ void <a href=#dom-workerglobalscope-close title=dom-WorkerGlobalScope-close>close</a>();
+<!-- v2-onclose attribute <span>Function</span>? <span title="handler-WorkerGlobalScope-onclose">onclose</span>;
+--> attribute <span>Function</span>? <a href=#handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror>onerror</a>;
+ attribute <span>Function</span>? <a href=#handler-workerglobalscope-onoffline title=handler-WorkerGlobalScope-onoffline>onoffline</a>;
+ attribute <span>Function</span>? <a href=#handler-workerglobalscope-ononline title=handler-WorkerGlobalScope-ononline>ononline</a>;
+};
+<a href=#workerglobalscope>WorkerGlobalScope</a> implements <a href=#workerutils>WorkerUtils</a>;
+<a href=#workerglobalscope>WorkerGlobalScope</a> implements <span>EventTarget</span>;</pre>
+
+ <p>The <dfn id=dom-workerglobalscope-self title=dom-WorkerGlobalScope-self><code>self</code></dfn> attribute
+ must return the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object itself.</p>
+
+ <p>The <dfn id=dom-workerglobalscope-location title=dom-WorkerGlobalScope-location><code>location</code></dfn>
+ attribute must return the <code><a href=#workerlocation>WorkerLocation</a></code> object created
+ for the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object when the worker was
+ created. It represents the <span>absolute URL</span> of the script
+ that was used to initialize the worker, after any redirects.</p>
+
+ <hr><p>When a script invokes the <dfn id=dom-workerglobalscope-close title=dom-WorkerGlobalScope-close><code>close()</code></dfn>
+ method on a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent
+ must run the following steps (atomically):</p>
+
+ <ol><li><p>Discard any <span title=concept-task>tasks</span> that
+ have been added to the <span>event loop</span>'s <span title="task
+ queue">task queues</span>.</p>
+
+<!-- v2-onclose
+ <li><p><span>Queue a task</span> to <span>fire a simple
+ event</span> named <code title="event-close">close</code> at the
+ <code>WorkerGlobalScope</code> object.</p></li>
+-->
+
+ <li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
+ <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
+ true. (This prevents any further tasks from being queued.)</li>
+
+ </ol><p>The following are the <span>event handlers</span> (and their
+ corresponding <span title="event handler event type">event handler
+ event types</span>) that must be supported, as IDL attributes, by
+ objects implementing the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
+ interface:</p>
+
+ <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
+ <tbody><!-- v2-onclose <tr><td><dfn title="handler-WorkerGlobalScope-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> --><tr><td><dfn id=handler-workerglobalscope-onerror title=handler-WorkerGlobalScope-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
+ <tr><td><dfn id=handler-workerglobalscope-onoffline title=handler-WorkerGlobalScope-onoffline><code>onoffline</code></dfn> <td> <code title=event-offline>offline</code> <!-- new -->
+ <tr><td><dfn id=handler-workerglobalscope-ononline title=handler-WorkerGlobalScope-ononline><code>ononline</code></dfn> <td> <code title=event-online>online</code> <!-- new -->
+ </table><hr><p>The <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface must not exist if
+ the interface's <span>relevant namespace object</span> is a
+ <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
+
+
+
+ <h4 id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface><span class=secno>4.1.2 </span>Dedicated workers and the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> interface</h4>
+
+ <pre class=idl>[Supplemental, NoInterfaceObject]
+interface <dfn id=dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
+ void <a href=#dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage>postMessage</a>(in any message, in optional sequence<<span>MessagePort</span>> ports);<!--
+ <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
+ attribute <span>Function</span>? <a href=#handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage>onmessage</a>;
+};</pre>
+
+ <p><code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects act as if they
+ had an implicit <code>MessagePort</code> associated with them. This
+ port is part of a channel that is set up when the worker is created,
+ but it is not exposed. This object must never be garbage collected
+ before the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
+
+ <p>All messages received by that port must immediately be retargeted
+ at the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>
+
+ <p>The <dfn id=dom-dedicatedworkerglobalscope-postmessage title=dom-DedicatedWorkerGlobalScope-postMessage><code>postMessage()</code></dfn><!--
+ and <dfn
+ title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
+ method<!--s (startConversation)--> on
+ <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects must act as if, when
+ invoked, it<!--/they (startConversation)--> immediately invoked the
+ method of the same name on the port, with the same arguments, and
+ returned the same return value.</p>
+
+ <p>The following are the <span>event handlers</span> (and their
+ corresponding <span title="event handler event type">event handler
+ event types</span>) that must be supported, as IDL attributes, by
+ objects implementing the <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
+ interface:</p>
+
+ <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
+ <tbody><tr><td><dfn id=handler-dedicatedworkerglobalscope-onmessage title=handler-DedicatedWorkerGlobalScope-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
+ </table><p>For the purposes of the <span>application cache</span> networking
+ model, a dedicated worker is an extension of the <span>cache
+ host</span> from which it was created.</p>
+
+
+
+ <h4 id=shared-workers-and-the-sharedworkerglobalscope-interface><span class=secno>4.1.3 </span>Shared workers and the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> interface</h4>
+
+ <pre class=idl>[Supplemental, NoInterfaceObject]
+interface <dfn id=sharedworkerglobalscope>SharedWorkerGlobalScope</dfn> : <a href=#workerglobalscope>WorkerGlobalScope</a> {
+ readonly attribute DOMString <a href=#dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name>name</a>;
+ readonly attribute <span>ApplicationCache</span> <span title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</span>;
+ attribute <span>Function</span>? <a href=#handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect>onconnect</a>;
+};</pre>
+
+ <p>Shared workers receive message ports through <code title=event-WorkerGlobalScope-connect>connect</code> events on
+ their global object for each connection.</p>
+
+ <p>The <dfn id=dom-sharedworkerglobalscope-name title=dom-SharedWorkerGlobalScope-name><code>name</code></dfn>
+ attribute must return the value it was assigned when the
+ <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object was created by the
+ "<a href=#run-a-worker>run a worker</a>" algorithm. Its value represents the name
+ that can be used to obtain a reference to the worker using the
+ <code><a href=#sharedworker>SharedWorker</a></code> constructor.</p>
+
+ <p>The following are the <span>event handlers</span> (and their
+ corresponding <span title="event handler event type">event handler
+ event types</span>) that must be supported, as IDL attributes, by
+ objects implementing the <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
+ interface:</p>
+
+ <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
+ <tbody><tr><td><dfn id=handler-sharedworkerglobalscope-onconnect title=handler-SharedWorkerGlobalScope-onconnect><code>onconnect</code></dfn> <td> <code title=event-connect>connect</code>
+ </table><p>For the purposes of the <span>application cache</span> networking
+ model, a shared worker is its own <span>cache host</span>. The
+ <a href=#run-a-worker>run a worker</a> algorithm takes care of associating the
+ worker with an <span>application cache</span>.</p>
+
+ <p class=note>The <code title=dom-SharedWorkerGlobalScope-applicationCache>applicationCache</code>
+ attribute returns the <code>ApplicationCache</code> object for the
+ worker.</p><!-- normative conf criteria is in the appcache section
+ -->
+
+
+ <h3 id=origins-of-workers><span class=secno>4.2 </span>Origins of workers</h3>
+
+ <p>Both the <span>origin</span> and <span>effective script
+ origin</span> of scripts running in workers are the
+ <span>origin</span> of the <span>absolute URL</span> given in that
+ the worker's <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
+ represents.</p>
+
+
+
+ <h3 id=the-event-loop><span class=secno>4.3 </span>The event loop</h3>
+
+ <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an <span>event
+ loop</span> distinct from those defined for <span title="unit of
+ related similar-origin browsing contexts">units of related
+ similar-origin browsing contexts</span>. This <span>event
+ loop</span> has no associated <span>browsing context</span>, and its
+ <span title="task queue">task queues</span> only have events,
+ callbacks, and networking activity as <span title=concept-task>tasks</span>. The processing model of these
+ <span title="event loop">event loops</span> is defined below in the
+ <a href=#run-a-worker>run a worker</a> algorithm.</p>
+
+ <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object also has a <dfn id=dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</dfn> flag, which must
+ initially be false, but which can get set to true by the algorithms
+ in the processing model section below.</p>
+
+ <p>Once the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set to
+ true, the <span>event loop</span>'s <span title="task queue">task
+ queues</span> must discard any further <span title=concept-task>tasks</span> that would be added to them (tasks
+ already on the queue are unaffected except where otherwise
+ specified). Effectively, once the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is true,
+ timers stop firing, notifications for all pending asynchronous
+ operations are dropped, etc.</p>
+
+
+
+ <h3 id="the-worker's-lifetime"><span class=secno>4.4 </span>The worker's lifetime</h3>
+
+ <p>Workers communicate with other workers and with <span title="browsing context">browsing contexts</span> through <span title="channel messaging">message channels</span> and their
+ <code>MessagePort</code> objects.</p>
+
+ <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var title="">worker global
+ scope</var> has a list of <dfn id="the-worker's-ports">the worker's ports</dfn>, which
+ consists of all the <code>MessagePort</code> objects that are
+ entangled with another port and that have one (but only one) port
+ owned by <var title="">worker global scope</var>. This list includes
+ <!--all the <code>MessagePort</code> objects that are in events
+ pending in the <span>event loop</span>, as well as (commented out
+ because in practice it makes no difference either way as far as I
+ can tell, and it would be hard to strictly implement since these
+ ports might not yet be across the thread boundary)--> the implicit
+ <code>MessagePort</code> in the case of <a href=#dedicatedworkerglobalscope title=DedicatedWorkerGlobalScope>dedicated workers</a>.</p>
+
+ <p>Each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> also has a list of <dfn id="the-worker's-workers">the
+ worker's workers</dfn>. Initially this list is empty; it is
+ populated when the worker creates or obtains further workers.</p>
+
+ <p>Finally, each <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> also has a list of
+ <dfn id="the-worker's-documents">the worker's <code>Document</code>s</dfn>. Initially this list
+ is empty; it is populated when the worker is created.</p>
+
+ <p>Whenever a <code>Document</code> <var title="">d</var> is <dfn id="add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">added to the
+ worker's <code>Document</code>s</dfn>, the user agent must, for each
+ worker in the list of <a href="#the-worker's-workers">the worker's workers</a> whose list
+ of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> does not contain
+ <var title="">d</var>, <a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's
+ documents">add <var title="">d</var> to <var title="">q</var>'s
+ <code>WorkerGlobalScope</code> owner's list of <span>the worker's
+ <code>Document</code>s</span></a>.</p> <!-- suggestions welcome
+ on making this sentence into understandable English -->
+
+ <p>Whenever a <code>Document</code> object is <span title="discard a
+ Document">discarded</span>, it must be removed from the list of
+ <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> of each worker
+ whose list contains that <code>Document</code>.</p>
+
+ <p>Given a <span>script's global object</span> <var title="">o</var>
+ when creating or obtaining a worker, the <dfn id=list-of-relevant-document-objects-to-add>list of relevant
+ <code>Document</code> objects to add</dfn> depends on the type of
+ <var title="">o</var>. If <var title="">o</var> is a
+ <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object (i.e. if we are creating a
+ nested worker), then the relevant <code>Document</code>s are the
+ <code>Document</code>s that are in <var title="">o</var>'s own list
+ of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a>. Otherwise, <var title="">o</var> is a <code>Window</code> object, and the relevant
+ <code>Document</code> is just the <code>Document</code> that is the
+ <span>active document</span> of the <code>Window</code> object <var title="">o</var>.</p>
+
+ <hr><p>A worker is said to be a <dfn id=permissible-worker>permissible worker</dfn> if its
+ list of <a href="#the-worker's-documents">the worker's <code>Document</code>s</a> is not
+ empty.</p>
+
+ <p>A worker is said to be a <dfn id=protected-worker>protected worker</dfn> if it is a
+ <a href=#permissible-worker>permissible worker</a> and either it has outstanding
+ timers, database transactions, or network connections, or its list
+ of <a href="#the-worker's-ports">the worker's ports</a> is not empty, or its
+ <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> is actually a
+ <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
+ shared worker).</p>
+
+ <p>A worker is said to be an <dfn id=active-needed-worker>active needed worker</dfn> if any
+ of the <code>Document</code> objects in <a href="#the-worker's-documents">the worker's
+ <code>Document</code>s</a> are <span>fully active</span>.</p>
+
+ <p>A worker is said to be a <dfn id=suspendable-worker>suspendable worker</dfn> if it is
+ not an <a href=#active-needed-worker>active needed worker</a> but it is a
+ <a href=#permissible-worker>permissible worker</a>.</p>
+
+
+ <h3 id=processing-model><span class=secno>4.5 </span>Processing model</h3>
+
+ <p>When a user agent is to <dfn id=run-a-worker>run a worker</dfn> for a script with
+ <span>URL</span> <var title="">url</var>, a <span>browsing
+ context</span> <var title="">owner browsing context</var>, a
+ <code>Document</code> <var title="">owner document</var>, an
+ <span>origin</span> <var title="">owner origin</var>, and with
+ global scope <var title="">worker global scope</var>, it must run
+ the following steps:</p>
+
+ <ol><li>
+
+ <p>Create a separate parallel execution environment (i.e. a
+ separate thread or process or equivalent construct), and run the
+ rest of these steps asynchronously in that context.</p>
+
+ </li>
+
+ <li><p>If <var title="">worker global scope</var> is actually a
+ <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object (i.e. the worker is a
+ shared worker), and there are any <span title="relevant application
+ cache">relevant application caches</span> that are identified by a
+ manifest URL with the <span>same origin</span> as <var title="">url</var> and that have <var title="">url</var> as one of
+ their entries, <em>not</em> excluding entries marked as <span title=concept-appcache-foreign>foreign</span>, then associate the
+ <var title="">worker global scope</var> with the <span title=concept-appcache-selection>most appropriate application
+ cache</span> of those that match.</li>
+
+ <li>
+
+ <p>Attempt to <span>fetch</span> the resource identified by <var title="">url</var>, from the <var title="">owner origin</var>,
+ with the <i>synchronous flag</i> set and the <i>force same-origin
+ flag</i> set.</p> <!-- not http-origin privacy sensitive (looking
+ forward to CORS) -->
+
+ <p>If the attempt fails, then for each <code><a href=#worker>Worker</a></code> or
+ <code><a href=#sharedworker>SharedWorker</a></code> object associated with <var title="">worker global scope</var>, <span>queue a task</span> to
+ <span>fire a simple event</span> named <code title=event-error>error</code> at that object. Abort these
+ steps.</p>
+
+ <p>If the attempt succeeds, then let <var title="">source</var> be
+ the script resource <span>decoded as UTF-8, with error
+ handling</span>.
+
+ <a href=#refsHTML>[HTML]</a>
+
+ </p>
+
+ <p>Let <var title="">language</var> be JavaScript.</p>
+
+ <p class=note>As with <code>script</code> elements, the MIME
+ type of the script is ignored. Unlike with <code>script</code>
+ elements, there is no way to override the type. It's always
+ assumed to be JavaScript.</p>
+
+ </li>
+
+ <li>
+
+ <p>A new <span title=concept-script>script</span> is now
+ created, as follows.</p>
+
+ <p>Create a new <span>script execution environment</span>
+ set up as appropriate for the scripting language <var title="">language</var>.</p>
+
+ <p>Parse/compile/initialize <var title="">source</var> using that
+ <span>script execution environment</span>, as appropriate for <var title="">language</var>, and thus obtain a <span>list of code
+ entry-points</span>; set the <i>initial code entry-point</i> to
+ the entry-point for any executable code to be immediately run.</p>
+
+ <p>Set the <span>script's global object</span> to <var title="">worker global scope</var>.</p>
+
+ <p>Set the <span>script's browsing context</span> to <var title="">owner browsing context</var>.</p>
+
+ <p>Set the <span>script's document</span> to <var title="">owner
+ document</var>.</p>
+
+ <p>Set the <span>script's URL character encoding</span> to
+ UTF-8. (This is just used for encoding non-ASCII characters in the
+ query component of URLs.)</p>
+
+ <p>Set the <span>script's base URL</span> to <var title="">url</var>.</p>
+
+ </li>
+
+ <li>
+
+ <p><strong>Closing orphan workers</strong>: Start monitoring the
+ worker such that no sooner than it stops being either a
+ <a href=#protected-worker>protected worker</a> or a <a href=#suspendable-worker>suspendable
+ worker</a>, and no later than it stops being a
+ <a href=#permissible-worker>permissible worker</a>, <var title="">worker global
+ scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
+ to true<!-- v2-onclose and <span title="queue a task">a task is
+ queued</span> to <span>fire a simple event</span> named <code
+ title="event-close">close</code> at <var title="">worker global
+ scope</var>-->.</p>
+
+ </li>
+
+ <li>
+
+ <p><strong>Suspending workers</strong>: Start monitoring the
+ worker, such that whenever <var title="">worker global
+ scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is false
+ and the worker is a <a href=#suspendable-worker>suspendable worker</a>, the user
+ agent suspends execution of script in that worker until such time
+ as either the <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag switches
+ to true or the worker stops being a <a href=#suspendable-worker>suspendable
+ worker</a>.</p>
+
+ </li>
+
+ <li>
+
+ <p><span title="jump to a code entry-point">Jump</span> to the
+ <span title=concept-script>script</span>'s <i>initial code
+ entry-point</i>, and let that run until it either returns, fails
+ to catch an exception, or gets prematurely aborted by the
+ "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>"
+ algorithms defined below.</p>
+
+<!-- v2-onclose
+ <p class="note">If the script gets aborted by the "<span>kill a
+ worker</span>" algorithm, then that same algorithm will cause
+ there to only be a single <span title="concept-task">task</span>
+ in the <span>event loop</span> at the next step, namely the task
+ for the <code title="message-close">close</code> event. The
+ "<span>terminate a worker</span>" algorithm removes all the
+ events.</p>
+-->
+
+ </li>
+
+ <li><p>If <var title="">worker global scope</var> is actually a
+ <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is
+ a dedicated worker), then enable the <span>port message
+ queue</span> of the worker's implicit port.</li>
+
+ <li>
+
+ <p><i title="">Event loop</i>: Wait until either there is a <span title=concept-task>task</span> in one of the <span>event
+ loop</span>'s <span title="task queue">task queues</span> or <var title="">worker global scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
+ to true.</p>
+
+ </li>
+
+ <li>
+
+ <p>Run the oldest task on one of the <span>event loop</span>'s
+ <span title="task queue">task queues</span>, if any. The user
+ agent may pick any <span>task queue</span>.</p>
+
+ <p class=note>The handling of events or the execution of
+ callbacks might get prematurely aborted by the "<a href=#kill-a-worker>kill a
+ worker</a>" or "<a href=#terminate-a-worker>terminate a worker</a>" algorithms
+ defined below.</p>
+
+ </li>
+
+ <li>
+
+ <p>If the <span>storage mutex</span> is now owned by the worker's
+ <span>event loop</span>, release it so that it is once again
+ free.</p>
+
+ </li>
+
+ <li>
+
+ <p>Remove the task just run in the earlier step, if any, from its
+ <span>task queue</span>.</p>
+
+ </li>
+
+ <li>
+
+ <p>If there are any more events in the <span>event loop</span>'s
+ <span title="task queue">task queues</span> or if <var title="">worker global scope</var>'s <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag is set
+ to false, then jump back to the step above labeled <i>event
+ loop</i>.</p>
+
+ </li>
+
+ <li>
+
+ <p>Empty the <var title="">worker global scope</var>'s <span>list
+ of active timeouts</span> and its <span>list of active
+ intervals</span>.</p>
+
+ </li>
+
+ <li>
+
+ <p>Disentangle all the ports in the list of <a href="#the-worker's-ports">the worker's
+ ports</a>.</p>
+
+ </li>
+
+<!-- v2-onclose
+ <li>
+
+ <p>For each <code>Worker</code> or <code>SharedWorker</code>
+ object associated with <var title="">worker global scope</var>,
+ <span>queue a task</span> to <span>fire a simple event</span>
+ named <code title="event-close">close</code> at that object.</p>
+
+ </li>
+-->
+ </ol><hr><p>When a user agent is to <dfn id=kill-a-worker>kill a worker</dfn> it must
+ run the following steps in parallel with the worker's main loop (the
+ "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
+
+ <ol><!-- v2-onclose
+ <li><p>If the worker's <code>WorkerGlobalScope</code> object's
+ <span title="dom-WorkerGlobalScope-closing">closing</span> flag is
+ false, <span>queue a task</span> to <span>fire a simple
+ event</span> named <code title="event-close">close</code> at the
+ worker's <code>WorkerGlobalScope</code> object.</p></li>
+--><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
+ true.</li>
+
+<!-- v2-onclose
+ <li><p>Wait a user-agent-defined amount of time. If the "<span>run
+ a worker</span>" processing model defined above immediately starts
+ running event listeners registered for the <code
+ title="event-close">close</code> event, this time should not be
+ zero — the idea is that the <code
+ title="event-close">close</code> event can be used to clean up
+ when shutting down unexpectedly.</p></li>
+-->
+
+ <li><p>If there are any <span title=concept-task>tasks</span>
+ queued in the <span>event loop</span>'s <span title="task
+ queue">task queues</span><!-- v2-onclose other than the <code
+ title="event-close">close</code> event that this algorithm just
+ added-->, discard them without processing them.</li>
+
+<!-- v2-onclose
+ <li><p>If the <code title="event-close">close</code> event that
+ this algorithm just queued hasn't yet been dispatched, then abort
+ the script currently running in the worker.</p></li>
+-->
+
+ <li><p>Wait a user-agent-defined amount of time.</li>
+
+ <li><p>Abort the script currently running in the worker<!--
+ v2-onclose (if any script is running, then it will be a handler for
+ the <code title="event-close">close</code> event)-->.</li>
+
+ </ol><p>User agents may invoke the "<a href=#kill-a-worker>kill a worker</a>"
+ processing model on a worker at any time, e.g. in response to user
+ requests, in response to CPU quota management, or when a worker
+ stops being an <a href=#active-needed-worker>active needed worker</a> if the worker
+ continues executing even after its <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag was
+ set to true.</p>
+
+ <hr><p>When a user agent is to <dfn id=terminate-a-worker>terminate a worker</dfn> it must run
+ the following steps in parallel with the worker's main loop (the
+ "<a href=#run-a-worker>run a worker</a>" processing model defined above):</p>
+
+ <ol><li><p>Set the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's
+ <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag to
+ true.</li>
+
+ <li><p>If there are any <span title=concept-task>tasks</span>
+ queued in the <span>event loop</span>'s <span title="task
+ queue">task queues</span>, discard them without processing
+ them.</li>
+
+ <li><p>Abort the script currently running in the worker.</li>
+
+ <li><p>If the worker's <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is
+ actually a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the
+ worker is a dedicated worker), then empty the <span>port message
+ queue</span> of the port that the worker's implicit port is
+ entangled with.</li>
+
+ </ol><hr><p>The <span>task source</span> for the tasks mentioned above is the
+ <span>DOM manipulation task source</span>.</p>
+
+
+ <h3 id=runtime-script-errors><span class=secno>4.6 </span>Runtime script errors</h3>
+
+ <p>Whenever an uncaught runtime script error occurs in one of the
+ worker's scripts, if the error did not occur while handling a
+ previous script error, the user agent must <span>report the
+ error</span> using the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's <code title=handler-WorkerGlobalScope-onerror><a href=#handler-workerglobalscope-onerror>onerror</a></code>
+ attribute.
+
+ <a href=#refsHTML>[HTML]</a>
+
+ </p>
+
+ <p>For shared workers, if the error is still <i title=concept-error-nothandled>not handled</i> afterwards, or if
+ the error occurred while handling a previous script error, the error
+ may be reported to the user.
+
+ <a href=#refsHTML>[HTML]</a>
+
+ </p>
+
+ <p>For dedicated workers, if the error is still <i title=concept-error-nothandled>not handled</i> afterwards, or if
+ the error occurred while handling a previous script error, the user
+ agent must <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
+ event</a> at the <code><a href=#worker>Worker</a></code> object associated with the
+ worker.</p>
+
+ <p>When the user agent is to <dfn id=fire-a-worker-error-event>fire a worker error event</dfn> at
+ a <code><a href=#worker>Worker</a></code> object, it must create and dispatch an event
+ that uses the <code><a href=#errorevent>ErrorEvent</a></code> interface, with the name <code title=event-error>error</code>, that doesn't bubble and is
+ cancelable, with its <code title=dom-ErrorEvent-message><a href=#dom-errorevent-message>message</a></code>, <code title=dom-ErrorEvent-filename><a href=#dom-errorevent-filename>filename</a></code>, and <code title=dom-ErrorEvent-lineno><a href=#dom-errorevent-lineno>lineno</a></code> attributes set
+ appropriately. The default action of this event depends on whether
+ the <code><a href=#worker>Worker</a></code> object is itself in a worker. If it is, and
+ that worker is also a dedicated worker, then the user agent must
+ again <span>queue a task</span> to <a href=#fire-a-worker-error-event>fire a worker error
+ event</a> at the <code><a href=#worker>Worker</a></code> object associated with
+ <em>that</em> worker. Otherwise, then the error may be reported to
+ the user.</p>
+
+ <p>The <span>task source</span> for the tasks mentioned above is the
+ <span>DOM manipulation task source</span>.</p>
+
+ <hr><pre class=idl>interface <dfn id=errorevent>ErrorEvent</dfn> : <span>Event</span> {
+ readonly attribute DOMString <a href=#dom-errorevent-message title=dom-ErrorEvent-message>message</a>;
+ readonly attribute DOMString <a href=#dom-errorevent-filename title=dom-ErrorEvent-filename>filename</a>;
+ readonly attribute unsigned long <a href=#dom-errorevent-lineno title=dom-ErrorEvent-lineno>lineno</a>;
+ void <a href=#dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent>initErrorEvent</a>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString messageArg, in DOMString filenameArg, in unsigned long linenoArg);
+};</pre>
+
+ <p>The <dfn id=dom-errorevent-initerrorevent title=dom-ErrorEvent-initErrorEvent><code>initErrorEvent()</code></dfn>
+ method must initialize the event in a manner analogous to the
+ similarly-named method in the DOM Events interfaces. <a href=#refsDOMEVENTS>[DOMEVENTS]</a></p>
+
+ <p>The <dfn id=dom-errorevent-message title=dom-ErrorEvent-message><code>message</code></dfn>
+ attribute represents the error message.</p>
+
+ <p>The <dfn id=dom-errorevent-filename title=dom-ErrorEvent-filename><code>filename</code></dfn>
+ attribute represents the <span>absolute URL</span> of the script in
+ which the error originally occurred.</p>
+
+ <p>The <dfn id=dom-errorevent-lineno title=dom-ErrorEvent-lineno><code>lineno</code></dfn>
+ attribute represents the line number where the error occurred in the
+ script.</p>
+
+
+
+ <h3 id=creating-workers><span class=secno>4.7 </span>Creating workers</h3>
+
+ <h4 id=the-abstractworker-abstract-interface><span class=secno>4.7.1 </span>The <code><a href=#abstractworker>AbstractWorker</a></code> abstract interface</h4>
+
+ <pre class=idl>[Supplemental, NoInterfaceObject]
+interface <dfn id=abstractworker>AbstractWorker</dfn> {
+ attribute <span>Function</span>? <a href=#handler-abstractworker-onerror title=handler-AbstractWorker-onerror>onerror</a>;
+<!-- v2-onclose attribute <span>Function</span>? <span title="handler-AbstractWorker-onclose">onclose</span>; -->
+};
+<a href=#abstractworker>AbstractWorker</a> implements <span>EventTarget</span>;</pre>
+
+ <p>The following are the <span>event handlers</span> (and their
+ corresponding <span title="event handler event type">event handler
+ event types</span>) that must be supported, as IDL attributes, by
+ objects implementing the <code><a href=#abstractworker>AbstractWorker</a></code> interface:</p>
+
+ <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
+ <tbody><tr><td><dfn id=handler-abstractworker-onerror title=handler-AbstractWorker-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
+<!-- v2-onclose <tr><td><dfn title="handler-AbstractWorker-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> -->
+ </table><h4 id=dedicated-workers-and-the-worker-interface><span class=secno>4.7.2 </span>Dedicated workers and the <code><a href=#worker>Worker</a></code> interface</h4>
+
+ <pre class=idl>[<a href=#dom-worker title=dom-Worker>Constructor</a>(in DOMString scriptURL)]
+interface <dfn id=worker>Worker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
+ void <a href=#dom-worker-terminate title=dom-Worker-terminate>terminate</a>();
+
+ void <a href=#dom-worker-postmessage title=dom-Worker-postMessage>postMessage</a>(in any message, in optional sequence<<span>MessagePort</span>> ports);<!--
+ <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
+ attribute <span>Function</span>? <a href=#handler-worker-onmessage title=handler-Worker-onmessage>onmessage</a>;
+};</pre>
+
+ <p>The <dfn id=dom-worker-terminate title=dom-Worker-terminate><code>terminate()</code></dfn> method,
+ when invoked, must cause the "<a href=#terminate-a-worker>terminate a worker</a>"
+ algorithm to be run on the worker with with the object is
+ associated.</p>
+
+ <p><code><a href=#worker>Worker</a></code> objects act as if they had an implicit
+ <code>MessagePort</code> associated with them. This port is part of
+ a channel that is set up when the worker is created, but it is not
+ exposed. This object must never be garbage collected before the
+ <code><a href=#worker>Worker</a></code> object.</p>
+
+ <p>All messages received by that port must immediately be retargeted
+ at the <code><a href=#worker>Worker</a></code> object.</p>
+
+ <p>The <dfn id=dom-worker-postmessage title=dom-Worker-postMessage><code>postMessage()</code></dfn><!--
+ and <dfn
+ title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
+ method<!--s (startConversation)--> on <code><a href=#worker>Worker</a></code> objects
+ must act as if, when invoked, it<!--/they (startConversation)-->
+ immediately invoked the method of the same name on the port, with
+ the same arguments, and returned the same return value.</p>
+
+ <p>The following are the <span>event handlers</span> (and their
+ corresponding <span title="event handler event type">event handler
+ event types</span>) that must be supported, as IDL attributes, by
+ objects implementing the <code><a href=#worker>Worker</a></code> interface:</p>
+
+ <table><thead><tr><th><span title="event handlers">Event handler</span> <th><span>Event handler event type</span>
+ <tbody><tr><td><dfn id=handler-worker-onmessage title=handler-Worker-onmessage><code>onmessage</code></dfn> <td> <code title=event-message>message</code>
+ </table><hr><p>When the <dfn id=dom-worker title=dom-Worker><code>Worker(<var title="">scriptURL</var>)</code></dfn> constructor is invoked, the
+ user agent must run the following steps:</p>
+
+ <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument relative to the <span>entry
+ script</span>'s <span title="script's base URL">base URL</span>,
+ when the method is invoked.</li>
+
+ <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
+ exception.</li>
+
+ <li>
+
+ <p>If the <span>origin</span> of the resulting <span>absolute
+ URL</span> is not the <span title="same origin">same</span> as the
+ origin of the <span>entry script</span>, then throw a
+ <code>SECURITY_ERR</code> exception.</p>
+
+ <p class=note>Thus, scripts must be external files with the same
+ scheme as the original page: you can't load a script from a <span title="data protocol"><code title="">data:</code> URL</span> or
+ <span title="javascript protocol"><code title="">javascript:</code> URL</span>, and an <code>https:</code>
+ page couldn't start workers using scripts with <code>http:</code>
+ URLs.</p>
+
+ </li>
+
+ <li><p>Create a new <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>
+ object. Let <var title="">worker global scope</var> be this new
+ object.</li>
+
+ <li><p>Create a new <code><a href=#worker>Worker</a></code> object, associated with
+ <var title="">worker global scope</var>. Let <var title="">worker</var> be this new object.</li>
+
+ <li><p><span>Create a new <code>MessagePort</code> object</span>
+ owned by the <span title="script's global object">global
+ object</span> of the <span title=concept-script>script</span> that
+ invoked the constructor. Let this be the <var title="">outside
+ port</var>.</li>
+
+ <li><p>Associate the <var title="">outside port</var> with <var title="">worker</var>.</li>
+
+ <li><p><span>Create a new <code>MessagePort</code> object</span>
+ owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
+
+ <li><p>Associate <var title="">inside port</var> with <var title="">worker global scope</var>.</li>
+
+ <li><p><span>Entangle</span> <var title="">outside port</var> and
+ <var title="">inside port</var>.</li>
+
+ <li><p>Return <var title="">worker</var>, and run the following
+ steps asynchronously.</li>
+
+<!-- (this is done by the "run a worker" algorithm)
+ <li><p>Enable <var title="">inside port</var>'s <span>port message
+ queue</span>.</p></li>
+-->
+
+ <li><p>Enable <var title="">outside port</var>'s <span>port message
+ queue</span>.</li>
+
+ <li>
+
+ <p>Let <var title="">docs</var> be the <a href=#list-of-relevant-document-objects-to-add>list of relevant
+ <code>Document</code> objects to add</a> given the <span title="script's global object">global object</span> of the <span title=concept-script>script</span> that invoked the
+ constructor.</p>
+
+ </li>
+
+ <li>
+
+ <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
+ <var title="">worker global scope</var>'s list of <span>the
+ worker's <code>Document</code>s</span></a> the
+ <code>Document</code> objects in <var title="">docs</var>.</p>
+
+ </li>
+
+ <li>
+
+ <p>If the <span title="script's global object">global object</span>
+ of the <span title=concept-script>script</span> that invoked the
+ constructor is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object (i.e. we
+ are creating a nested worker), add <var title="">worker global
+ scope</var> to the list of <a href="#the-worker's-workers">the worker's workers</a> of the
+ <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object that is the <span title="script's global object">global object</span> of the <span title=concept-script>script</span> that invoked the
+ constructor.</p>
+
+ </li>
+
+ <li>
+
+ <p><a href=#run-a-worker>Run a worker</a> for the resulting <span>absolute
+ URL</span>, with the <span>script's browsing context</span> of the
+ script that invoked the method as the <var title="">owner browsing
+ context</var>, with the <span>script's document</span> of the
+ script that invoked the method as the <var title="">owner
+ document</var>, with the <span>origin</span> of the <span>entry
+ script</span> as the <var title="">owner origin</var>, and with
+ <var title="">worker global scope</var> as the global scope.</p>
+
+ </li>
+
+ </ol><p>This constructor must be visible when the <span>script's global
+ object</span> is either a <code>Window</code> object or an object
+ implementing the <code><a href=#workerutils>WorkerUtils</a></code> interface.</p>
+
+
+ <h4 id=shared-workers-and-the-sharedworker-interface><span class=secno>4.7.3 </span>Shared workers and the <code><a href=#sharedworker>SharedWorker</a></code> interface</h4>
+
+ <pre class=idl>[<a href=#dom-sharedworker title=dom-SharedWorker>Constructor</a>(in DOMString scriptURL, in optional DOMString name)]
+interface <dfn id=sharedworker>SharedWorker</dfn> : <a href=#abstractworker>AbstractWorker</a> {
+ readonly attribute <span>MessagePort</span> <a href=#dom-sharedworker-port title=dom-SharedWorker-port>port</a>;
+};</pre>
+
+ <p>The <dfn id=dom-sharedworker-port title=dom-SharedWorker-port><code>port</code></dfn>
+ attribute must return the value it was assigned by the object's
+ constructor. It represents the <code>MessagePort</code> for
+ communicating with the shared worker.</p>
+
+ <p>When the <dfn id=dom-sharedworker title=dom-SharedWorker><code>SharedWorker(<var title="">scriptURL</var>, <var title="">name</var>)</code></dfn>
+ constructor is invoked, the user agent must run the following
+ steps:</p>
+
+ <ol><li><p><span title="resolve a url">Resolve</span> the <var title="">scriptURL</var> argument.</li>
+
+ <li><p>If this fails, throw a <code>SYNTAX_ERR</code>
+ exception.</li>
+
+ <li><p>Otherwise, let <var title="">scriptURL</var> be the
+ resulting <span>absolute URL</span>.</li>
+
+ <li><p>Let <var title="">name</var> be the value of the second
+ argument, or the empty string if the second argument was
+ omitted.</li>
+
+ <li>
+
+ <p>If the <span>origin</span> of <var title="">scriptURL</var> is
+ not the <span title="same origin">same</span> as the origin of the
+ <span>entry script</span>, then throw a <code>SECURITY_ERR</code>
+ exception.</p>
+
+ <p class=note>Thus, scripts must be external files with the same
+ scheme as the original page: you can't load a script from a <span title="data protocol"><code title="">data:</code> URL</span> or
+ <span title="javascript protocol"><code title="">javascript:</code> URL</span>, and a <code>https:</code>
+ page couldn't start workers using scripts with <code>http:</code>
+ URLs.</p>
+
+ </li>
+
+ <li>
+
+ <p>Let <var title="">docs</var> be the <a href=#list-of-relevant-document-objects-to-add>list of relevant
+ <code>Document</code> objects to add</a> given the <span title="script's global object">global object</span> of the <span title=concept-script>script</span> that invoked the
+ constructor.</p>
+
+ </li>
+
+ <li>
+
+ <p>Execute the following substeps atomically:</p>
+
+ <ol><li><p>Create a new <code><a href=#sharedworker>SharedWorker</a></code> object, which will
+ shortly be associated with a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
+ object. Let this <code><a href=#sharedworker>SharedWorker</a></code> object be <var title="">worker</var>.</li>
+
+ <li><p><span>Create a new <code>MessagePort</code> object</span>
+ owned by the <span title="script's global object">global
+ object</span> of the script that invoked the method. Let this be
+ the <var title="">outside port</var>.</li>
+
+ <li><p>Assign <var title="">outside port</var> to the <code title=dom-SharedWorker-port><a href=#dom-sharedworker-port>port</a></code> attribute of <var title="">worker</var>.</li>
+
+ <li><p>Let <var title="">worker global scope</var> be
+ null.</li>
+
+ <li><p>If <var title="">name</var> is not the empty string and
+ there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object whose
+ <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a> flag
+ is false, whose <code title=dom-WorkerGlobalScope-name>name</code> attribute is
+ exactly equal to <var title="">name</var>, and whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
+ represents an <span>absolute URL</span> with the <span>same
+ origin</span> as <var title="">scriptURL</var>, then let <var title="">worker global scope</var> be that
+ <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object.</li>
+
+ <li><p>Otherwise, if <var title="">name</var> is the empty string
+ and there exists a <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object
+ whose <a href=#dom-workerglobalscope-closing title=dom-WorkerGlobalScope-closing>closing</a>
+ flag is false, and whose <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code> attribute
+ represents an <span>absolute URL</span> that is exactly equal to
+ <var title="">scriptURL</var>, then let <var title="">worker
+ global scope</var> be that <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
+ object.</li>
+
+ <li>
+
+ <p>If <var title="">worker global scope</var> is not null, then
+ run these steps:</p>
+
+ <ol><li><p>If <var title="">worker global scope</var>'s <code title=dom-WorkerGlobalScope-location><a href=#dom-workerglobalscope-location>location</a></code>
+ attribute represents an <span>absolute URL</span> that is not
+ exactly equal to <var title="">scriptURL</var>, then throw a
+ <code>URL_MISMATCH_ERR</code> exception and abort all these
+ steps.</li>
+
+ <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
+
+ <li><p><span>Create a new <code>MessagePort</code>
+ object</span> owned by <var title="">worker global
+ scope</var>. Let this be the <var title="">inside
+ port</var>.</li>
+
+ <li><p><span>Entangle</span> <var title="">outside port</var>
+ and <var title="">inside port</var>.</li>
+
+ <li><p>Return <var title="">worker</var> and perform the next
+ step asynchronously.</li>
+
+ <li><p>Create an event that uses the <code>MessageEvent</code>
+ interface, with the name <code title=event-connect>connect</code>, which does not bubble, is
+ not cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value
+ is the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose
+ value is a <span title=dfn-read-only-array>read only</span>
+ array containing only the newly created port, and <span>queue a
+ task</span> to dispatch the event at <var title="">worker
+ global scope</var>.</li>
+
+ <li>
+
+ <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
+ <var title="">worker global scope</var>'s list of <span>the
+ worker's <code>Document</code>s</span></a> the
+ <code>Document</code> objects in <var title="">docs</var>.</p>
+
+ </li>
+
+ <li>
+
+ <p>If the <span title="script's global object">global
+ object</span> of the <span title=concept-script>script</span>
+ that invoked the constructor is a
+ <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, add <var title="">worker global scope</var> to the list of <a href="#the-worker's-workers">the
+ worker's workers</a> of the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
+ object that is the <span title="script's global object">global
+ object</span> of the <span title=concept-script>script</span>
+ that invoked the constructor.</p>
+
+ </li>
+
+ <li><p>Abort all these steps.</li>
+
+ </ol></li>
+
+ <li><p>Create a new <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>
+ object. Let <var title="">worker global scope</var> be this new
+ object.</li>
+
+ <li><p>Associate <var title="">worker</var> with <var title="">worker global scope</var>.</li>
+
+ <li><p>Set the <code title=dom-SharedWorkerGlobalScope-name><a href=#dom-sharedworkerglobalscope-name>name</a></code> attribute of
+ <var title="">worker global scope</var> to <var title="">name</var>.</li>
+
+ <li><p><span>Create a new <code>MessagePort</code> object</span>
+ owned by <var title="">worker global scope</var>. Let <var title="">inside port</var> be this new object.</li>
+
+ <li><p><span>Entangle</span> <var title="">outside port</var> and
+ <var title="">inside port</var>.</li>
+
+ </ol></li>
+
+ <li><p>Return <var title="">worker</var> and perform the remaining
+ steps asynchronously.</li>
+
+ <li><p>Create an event that uses the <code>MessageEvent</code>
+ interface, with the name <code title=event-connect>connect</code>, which does not bubble, is not
+ cancelable, has no default action, has a <code title=dom-MessageEvent-data>data</code> attribute whose value is
+ the empty string and has a <code title=dom-MessageEvent-ports>ports</code> attribute whose value
+ is a <span title=dfn-read-only-array>read only</span> array
+ containing only the newly created port, and <span>queue a
+ task</span> to dispatch the event at <var title="">worker global
+ scope</var>.</li>
+
+ <li>
+
+ <p><a href="#add-a-document-to-the-worker's-documents" title="add a document to the worker's documents">Add to
+ <var title="">worker global scope</var>'s list of <span>the
+ worker's <code>Document</code>s</span></a> the
+ <code>Document</code> objects in <var title="">docs</var>.</p>
+
+ </li>
+
+ <li>
+
+ <p>If the <span title="script's global object">global object</span>
+ of the <span title=concept-script>script</span> that invoked the
+ constructor is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, add <var title="">worker global scope</var> to the list of <a href="#the-worker's-workers">the
+ worker's workers</a> of the <code><a href=#workerglobalscope>WorkerGlobalScope</a></code>
+ object that is the <span title="script's global object">global
+ object</span> of the <span title=concept-script>script</span>
+ that invoked the constructor.</p>
+
+ </li>
+
+ <li>
+
+ <p><a href=#run-a-worker>Run a worker</a> for <var title="">scriptURL</var>,
+ with the <span>script's browsing context</span> of the script that
+ invoked the method as the <var title="">owner browsing
+ context</var>, with the <span>script's document</span> of the
+ script that invoked the method as the <var title="">owner
+ document</var>, with the <span>origin</span> of the <span>entry
+ script</span> as the <var title="">owner origin</var>, and with
+ <var title="">worker global scope</var> as the global scope.</p>
+
+ </li>
+
+ </ol><p>This constructor must be visible when the <span>script's global
+ object</span> is either a <code>Window</code> object or an object
+ implementing the <code><a href=#workerutils>WorkerUtils</a></code> interface.</p>
+
+ <p>The <span>task source</span> for the tasks mentioned above is the
+ <span>DOM manipulation task source</span>.</p>
+
+
+
+ <h2 id=apis-available-to-workers><span class=secno>5 </span>APIs available to workers</h2>
+
+ <pre class=idl>[Supplemental, NoInterfaceObject]
+interface <dfn id=workerutils>WorkerUtils</dfn> {
+ void <a href=#dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts>importScripts</a>(in DOMString... urls);
+ readonly attribute <a href=#workernavigator>WorkerNavigator</a> <a href=#dom-worker-navigator title=dom-worker-navigator>navigator</a>;
+};
+<a href=#workerutils>WorkerUtils</a> implements <span>WindowTimers</span>;
+<a href=#workerutils>WorkerUtils</a> implements <span>WindowBase64</span>;</pre>
+
+ <p>The DOM APIs (<code>Node</code> objects, <code>Document</code>
+ objects, etc) are not available to workers in this version of this
+ specification.</p>
+
+
+ <h3 id=importing-scripts-and-libraries><span class=secno>5.1 </span>Importing scripts and libraries</h3>
+
+ <p>When a script invokes the <dfn id=dom-workerglobalscope-importscripts title=dom-WorkerGlobalScope-importScripts><code>importScripts(<var title="">urls</var>)</code></dfn> method on a
+ <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, the user agent must run the
+ following steps:</p>
+
+ <ol><li><p>If there are no arguments, return without doing
+ anything. Abort these steps.</li>
+
+ <li><p><span title="resolve a url">Resolve</span> each
+ argument.</li>
+
+ <li><p>If any fail, throw a <code>SYNTAX_ERR</code>
+ exception.</li>
+
+<!--
+ <li><p>If any of the resulting <span title="absolute URL">absolute
+ URLs</span> have an <span>origin</span> that is not the <span
+ title="same origin">same</span> as the origin of the script that
+ invoked the method, then throw a <code>SECURITY_ERR</code>
+ exception.</p></li>
+-->
+
+ <li>
+
+ <p>Attempt to <span>fetch</span> each resource identified by the
+ resulting <span title="absolute URL">absolute URLs</span>, from
+ the <span>entry script</span>'s <span>origin</span>, with the
+ <i>synchronous flag</i> set.</p> <!-- not http-origin privacy
+ sensitive -->
+
+ </li>
+
+ <li>
+
+ <p>For each argument in turn, in the order given, starting with
+ the first one, run these substeps:</p>
+
+ <ol><li>
+
+ <p>Wait for the fetching attempt for the corresponding resource
+ to complete.</p>
+
+ <p>If the fetching attempt failed, throw a
+ <code>NETWORK_ERR</code> exception and abort all these
+ steps.</p>
+
+ <p>If the attempt succeeds, then let <var title="">source</var> be
+ the script resource <span>decoded as UTF-8, with error
+ handling</span>.
+
+ <a href=#refsHTML>[HTML]</a>
+
+ </p>
+
+ <p>Let <var title="">language</var> be JavaScript.</p>
+
+ <p class=note>As with the worker's script, the script here is
+ always assumed to be JavaScript, regardless of the MIME
+ type.</p>
+
+ </li>
+
+ <li>
+
+ <p><span>Create a script</span>, using <var title="">source</var> as the script source and <var title="">language</var> as the scripting language, using the
+ same global object, browsing context, URL character encoding,
+ base URL, and script group as the <span title=concept-script>script</span> that was created by the
+ worker's <a href=#run-a-worker>run a worker</a> algorithm.</p>
+
+ <p>Let the newly created <span title=concept-script>script</span> run until it either
+ returns, fails to parse, fails to catch an exception, or gets
+ prematurely aborted by the "<a href=#kill-a-worker>kill a worker</a>" or
+ "<a href=#terminate-a-worker>terminate a worker</a>" algorithms defined above.</p>
+
+ <p>If it failed to parse, then throw an ECMAScript
+ <code>SyntaxError</code> exception and abort all these
+ steps. <a href=#refsECMA262>[ECMA262]</a></p>
+
+ <p>If an exception was raised or if the script was prematurely
+ aborted, then abort all these steps, letting the exception or
+ aborting continue to be processed by the script that called the
+ <code title=dom-WorkerGlobalScope-importScripts><a href=#dom-workerglobalscope-importscripts>importScripts()</a></code>
+ method.</p>
+
+ <p>If the "<a href=#kill-a-worker>kill a worker</a>" or "<a href=#terminate-a-worker>terminate a
+ worker</a>" algorithms abort the script then abort all these
+ steps.</p>
+
+ </li>
+
+ </ol></li>
+
+ </ol><h3 id=the-workernavigator-object><span class=secno>5.2 </span>The <code><a href=#workernavigator>WorkerNavigator</a></code> object</h3>
+
+ <p>The <dfn id=dom-worker-navigator title=dom-worker-navigator><code>navigator</code></dfn> attribute
+ of the <code><a href=#workerutils>WorkerUtils</a></code> interface must return an instance of
+ the <code><a href=#workernavigator>WorkerNavigator</a></code> interface, which represents the
+ identity and state of the user agent (the client):</p>
+
+ <pre class=idl>interface <dfn id=workernavigator>WorkerNavigator</dfn> {};
+<a href=#workernavigator>WorkerNavigator</a> implements <span>NavigatorID</span>;
+<a href=#workernavigator>WorkerNavigator</a> implements <span>NavigatorOnLine</span>;</pre>
+
+ <p>Objects implementing the <code><a href=#workernavigator>WorkerNavigator</a></code> interface
+ also implement the <code>NavigatorID</code> and
+ <code>NavigatorOnLine</code> interfaces.
+
+ <a href=#refsHTML>[HTML]</a>
+
+ </p>
+
+ <p>This <code><a href=#workernavigator>WorkerNavigator</a></code> interface must not exist if the
+ interface's <span>relevant namespace object</span> is a
+ <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
+
+
+
+
+ <h3 id=interface-objects-and-constructors><span class=secno>5.3 </span>Interface objects and constructors</h3>
+
+ <p>There must be no interface objects and constructors available in
+ the global scope of scripts whose <span>script's global
+ object</span> is a <code><a href=#workerglobalscope>WorkerGlobalScope</a></code> object except for
+ the following:</p>
+
+ <ul><li><p><code>XMLHttpRequest</code> and all interface objects and
+ constructors defined by the XMLHttpRequest specifications, except
+ that the <span>document response entity body</span> must always be
+ null. The <span><code>XMLHttpRequest</code> base URL</span> is the
+ <span>script's base URL</span>; the
+ <span><code>XMLHttpRequest</code> origin</span> is the script's
+ <span>origin</span>. <a href=#refsXHR>[XHR]</a></li>
+
+ <li><p>The interface objects and constructors defined by this
+ specification.</li>
+
+ <li><p>Constructors defined by specifications that explicitly say
+ that they should be visible when the <span>script's global
+ object</span> is a <code><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>, a
+ <code><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>, or an object implementing the
+ <code><a href=#workerutils>WorkerUtils</a></code> interface; the interfaces of any objects
+ with such constructors; and the interfaces of any objects made
+ accessible through APIs exposed by those constructors or made
+ accessible through interfaces to be implemented by any objects that
+ are themselves accessible to scripts whose <span>script's global
+ object</span> implements the <code><a href=#workerutils>WorkerUtils</a></code>
+ interface.</li>
+
+ </ul><p class=note>These requirements do not override the requirements
+ defined by the Web IDL specification, in particular concerning the
+ visibility of interfaces annotated with the <code title="">[NoInterfaceObject]</code> extended attribute.</p>
+
+
+ <h3 id=worker-locations><span class=secno>5.4 </span>Worker locations</h3>
+
+ <pre class=idl>interface <dfn id=workerlocation>WorkerLocation</dfn> {
+ // <span>URL decomposition IDL attributes</span>
+ readonly attribute DOMString <a href=#dom-workerlocation-href title=dom-WorkerLocation-href>href</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-protocol title=dom-WorkerLocation-protocol>protocol</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-host title=dom-WorkerLocation-host>host</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-hostname title=dom-WorkerLocation-hostname>hostname</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-port title=dom-WorkerLocation-port>port</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-pathname title=dom-WorkerLocation-pathname>pathname</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-search title=dom-WorkerLocation-search>search</a>;
+ readonly attribute DOMString <a href=#dom-workerlocation-hash title=dom-WorkerLocation-hash>hash</a>;
+};</pre>
+
+ <p>A <code><a href=#workerlocation>WorkerLocation</a></code> object represents an <span>absolute
+ URL</span> set at its creation.</p>
+
+ <p>The <dfn id=dom-workerlocation-href title=dom-WorkerLocation-href><code>href</code></dfn>
+ attribute must return the <span>absolute URL</span> that the object
+ represents.</p>
+
+ <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface also has the complement
+ of <span>URL decomposition IDL attributes</span>, <dfn id=dom-workerlocation-protocol title=dom-WorkerLocation-protocol><code>protocol</code></dfn>,
+ <dfn id=dom-workerlocation-host title=dom-WorkerLocation-host><code>host</code></dfn>, <dfn id=dom-workerlocation-port title=dom-WorkerLocation-port><code>port</code></dfn>, <dfn id=dom-workerlocation-hostname title=dom-WorkerLocation-hostname><code>hostname</code></dfn>,
+ <dfn id=dom-workerlocation-pathname title=dom-WorkerLocation-pathname><code>pathname</code></dfn>,
+ <dfn id=dom-workerlocation-search title=dom-WorkerLocation-search><code>search</code></dfn>,
+ and <dfn id=dom-workerlocation-hash title=dom-WorkerLocation-hash><code>hash</code></dfn>.
+ These must follow the rules given for <span>URL decomposition IDL
+ attributes</span>, with the <span title=concept-uda-input>input</span> being the <span>absolute
+ URL</span> that the object represents (same as the <code title=dom-WorkerLocation-href><a href=#dom-workerlocation-href>href</a></code> attribute), and the
+ <span title=concept-uda-setter>common setter action</span> being a
+ no-op, since the attributes are defined to be readonly.
+
+ <a href=#refsHTML>[HTML]</a>
+
+ </p>
+
+ <p>The <code><a href=#workerlocation>WorkerLocation</a></code> interface must not exist if the
+ interface's <span>relevant namespace object</span> is a
+ <code>Window</code> object. <a href=#refsWEBIDL>[WEBIDL]</a></p>
+
+
+
+
+ <h2 class=no-num id=references>References</h2><!--REFS-->
+
+ <p>All references are normative unless marked "Non-normative".</p>
+
+ <!-- Dates are only included for standards older than the Web, because the newer ones keep changing. -->
+
+ <dl><dt id=refsDOMCORE>[DOMCORE]</dt>
+ <dd><cite><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html>Web DOM Core</a></cite>, A. van Kesteren. W3C.</dd>
+
+ <dt id=refsDOMEVENTS>[DOMEVENTS]</dt>
+ <!--
+ <dd><cite><a
+ href="http://www.w3.org/TR/DOM-Level-3-Events/">Document Object
+ Model (DOM) Level 3 Events Specification</a></cite>,
+ B. Höhrmann, P. Le Hegaret, T. Pixley. W3C.</dd>
+ -->
+ <dd><cite><a href=http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html>Document
+ Object Model (DOM) Level 3 Events Specification</a></cite>,
+ D. Schepers. W3C.</dd>
+
+ <dt id=refsECMA262>[ECMA262]</dt>
+ <dd><cite><a href=http://www.ecma-international.org/publications/standards/Ecma-262.htm>ECMAScript
+ Language Specification</a></cite>. ECMA.</dd>
+
+ <dt id=refsHTML>[HTML]</dt>
+ <dd><cite><a href=http://www.whatwg.org/specs/web-apps/current-work/>HTML</a></cite>,
+ I. Hickson. WHATWG.</dd>
+
+ <dt id=refsRFC2119>[RFC2119]</dt>
+ <dd><cite><a href=http://tools.ietf.org/html/rfc2119>Key words for use in
+ RFCs to Indicate Requirement Levels</a></cite>, S. Bradner. IETF.</dd>
+
+ <dt id=refsWEBIDL>[WEBIDL]</dt>
+ <!--
+ <dd><cite><a href="http://www.w3.org/TR/WebIDL/">Web
+ IDL</a></cite>, C. McCormack. W3C.</dd>
+ -->
+ <dd><cite><a href=http://dev.w3.org/2006/webapi/WebIDL/>Web
+ IDL</a></cite>, C. McCormack. W3C.</dd>
+
+ <dt id=refsXHR>[XHR]</dt>
+ <!--
+ <dd><cite><a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest
+ Object</a></cite>, A. van Kesteren. W3C.</dd>
+ -->
+ <dd><cite><a href=http://dev.w3.org/2006/webapi/XMLHttpRequest-2/><code>XMLHttpRequest</code></a></cite>,
+ A. van Kesteren. W3C.</dd>
+
+ </dl><h2 class=no-num id=acknowledgements>Acknowledgements</h2> <!-- ACKS -->
+
+ <p>Thanks to
+
+ Aaron Boodman,
+ Алексей Проскуряков (Alexey Proskuryakov),
+ Anne van Kesteren,
+ Ben Turner,
+ Dmitry Titov,
+ Drew Wilson,
+ Jeremy Orlow,
+ Jonas Sicking,
+ Justin James,
+ Kevin Hakanson,
+ Maciej Stachowiak,
+ Michael Nordman,
+ Mike Smith,
+
+ and
+
+ Philip Taylor
+
+ for their useful and substantial comments.</p>
+
+ <p>Huge thanks to the whole Gears team, who pioneered this
+ technology and whose experience has been a huge influence on this
+ specification.</p>
+
+
Previous | Next