Skip to content

Commit 2f71190

Browse files
authored
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
1 parent 7f2b6e1 commit 2f71190

File tree

2 files changed

+116
-100
lines changed

2 files changed

+116
-100
lines changed

docs/index.bs

+58-50
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
208208

209209
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.
210210

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+
211213
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`".
212214

213215
A [=/service worker registration=] has an associated <dfn export id="dfn-uninstalling-flag">uninstalling flag</dfn>. It is initially unset.
@@ -374,6 +376,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
374376

375377
1. If the {{ServiceWorker/state}} attribute value of the <a>context object</a> is {{"redundant"}}, [=throw=] an "{{InvalidStateError}}" {{DOMException}}.
376378
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.
377380
1. Invoke <a>Run Service Worker</a> algorithm with |serviceWorker| as the argument.
378381
1. Let |incumbentSettings| be the <a>incumbent settings object</a>, and |incumbentGlobal| its [=environment settings object/global object=].
379382
1. Let |serializeWithTransferResult| be <a abstract-op>StructuredSerializeWithTransfer</a>(|message|, |options|.transfer). Rethrow any exceptions.
@@ -2103,7 +2106,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
21032106
1. Set |request|'s [=request/cache mode=] to "`no-cache`" if any of the following are true:
21042107
* |registration|'s [=service worker registration/update via cache mode=] is "`none`".
21052108
* 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=].
21072110
1. Let |response| be the result of [=fetch|fetching=] |request|.
21082111
1. If |response|’s [=response/cache state=] is not "`local`", set |registration|’s [=service worker registration/last update check time=] to the current time.
21092112
1. If |response|'s [=unsafe response=] is a [=bad import script response=], then return a [=network error=].
@@ -2481,7 +2484,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
24812484
1. Set |request|'s [=request/cache mode=] to "<code>no-cache</code>" if any of the following are true:
24822485
* |registration|'s [=service worker registration/update via cache mode=] is not "`all`".
24832486
* |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=].
24852488

24862489
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.
24872490

@@ -2529,7 +2532,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
25292532
1. Set |importRequest|'s [=request/cache mode=] to "`no-cache`" if any of the following are true:
25302533
* |registration|'s [=service worker registration/update via cache mode=] is "`none`".
25312534
* |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=].
25332536
1. Let |fetchedResponse| be the result of [=fetch|fetching=] |importRequest|.
25342537
1. Set |updatedResourceMap|[|importRequest|'s [=request/url=]] to |fetchedResponse|.
25352538
1. Set |fetchedResponse| to |fetchedResponse|'s [=unsafe response=].
@@ -2611,19 +2614,20 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
26112614
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
26122615
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|.
26132616
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.
26272631
1. If |installFailed| is true, then:
26282632
1. Run the <a>Update Worker State</a> algorithm passing |registration|'s [=installing worker=] and *redundant* as the arguments.
26292633
1. Run the <a>Update Registration State</a> algorithm passing |registration|, "<code>installing</code>" and null as the arguments.
@@ -2678,14 +2682,15 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
26782682
1. Set |client|'s <a>active worker</a> to |registration|'s <a>active worker</a>.
26792683
1. Invoke <a>Notify Controller Change</a> algorithm with |client| as the argument.
26802684
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.
26892694
1. Run the <a>Update Worker State</a> algorithm passing |registration|'s <a>active worker</a> and *activated* as the arguments.
26902695
</section>
26912696

@@ -2789,7 +2794,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
27892794
<section algorithm>
27902795
<h3 id="on-fetch-request-algorithm"><dfn export>Handle Fetch</dfn></h3>
27912796

2792-
The <a>Handle Fetch</a> algorithm is the entry point for the [=/fetch=] handling handed to the [=/service worker=] context.
2797+
The [=Handle Fetch=] algorithm is the entry point for the [=/fetch=] handling handed to the [=/service worker=] context.
27932798

27942799
: Input
27952800
:: |request|, a [=/request=]
@@ -2846,13 +2851,12 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
28462851
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>.
28472852
1. Else, return null.
28482853
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.
28562860
1. If |activeWorker|'s <a>state</a> is *activating*, wait for |activeWorker|'s <a>state</a> to become *activated*.
28572861
1. Invoke <a>Run Service Worker</a> algorithm with |activeWorker| as the argument.
28582862
1. <a>Queue a task</a> |task| to run the following substeps:
@@ -2880,17 +2884,24 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
28802884
The |task| *must* use |activeWorker|'s <a>event loop</a> and the <a>handle fetch task source</a>.
28812885

28822886
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=].
2890+
1. Return |response|.
2891+
</section>
2892+
2893+
<section algorithm>
2894+
<h3 id="should-skip-event"><dfn>Should Skip Event</dfn></h3>
2895+
: Input
2896+
:: |eventName|, a string
2897+
:: |serviceWorker|, a [=/service worker=]
2898+
: Output
2899+
:: a boolean
2900+
2901+
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.
2904+
1. Return false.
28942905
</section>
28952906

28962907
<section algorithm>
@@ -2908,12 +2919,9 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
29082919
1. Assert: [=scope to registration map=] contains a value equal to |registration|.
29092920
1. Assert: |registration|'s [=active worker=] is not null.
29102921
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.
29172925
1. If |activeWorker|'s [=state=] is *activating*, wait for |activeWorker|'s [=state=] to become *activated*.
29182926
1. Invoke [=Run Service Worker=] algorithm with |activeWorker| as the argument.
29192927
1. [=Queue a task=] |task| to run these substeps:
@@ -2926,7 +2934,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
29262934
The |task| *must* use |activeWorker|'s [=event loop=] and the [=handle functional event task source=].
29272935

29282936
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|.
29302938

29312939
<div class="example">
29322940
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

Comments
 (0)