A
job has a
job type, which is one of *register*, *update*, and *unregister*.
+ A
job has an
origin.
+
+ A
job has an
id.
+
A
job has a
scope url (a [=/URL=]).
A
job has a
script url (a [=/URL=]).
@@ -2408,12 +2448,13 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
Two
jobs are
equivalent when their
job type is the same and:
- * For *register* and *update*
jobs, their [=job/scope url=], [=job/script url=], [=job/worker type=], and [=job/update via cache mode=] are the same.
- * For *unregister*
jobs, their [=job/scope url=] is the same.
+ * For *register*
jobs, their [=job/origin=], [=job/id=], [=job/scope url=], [=job/script url=], [=job/worker type=], and [=job/update via cache mode=] are the same.
+ * For *update*
jobs, their [=job/origin=], [=job/id=], [=job/script url=], [=job/worker type=], and [=job/update via cache mode=] are the same.
+ * For *unregister*
jobs, their [=job/origin=] and [=job/id=] are the same.
A
job queue is a thread safe [=queue=] used to synchronize the set of concurrent [=jobs=]. The [=job queue=] contains [=jobs=] as its [=queue/items=]. A [=job queue=] is initially empty.
- A
scope to job queue map is an
ordered map where the keys are [=service worker registration/scope urls=], [=URL serializer|serialized=], and the values are [=job queues=].
+ A
job queue map is an
ordered map where the keys are ([=environment settings object/origin=],[=service worker registration/ids=]) and the values are [=job queues=].
A
bad import script response is a [=/response=] for which any of the following conditions are met:
@@ -2428,6 +2469,8 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
: Input
:: |jobType|, a
job type
+ :: |origin|, an [=environment settings object/origin=]
+ :: |id|, an [=service worker registration/id=]
:: |scopeURL|, a [=/URL=]
:: |scriptURL|, a [=/URL=]
:: |promise|, a
promise
@@ -2437,6 +2480,8 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. Let |job| be a new
job.
1. Set |job|'s [=job/job type=] to |jobType|.
+ 1. Set |job|'s [=job/origin=] to |origin|.
+ 1. Set |job|'s [=job/id=] to |id|.
1. Set |job|'s [=job/scope url=] to |scopeURL|.
1. Set |job|'s [=job/script url=] to |scriptURL|.
1. Set |job|'s [=job/job promise=] to |promise|.
@@ -2454,9 +2499,11 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
:: none
1. Let |jobQueue| be null.
- 1. Let |jobScope| be |job|'s [=job/scope url=], [=URL serializer|serialized=].
- 1. If [=scope to job queue map=][|jobScope|] does not [=map/exist=], [=map/set=] [=scope to job queue map=][|jobScope|] to a new [=job queue=].
- 1. Set |jobQueue| to [=scope to job queue map=][|jobScope|].
+ 1. Let |origin| be |job|'s [=job/origin=].
+ 1. Let |id| be |job|'s [=job/id=].
+ 1. Let |key| be (|origin|,|id|).
+ 1. If [=job queue map=][|key|] does not [=map/exist=], [=map/set=] [=job queue map=][|key|] to a new [=job queue=].
+ 1. Set |jobQueue| to [=job queue map=][|key|].
1. If |jobQueue| is empty, then:
1. Set |job|'s [=containing job queue=] to |jobQueue|, and [=queue/enqueue=] |job| to |jobQueue|.
1. Invoke [=Run Job=] with |jobQueue|.
@@ -2541,6 +2588,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
Start Register
: Input
+ :: |id|, a [=service worker registration/id=] or null
:: |scopeURL|, a [=/URL=] or failure or null
:: |scriptURL|, a [=/URL=] or failure
:: |promise|, a
promise
@@ -2569,7 +2617,8 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. If |scopeURL|'s [=url/scheme=] is not one of "
http
" and "
https
", reject |promise| with a
TypeError
and abort these steps.
1. If any of the strings in |scopeURL|'s [=url/path=] contains either
ASCII case-insensitive "
%2f
" or
ASCII case-insensitive "
%5c
", reject |promise| with a
TypeError
and abort these steps.
- 1. Let |job| be the result of running [=Create Job=] with *register*, |scopeURL|, |scriptURL|, |promise|, and |client|.
+ 1. If |id| is null, set |id| to |scopeURL|.
+ 1. Let |job| be the result of running [=Create Job=] with *register*, |client|' [=service worker client/origin=], |id|, |scopeURL|, |scriptURL|, |promise|, and |client|.
1. Set |job|'s [=job/worker type=] to |workerType|.
1. Set |job|'s [=job/update via cache mode=] to |updateViaCache|.
1. Set |job|'s [=job/referrer=] to |referrer|.
@@ -2584,23 +2633,30 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
: Output
:: none
- 1. If the result of running
potentially trustworthy origin with the [=environment settings object/origin=] of |job|'s [=job/script url=] as the argument is
Not Trusted
, then:
+ 1. If the result of running
potentially trustworthy origin with |job|'s [=job/origin=] as the argument is
Not Trusted
, then:
+ 1. Invoke [=Reject Job Promise=] with |job| and "{{SecurityError}}" {{DOMException}}.
+ 1. Invoke
Finish Job with |job| and abort these steps.
+ 1. If |job|'s [=job/script url=]'s [=url/origin=] and |job|'s [=job/origin=] are not [=same origin=], then:
1. Invoke [=Reject Job Promise=] with |job| and "{{SecurityError}}" {{DOMException}}.
1. Invoke
Finish Job with |job| and abort these steps.
- 1. If |job|'s [=job/script url=]'s [=url/origin=] and |job|'s [=job/referrer=]'s [=url/origin=] are not [=same origin=], then:
+ 1. If |job|'s [=job/scope url=]'s [=url/origin=] and |job|'s [=job/origin=] are not [=same origin=], then:
1. Invoke [=Reject Job Promise=] with |job| and "{{SecurityError}}" {{DOMException}}.
1. Invoke
Finish Job with |job| and abort these steps.
- 1. If |job|'s [=job/scope url=]'s [=url/origin=] and |job|'s [=job/referrer=]'s [=url/origin=] are not [=same origin=], then:
+ 1. If |job|'s [=job/referrer=]'s [=url/origin=] and |job|'s [=job/origin=] are not [=same origin=], then:
1. Invoke [=Reject Job Promise=] with |job| and "{{SecurityError}}" {{DOMException}}.
1. Invoke
Finish Job with |job| and abort these steps.
- 1. Let |registration| be the result of running the
Get Registration algorithm passing |job|'s [=job/scope url=] as the argument.
+ 1. Let |registration| be the result of running the
Get Registration algorithm passing |job|'s [=job/origin=] and [=job/id=] as the arguments.
1. If |registration| is not null, then:
1. Let |newestWorker| be the result of running the
Get Newest Worker algorithm passing |registration| as the argument.
- 1. If |newestWorker| is not null, |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=], |job|'s [=job/worker type=] equals |newestWorker|'s [=service worker/type=], and |job|'s [=job/update via cache mode=]'s value equals |registration|'s [=service worker registration/update via cache mode=], then:
+ 1. If |newestWorker| is not null, |job|'s [=job/scope url=] [=url/equals=] |newestWorker|'s [=service worker/scope url=], |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=], |job|'s [=job/worker type=] equals |newestWorker|'s [=service worker/type=], and |job|'s [=job/update via cache mode=]'s value equals |registration|'s [=service worker registration/update via cache mode=], then:
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
1. Invoke
Finish Job with |job| and abort these steps.
+ 1. Let |scopeRegistration| be the result of running the
Get Registration By Scope algorithm passing |job|'s [=job/scope url=] as the argument.
+ 1. If |scopeRegistration| is not null, |scopeRegistration| is not |registration|, and |scopeRegistration|'s
active worker's [=service worker/scope url=] [=url/equals=] |job|'s [=job/scope url=], then:
+ 1. Invoke [=Reject Job Promise=] with |job| and "{{InvalidStateError}}" {{DOMException}}.
+ 1. Invoke
Finish Job with |job| and abort these steps.
1. Else:
- 1. Invoke
Set Registration algorithm with |job|'s [=job/scope url=] and |job|'s [=job/update via cache mode=].
+ 1. Invoke
Set Registration algorithm with |job|'s [=job/origin=], |job|'s [=job/id=], and |job|'s [=job/update via cache mode=].
1. Invoke
Update algorithm passing |job| as the argument.
@@ -2612,7 +2668,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
: Output
:: none
- 1. Let |registration| be the result of running the
Get Registration algorithm passing |job|'s [=job/scope url=] as the argument.
+ 1. Let |registration| be the result of running the
Get Registration algorithm passing |job|'s [=job/origin=] and [=job/id=] as the arguments.
1. If |registration| is null, then:
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
1. Invoke
Finish Job with |job| and abort these steps.
@@ -2661,7 +2717,14 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. Set |policyContainer| to the result of
creating a policy container from a fetch response given |response|.
1. If |serviceWorkerAllowed| is failure, then:
1. Asynchronously complete these steps with a
network error.
- 1. Let |scopeURL| be |registration|'s [=service worker registration/scope url=].
+ 1. Let |origin| be |registration|'s [=service worker registration/origin=].
+ 1. Let |id| be |registration|'s [=service worker registration/id=].
+ 1. If |job|'s [=job/scope url=] is null, then:
+ 1. Assert: |job|'s [=job/job type=] is *update*.
+ 1. Let |scopeURL| be |newest worker|'s [=service worker/scope url=].
+ 1. Else:
+ 1. Assert: |job|'s [=job/job type=] is *register*.
+ 1. Let |scopeURL| be |job|'s [=job/scope url=].
1. Let |maxScopeString| be null.
1. If |serviceWorkerAllowed| is null, then:
1. Let |resolvedScope| be the result of [=URL parser|parsing=] "`./`" using |job|'s [=job/script url=] as the [=base URL=].
@@ -2715,21 +2778,21 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
Note: This will do nothing if [=Reject Job Promise=] was previously invoked with "{{SecurityError}}" {{DOMException}}.
- 1. If |newestWorker| is null, then [=map/remove=] [=scope to registration map=][|scopeURL|, [=URL serializer|serialized=]].
+ 1. If |newestWorker| is null, then [=map/remove=] [=registration map=][(|origin|,|id|)].
1. Invoke [=Finish Job=] with |job| and abort these steps.
1. If |hasUpdatedResources| is false, then:
1. Set |registration|'s [=service worker registration/update via cache mode=] to |job|'s [=job/update via cache mode=].
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
1. Invoke [=Finish Job=] with |job| and abort these steps.
1. Let |worker| be a new [=/service worker=].
- 1. Set |worker|'s [=service worker/script url=] to |job|'s [=job/script url=], |worker|'s [=script resource=] to |script|, |worker|'s [=service worker/type=] to |job|'s [=worker type=], and |worker|'s [=script resource map=] to |updatedResourceMap|.
+ 1. Set |worker|'s [=service worker/script url=] to |job|'s [=job/script url=], |worker|'s [=service worker/scope url=] to |job|'s [=job/scope url=], |worker|'s [=script resource=] to |script|, |worker|'s [=service worker/type=] to |job|'s [=worker type=], and |worker|'s [=script resource map=] to |updatedResourceMap|.
1. Append |url| to |worker|'s [=set of used scripts=].
1. Set |worker|'s
script resource's [=script resource/policy container=] to |policyContainer|.
1. Let |forceBypassCache| be true if |job|'s [=job/force bypass cache flag=] is set, and false otherwise.
1. Let |runResult| be the result of running the [=Run Service Worker=] algorithm with |worker| and |forceBypassCache|.
1. If |runResult| is *failure* or an [=abrupt completion=], then:
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
- 1. If |newestWorker| is null, then [=map/remove=] [=scope to registration map=][|registration|'s [=service worker registration/scope url=], [[=URL serializer|serialized=]].
+ 1. If |newestWorker| is null, then [=map/remove=] [=registration map=][(|origin|,|id|)].
1. Invoke [=Finish Job=] with |job|.
1. Else, invoke [=Install=] algorithm with |job|, |worker|, and |registration| as its arguments.
@@ -2750,7 +2813,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. Let |newestWorker| be the result of running
Get Newest Worker algorithm passing |registration| as its argument.
1. If |newestWorker| is null, abort these steps.
- 1. Let |job| be the result of running
Create Job with *update*, |registration|'s [=service worker registration/scope url=], |newestWorker|'s [=service worker/script url=], null, and null.
+ 1. Let |job| be the result of running
Create Job with *update*, |registration|'s [=service worker registration/origin=], |registration|'s [=service worker registration/id=], |newestWorker|'s [=service worker/scope url=], |newestWorker|'s [=service worker/script url=], null, and null.
1. Set |job|'s
worker type to |newestWorker|'s [=service worker/type=].
1. Set |job|'s [=force bypass cache flag=] if |forceBypassCache| is true.
1. Invoke
Schedule Job with |job|.
@@ -2773,7 +2836,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. Run the
Update Worker State algorithm passing |registration|'s
installing worker and "`installing`" as the arguments.
1. Assert: |job|'s [=job/job promise=] is not null.
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
- 1. Let |settingsObjects| be all [=environment settings objects=] whose [=environment settings object/origin=] is |registration|'s [=service worker registration/scope url=]'s [=url/origin=].
+ 1. Let |settingsObjects| be all [=environment settings objects=] whose [=environment settings object/origin=] is |job|'s [=job/origin=].
1. For each |settingsObject| of |settingsObjects|, [=queue a task=] on |settingsObject|'s [=responsible event loop=] in the [=DOM manipulation task source=] to run the following steps:
1. Let |registrationObjects| be every {{ServiceWorkerRegistration}} object in |settingsObject|'s [=environment settings object/realm=], whose [=ServiceWorkerRegistration/service worker registration=] is |registration|.
1. For each |registrationObject| of |registrationObjects|, [=fire an event=] on |registrationObject| named `updatefound`.
@@ -2800,7 +2863,9 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. If |installFailed| is true, then:
1. Run the
Update Worker State algorithm passing |registration|'s [=installing worker=] and "`redundant`" as the arguments.
1. Run the
Update Registration State algorithm passing |registration|, "
installing
" and null as the arguments.
- 1. If |newestWorker| is null, then [=map/remove=] [=scope to registration map=][|registration|'s [=service worker registration/scope url=], [[=URL serializer|serialized=]].
+ 1. Let |id| be |registration|'s [=service worker registration/id=].
+ 1. Let |origin| be |registration|'s [=service worker registration/origin=].
+ 1. If |newestWorker| is null, then [=map/remove=] [=registration map=][(|origin|,|id|)].
1. Invoke
Finish Job with |job| and abort these steps.
1. Let |map| be |registration|'s [=installing worker=]'s [=script resource map=].
1. Let |usedSet| be |registration|'s [=installing worker=]'s [=set of used scripts=].
@@ -2831,6 +2896,10 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. If |registration|'s [=active worker=] is not null, then:
1. [=Terminate Service Worker|Terminate=] |registration|'s [=active worker=].
1. Run the [=Update Worker State=] algorithm passing |registration|'s [=active worker=] and "`redundant`" as the arguments.
+ 1. Let |oldUsingClients| be a [=list=] of [=/service worker clients=] who are
using |registration|.
+
+ Note: We must get the list of clients prior to clearing the old
active worker from |registration|. Otherwise the [=/service worker client=] will not be considered to be
using |registration| any more since |registration| will no longer be the
containing service worker registration.
+
1. Run the
Update Registration State algorithm passing |registration|, "
active
" and |registration|'s
waiting worker as the arguments.
1. Run the
Update Registration State algorithm passing |registration|, "
waiting
" and null as the arguments.
1. Run the
Update Worker State algorithm passing |registration|'s
active worker and "`activating`" as the arguments.
@@ -2839,7 +2908,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
Note: Make sure to design activation handlers to do non-essential work (like cleanup). This is because activation handlers may not all run to completion, especially in the case of browser termination during activation. A Service Worker should be designed to function properly, even if the activation handlers do not all complete successfully.
- 1. Let |matchedClients| be a [=list=] of [=/service worker clients=] whose
creation URL matches |registration|'s [=service worker registration/scope url=].
+ 1. Let |matchedClients| be a [=list=] of [=/service worker clients=] whose
creation URL matches |registration|'s [=active worker=]'s [=service worker/scope url=].
1. [=list/For each=] |client| of |matchedClients|, [=queue a task=] on |client|'s [=responsible event loop=], using the [=DOM manipulation task source=], to run the following substeps:
1. Let |readyPromise| be |client|'s [=environment settings object/global object=]'s {{ServiceWorkerContainer}} object's [=ServiceWorkerContainer/ready promise=].
1. If |readyPromise| is null, then [=continue=].
@@ -2850,9 +2919,12 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
Note: Resources will now use the service worker registration instead of the existing application cache.
- 1. For each [=/service worker client=] |client| who is
using |registration|:
- 1. Set |client|'s
active worker to |registration|'s
active worker.
- 1. Invoke
Notify Controller Change algorithm with |client| as the argument.
+ 1. [=list/For each=] |oldClient| of |oldUsingClients|:
+ 1. If |oldClient|'s
creation URL matches |registration|'s [=active worker=]'s [=service worker/scope url=], then:
+ 1. Set |client|'s
active worker to |registration|'s
active worker.
+ 1. Else:
+ 1. Set |oldClient|'s
active worker to null.
+ 1. Invoke
Notify Controller Change algorithm with |oldClient| as the argument.
1. Let |activeWorker| be |registration|'s
active worker.
1. If the result of running the [=Should Skip Event=] algorithm with |activeWorker| and "activate" is false, then:
1. If the result of running the [=Run Service Worker=] algorithm with |activeWorker| is not *failure*, then:
@@ -3189,7 +3261,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
: Output
:: None
- 1. [=map/For each=]
scope → |registration| of
scope to registration map:
+ 1. [=map/For each=]
key → |registration| of
registration map:
1. If |registration|'s
installing worker |installingWorker| is not null, then:
1. If |registration|'s [=waiting worker=] is null and |registration|'s [=active worker=] is null, invoke
Clear Registration with |registration| and continue to the next iteration of the loop.
1. Else, set |installingWorker| to null.
@@ -3220,14 +3292,14 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
: Output
:: none
- 1. If the [=environment settings object/origin=] of |job|'s [=job/scope url=] is not |job|'s [=job/client=]'s [=environment settings object/origin=], then:
+ 1. If |job|'s [=job/origin=] is not |job|'s [=job/client=]'s [=environment settings object/origin=], then:
1. Invoke [=Reject Job Promise=] with |job| and "{{SecurityError}}" {{DOMException}}.
1. Invoke
Finish Job with |job| and abort these steps.
- 1. Let |registration| be the result of running
Get Registration algorithm passing |job|'s [=job/scope url=] as the argument.
+ 1. Let |registration| be the result of running
Get Registration algorithm passing |job|'s [=job/origin=] and [=job/id=] as the arguments.
1. If |registration| is null, then:
1. Invoke
Resolve Job Promise with |job| and false.
1. Invoke
Finish Job with |job| and abort these steps.
- 1. [=map/Remove=] [=scope to registration map=][|job|'s [=job/scope url=]].
+ 1. [=map/Remove=] [=registration map=][(|job|'s [=job/origin=],|job|'s [=job/id=])].
1. Invoke
Resolve Job Promise with |job| and true.
1. Invoke [=Try Clear Registration=] with |registration|.
@@ -3240,15 +3312,16 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
Set Registration
: Input
- :: |scope|, a [=/URL=]
+ :: |origin|, an [=environment settings object/origin=]
+ :: |id|, an [=service worker registration/id=]
:: |updateViaCache|, an [=service worker registration/update via cache mode=]
: Output
:: |registration|, a [=/service worker registration=]
1. Run the following steps atomically.
1. Let |scopeString| be [=URL serializer|serialized=] |scope| with the *exclude fragment flag* set.
- 1. Let |registration| be a new [=/service worker registration=] whose [=service worker registration/scope url=] is set to |scope| and [=service worker registration/update via cache mode=] is set to |updateViaCache|.
- 1. [=map/Set=]
scope to registration map[|scopeString|] to |registration|.
+ 1. Let |registration| be a new [=/service worker registration=] whose [=service worker registration/origin=] is set to |origin|, [=service worker registration/id=] is set to |id|, and [=service worker registration/update via cache mode=] is set to |updateViaCache|.
+ 1. [=map/Set=]
registration map[|id|] to |registration|.
1. Return |registration|.
@@ -3364,7 +3437,12 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. Run the following steps atomically.
1. Let |clientURLString| be
serialized |clientURL|.
1. Let |matchingScopeString| be the empty string.
- 1. Let |scopeStringSet| be the result of [=map/get the keys|getting the keys=] from
scope to registration map.
+ 1. Let |scopeMap| be the empty map.
+ 1. [=map/For each=] |key| → |value| of
registration map:
+ 1. Let |activeWorker| be |value|'s [=service worker registration/active worker=],
+ 1. If |activeWorker| is null, then [=continue=].
+ 1. [=map/Set=] |scopeMap|[|active worker|'s [=service worker/scope url] to |value|.
+ 1. Let |scopeStringSet| be the result of [=map/get the keys|getting the keys=] from |scopeMap|.
1. Set |matchingScopeString| to the longest value in |scopeStringSet| which the value of |clientURLString| starts with, if it exists.
Note: The URL string matching in this step is prefix-based rather than path-structural. E.g. a client URL string with "https://example.com/prefix-of/resource.html" will match a registration for a scope with "https://example.com/prefix". The URL string comparison is safe for the same-origin security as HTTP(S) URLs are always [=URL serializer|serialized=] with a trailing slash at the end of the origin part of the URLs.
@@ -3373,23 +3451,38 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. If |matchingScopeString| is not the empty string, then:
1. Set |matchingScope| to the result of
parsing |matchingScopeString|.
1. Assert: |matchingScope|'s [=url/origin=] and |clientURL|'s [=url/origin=] are [=same origin=].
- 1. Return the result of running [=Get Registration=] algorithm passing |matchingScope| as the argument.
+ 1. Return |scopeMap|[|matchingScopeString|].
Get Registration
: Input
- :: |scope|, a [=/URL=]
+ :: |origin|, a [=environment settings object/origin=]
+ :: |id|, a [=service worker registration/id=]
: Output
- :: A [=/service worker registration=]
+ :: A [=/service worker registration=] or null.
+
+ 1. Run the following steps atomically.
+ 1. [=map/Get=] (|origin|,|id|) from [=registration map=] and return the result.
+
+
+
+ Get Registration By Scope
+
+ : Input
+ :: |scope|, a [=URL=]
+ : Output
+ :: A [=/service worker registration=] or null.
1. Run the following steps atomically.
- 1. Let |scopeString| be the empty string.
- 1. If |scope| is not null, set |scopeString| to [=URL serializer|serialized=] |scope| with the *exclude fragment flag* set.
- 1. [=map/For each=] |key| → |value| of scope to registration map:
- 1. If |scopeString| matches |key|, then return |value|.
+ 1. [=map/For each=] |key| → |value| of registration map:
+ 1. If |value|'s active worker's [=service worker/scope url=] [=url/equals=] |scope|, then return |value|.
+ 1. If |value|'s waiting worker's [=service worker/scope url=] [=url/equals=] |scope|, then return |value|.
+ 1. If |value|'s installing worker's [=service worker/scope url=] [=url/equals=] |scope|, then return |value|.
1. Return null.
+
+ Note: Only one registration should be associated with a given scope at a time since we fail Register when there is a conflicting registration with the same scope.
@@ -3408,6 +3501,22 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
1. Return |newestWorker|.
+
+ Get Oldest Worker
+
+ : Input
+ :: |registration|, a [=/service worker registration=]
+ : Output
+ :: |oldestWorker|, a [=/service worker=]
+
+ 1. Run the following steps atomically.
+ 1. Let |oldestWorker| be null.
+ 1. If |registration|'s active worker is not null, set |oldestWorker| to |registration|'s active worker.
+ 1. Else if |registration|'s waiting worker is not null, set |oldestWorker| to |registration|'s waiting worker.
+ 1. Else if |registration|'s installing worker is not null, set |oldestWorker| to |registration|'s installing worker.
+ 1. Return |oldestWorker|.
+
+
Service Worker Has No Pending Events
@@ -3649,7 +3758,7 @@ spec: rfc7231; urlPrefix: https://tools.ietf.org/html/rfc7231
An HTTP response to a [=/service worker=]'s script resource request can include the following header:
: \`Service-Worker-Allowed
\`
- :: Indicates the user agent will override the path restriction, which limits the maximum allowed [=service worker registration/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 [=service worker/scope url=] that the script can control, to the given value.
Note: The value is a URL. If a relative URL is given, it is parsed against the script's URL.