diff --git a/demos/workers/modules/filters.js b/demos/workers/modules/filters.js new file mode 100644 index 00000000000..2c3a892ad77 --- /dev/null +++ b/demos/workers/modules/filters.js @@ -0,0 +1,17 @@ +export function none() {} + +export function grayscale({ data: d }) { + for (let i = 0; i < d.length; i += 4) { + const [r, g, b] = [d[i], d[i + 1], d[i + 2]]; + + // CIE luminance for the RGB + // The human eye is bad at seeing red and blue, so we de-emphasize them. + d[i] = d[i + 1] = d[i + 2] = 0.2126 * r + 0.7152 * g + 0.0722 * b; + } +}; + +export function brighten({ data: d }) { + for (let i = 0; i < d.length; ++i) { + d[i] *= 1.2; + } +}; \ No newline at end of file diff --git a/demos/workers/modules/page.html b/demos/workers/modules/page.html new file mode 100644 index 00000000000..267fb935bb9 --- /dev/null +++ b/demos/workers/modules/page.html @@ -0,0 +1,64 @@ + + +
RequestCredentials enumerationTo fetch a classic worker script given a url, a referrer, a + settings object, and a boolean is shared, run these steps. The algorithm + will asynchronously complete with either null (on failure) or a new classic script + (on success).
+ +Let request be a new request whose
+ url is url, client is settings object, type is "script", destination is "sharedworker" if is shared is true and "worker" otherwise, referrer is
+ referrer, mode is "same-origin", credentials
+ mode is "same-origin", and whose use-URL-credentials
+ flag is set.
Fetch request.
Return from this algorithm, and run the remaining steps as part of the fetch's + process response for the response + response.
If response's type is "error", or response's status is not an ok status, asynchronously
+ complete this algorithm with null, and abort these steps.
Let source text be the result of UTF-8 + decoding response's body.
Let script be the result of creating a classic script using + source text and settings object.
To fetch a module script tree given a url, a credentials mode, and a settings object, run these steps. The algorithm will asynchronously complete with either null (on failure) or a new module script (on success).
@@ -93089,6 +93129,41 @@ function showLogout() { +All of our examples so far show workers that run classic
+ scripts. Workers can instead be instantiated using module
+ scripts, which have the usual benefits: the ability to use the JavaScript
+ import statement to import other modules; strict mode by default; and
+ top-level declarations not polluting the worker's global scope.
Note that such module-based workers follow different restrictions regarding cross-origin
+ content, compared to classic workers. Unlike classic workers, module workers can be instantiated
+ using a cross-origin script, as long as that script is exposed using the CORS
+ protocol. Additionally, the importScripts will automatically fail inside
+ module workers; the JavaScript import statement is generally a better
+ choice.
In this example, the main document uses a worker to do off-main-thread image manipulation. + It imports the filters used from another module.
+ +The main page is as follows:
+ +EXAMPLE workers/modules/page.html+ +
The worker file is then:
+ +EXAMPLE workers/modules/worker.js+ +
Which imports the file filters.js:
EXAMPLE workers/modules/filters.js+ + +
var worker = new Worker('helper.js');
+ If you want your worker script to be interpreted as a module script instead of + the default classic script, you need to use a slightly different signature:
+ +var worker = new Worker('helper.js', { type: "module" });
+
A WorkerGlobalScope object has an associated type ("classic" or "module"). It is set during creation.
+
A WorkerGlobalScope object has an associated url (null or a URL). It is initially
null.
@@ -93675,8 +93759,9 @@ interface WorkerGlobalScope : EventTarget {
SharedWorker object worker, URL url,
URL referrer, MessagePort outside port,
list of relevant Document objects to add docs, possible
- WorkerGlobalScope parent worker global scope, and a boolean flag is
- shared, it must run the following steps:
WorkerGlobalScope parent worker global scope, a boolean flag is
+ shared, and a WorkerOptions dictionary options, it must run the
+ following steps:
Let request be a new request whose
- url is url, client is settings object, type is "script", destination is "sharedworker" if is shared is true and "worker" otherwise, referrer is
- referrer, synchronous flag is set, mode is "same-origin", credentials mode is "same-origin", and whose use-URL-credentials flag is set.
Let response be the result of fetching request.
If response's status is an - ok status, then let source be the result of running the UTF-8 - decode algorithm on response's body.
- -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.
Otherwise, queue a task to fire a simple event named
- error at worker. Abort these steps.
Call the JavaScript WorkerGlobalScope : EventTarget {
Set up a worker environment settings object with realm execution
context, and let settings object be the result. Obtain script by switching on the value of options's If the algorithm asynchronously completes with null, queue a task to fire
+ a simple event named Associate worker with worker global scope. Create a new Set worker global scope's type to the value of the Execute the Initialize a Let script be the result of creating a classic script using
- source and settings object. Run the classic script script. If script is a classic script, then run the classic script script. Otherwise, it is a module
+ script; run the module script
+ script. In addition to the usual possibilities of returning a value or failing due to
an exception, this could be prematurely aborted by the "kill a worker" or
@@ -94101,13 +94181,21 @@ interface AbstractWorker {
The When the When the Run a worker given worker, worker URL, the
incumbent settings object's creation URL, outside port,
- docs, parent worker global scope, and false.type member:
+
+
+ classic"module"credentials member of options, and settings
+ object.error at worker, and
+ abort these steps. Otherwise, continue the rest of these steps after the algorithm's
+ asynchronous completion, with script being the asynchronous completion value.MessagePort object whose WorkerGlobalScope : EventTarget {
data-x="concept-WorkerGlobalScope-https-state">HTTPS state to response's HTTPS state.type member of options.global object's CSP list
algorithm on worker global scope and response. Dedicated workers and the
- Worker interface[Constructor(DOMString scriptURL), Exposed=(Window,Worker)]
+
[Constructor(DOMString scriptURL, optional WorkerOptions options), Exposed=(Window,Worker)]
interface Worker : EventTarget {
void terminate();
void postMessage(any message, optional sequence<Transferable> transfer);
attribute EventHandler onmessage;
};
+
+dictionary WorkerOptions {
+ WorkerType type = "classic";
+ RequestCredentials credentials = "omit"; // credentials is only used if type is "module"
+};
+
+enum WorkerType { "classic", "module" };
+
Worker implements AbstractWorker;
terminate() method, when invoked, must
@@ -94148,8 +94236,9 @@ interface Worker : EventTarget {
- Worker(scriptURL) constructor
- is invoked, the user agent must run the following steps:Worker(scriptURL,
+ options) constructor is invoked, the user agent must run the following
+ steps:
@@ -94191,7 +94280,7 @@ interface Worker : EventTarget {
SharedWorker interface[Constructor(DOMString scriptURL, optional DOMString name = ""), Exposed=(Window,Worker)] +[Constructor(DOMString scriptURL, optional DOMString name = "", optional WorkerOptions options), Exposed=(Window,Worker)] interface SharedWorker : EventTarget { readonly attribute MessagePort port; }; @@ -94209,8 +94298,9 @@ interface SharedWorker : EventTarget { it was assigned by the object's constructor. It represents theMessagePortfor communicating with the shared worker. -When the
+SharedWorker(scriptURL, name)constructor is invoked, the user agent must run the following - steps:When the
SharedWorker(scriptURL, + name, options)constructor is invoked, the user agent must run + the following steps:@@ -94349,7 +94439,7 @@ interface SharedWorker : EventTarget {
@@ -94401,6 +94491,8 @@ interface SharedWorker : EventTarget {- + docs, parent worker global scope, true, and options.
Run a worker given worker, urlRecord, the incumbent settings object's creation URL, outside port, - docs, parent worker global scope, and true.
To import scripts into worker global scope, the user agent must run the following steps:
+
If this
WorkerGlobalScopeobject's type is + "module", throw aTypeErrorand abort these steps.- @@ -116645,6 +116737,7 @@ INSERT INTERFACES HERE Patrick H. Lauke, Patrik Persson, Paul Adenot, + Paul Lewis, Paul Norman, Per-Erik Brodin, Perry Smith, @@ -116931,6 +117024,14 @@ INSERT INTERFACES HERE (CC0 1.0) +
Let settings object be the incumbent settings object.
++The image decoding demo used to demonstrate module-based workers draws on some example code + from a + tutorial by Ilmari Heikkinen. + (CC BY 3.0)
+Parts of this specification are © Copyright 2004-2014 Apple Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document.