From b64751e0ecf7fe2cd00f285157bff8e0a31e06be Mon Sep 17 00:00:00 2001 From: Jungkee Song Date: Tue, 13 Sep 2016 20:58:09 +0900 Subject: [PATCH] (WIP) Improve registration matching and exposing reserved/target client This patch fixes the client matching flow and exposes reserved client and target client information by adding necessary hooks to fetch and HTML. Related issue: https://github.com/w3c/ServiceWorker/issues/870 Call flow: https://github.com/w3c/ServiceWorker/issues/870#issuecomment-241341776 Expected behavior: https://github.com/w3c/ServiceWorker/issues/870#issuecomment-245559217 Related changes: - HTML: https://github.com/whatwg/html/pull/1776 - Fetch: https://github.com/whatwg/fetch/pull/383 * Work on Handle Fetch is done. Work on the client API is in progress. --- spec/service_worker/index.bs | 31 +- spec/service_worker/index.html | 636 +++++++++++++++---------------- spec/service_worker_1/index.bs | 28 +- spec/service_worker_1/index.html | 601 ++++++++++++++--------------- 4 files changed, 633 insertions(+), 663 deletions(-) diff --git a/spec/service_worker/index.bs b/spec/service_worker/index.bs index b707048f..af164031 100644 --- a/spec/service_worker/index.bs +++ b/spec/service_worker/index.bs @@ -377,10 +377,6 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/

Service Worker Client

A service worker client is a type of environment settings object.

-

A service worker client has an associated active worker (an active worker) which currently controls it. It is initially set to null.

- -

A service worker client has an associated id (an opaque string), which uniquely identifies itself during its lifetime. It is initially set to a new unique value when the corresponding environment settings object that it represents is created.

-

A service worker client has an associated frame type, which is one of auxiliary, top-level, nested, and none. Unless stated otherwise it is none.

A window client is a service worker client whose global object is a {{Window}} object.

@@ -634,7 +630,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
-

The {{ServiceWorkerRegistration/unregister()}} method unregisters the service worker registration. It is important to note that the currently controlled service worker client's active worker's containing service worker registration is effective until all the service worker clients (including itself) using this service worker registration unload. That is, the {{ServiceWorkerRegistration/unregister()}} method only affects subsequent navigations.

+

The {{ServiceWorkerRegistration/unregister()}} method unregisters the service worker registration. It is important to note that the currently controlled service worker client's active worker's containing service worker registration is effective until all the service worker clients (including itself) using this service worker registration unload. That is, the {{ServiceWorkerRegistration/unregister()}} method only affects subsequent navigations.

unregister() method must run these steps:

@@ -730,7 +726,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
  1. Let client be the context object's service worker client.
  2. -
  3. Return the {{ServiceWorker}} object that represents client's active worker.
  4. +
  5. Return the {{ServiceWorker}} object that represents client's active worker.

{{ServiceWorkerContainer/controller|navigator.serviceWorker.controller}} returns null if the request is a force refresh (shift+refresh). The {{ServiceWorker}} objects returned from this attribute getter that represent the same service worker are the same objects.

@@ -988,7 +984,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/ controllerchange {{Event}} - The service worker client's active worker changes. (See step 9.2 of the Activate algorithm. The skip waiting flag of a service worker causes activation of the service worker registration to occur while service worker clients are using the service worker registration, {{ServiceWorkerContainer/controller|navigator.serviceWorker.controller}} immediately reflects the active worker as the service worker that controls the service worker client.) + The service worker client's active worker changes. (See step 9.2 of the Activate algorithm. The skip waiting flag of a service worker causes activation of the service worker registration to occur while service worker clients are using the service worker registration, {{ServiceWorkerContainer/controller|navigator.serviceWorker.controller}} immediately reflects the active worker as the service worker that controls the service worker client.) message @@ -1209,7 +1205,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/

{{Client/id}}

-

The id attribute must return its associated service worker client's id.

+

The id attribute must return its associated service worker client's id.

@@ -1289,7 +1285,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
  • Let url be the result of parsing url with the context object's relevant settings object's API base URL.
  • If url is failure, return a promise rejected with a TypeError.
  • If url is about:blank, return a promise rejected with a TypeError.
  • -
  • If the context object's associated service worker client's active worker is not the context object's relevant global object's service worker, return a promise rejected with a TypeError.
  • +
  • If the context object's associated service worker client's active worker is not the context object's relevant global object's service worker, return a promise rejected with a TypeError.
  • Let promise be a new promise.
  • Run these substeps in parallel:
      @@ -1364,7 +1360,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
      1. For each service worker client client whose origin is the same as the associated service worker's origin:
          -
        1. If client's id is id, then: +
        2. If client's id is id, then:
          1. If client is not a secure context, reject promise with a "{{SecurityError}}" exception and abort these steps.
          2. If client is a window client, then: @@ -1415,7 +1411,7 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
          3. If client is not a secure context, continue to the next iteration of the loop.
          4. If options.{{ClientQueryOptions/includeUncontrolled}} is false, then:
              -
            1. If client's active worker is the associated service worker, add client to targetClients.
            2. +
            3. If client's active worker is the associated service worker, add client to targetClients.
          5. Else: @@ -3603,17 +3599,16 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
          6. Else if request is a non-subresource request, then:

            If the non-subresource request is under the scope of a service worker registration, application cache is completely bypassed regardless of whether the non-subresource request uses the service worker registration.

              -
            1. If client is not a secure context, return null.
            2. If request is a navigation request and the navigation triggering it was initiated with a shift+reload or equivalent, return null.
            3. -
            4. Set registration to the result of running Match Service Worker Registration algorithm passing request's url as the argument.
            5. +
            6. If request's reserved client is not null and request's reserved client's active worker activeWorker is not null, set registration to activeWorker's containing service worker registration.
            7. +
            8. Else, set registration to the result of running Match Service Worker Registration algorithm passing request's url as the argument.
            9. If registration is null or registration's active worker is null, return null.
            10. -
            11. Set client's active worker to registration's active worker.
            -

            From this point, the service worker client starts to use its active worker's containing service worker registration.

            +

            From this point, the service worker client starts to use its active worker's containing service worker registration.

          7. Else if request is a subresource request, then:
              -
            1. If client's active worker is non-null, set registration to client's active worker's containing service worker registration.
            2. +
            3. If client's active worker is non-null, set registration to client's active worker's containing service worker registration.
            4. Else, return null.
          8. @@ -3627,7 +3622,9 @@ spec: webidl; urlPrefix: https://heycam.github.io/webidl/
            1. Create a trusted event e that uses the {{FetchEvent}} interface, with the event type fetch, which does not bubble.
            2. Let the request attribute of e be initialized to r.
            3. -
            4. Let the clientId attribute of e be initialized to client's id if request is not a non-subresource request, and to null otherwise.
            5. +
            6. Initialize e's clientId attribute to client's id.
            7. +
            8. If request is a non-subresource request, initialize e's reservedClientId attribute to request's reserved client's id, and to undefined otherwise.
            9. +
            10. If request is a navigation request, initialize e's targetClientId attribute to request's target browsing context's active document's relevant settings object's id, and to undefined otherwise.
            11. Let the isReload attribute of e be initialized to true if request's client is a window client and the event was dispatched with the user's intention for the page reload, and false otherwise.
            12. Dispatch e at activeWorker's environment settings object's global object.
            13. If e's respond-with entered flag is set, set respondWithEntered to true.
            14. diff --git a/spec/service_worker/index.html b/spec/service_worker/index.html index 1a96f8dd..bbdee113 100644 --- a/spec/service_worker/index.html +++ b/spec/service_worker/index.html @@ -1422,7 +1422,7 @@

              Service Workers Nightly

              -

              Editor’s Draft,

              +

              Editor’s Draft,

              This version: @@ -1790,20 +1790,18 @@

              2.3. Service Worker Client

              A service worker client is a type of environment settings object.

              -

              A service worker client has an associated active worker (an active worker) which currently controls it. It is initially set to null.

              -

              A service worker client has an associated id (an opaque string), which uniquely identifies itself during its lifetime. It is initially set to a new unique value when the corresponding environment settings object that it represents is created.

              -

              A service worker client has an associated frame type, which is one of auxiliary, top-level, nested, and none. Unless stated otherwise it is none.

              -

              A window client is a service worker client whose global object is a Window object.

              -

              A dedicated worker client is a service worker client whose global object is a DedicatedWorkerGlobalScope object.

              -

              A shared worker client is a service worker client whose global object is a SharedWorkerGlobalScope object.

              +

              A service worker client has an associated frame type, which is one of auxiliary, top-level, nested, and none. Unless stated otherwise it is none.

              +

              A window client is a service worker client whose global object is a Window object.

              +

              A dedicated worker client is a service worker client whose global object is a DedicatedWorkerGlobalScope object.

              +

              A shared worker client is a service worker client whose global object is a SharedWorkerGlobalScope object.

              A worker client is either a dedicated worker client or a shared worker client.

  • 2.4. Selection and Use

    -

    A service worker client independently selects and uses a service worker registration for its own loading and its subresources. The selection of a service worker registration, upon a non-subresource request, is a process of either matching a service worker registration from scope to registration map or inheriting an existing service worker registration from its parent or owner context depending on the request’s url.

    -

    When the request’s url is not local, a service worker client matches a service worker registration from scope to registration map. That is, the service worker client attempts to consult a service worker registration whose scope url matches its creation url.

    -

    When the request’s url is local, if the service worker client’s responsible browsing context is a nested browsing context or the service worker client is a worker client, the service worker client inherits the service worker registration from its parent browsing context’s environment or one of the worker’s Documents' environment, respectively, if it exists.

    -

    If the selection was successful, the selected service worker registration’s active worker starts to control the service worker client. Otherwise, the flow returns to fetch where it falls back to the default behavior. When a service worker client is controlled by an active worker, it is considered that the service worker client is using the active worker’s containing service worker registration.

    +

    A service worker client independently selects and uses a service worker registration for its own loading and its subresources. The selection of a service worker registration, upon a non-subresource request, is a process of either matching a service worker registration from scope to registration map or inheriting an existing service worker registration from its parent or owner context depending on the request’s url.

    +

    When the request’s url is not local, a service worker client matches a service worker registration from scope to registration map. That is, the service worker client attempts to consult a service worker registration whose scope url matches its creation url.

    +

    When the request’s url is local, if the service worker client’s responsible browsing context is a nested browsing context or the service worker client is a worker client, the service worker client inherits the service worker registration from its parent browsing context’s environment or one of the worker’s Documents' environment, respectively, if it exists.

    +

    If the selection was successful, the selected service worker registration’s active worker starts to control the service worker client. Otherwise, the flow returns to fetch where it falls back to the default behavior. When a service worker client is controlled by an active worker, it is considered that the service worker client is using the active worker’s containing service worker registration.

    2.5. Task Sources

    @@ -1822,7 +1820,7 @@

    A user agent must maintain the state of its stored service worker registrations across restarts with the following rules:

    To attain this, the user agent must invoke Handle User Agent Shutdown when it terminates.

    @@ -1832,22 +1830,23 @@

    3. Client Context

    Bootstrapping with a ServiceWorker: -
    // scope defaults to the path the script sits in
    -// "/" in this example
    -navigator.serviceWorker.register("/serviceworker.js").then(
    -  function(registration) {
    -    console.log("success!");
    -    if (registration.installing) {
    -      registration.installing.postMessage("Howdy from your installing page.");
    +
    // scope defaults to the path the script sits in
    +// "/" in this example
    +navigator.serviceWorker.register("/serviceworker.js").then(
    +  function(registration) {
    +    console.log("success!");
    +    if (registration.installing) {
    +      registration.installing.postMessage("Howdy from your installing page.");
         }
    -  },
    -  function(why) {
    -    console.error("Installing the worker failed!:", why);
    -  });
    + }, + function(why) { + console.error("Installing the worker failed!:", why); + }); +

    3.1. ServiceWorker

    -
    [SecureContext, Exposed=(Window,Worker)]
    +
    [SecureContext, Exposed=(Window,Worker)]
     interface ServiceWorker : EventTarget {
       readonly attribute USVString scriptURL;
       readonly attribute ServiceWorkerState state;
    @@ -1874,8 +1873,9 @@ 

    For example, consider a document created by a navigation to https://example.com/app.html which matches via the following registration call which has been previously executed:

    -
    // Script on the page https://example.com/app.html
    -navigator.serviceWorker.register("/service_worker.js", { scope: "/" });
    +
    // Script on the page https://example.com/app.html
    +navigator.serviceWorker.register("/service_worker.js", { scope: "/" });
    +

    The value of navigator.serviceWorker.controller.scriptURL will be "https://example.com/service_worker.js".

    @@ -1891,7 +1891,7 @@

    <
  • Let serviceWorker be the service worker represented by the context object.
  • Invoke Run Service Worker algorithm with serviceWorker as the argument.
  • Let destination be the ServiceWorkerGlobalScope object associated with serviceWorker. -
  • Let targetRealm be destination’s Realm. +
  • Let targetRealm be destination’s Realm.
  • Let incumbentSettings be the incumbent settings object, and incumbentGlobal its global object.
  • Let cloneRecord be StructuredCloneWithTransfer(message, transfer, targetRealm). If this throws an exception, rethrow that exception and abort these steps.
  • Let clonedMessage be cloneRecord.[[Clone]]. @@ -1928,7 +1928,7 @@

    3.2. ServiceWorkerRegistration

    -
    [SecureContext, Exposed=(Window,Worker)]
    +
    [SecureContext, Exposed=(Window,Worker)]
     interface ServiceWorkerRegistration : EventTarget {
       readonly attribute ServiceWorker? installing;
       readonly attribute ServiceWorker? waiting;
    @@ -1936,8 +1936,8 @@ 

    readonly attribute USVString scope; - [NewObject] Promise<void> update(); - [NewObject] Promise<boolean> unregister(); + [NewObject] Promise<void> update(); + [NewObject] Promise<boolean> unregister(); // event attribute EventHandler onupdatefound; @@ -1981,7 +1981,7 @@

    -

    The unregister() method unregisters the service worker registration. It is important to note that the currently controlled service worker client’s active worker’s containing service worker registration is effective until all the service worker clients (including itself) using this service worker registration unload. That is, the unregister() method only affects subsequent navigations.

    +

    The unregister() method unregisters the service worker registration. It is important to note that the currently controlled service worker client’s active worker’s containing service worker registration is effective until all the service worker clients (including itself) using this service worker registration unload. That is, the unregister() method only affects subsequent navigations.

    unregister() method must run these steps:

    1. Let p be a promise. @@ -2008,26 +2008,26 @@

      3.3. navigator.serviceWorker

      partial interface Navigator {
      -  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
      +  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
       };
       
       partial interface WorkerNavigator {
      -  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
      +  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
       };
       

      The serviceWorker attribute must return the ServiceWorkerContainer object that is associated with the context object.

    3.4. ServiceWorkerContainer

    -
    [SecureContext, Exposed=(Window,Worker)]
    +
    [SecureContext, Exposed=(Window,Worker)]
     interface ServiceWorkerContainer : EventTarget {
       readonly attribute ServiceWorker? controller;
    -  [SameObject] readonly attribute Promise<ServiceWorkerRegistration> ready;
    +  [SameObject] readonly attribute Promise<ServiceWorkerRegistration> ready;
     
    -  [NewObject] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options);
    +  [NewObject] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options);
     
    -  [NewObject] Promise<any> getRegistration(optional USVString clientURL = "");
    -  [NewObject] Promise<sequence<ServiceWorkerRegistration>> getRegistrations();
    +  [NewObject] Promise<any> getRegistration(optional USVString clientURL = "");
    +  [NewObject] Promise<sequence<ServiceWorkerRegistration>> getRegistrations();
     
       void startMessages();
     
    @@ -2044,7 +2044,7 @@ 

    The user agent must create a ServiceWorkerContainer object when a Navigator object or a WorkerNavigator object is created and associate it with that object.

    A ServiceWorkerContainer provides capabilities to register, unregister, and update the service worker registrations, and provides access to the state of the service worker registrations and their associated service workers.

    -

    A ServiceWorkerContainer has an associated service worker client, which is a service worker client whose global object is associated with the Navigator object or the WorkerNavigator object that the ServiceWorkerContainer is retrieved from.

    +

    A ServiceWorkerContainer has an associated service worker client, which is a service worker client whose global object is associated with the Navigator object or the WorkerNavigator object that the ServiceWorkerContainer is retrieved from.

    A ServiceWorkerContainer object has an associated ready promise (a promise). It is initially set to a new promise.

    A ServiceWorkerContainer object has a task source called the client message queue, initially empty. A client message queue can be enabled or disabled, and is initially disabled. When a ServiceWorkerContainer object’s client message queue is enabled, the event loop must use it as one of its task sources. When the ServiceWorkerContainer object’s relevant global object is a Window object, all tasks queued on its client message queue must be associated with its relevant settings object’s responsible document.

    @@ -2052,7 +2052,7 @@
    @@ -2079,13 +2079,13 @@

    @@ -2173,12 +2173,12 @@

    3.5. ServiceWorkerMessageEvent

    -
    [Constructor(DOMString type, optional ServiceWorkerMessageEventInit eventInitDict), Exposed=(Window,Worker)]
    +
    [Constructor(DOMString type, optional ServiceWorkerMessageEventInit eventInitDict), Exposed=(Window,Worker)]
     interface ServiceWorkerMessageEvent : Event {
       readonly attribute any data;
       readonly attribute DOMString origin;
       readonly attribute DOMString lastEventId;
    -  [SameObject] readonly attribute (ServiceWorker or MessagePort)? source;
    +  [SameObject] readonly attribute (ServiceWorker or MessagePort)? source;
       readonly attribute FrozenArray<MessagePort>? ports;
     };
     
    @@ -2251,7 +2251,7 @@

    controllerchange Event - The service worker client’s active worker changes. (See step 9.2 of the Activate algorithm. The skip waiting flag of a service worker causes activation of the service worker registration to occur while service worker clients are using the service worker registration, navigator.serviceWorker.controller immediately reflects the active worker as the service worker that controls the service worker client.) + The service worker client’s active worker changes. (See step 9.2 of the Activate algorithm. The skip waiting flag of a service worker causes activation of the service worker registration to occur while service worker clients are using the service worker registration, navigator.serviceWorker.controller immediately reflects the active worker as the service worker that controls the service worker client.) message ServiceWorkerMessageEvent @@ -2263,49 +2263,50 @@

    4. Execution Context

    Serving Cached Resources: -
    // caching.js
    -this.addEventListener("install", function(e) {
    -  e.waitUntil(
    -    // Open a cache of resources.
    -    caches.open("shell-v1").then(function(cache) {
    -      // Begins the process of fetching them.
    -      // The coast is only clear when all the resources are ready.
    -      return cache.addAll([
    +
    // caching.js
    +this.addEventListener("install", function(e) {
    +  e.waitUntil(
    +    // Open a cache of resources.
    +    caches.open("shell-v1").then(function(cache) {
    +      // Begins the process of fetching them.
    +      // The coast is only clear when all the resources are ready.
    +      return cache.addAll([
             "/app.html",
             "/assets/v1/base.css",
             "/assets/v1/app.js",
             "/assets/v1/logo.png",
             "/assets/v1/intro_video.webm"
    -      ]);
    -    })
    -  );
    -});
    -
    -this.addEventListener("fetch", function(e) {
    -  // No "fetch" events are dispatched to the service worker until it
    -  // successfully installs and activates.
    -
    -  // All operations on caches are async, including matching URLs, so we use
    -  // promises heavily. e.respondWith() even takes promises to enable this:
    -  e.respondWith(
    -    caches.match(e.request).then(function(response) {
    -      return response || fetch(e.request);
    -    }).catch(function() {
    -      return caches.match("/fallback.html");
    -    })
    -  );
    -});
    + ]); + }) + ); +}); + +this.addEventListener("fetch", function(e) { + // No "fetch" events are dispatched to the service worker until it + // successfully installs and activates. + + // All operations on caches are async, including matching URLs, so we use + // promises heavily. e.respondWith() even takes promises to enable this: + e.respondWith( + caches.match(e.request).then(function(response) { + return response || fetch(e.request); + }).catch(function() { + return caches.match("/fallback.html"); + }) + ); +}); +

    4.1. ServiceWorkerGlobalScope

    -
    [Global=(Worker,ServiceWorker), Exposed=ServiceWorker]
    +
    [Global=(Worker,ServiceWorker), Exposed=ServiceWorker]
     interface ServiceWorkerGlobalScope : WorkerGlobalScope {
       // A container for a list of Client objects that correspond to
       // browsing contexts (or shared workers) that are on the origin of this SW
    -  [SameObject] readonly attribute Clients clients;
    -  [SameObject] readonly attribute ServiceWorkerRegistration registration;
    +  [SameObject] readonly attribute Clients clients;
    +  [SameObject] readonly attribute ServiceWorkerRegistration registration;
     
    -  [NewObject] Promise<void> skipWaiting();
    +  [NewObject] Promise<void> skipWaiting();
     
       attribute EventHandler oninstall;
       attribute EventHandler onactivate;
    @@ -2317,7 +2318,7 @@ 

    A ServiceWorkerGlobalScope object represents the global execution context of a service worker. A ServiceWorkerGlobalScope object has an associated service worker (a service worker).

    -

    ServiceWorkerGlobalScope object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully registered, a service worker is started, kept alive and killed by their relationship to events, not service worker clients. Any type of synchronous requests must not be initiated inside of a service worker.

    +

    ServiceWorkerGlobalScope object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully registered, a service worker is started, kept alive and killed by their relationship to events, not service worker clients. Any type of synchronous requests must not be initiated inside of a service worker.

    4.1.1. clients

    clients attribute must return the Clients object that is associated with the context object.

    @@ -2328,7 +2329,7 @@

    4.1.3. skipWaiting()

    -

    The skipWaiting() method allows this service worker to progress from the registration’s waiting position to active even while service worker clients are using the registration.

    +

    The skipWaiting() method allows this service worker to progress from the registration’s waiting position to active even while service worker clients are using the registration.

    skipWaiting() method must run these steps:

    1. Let promise be a new promise. @@ -2375,7 +2376,7 @@

      4.2. Client

      -
      [Exposed=ServiceWorker]
      +
      [Exposed=ServiceWorker]
       interface Client {
         readonly attribute USVString url;
         readonly attribute FrameType frameType;
      @@ -2383,12 +2384,12 @@ 

      4.2 void postMessage(any message, optional sequence<object> transfer); }; -[Exposed=ServiceWorker] +[Exposed=ServiceWorker] interface WindowClient : Client { readonly attribute VisibilityState visibilityState; readonly attribute boolean focused; - [NewObject] Promise<WindowClient> focus(); - [NewObject] Promise<WindowClient> navigate(USVString url); + [NewObject] Promise<WindowClient> focus(); + [NewObject] Promise<WindowClient> navigate(USVString url); }; enum FrameType { @@ -2398,7 +2399,7 @@

      4.2 "none" };

      -

      A Client object has an associated service worker client (a service worker client).

      +

      A Client object has an associated service worker client (a service worker client).

      A WindowClient object has an associated visibility state, which is one of visibilityState attribute value.

      A WindowClient object has an associated focus state, which is either true or false (initially false).

      @@ -2427,7 +2428,7 @@

      4.2.3. id

      -

      The id attribute must return its associated service worker client’s id.

      +

      The id attribute must return its associated service worker client’s id.

      4.2.4. postMessage(message, transfer)

      @@ -2494,7 +2495,7 @@

      Let url be the result of parsing url with the context object’s relevant settings object’s API base URL.
    2. If url is failure, return a promise rejected with a TypeError.
    3. If url is about:blank, return a promise rejected with a TypeError. -
    4. If the context object’s associated service worker client’s active worker is not the context object’s relevant global object’s service worker, return a promise rejected with a TypeError. +
    5. If the context object’s associated service worker client’s active worker is not the context object’s relevant global object’s service worker, return a promise rejected with a TypeError.
    6. Let promise be a new promise.
    7. Run these substeps in parallel: @@ -2529,13 +2530,13 @@

      4.3. Clients

      -
      [Exposed=ServiceWorker]
      +
      [Exposed=ServiceWorker]
       interface Clients {
         // The objects returned will be new instances every time
      -  [NewObject] Promise<any> get(DOMString id);
      -  [NewObject] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options);
      -  [NewObject] Promise<WindowClient?> openWindow(USVString url);
      -  [NewObject] Promise<void> claim();
      +  [NewObject] Promise<any> get(DOMString id);
      +  [NewObject] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options);
      +  [NewObject] Promise<WindowClient?> openWindow(USVString url);
      +  [NewObject] Promise<void> claim();
       };
       
      dictionary ClientQueryOptions {
      @@ -2560,10 +2561,10 @@ 

      in parallel:
      1. - For each service worker client client whose origin is the same as the associated service worker’s origin: + For each service worker client client whose origin is the same as the associated service worker’s origin:
        1. - If client’s id is id, then: + If client’s id is id, then:
          1. If client is not a secure context, reject promise with a "SecurityError" exception and abort these steps.
          2. @@ -2605,13 +2606,13 @@

            service worker client client whose origin is the same as the associated service worker’s origin: + For each service worker client client whose origin is the same as the associated service worker’s origin:
            1. If client is not a secure context, continue to the next iteration of the loop.
            2. If options.includeUncontrolled is false, then:
                -
              1. If client’s active worker is the associated service worker, add client to targetClients. +
              2. If client’s active worker is the associated service worker, add client to targetClients.
            3. Else: @@ -2621,7 +2622,7 @@

              service worker client client in targetClients, in the most recently focused order for window clients: + For each service worker client client in targetClients, in the most recently focused order for window clients:
              1. If options.type is "window", and client is a window client, then: @@ -2743,22 +2744,22 @@

                4.3.4. claim()

                The claim() method must run these steps:

                  -
                1. If the service worker is not an active worker, return a promise rejected with an "InvalidStateError" exception. +
                2. If the service worker is not an active worker, return a promise rejected with an "InvalidStateError" exception.
                3. Let promise be a new promise.
                4. Run the following substeps in parallel:
                  1. - For each service worker client client whose origin is the same as the service worker’s origin: + For each service worker client client whose origin is the same as the service worker’s origin:
                    1. If client is not a secure context, continue to the next iteration of the loop.
                    2. Let registration be the result of running Match Service Worker Registration algorithm passing client’s creation url as the argument.
                    3. If registration is not the service worker’s containing service worker registration, continue to the next iteration of the loop.
                    4. - If client’s active worker is not the service worker, then: + If client’s active worker is not the service worker, then:
                      1. Invoke Handle Service Worker Client Unload with client as the argument. -
                      2. Set client’s active worker to service worker. +
                      3. Set client’s active worker to service worker.
                      4. Invoke Notify Controller Change algorithm with client as the argument.
                    @@ -2770,7 +2771,7 @@

                    4.4. ExtendableEvent

                    -
                    [Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker]
                    +
                    [Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker]
                     interface ExtendableEvent : Event {
                       void waitUntil(Promise<any> f);
                     };
                    @@ -2815,12 +2816,12 @@ 

                    Service workers define the following behaviors for install event and activate event, respectively:

      4.5. InstallEvent

      -
      [Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker]
      +
      [Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker]
       interface InstallEvent : ExtendableEvent {
         void registerForeignFetch(ForeignFetchOptions options);
       };
      @@ -2872,9 +2873,9 @@ 

      4.6. FetchEvent

      -
      [Constructor(DOMString type, FetchEventInit eventInitDict), Exposed=ServiceWorker]
      +
      [Constructor(DOMString type, FetchEventInit eventInitDict), Exposed=ServiceWorker]
       interface FetchEvent : ExtendableEvent {
      -  [SameObject] readonly attribute Request request;
      +  [SameObject] readonly attribute Request request;
         readonly attribute DOMString? clientId;
         readonly attribute boolean isReload;
       
      @@ -3007,9 +3008,9 @@ 

      4.7. ForeignFetchEvent

      -
      [Constructor(DOMString type, ForeignFetchEventInit eventInitDict), Exposed=ServiceWorker]
      +
      [Constructor(DOMString type, ForeignFetchEventInit eventInitDict), Exposed=ServiceWorker]
       interface ForeignFetchEvent : ExtendableEvent {
      -  [SameObject] readonly attribute Request request;
      +  [SameObject] readonly attribute Request request;
         readonly attribute USVString origin;
       
         void respondWith(Promise<ForeignFetchResponse> r);
      @@ -3027,7 +3028,7 @@ 

      Service workers have a functional event foreignfetch. For foreignfetch events, service workers use the ForeignFetchEvent interface which extends the ExtendableEvent interface.

      -

      Each event using ForeignFetchEvent interface has an associated potential response (a response), initially set to null, an associated origin (a USVString or null), initially set to null, an associated list of exposed headers (whose element type is a byte string), initially set to an empty list, and the following associated flags that are initially unset:

      +

      Each event using ForeignFetchEvent interface has an associated potential response (a response), initially set to null, an associated origin (a USVString or null), initially set to null, an associated list of exposed headers (whose element type is a byte string), initially set to an empty list, and the following associated flags that are initially unset:

      @@ -3291,7 +3294,7 @@

      6.3. self.caches

      partial interface WindowOrWorkerGlobalScope {
      -  [SecureContext, SameObject] readonly attribute CacheStorage caches;
      +  [SecureContext, SameObject] readonly attribute CacheStorage caches;
       };
       
      @@ -3301,15 +3304,15 @@

      6.4. Cache

      -
      [SecureContext, Exposed=(Window,Worker)]
      +
      [SecureContext, Exposed=(Window,Worker)]
       interface Cache {
      -  [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options);
      -  [NewObject] Promise<sequence<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
      -  [NewObject] Promise<void> add(RequestInfo request);
      -  [NewObject] Promise<void> addAll(sequence<RequestInfo> requests);
      -  [NewObject] Promise<void> put(RequestInfo request, Response response);
      -  [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options);
      -  [NewObject] Promise<sequence<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options);
      +  [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options);
      +  [NewObject] Promise<sequence<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
      +  [NewObject] Promise<void> add(RequestInfo request);
      +  [NewObject] Promise<void> addAll(sequence<RequestInfo> requests);
      +  [NewObject] Promise<void> put(RequestInfo request, Response response);
      +  [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options);
      +  [NewObject] Promise<sequence<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options);
       };
       
      dictionary CacheQueryOptions {
      @@ -3698,13 +3701,13 @@ 

      6.5. CacheStorage

      -
      [SecureContext, Exposed=(Window,Worker)]
      +
      [SecureContext, Exposed=(Window,Worker)]
       interface CacheStorage {
      -  [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options);
      -  [NewObject] Promise<boolean> has(DOMString cacheName);
      -  [NewObject] Promise<Cache> open(DOMString cacheName);
      -  [NewObject] Promise<boolean> delete(DOMString cacheName);
      -  [NewObject] Promise<sequence<DOMString>> keys();
      +  [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options);
      +  [NewObject] Promise<boolean> has(DOMString cacheName);
      +  [NewObject] Promise<Cache> open(DOMString cacheName);
      +  [NewObject] Promise<boolean> delete(DOMString cacheName);
      +  [NewObject] Promise<sequence<DOMString>> keys();
       };
       

      CacheStorage interface is designed to largely conform to ECMAScript 6 Map objects but entirely async, and with additional convenience methods. The methods, clear, forEach, entries and values, are intentionally excluded from the scope of the first version resorting to the ongoing discussion about the async iteration by TC39.

      @@ -3844,7 +3847,7 @@

      7. Security Considerations

      7.1. Secure Context

      -

      Service workers must execute in secure contexts. Service worker clients must also be secure contexts to register a service worker registration, to get access to the service worker registrations and the service workers, to do messaging with the service workers, and to be manipulated by the service workers. This effectively means that service workers and their service worker clients should be hosted over HTTPS. A user agent may allow localhost, 127.0.0.0/8, and ::1/128 for development purpose. (Note that they may still be secure contexts.) The primary reason for this restriction is to protect users from the risks associated with insecure contexts.

      +

      Service workers must execute in secure contexts. Service worker clients must also be secure contexts to register a service worker registration, to get access to the service worker registrations and the service workers, to do messaging with the service workers, and to be manipulated by the service workers. This effectively means that service workers and their service worker clients should be hosted over HTTPS. A user agent may allow localhost, 127.0.0.0/8, and ::1/128 for development purpose. (Note that they may still be secure contexts.) The primary reason for this restriction is to protect users from the risks associated with insecure contexts.

      7.2. Content Security Policy

      @@ -3861,7 +3864,7 @@

      7.3.1. Origin restriction

      This section is non-normative.

      -

      A Service worker executes in the registering service worker client’s origin. One of the advanced concerns that major applications would encounter is whether they can be hosted from a CDN. By definition, these are servers in other places, often on other origins. Therefore, service workers cannot be hosted on CDNs. But they can include resources via importScripts(). The reason for this restriction is that service workers create the opportunity for a bad actor to turn a bad day into a bad eternity.

      +

      A Service worker executes in the registering service worker client’s origin. One of the advanced concerns that major applications would encounter is whether they can be hosted from a CDN. By definition, these are servers in other places, often on other origins. Therefore, service workers cannot be hosted on CDNs. But they can include resources via importScripts(). The reason for this restriction is that service workers create the opportunity for a bad actor to turn a bad day into a bad eternity.

      7.3.2. importScripts(urls)

      @@ -3961,7 +3964,7 @@

      Appendix A: Al

      A job has a scope url (a URL).

      A job has a script url (a URL).

      A job has a worker type ("classic" or "module").

      -

      A job has a client (a service worker client). It is initially null.

      +

      A job has a client (a service worker client). It is initially null.

      A job has a referrer (a URL or null).

      A job has a promise (a promise). It is initially null.

      A job has a list of equivalent jobs (a list of jobs). It is initially the empty list.

      @@ -3981,7 +3984,7 @@

      Crea
      scopeURL, a URL
      scriptURL, a URL
      promise, a promise -
      client, a service worker client +
      client, a service worker client
      Output
      job, a job @@ -4098,7 +4101,7 @@

      scopeURL, a URL or failure or null
      scriptURL, a URL or failure
      promise, a promise -
      client, a service worker client +
      client, a service worker client
      referrer, a URL
      workerType, a worker type
      Output @@ -4274,7 +4277,7 @@

      Update
    8. Let worker be a new service worker. -
    9. Generate a unique opaque string and set worker’s id to the value. +
    10. Generate a unique opaque string and set worker’s id to the value.
    11. Set worker’s script url to job’s script url, worker’s script resource to script, and worker’s type to job’s worker type.
    12. Invoke Run Service Worker algorithm with worker as the argument.
    13. @@ -4326,7 +4329,7 @@

      In
    14. Run the Update Worker State algorithm passing registration’s installing worker and installing as the arguments.
    15. Assert: job’s promise is not null.
    16. Invoke Resolve Job Promise with job and the ServiceWorkerRegistration object which represents registration. -
    17. Queue a task to fire a simple event named updatefound at all the ServiceWorkerRegistration objects for all the service worker clients whose creation url matches registration’s scope url and all the service workers whose containing service worker registration is registration. +
    18. Queue a task to fire a simple event named updatefound at all the ServiceWorkerRegistration objects for all the service worker clients whose creation url matches registration’s scope url and all the service workers whose containing service worker registration is registration.
    19. Let installingWorker be registration’s installing worker.
    20. Invoke Run Service Worker algorithm with installingWorker as the argument.
    21. @@ -4373,7 +4376,7 @@

      In

  • Invoke Finish Job with job.
  • Wait for all the tasks queued by Update Worker State invoked in this algorithm have executed. -
  • Wait until no service worker client is using registration or registration’s waiting worker’s skip waiting flag is set. +
  • Wait until no service worker client is using registration or registration’s waiting worker’s skip waiting flag is set.
  • If registration’s waiting worker waitingWorker is not null and waitingWorker’s skip waiting flag is not set, invoke Activate algorithm with registration as its argument.
  • @@ -4389,32 +4392,32 @@

    Acti
  • If registration’s waiting worker is null, abort these steps.
  • Let redundantWorker be null.
  • - If registration’s active worker is not null, then: + If registration’s active worker is not null, then:
      -
    1. Set redundantWorker to registration’s active worker. +
    2. Set redundantWorker to registration’s active worker.
    3. Wait for redundantWorker to finish handling any in-progress requests.
    4. Terminate redundantWorker.
  • Run the Update Registration State algorithm passing registration, "active" and registration’s waiting worker as the arguments.
  • Run the Update Registration State algorithm passing registration, "waiting" and null as the arguments.
  • - Run the Update Worker State algorithm passing registration’s active worker and activating as the arguments. + Run the Update Worker State algorithm passing registration’s active worker and activating as the arguments.

    Once an active worker is activating, neither a runtime script error nor a force termination of the active worker prevents the active worker from getting activated.

  • If redundantWorker is not null, run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
  • - For each service worker client client whose creation url matches registration’s scope url: + For each service worker client client whose creation url matches registration’s scope url:
    1. If client is a window client, unassociate client’s responsible document from its application cache, if it has one.
    2. Else if client is a shared worker client, unassociate client’s global object from its application cache, if it has one.

    Resources will now use the service worker registration instead of the existing application cache.

  • - For each service worker client client who is using registration: + For each service worker client client who is using registration:
      -
    1. Set client’s active worker to registration’s active worker. +
    2. Set client’s active worker to registration’s active worker.
    3. Invoke Notify Controller Change algorithm with client as the argument.
    -
  • Let activeWorker be registration’s active worker. +
  • Let activeWorker be registration’s active worker.
  • Invoke Run Service Worker algorithm with activeWorker as the argument.
  • Queue a task task to run the following substeps: @@ -4425,7 +4428,7 @@

    Acti
  • Wait for task to have executed or been discarded, or the script to have been aborted by the termination of activeWorker.
  • Wait for the step labeled WaitForAsynchronousExtensions to complete. -
  • Run the Update Worker State algorithm passing registration’s active worker and activated as the arguments. +
  • Run the Update Worker State algorithm passing registration’s active worker and activated as the arguments.
  • @@ -4448,7 +4451,7 @@

    JavaScript execution context.
  • Let workerEventLoop be a newly created event loop. -
  • Let workerGlobalScope be realmExecutionContext’s global object. +
  • Let workerGlobalScope be realmExecutionContext’s global object.
  • Let settingsObject be a new environment settings object whose algorithms are defined as follows:
    @@ -4466,7 +4469,7 @@

    API base URL
    Return serviceWorker’s script url.
    The origin -
    Return its registering service worker client’s origin. +
    Return its registering service worker client’s origin.
    The creation URL
    Return workerGlobalScope’s url.
    The HTTPS state @@ -4476,7 +4479,7 @@

    HTTPS state to serviceWorker’s script resource’s HTTPS state.
  • Set workerGlobalScope’s type to serviceWorker’s type.
  • Create a new WorkerLocation object and associate it with workerGlobalScope. -
  • If serviceWorker is an active worker, and there are any tasks queued in serviceWorker’s containing service worker registration’s task queues, queue them to serviceWorker’s event loop’s task queues in the same order using their original task sources. +
  • If serviceWorker is an active worker, and there are any tasks queued in serviceWorker’s containing service worker registration’s task queues, queue them to serviceWorker’s event loop’s task queues in the same order using their original task sources.
  • 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 terminate a worker algorithms.

    @@ -4528,7 +4531,7 @@

    guard to immutable.
  • Let response be null.
  • Let registration be null. -
  • Let client be the service worker client that corresponds to request’s client. +
  • Let client be the service worker client that corresponds to request’s client.
  • Assert: request’s destination is not "serviceworker".
  • If request is a potential-navigation-or-subresource request, then: @@ -4539,20 +4542,19 @@

    non-subresource request, then:

    If the non-subresource request is under the scope of a service worker registration, application cache is completely bypassed regardless of whether the non-subresource request uses the service worker registration.

      -
    1. If client is not a secure context, return null.
    2. If request is a navigation request and the navigation triggering it was initiated with a shift+reload or equivalent, return null. -
    3. Set registration to the result of running Match Service Worker Registration algorithm passing request’s url as the argument. -
    4. If registration is null or registration’s active worker is null, return null. -
    5. Set client’s active worker to registration’s active worker. +
    6. If request’s reserved client is not null and request’s reserved client’s active worker activeWorker is not null, set registration to activeWorker’s containing service worker registration. +
    7. Else, set registration to the result of running Match Service Worker Registration algorithm passing request’s url as the argument. +
    8. If registration is null or registration’s active worker is null, return null.
    -

    From this point, the service worker client starts to use its active worker’s containing service worker registration.

    +

    From this point, the service worker client starts to use its active worker’s containing service worker registration.

  • Else if request is a subresource request, then:
      -
    1. If client’s active worker is non-null, set registration to client’s active worker’s containing service worker registration. +
    2. If client’s active worker is non-null, set registration to client’s active worker’s containing service worker registration.
    3. Else, return null.
    -
  • Let activeWorker be registration’s active worker. +
  • Let activeWorker be registration’s active worker.
  • If activeWorker’s set of event types to handle does not contain fetch, return null.

    To avoid unnecessary delays, the Handle Fetch enforces early return when no event listeners have been deterministically added in the service worker’s global during the very first script execution.

    @@ -4563,7 +4565,9 @@

    trusted event e that uses the FetchEvent interface, with the event type fetch, which does not bubble.
  • Let the request attribute of e be initialized to r. -
  • Let the clientId attribute of e be initialized to client’s id if request is not a non-subresource request, and to null otherwise. +
  • Initialize e’s clientId attribute to client’s id. +
  • If request is a non-subresource request, initialize e’s reservedClientId attribute to request’s reserved client’s id, and to undefined otherwise. +
  • If request is a navigation request, initialize e’s targetClientId attribute to request’s target browsing context’s active document’s relevant settings object’s id, and to undefined otherwise.
  • Let the isReload attribute of e be initialized to true if request’s client is a window client and the event was dispatched with the user’s intention for the page reload, and false otherwise.
  • Dispatch e at activeWorker’s environment settings object’s global object.
  • If e’s respond-with entered flag is set, set respondWithEntered to true. @@ -4708,8 +4712,8 @@

    Assert: a Record with the [[value]] equals to registration is contained in scope to registration map. -
  • Assert: registration’s active worker is not null. -
  • Let activeWorker be registration’s active worker. +
  • Assert: registration’s active worker is not null. +
  • Let activeWorker be registration’s active worker.
  • If activeWorker’s set of event types to handle does not contain the event type for this functional event, return.

    To avoid unnecessary delays, the Handle Functional Event enforces early return when no event listeners have been deterministically added in the service worker’s global during the very first script execution.

    @@ -4724,10 +4728,10 @@

    Handle Service Worker Client Unload

    -

    The user agent must run these steps when a service worker client unloads by unloading, being killed, or terminating.

    +

    The user agent must run these steps when a service worker client unloads by unloading, being killed, or terminating.

    Input -
    client, a service worker client +
    client, a service worker client
    Output
    None
    @@ -4735,7 +4739,7 @@

    service worker registration used by client.
  • If registration is null, abort these steps. -
  • If any other service worker client is using registration, abort these steps. +
  • If any other service worker client is using registration, abort these steps.
  • If registration’s uninstalling flag is set, invoke Clear Registration algorithm passing registration as its argument and abort these steps.
  • If registration’s waiting worker is not null, run Activate algorithm with registration as the argument. @@ -4792,7 +4796,7 @@

    Unre
  • Set registration’s uninstalling flag.
  • Invoke Resolve Job Promise with job and true.
  • - If no service worker client is using registration, invoke Clear Registration algorithm passing registration as its argument. + If no service worker client is using registration, invoke Clear Registration algorithm passing registration as its argument.

    When the registration is being used for a client, the deletion of the registration is handled by the Handle Service Worker Client Unload algorithm.

  • Invoke Finish Job with job. @@ -4843,9 +4847,9 @@

    Update Worker State algorithm passing redundantWorker and redundant as the arguments.
  • - If registration’s active worker is not null, then: + If registration’s active worker is not null, then:
      -
    1. Set redundantWorker to registration’s active worker. +
    2. Set redundantWorker to registration’s active worker.
    3. Terminate redundantWorker.
    4. The user agent may abort in-flight requests triggered by redundantWorker.
    5. Run the Update Registration State algorithm passing registration, "active" and null as the arguments. @@ -4889,11 +4893,11 @@

      Else if target is "active", then:
        -
      1. Set registration’s active worker to source. +
      2. Set registration’s active worker to source.
      3. For each registrationObject in registrationObjects:
          -
        1. Queue a task to set the active attribute of registrationObject to the ServiceWorker object that represents registration’s active worker, or null if registration’s active worker is null. +
        2. Queue a task to set the active attribute of registrationObject to the ServiceWorker object that represents registration’s active worker, or null if registration’s active worker is null.

      The task must use registrationObject’s relevant settings object’s responsible event loop and the DOM manipulation task source.

      @@ -4931,11 +4935,11 @@

      Up
      activating
      "activating" -

      The service worker in this state is considered an active worker. During this state, event.waitUntil(f) can be called inside the onactivate event handler to extend the life of the active worker until the passed promise resolves successfully. No functional events are dispatched until the state becomes activated.

      +

      The service worker in this state is considered an active worker. During this state, event.waitUntil(f) can be called inside the onactivate event handler to extend the life of the active worker until the passed promise resolves successfully. No functional events are dispatched until the state becomes activated.

      activated
      "activated" -

      The service worker in this state is considered an active worker ready to handle functional events.

      +

      The service worker in this state is considered an active worker ready to handle functional events.

      redundant
      "redundant" @@ -4951,7 +4955,7 @@

      Up

      Notify Controller Change

      Input -
      client, a service worker client +
      client, a service worker client
      Output
      None
      @@ -4995,7 +4999,7 @@

      Run the following steps atomically.
    6. Let registration be the result of running the Match Service Worker Registration algorithm passing requestURL as the argument.
    7. If registration is null, return null. -
    8. Let worker be registration’s active worker. +
    9. Let worker be registration’s active worker.
    10. If worker is null, return null.
    11. Let requestURLString be the serialized requestURL.
    12. @@ -5041,7 +5045,7 @@

      installing worker is not null, set newestWorker to registration’s installing worker.
    13. Else if registration’s waiting worker is not null, set newestWorker to registration’s waiting worker. -
    14. Else if registration’s active worker is not null, set newestWorker to registration’s active worker. +
    15. Else if registration’s active worker is not null, set newestWorker to registration’s active worker.
    16. Return newestWorker.
  • @@ -5049,7 +5053,7 @@

    Create Client

    Input -
    client, a service worker client +
    client, a service worker client
    Output
    clientObject, a Client object
    @@ -5063,7 +5067,7 @@

    C

    Create Window Client

    Input -
    client, a service worker client +
    client, a service worker client
    visibilityState, a string
    focusState, a boolean
    Output @@ -5252,40 +5256,44 @@

    Service-Worker-Allowed`
    - Indicates the user agent will override the path restriction, which limits the maximum allowed scope url that the script can control, to the given value. + Indicates the user agent will override the path restriction, which limits the maximum allowed scope url that the script can control, to the given value.

    The value is a URL. If a relative URL is given, it is parsed against the script’s URL.

    Default scope: -
    // Maximum allowed scope defaults to the path the script sits in
    -// "/js" in this example
    -navigator.serviceWorker.register("/js/sw.js").then(function() {
    -  console.log("Install succeeded with the default scope '/js'.");
    -});
    +
    // Maximum allowed scope defaults to the path the script sits in
    +// "/js" in this example
    +navigator.serviceWorker.register("/js/sw.js").then(function() {
    +  console.log("Install succeeded with the default scope '/js'.");
    +});
    +
    Upper path without Service-Worker-Allowed header: -
    // Set the scope to an upper path of the script location
    -// Response has no Service-Worker-Allowed header
    -navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).catch(function() {
    -  console.error("Install failed due to the path restriction violation.");
    -});
    +
    // Set the scope to an upper path of the script location
    +// Response has no Service-Worker-Allowed header
    +navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).catch(function() {
    +  console.error("Install failed due to the path restriction violation.");
    +});
    +
    Upper path with Service-Worker-Allowed header: -
    // Set the scope to an upper path of the script location
    -// Response included "Service-Worker-Allowed : /"
    -navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).then(function() {
    -  console.log("Install succeeded as the max allowed scope was overriden to '/'.");
    -});
    +
    // Set the scope to an upper path of the script location
    +// Response included "Service-Worker-Allowed : /"
    +navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).then(function() {
    +  console.log("Install succeeded as the max allowed scope was overriden to '/'.");
    +});
    +
    A path restriction voliation even with Service-Worker-Allowed header: -
    // Set the scope to an upper path of the script location
    -// Response included "Service-Worker-Allowed : /foo"
    -navigator.serviceWorker.register("/foo/bar/sw.js", { scope: "/" }).catch(function() {
    -  console.error("Install failed as the scope is still out of the overriden maximum allowed scope.");
    -});
    +
    // Set the scope to an upper path of the script location
    +// Response included "Service-Worker-Allowed : /foo"
    +navigator.serviceWorker.register("/foo/bar/sw.js", { scope: "/" }).catch(function() {
    +  console.error("Install failed as the scope is still out of the overriden maximum allowed scope.");
    +});
    +

    @@ -5350,12 +5358,7 @@

    activating, in §3.1
  • "activating", in §3.1
  • active, in §3.2.3 -
  • - active worker - +
  • active worker, in §2.2
  • addAll(requests), in §6.4.4
  • add(request), in §6.4.3
  • all, in §4.3 @@ -5443,7 +5446,6 @@

    dfn for service worker, in §2.1 -
  • dfn for service worker client, in §2.3
  • attribute for Client, in §4.2.3
  • ignoreMethod, in §6.4 @@ -5939,8 +5941,6 @@

    task source
  • tasks
  • terminate a worker -
  • the global object's realm -
  • the realm's global object
  • the worker's documents
  • top-level browsing context
  • triggered by user activation @@ -6011,11 +6011,16 @@

    [WebIDL-1] defines the following terms: - - - -