You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unify the event skipping algorithm when there is no event handler. (#1417)
This makes {install,activate,fetch,message} events and
functional events use the same algorithm to determine
whether to skip firing the event, and makes it a may
rather than must.
It also unifies the concept of a stale registration to reduce
duplicated text.
Addresses #1200
A [=/service worker registration=] has an associated <dfn export id="dfn-last-update-check-time">last update check time</dfn>. It is initially set to null.
210
210
211
+
A [=/service worker registration=] is said to be <dfn>stale</dfn> if the registration's [=last update check time=] is non-null and the time difference in seconds calculated by the current time minus the registration's [=last update check time=] is greater than 86400.
212
+
211
213
A [=/service worker registration=] has an associated <dfn export id="dfn-update-via-cache">update via cache mode</dfn>, which is "`imports`", "`all`", or "`none`". It is initially set to "`imports`".
212
214
213
215
A [=/service worker registration=] has an associated <dfn export id="dfn-uninstalling-flag">uninstalling flag</dfn>. It is initially unset.
1. If the {{ServiceWorker/state}} attribute value of the <a>context object</a> is {{"redundant"}}, [=throw=] an "{{InvalidStateError}}" {{DOMException}}.
376
378
1. Let |serviceWorker| be the [=/service worker=] represented by the <a>context object</a>.
379
+
1. If the result of running the [=Should Skip Event=] algorithm with "message" and |serviceWorker|, is true, then return.
377
380
1. Invoke <a>Run Service Worker</a> algorithm with |serviceWorker| as the argument.
378
381
1. Let |incumbentSettings| be the <a>incumbent settings object</a>, and |incumbentGlobal| its [=environment settings object/global object=].
379
382
1. Let |serializeWithTransferResult| be <a abstract-op>StructuredSerializeWithTransfer</a>(|message|, |options|.transfer). Rethrow any exceptions.
1. Set |request|'s [=request/cache mode=] to "`no-cache`" if any of the following are true:
2104
2107
* |registration|'s [=service worker registration/update via cache mode=] is "`none`".
2105
2108
* The [=current global object=]'s [=force bypass cache for importscripts flag=] is set.
2106
-
* |registration|'s [=last update check time=]is not null and the time difference in seconds calculated by the current time minus |registration|’s [=last update check time=] is greater than 86400.
2109
+
* |registration|is [=stale=].
2107
2110
1. Let |response| be the result of [=fetch|fetching=] |request|.
2108
2111
1. If |response|’s [=response/cache state=] is not "`local`", set |registration|’s [=service worker registration/last update check time=] to the current time.
2109
2112
1. If |response|'s [=unsafe response=] is a [=bad import script response=], then return a [=network error=].
1. Set |request|'s [=request/cache mode=] to "<code>no-cache</code>" if any of the following are true:
2482
2485
* |registration|'s [=service worker registration/update via cache mode=] is not "`all`".
2483
2486
* |job|'s [=force bypass cache flag=] is set.
2484
-
* |newestWorker| is not null, and |registration|'s [=last update check time=]is not null and the time difference in seconds calculated by the current time minus |registration|’s [=last update check time=] is greater than 86400.
2487
+
* |newestWorker| is not null and |registration|is [=stale=].
2485
2488
2486
2489
Note: Even if the cache mode is not set to "<code>no-cache</code>", the user agent obeys Cache-Control header's max-age value in the network layer to determine if it should bypass the browser cache.
1. Set |importRequest|'s [=request/cache mode=] to "`no-cache`" if any of the following are true:
2530
2533
* |registration|'s [=service worker registration/update via cache mode=] is "`none`".
2531
2534
* |job|'s [=force bypass cache flag=] is set.
2532
-
* |registration|'s [=last update check time=]is not null and the time difference in seconds calculated by the current time minus |registration|’s [=last update check time=] is greater than 86400.
2535
+
* |registration|is [=stale=].
2533
2536
1. Let |fetchedResponse| be the result of [=fetch|fetching=] |importRequest|.
2534
2537
1. Set |updatedResourceMap|[|importRequest|'s [=request/url=]] to |fetchedResponse|.
2535
2538
1. Set |fetchedResponse| to |fetchedResponse|'s [=unsafe response=].
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
2612
2615
1. <a>Queue a task</a> to <a>fire an event</a> named <code>updatefound</code> at all the {{ServiceWorkerRegistration}} objects for all the [=/service worker clients=] whose <a>creation URL</a><a lt="Match Service Worker Registration">matches</a> |registration|'s [=service worker registration/scope url=] and all the [=/service workers=] whose <a>containing service worker registration</a> is |registration|.
2613
2616
1. Let |installingWorker| be |registration|'s <a>installing worker</a>.
2614
-
1. Invoke <a>Run Service Worker</a> algorithm given |installingWorker|, and with the *force bypass cache for importscripts flag* set if |job|'s [=job/force bypass cache flag=] is set.
2615
-
1. <a>Queue a task</a> |task| to run the following substeps:
2616
-
1. Let |e| be the result of <a>creating an event</a> with {{ExtendableEvent}}.
2617
-
1. Initialize |e|’s {{Event/type}} attribute to {{install!!event}}.
2618
-
1. <a>Dispatch</a> |e| at |installingWorker|'s [=service worker/global object=].
2619
-
1. *WaitForAsynchronousExtensions*: Run the following substeps <a>in parallel</a>:
2620
-
1. <span id="install-settle-step">Wait until |e| is not [=ExtendableEvent/active=].</span>
2621
-
1. If |e|'s [=ExtendableEvent/timed out flag=] is set, or the result of [=waiting for all=] of |e|'s [=extend lifetime promises=] rejected, set |installFailed| to true.
2622
-
2623
-
If |task| is discarded or the script has been aborted by the <a lt="Terminate Service Worker">termination</a> of |installingWorker|, set |installFailed| to true.
2624
-
2625
-
1. Wait for |task| to have executed or been discarded.
2626
-
1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete.
2617
+
1. If the result of running the [=Should Skip Event=] algorithm with |installingWorker| and "install" is false, then:
2618
+
1. Invoke <a>Run Service Worker</a> algorithm given |installingWorker|, and with the *force bypass cache for importscripts flag* set if |job|'s [=job/force bypass cache flag=] is set.
2619
+
1. <a>Queue a task</a> |task| to run the following substeps:
2620
+
1. Let |e| be the result of <a>creating an event</a> with {{ExtendableEvent}}.
2621
+
1. Initialize |e|’s {{Event/type}} attribute to {{install!!event}}.
2622
+
1. <a>Dispatch</a> |e| at |installingWorker|'s [=service worker/global object=].
2623
+
1. *WaitForAsynchronousExtensions*: Run the following substeps <a>in parallel</a>:
2624
+
1. <span id="install-settle-step">Wait until |e| is not [=ExtendableEvent/active=].</span>
2625
+
1. If |e|'s [=ExtendableEvent/timed out flag=] is set, or the result of [=waiting for all=] of |e|'s [=extend lifetime promises=] rejected, set |installFailed| to true.
2626
+
2627
+
If |task| is discarded or the script has been aborted by the <a lt="Terminate Service Worker">termination</a> of |installingWorker|, set |installFailed| to true.
2628
+
2629
+
1. Wait for |task| to have executed or been discarded.
2630
+
1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete.
2627
2631
1. If |installFailed| is true, then:
2628
2632
1. Run the <a>Update Worker State</a> algorithm passing |registration|'s [=installing worker=] and *redundant* as the arguments.
2629
2633
1. Run the <a>Update Registration State</a> algorithm passing |registration|, "<code>installing</code>" and null as the arguments.
1. Set |client|'s <a>active worker</a> to |registration|'s <a>active worker</a>.
2679
2683
1. Invoke <a>Notify Controller Change</a> algorithm with |client| as the argument.
2680
2684
1. Let |activeWorker| be |registration|'s <a>active worker</a>.
2681
-
1. Invoke <a>Run Service Worker</a> algorithm with |activeWorker| as the argument.
2682
-
1. <a>Queue a task</a> |task| to run the following substeps:
2683
-
1. Let |e| be the result of <a>creating an event</a> with {{ExtendableEvent}}.
2684
-
1. Initialize |e|’s {{Event/type}} attribute to {{activate!!event}}.
2685
-
1. <a>Dispatch</a> |e| at |activeWorker|'s [=service worker/global object=].
2686
-
1. <span id="activate-settle-step">*WaitForAsynchronousExtensions*: Wait, [=in parallel=], until |e| is not [=ExtendableEvent/active=].</span>
2687
-
1. Wait for |task| to have executed or been discarded, or the script to have been aborted by the <a lt="terminate service worker">termination</a> of |activeWorker|.
2688
-
1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete.
2685
+
1. If the result of running the [=Should Skip Event=] algorithm with |activeWorker| and "activate" is false, then:
2686
+
1. Invoke <a>Run Service Worker</a> algorithm with |activeWorker| as the argument.
2687
+
1. <a>Queue a task</a> |task| to run the following substeps:
2688
+
1. Let |e| be the result of <a>creating an event</a> with {{ExtendableEvent}}.
2689
+
1. Initialize |e|’s {{Event/type}} attribute to {{activate!!event}}.
2690
+
1. <a>Dispatch</a> |e| at |activeWorker|'s [=service worker/global object=].
2691
+
1. <span id="activate-settle-step">*WaitForAsynchronousExtensions*: Wait, [=in parallel=], until |e| is not [=ExtendableEvent/active=].</span>
2692
+
1. Wait for |task| to have executed or been discarded, or the script to have been aborted by the <a lt="terminate service worker">termination</a> of |activeWorker|.
2693
+
1. Wait for the step labeled *WaitForAsynchronousExtensions* to complete.
2689
2694
1. Run the <a>Update Worker State</a> algorithm passing |registration|'s <a>active worker</a> and *activated* as the arguments.
1. If |client|'s <a>active service worker</a> is non-null, set |registration| to |client|'s <a>active service worker</a>'s <a>containing service worker registration</a>.
2847
2852
1. Else, return null.
2848
2853
1. Let |activeWorker| be |registration|'s <a>active worker</a>.
2849
-
1. If |activeWorker|'s <a>set of event types to handle</a> does not [=set/contain=]<code>fetch</code>, then:
2850
-
1. Return null and continue running these steps <a>in parallel</a>.
2851
-
1. If |request| is a <a>non-subresource request</a>, or |request| is a <a>subresource request</a> and the time difference in seconds calculated by the current time minus |registration|'s <a>last update check time</a> is greater than 86400, invoke <a>Soft Update</a> algorithm with |registration|.
2852
-
1. Abort these steps.
2853
-
2854
-
Note: 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.
2855
-
2854
+
1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise:
2855
+
* |request| is a [=non-subresource request=].
2856
+
* |request| is a [=subresource request=] and |registration| is [=stale=].
2857
+
1. If the result of running the [=Should Skip Event=] algorithm with "fetch" and |activeWorker| is true, then:
2858
+
1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|.
2859
+
1. Return.
2856
2860
1. If |activeWorker|'s <a>state</a> is *activating*, wait for |activeWorker|'s <a>state</a> to become *activated*.
2857
2861
1. Invoke <a>Run Service Worker</a> algorithm with |activeWorker| as the argument.
2858
2862
1. <a>Queue a task</a> |task| to run the following substeps:
The |task| *must* use |activeWorker|'s <a>event loop</a> and the <a>handle fetch task source</a>.
2881
2885
2882
2886
1. Wait for |task| to have executed or been discarded.
2883
-
1. If |respondWithEntered| is false, then:
2884
-
1. If |eventCanceled| is true, return a <a>network error</a> and continue running these steps <a>in parallel</a>.
2885
-
1. Else, return null and continue running these steps <a>in parallel</a>.
2886
-
1. If |request| is a <a>non-subresource request</a>, or |request| is a <a>subresource request</a> and the time difference in seconds calculated by the current time minus |registration|'s <a>last update check time</a> is greater than 86400, invoke <a>Soft Update</a> algorithm with |registration|.
2887
-
1. Abort these steps.
2888
-
1. If |handleFetchFailed| is true, then:
2889
-
1. Return a <a>network error</a> and continue running these steps <a>in parallel</a>.
2890
-
1. If |request| is a <a>non-subresource request</a>, or |request| is a <a>subresource request</a> and the time difference in seconds calculated by the current time minus |registration|'s <a>last update check time</a> is greater than 86400, invoke <a>Soft Update</a> algorithm with |registration|.
2891
-
1. Else:
2892
-
1. Return |response| and continue running these steps <a>in parallel</a>.
2893
-
1. If |request| is a <a>non-subresource request</a>, or |request| is a <a>subresource request</a> and the time difference in seconds calculated by the current time minus |registration|'s <a>last update check time</a> is greater than 86400, invoke <a>Soft Update</a> algorithm with |registration|.
2887
+
1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|.
2888
+
1. If |respondWithEntered| is false, then return a [=network error=] if |eventCanceled| is true and null otherwise.
2889
+
1. If |handleFetchFailed| is true, then return a [=network error=].
Note: To avoid unnecessary delays, this specification permits skipping event dispatch when no event listeners for the event have been deterministically added in the service worker's global during the very first script execution.
2902
+
2903
+
1. If |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] |eventName|, then the user agent *may* return true.
1. Assert: [=scope to registration map=] contains a value equal to |registration|.
2909
2920
1. Assert: |registration|'s [=active worker=] is not null.
2910
2921
1. Let |activeWorker| be |registration|'s [=active worker=].
2911
-
1. If |activeWorker|'s [=set of event types to handle=] does not [=set/contain=] |eventName|, then return and run the following steps [=in parallel=]:
2912
-
1. If the time difference in seconds calculated by the current time minus |registration|'s [=last update check time=] is greater than 86400, invoke [=Soft Update=] algorithm with |registration|.
2913
-
1. Abort these steps.
2914
-
2915
-
Note: 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.
2916
-
2922
+
1. If the result of running [=Should Skip Event=] with |eventName| and |activeWorker| is true, then:
2923
+
1. If |registration| is [=stale=], then [=in parallel=] run the [=Soft Update=] algorithm with |registration|.
2924
+
2. Return.
2917
2925
1. If |activeWorker|'s [=state=] is *activating*, wait for |activeWorker|'s [=state=] to become *activated*.
2918
2926
1. Invoke [=Run Service Worker=] algorithm with |activeWorker| as the argument.
The |task| *must* use |activeWorker|'s [=event loop=] and the [=handle functional event task source=].
2927
2935
2928
2936
1. Wait for |task| to have executed or been discarded.
2929
-
1. If the time difference in seconds calculated by the current time minus |registration|'s [=last update check time=]is greater than 86400, invoke[=Soft Update=] algorithm with |registration|.
2937
+
1. If |registration| is [=stale=], then [=in parallel=]run the[=Soft Update=] algorithm with |registration|.
2930
2938
2931
2939
<div class="example">
2932
2940
To fire an "`amazingthing`" event (which is of type `AmazingThingEvent`) on a particular |serviceWorkerRegistration|, and initialize the event object's properties, the prose would be:
0 commit comments