16 Terminology

The construction "a Foo object", where Foo is actually an interface, is sometimes used instead of the more accurate "an object implementing the interface Foo".

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 Document object or of any other Node objects as defined in the DOM specifications. [DOM]

An IDL attribute is said to be getting when its value is being retrieved (e.g. by author script), and is said to be setting when a new value is assigned to it.

The term "JavaScript" is used to refer to ECMA262, rather than the official term ECMAScript, since the term JavaScript is more widely known. [ECMA262]

16.1 Infrastructure

There are two kinds of workers; dedicated workers, and shared workers. Dedicated workers, once created, 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 origin can obtain a reference to that worker and communicate with it.

16.1.1 The global scope

The global scope is the "inside" of a worker.

16.1.1.1 The WorkerGlobalScope common interface
[Exposed=Worker] 
interface WorkerGlobalScope : EventTarget {
  readonly attribute WorkerGlobalScope self;
  readonly attribute WorkerLocation location;

  void close();
           attribute OnErrorEventHandler onerror;
           attribute EventHandler onlanguagechange;
           attribute EventHandler onoffline;
           attribute EventHandler ononline;
};

The self attribute must return the WorkerGlobalScope object itself.

The location attribute must return the WorkerLocation object created for the WorkerGlobalScope object when the worker was created. It represents the absolute URL of the script that was used to initialise the worker, after any redirects.


When a script invokes the close() method on a WorkerGlobalScope object, the user agent must run the following steps (atomically):

  1. Discard any tasks that have been added to the WorkerGlobalScope object's event loop's task queues.

  2. Set the worker's WorkerGlobalScope object's closing flag to true. (This prevents any further tasks from being queued.)


The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by objects implementing the WorkerGlobalScope interface:

Event handler Event handler event type
onerror error
onlanguagechange languagechange
onoffline offline
ononline online

For data: URLs, this is the origin specified by the entry settings object when the constructor was called. For other URLs, this is the origin of the value of the absolute URL given in the worker's location attribute.

16.1.1.2 Dedicated workers and the DedicatedWorkerGlobalScope interface
[Global=Worker,DedicatedWorker]
/*sealed*/ interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
  void postMessage(any message, optional sequence<Transferable> transfer);
           attribute EventHandler onmessage;
};

DedicatedWorkerGlobalScope objects act as if they had an implicit MessagePort 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 DedicatedWorkerGlobalScope object.

All messages received by that port must immediately be retargeted at the DedicatedWorkerGlobalScope object.

The postMessage() method on DedicatedWorkerGlobalScope objects must act as if, when invoked, it immediately invoked the method of the same name on the port, with the same arguments, and returned the same return value.

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by objects implementing the DedicatedWorkerGlobalScope interface:

Event handler Event handler event type
onmessage message

For the purposes of the application cache networking model, a dedicated worker is an extension of the cache host from which it was created.

16.1.1.3 Shared workers and the SharedWorkerGlobalScope interface
[Global=Worker,SharedWorker]
/*sealed*/ interface SharedWorkerGlobalScope : WorkerGlobalScope {
  readonly attribute DOMString name;
  readonly attribute ApplicationCache applicationCache;
           attribute EventHandler onconnect;
};

Shared workers receive message ports through connect events on their SharedWorkerGlobalScope object for each connection.

The name attribute must return the value it was assigned when the SharedWorkerGlobalScope object was created by the "run a worker" algorithm. Its value represents the name that can be used to obtain a reference to the worker using the SharedWorker constructor.

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by objects implementing the SharedWorkerGlobalScope interface:

Event handler Event handler event type
onconnect connect

For the purposes of the application cache networking model, a shared worker is its own cache host. The run a worker algorithm takes care of associating the worker with an application cache.

The applicationCache attribute returns the ApplicationCache object for the worker.

16.1.2 The event loop

Each WorkerGlobalScope object has a distinct event loop, separate from those used by units of related similar-origin browsing contexts. This event loop has no associated browsing context, and its task queues only have events, callbacks, and networking activity as tasks. These event loops are created by the run a worker algorithm.

Each WorkerGlobalScope object also has a closing flag, which must initially be false, but which can get set to true by the algorithms in the processing model section below.

Once the WorkerGlobalScope's closing flag is set to true, the event loop's task queues must discard any further tasks that would be added to them (tasks already on the queue are unaffected except where otherwise specified). Effectively, once the closing flag is true, timers stop firing, notifications for all pending asynchronous operations are dropped, etc.

16.1.3 The worker's lifetime

Workers communicate with other workers and with browsing contexts through message channels and their MessagePort objects.

Each WorkerGlobalScope worker global scope has a list of the worker's ports, which consists of all the MessagePort objects that are entangled with another port and that have one (but only one) port owned by worker global scope. This list includes the implicit MessagePort in the case of dedicated workers.

Each WorkerGlobalScope also has a list of the worker's workers. Initially this list is empty; it is populated when the worker creates or obtains further workers.

Finally, each WorkerGlobalScope also has a list of the worker's Documents. Initially this list is empty; it is populated when the worker is created.

Whenever a Document d is added to the worker's Documents, the user agent must, for each worker q in the list of the worker's workers whose list of the worker's Documents does not contain d, add d to q's WorkerGlobalScope owner's list of the worker's Documents.

Whenever a Document object is discarded, it must be removed from the list of the worker's Documents of each worker whose list contains that Document.

Given a settings object o when creating or obtaining a worker, the list of relevant Document objects to add depends on the type of global object specified by o's. If o specifies a global object that is a WorkerGlobalScope object (i.e. if we are creating a nested worker), then the relevant Documents are the the worker's Documents of the global object specified by o. Otherwise, o specifies a global object that is a Window object, and the relevant Document is just the responsible document specified by o.


A worker is said to be a permissible worker if its list of the worker's Documents is not empty.

A worker is said to be an active needed worker if any of the Document objects in the worker's Documents are fully active.

A worker is said to be a protected worker if it is an active needed worker and either it has outstanding timers, database transactions, or network connections, or its list of the worker's ports is not empty, or its WorkerGlobalScope is actually a SharedWorkerGlobalScope object (i.e. the worker is a shared worker).

A worker is said to be a suspendable worker if it is not an active needed worker but it is a permissible worker.

16.1.4 Processing model

When a user agent is to run a worker for a script with URL url and a script settings object settings object, it must run the following steps:

  1. 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.

    For the purposes of timing APIs, this is the official moment of creation of the worker.

  2. Let worker global scope be the global object specified by settings object.

  3. If worker global scope is actually a SharedWorkerGlobalScope object (i.e. the worker is a shared worker), and there are any relevant application caches that are identified by a manifest URL with the same origin as url and that have url as one of their entries, not excluding entries marked as foreign, then associate the worker global scope with the most appropriate application cache of those that match.

  4. Attempt to fetch the resource identified by url, from the origin specified by settings object, using the responsible document specified by settings object as the referrer source (not the specified API referrer source!), and with the synchronous flag set and the force same-origin flag set.

    If the attempt fails, then for each Worker or SharedWorker object associated with worker global scope, queue a task to fire a simple event named error at that object. Abort these steps.

    If the attempt succeeds, then let source be the result of running the UTF-8 decode algorithm on the script resource.

    Let language be JavaScript.

    As with script elements, the MIME type of the script is ignored. Unlike with script elements, there is no way to override the type. It's always assumed to be JavaScript.

  5. In the newly created execution environment, create a JavaScript global environment whose global object is worker global scope. If worker global scope is a DedicatedWorkerGlobalScope object, then this is a dedicated worker environment. Otherwise, worker global scope is a SharedWorkerGlobalScope object, and this is a shared worker environment. (In either case, by definition, it is a worker environment.)

  6. Let script be a new script.

    Obtain the appropriate script execution environment for the scripting language language from settings object.

    Parse/compile/initialise source using that script execution environment, as appropriate for language, and thus obtain a code entry-point. If the script was not compiled successfully, let the code entry-point be a no-op script, and act as if a corresponding uncaught script error had occurred.

    Let script's settings object be settings object.

  7. Closing orphan workers: Start monitoring the worker such that no sooner than it stops being a protected worker, and no later than it stops being a permissible worker, worker global scope's closing flag is set to true.

  8. Suspending workers: Start monitoring the worker, such that whenever worker global scope's closing flag is false and the worker is a suspendable worker, the user agent suspends execution of script in that worker until such time as either the closing flag switches to true or the worker stops being a suspendable worker.

  9. Jump to the script's code entry-point, and let that run until it either returns, fails to catch an exception, or gets prematurely aborted by the "kill a worker" or "terminate a worker" algorithms defined below.

  10. If worker global scope is actually a DedicatedWorkerGlobalScope object (i.e. the worker is a dedicated worker), then enable the port message queue of the worker's implicit port.

  11. Event loop: Run the responsible event loop specified by settings object until it is destroyed.

    The handling of events or the execution of callbacks by tasks run by the event loop might get prematurely aborted by the "kill a worker" or "terminate a worker" algorithms defined below.

    The worker processing model remains on this step until the event loop is destroyed, which happens after the closing flag is set to true, as described in the event loop processing model.

  12. Empty the worker global scope's list of active timers.

  13. Disentangle all the ports in the list of the worker's ports.

  14. Empty the worker's list of the worker's Documents.


When a user agent is to kill a worker it must run the following steps in parallel with the worker's main loop (the "run a worker" processing model defined above):

  1. Set the worker's WorkerGlobalScope object's closing flag to true.

  2. If there are any tasks queued in the WorkerGlobalScope object's event loop's task queues, discard them without processing them.

  3. Wait a user-agent-defined amount of time.

  4. Abort the script currently running in the worker.

User agents may invoke the "kill a worker" 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 active needed worker if the worker continues executing even after its closing flag was set to true.


When a user agent is to terminate a worker it must run the following steps in parallel with the worker's main loop (the "run a worker" processing model defined above):

  1. Set the worker's WorkerGlobalScope object's closing flag to true.

  2. If there are any tasks queued in the WorkerGlobalScope object's event loop's task queues, discard them without processing them.

  3. Abort the script currently running in the worker.

  4. If the worker's WorkerGlobalScope object is actually a DedicatedWorkerGlobalScope object (i.e. the worker is a dedicated worker), then empty the port message queue of the port that the worker's implicit port is entangled with.


The task source for the tasks mentioned above is the DOM manipulation task source.

16.1.5 Runtime script errors

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 report the error for that script, with the position (line number and column number) where the error occurred, using the WorkerGlobalScope object as the target. [HTML]

For shared workers, if the error is still not handled afterwards, the error may be reported to the user. [HTML]

For dedicated workers, if the error is still not handled afterwards, the user agent must queue a task to fire a trusted event that uses the ErrorEvent interface, with the name error, that doesn't bubble and is cancelable, with its message, filename, lineno, colno, attributes initialised appropriately, and with the error attribute initialised to null, at the Worker object associated with the worker. If the event is not canceled, the user agent must act as if the uncaught runtime script error had occurred in the global scope that the Worker object is in, thus repeating the entire runtime script error reporting process one level up.

If the implicit port connecting the worker to its Worker object has been disentangled (i.e. if the parent worker has been terminated), then the user agent must act as if the Worker object had no error event handler and as if that worker's onerror attribute was null, but must otherwise act as described above.

Thus, error reports propagate up to the chain of dedicated workers up to the original Document, even if some of the workers along this chain have been terminated and garbage collected.

The task source for the task mentioned above is the DOM manipulation task source.

16.1.6 Creating workers

16.1.6.1 The AbstractWorker abstract interface
[NoInterfaceObject, Exposed=Window,Worker]
interface AbstractWorker {
           attribute EventHandler onerror;
};

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by objects implementing the AbstractWorker interface:

Event handler Event handler event type
onerror error
16.1.6.2 Script settings for workers

When the user agent is required to set up a worker script settings object, given a worker global scope and a URL script address, it must run the following steps:

  1. Let inherited responsible browsing context be the responsible browsing context specified by the incumbent settings object.

  2. Let inherited responsible document be the responsible document specified by the incumbent settings object.

  3. Let inherited origin be the origin specified by the incumbent settings object.

  4. Let worker event loop be a newly created event loop.

  5. Let settings object be a new script settings object whose algorithms are defined as follows:

    The script execution environments

    When the script settings object is created, for each language supported by the user agent, create an appropriate execution environment as defined by the relevant specification.

    When a script execution environment is needed, return the appropriate one from those created when the script settings object was created.

    Currently, workers only support JavaScript, so only a JavaScript execution environment is actually needed here.

    The global object

    Return worker global scope.

    The responsible browsing context

    Return inherited responsible browsing context.

    The responsible document

    Return inherited responsible document.

    The responsible event loop

    Return worker event loop.

    The API referrer source

    Return script address.

    The API URL character encoding

    Return UTF-8.

    The API base URL

    Return worker URL.

    The origin and effective script origin

    Return inherited origin.

  6. Return settings object.

16.1.6.3 Dedicated workers and the Worker interface
[Constructor(DOMString scriptURL), Exposed=Window,Worker]
interface Worker : EventTarget {
  void terminate();

  void postMessage(any message, optional sequence<Transferable> transfer);
           attribute EventHandler onmessage;
};
Worker implements AbstractWorker;

The terminate() method, when invoked, must cause the "terminate a worker" algorithm to be run on the worker with which the object is associated.

Worker objects act as if they had an implicit MessagePort 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 Worker object.

All messages received by that port must immediately be retargeted at the Worker object.

The postMessage() method on Worker objects must act as if, when invoked, it immediately invoked the method of the same name on the port, with the same arguments, and returned the same return value.

The postMessage() method's first argument can be structured data:

worker.postMessage({opcode: 'activate', device: 1938, parameters: [23, 102]});

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by objects implementing the Worker interface:

Event handler Event handler event type
onmessage message

When the Worker(scriptURL) constructor is invoked, the user agent must run the following steps:

  1. The user agent may throw a SecurityError exception and abort these steps if the request violates a policy decision (e.g. if the user agent is configured to not allow the page to start dedicated workers).

  2. Resolve the scriptURL argument relative to the API base URL specified by the entry settings object when the method was invoked.

  3. If this fails, throw a SyntaxError exception and abort these steps.

  4. Let worker URL be the resulting absolute URL.

  5. If the scheme component of worker URL is not "data", and the origin of worker URL is not the same as the origin specified by the incumbent settings object, then throw a SecurityError exception and abort these steps.

    For example, scripts can be external files with the same scheme, host, and port as the original page, or data: URLs, or same-origin blob: URLs. Thus, an https: page couldn't start workers using scripts with http: URLs. [FILEAPI].

  6. Create a new DedicatedWorkerGlobalScope object. Let worker global scope be this new object.

  7. Set up a worker script settings object with worker global scope and worker URL, and let settings object be the result.

  8. Create a new Worker object, associated with worker global scope. Let worker be this new object.

  9. Create a new MessagePort object whose owner is the incumbent settings object. Let this be the outside port.

  10. Associate the outside port with worker.

  11. Create a new MessagePort object whose owner is script settings. Let inside port be this new object.

  12. Associate inside port with worker global scope.

  13. Entangle outside port and inside port.

  14. Return worker, and run the following steps asynchronously.

  15. Enable outside port's port message queue.

  16. Let docs be the list of relevant Document objects to add given the incumbent settings object.

  17. Add to worker global scope's list of the worker's Documents the Document objects in docs.

  18. If the global object specified by the incumbent settings object is a WorkerGlobalScope object (i.e. we are creating a nested worker), add worker global scope to the list of the worker's workers of the WorkerGlobalScope object that is the global object specified by the incumbent settings object.

  19. Run a worker for the script with URL worker URL and the script settings object settings object.

16.1.6.4 Shared workers and the SharedWorker interface
[Constructor(DOMString scriptURL, optional DOMString name), Exposed=Window,Worker]
interface SharedWorker : EventTarget {
  readonly attribute MessagePort port;
};
SharedWorker implements AbstractWorker;

The port attribute must return the value it was assigned by the object's constructor. It represents the MessagePort for communicating with the shared worker.

When the SharedWorker(scriptURL, name) constructor is invoked, the user agent must run the following steps:

  1. The user agent may throw a SecurityError exception and abort these steps if the request violates a policy decision (e.g. if the user agent is configured to not allow the page to start shared workers).

  2. Resolve the scriptURL argument.

  3. If this fails, throw a SyntaxError exception and abort these steps.

  4. Let scriptURL be the resulting absolute URL and parsed scriptURL be the resulting parsed URL.

  5. Let name be the value of the second argument, or the empty string if the second argument was omitted.

  6. If the scheme component of parsed scriptURL is not "data", and the origin of scriptURL is not the same as the origin specified by the incumbent settings object, then throw a SecurityError exception and abort these steps.

    Thus, scripts must either be external files with the same scheme, host, and port as the original page, or data: URLs. For example, an https: page couldn't start workers using scripts with http: URLs.

  7. Let docs be the list of relevant Document objects to add given the incumbent settings object.

  8. Execute the following substeps atomically:

    1. Create a new SharedWorker object, which will shortly be associated with a SharedWorkerGlobalScope object. Let this SharedWorker object be worker.

    2. Create a new MessagePort object whose owner is the incumbent settings object. Let this be the outside port.

    3. Assign outside port to the port attribute of worker.

    4. Let worker global scope be null.

    5. If name is not the empty string and there exists a SharedWorkerGlobalScope object whose closing flag is false, whose name attribute is exactly equal to name, and that is the global object specified by a script settings object that specifies as its origin the same origin as the origin of scriptURL, then let worker global scope be that SharedWorkerGlobalScope object.

      Otherwise, if name is the empty string and there exists a SharedWorkerGlobalScope object whose closing flag is false, whose name attribute is the empty string, and whose location attribute represents an absolute URL that is exactly equal to scriptURL, then let worker global scope be that SharedWorkerGlobalScope object.

    6. If worker global scope is not null, but the user agent has been configured to disallow communication between the worker represented by the worker global scope and the scripts whose settings objects are the incumbent settings object, then set worker global scope to null.

      For example, a user agent could have a development mode that isolates a particular top-level browsing context from all other pages, and scripts in that development mode could be blocked from connecting to shared workers running in the normal browser mode.

    7. If worker global scope is not null, then run these steps:

      1. If worker global scope's location attribute represents an absolute URL that is not exactly equal to scriptURL, then throw a URLMismatchError exception and abort all these steps.

      2. Associate worker with worker global scope.

      3. Let settings object be the script settings object whose global object is worker global scope.

      4. Create a new MessagePort object whose owner is settings object. Let this be the inside port.

      5. Entangle outside port and inside port.

      6. Create a trusted event that uses the MessageEvent interface, with the name connect, which does not bubble, is not cancelable, has no default action, has a data attribute whose value is initialised to the empty string, has a ports attribute whose value is initialised to a read only array containing only the newly created port, and has a source attribute whose value is initialised to the newly created port, and queue a task to dispatch the event at worker global scope.

      7. Add to worker global scope's list of the worker's Documents the Document objects in docs.

      8. If the global object specified by the incumbent settings object is a WorkerGlobalScope object, add worker global scope to the list of the worker's workers of the WorkerGlobalScope object that is the global object specified by the incumbent settings object.

      9. Return worker and abort all these steps.

    8. Create a new SharedWorkerGlobalScope object. Let worker global scope be this new object.

    9. Set up a worker script settings object with worker global scope and scriptURL, and let settings object be the result.

    10. Associate worker with worker global scope.

    11. Set the name attribute of worker global scope to name.

    12. Create a new MessagePort object whose owner is settings object. Let inside port be this new object.

    13. Entangle outside port and inside port.

  9. Return worker and perform the remaining steps asynchronously.

  10. Create a trusted event that uses the MessageEvent interface, with the name connect, which does not bubble, is not cancelable, has no default action, has a data attribute whose value is initialised to the empty string, has a ports attribute whose value is initialised to a read only array containing only the newly created port, and has a source attribute whose value is initialized to the newly created port, and queue a task to dispatch the event at worker global scope.

  11. Add to worker global scope's list of the worker's Documents the Document objects in docs.

  12. If the global object specified by the incumbent settings object is a WorkerGlobalScope object, add worker global scope to the list of the worker's workers of the WorkerGlobalScope object that is the global object specified by the incumbent settings object.

  13. Run a worker for the script with URL scriptURL and the script settings object settings object.

The task source for the tasks mentioned above is the DOM manipulation task source.

16.2 APIs available to workers

[Exposed=Worker]
partial interface WorkerGlobalScope {
  void importScripts(DOMString... urls);
  readonly attribute WorkerNavigator navigator;
};
WorkerGlobalScope implements WindowTimers;
WorkerGlobalScope implements WindowBase64;

16.2.1 Importing scripts and libraries

When a script invokes the importScripts(urls) method on a WorkerGlobalScope object, the user agent must run the following steps:

  1. If there are no arguments, return without doing anything. Abort these steps.

  2. Let settings object be the incumbent settings object.

  3. Resolve each argument.

  4. If any fail, throw a SyntaxError exception and abort these steps.

  5. Attempt to fetch each resource identified by the resulting absolute URLs, from the origin specified by settings object, using the API referrer source specified by settings object, and with the synchronous flag set.

  6. For each argument in turn, in the order given, starting with the first one, run these substeps:

    1. Wait for the fetching attempt for the corresponding resource to complete.

      If the fetching attempt failed, throw a NetworkError exception and abort all these steps.

      If the attempt succeeds, then let source be the result of running the UTF-8 decode algorithm on the script resource.

      Let language be JavaScript.

      As with the worker's script, the script here is always assumed to be JavaScript, regardless of the MIME type.

    2. Create a script using source as the script source, the URL from which source was obtained, language as the scripting language, and settings object as the script settings object.

      If the script came from a resource whose URL does not have the same origin as the origin specified by the incumbent settings object, then pass the muted errors flag to the create a script algorithm as well.

      Let the newly created script run until it either returns, fails to parse, fails to catch an exception, or gets prematurely aborted by the "kill a worker" or "terminate a worker" algorithms defined above.

      If it failed to parse, then throw an ECMAScript SyntaxError exception and abort all these steps. [ECMA262]

      If an exception was thrown or if the script was prematurely aborted, then abort all these steps, letting the exception or aborting continue to be processed by the calling script.

      If the "kill a worker" or "terminate a worker" algorithms abort the script then abort all these steps.

16.2.2 The WorkerNavigator object

The navigator attribute of the WorkerGlobalScope interface must return an instance of the WorkerNavigator interface, which represents the identity and state of the user agent (the client):

[Exposed=Worker]
interface WorkerNavigator {};
WorkerNavigator implements NavigatorID;
WorkerNavigator implements NavigatorLanguage;
WorkerNavigator implements NavigatorOnLine;

16.2.3 Worker locations

[Exposed=Worker]
interface WorkerLocation { };
WorkerLocation implements URLUtilsReadOnly;

A WorkerLocation object represents an absolute URL set at its creation.

The WorkerLocation interface supports the URLUtilsReadOnly interface. [URL]

When the object is created, the user agent must invoke the element's URLUtilsReadOnly interface's set the input algorithm with the absolute URL that the WorkerLocation object represents as the given value.

The element's URLUtilsReadOnly interface's get the base algorithm must return null.