Skip to content

Commit febe56b

Browse files
Rewrite .subscribe() to fix various bugs (#350)
1 parent 629bb64 commit febe56b

File tree

1 file changed

+101
-50
lines changed

1 file changed

+101
-50
lines changed

index.html

Lines changed: 101 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
companyURL: "https://www.mozilla.org/",
2626
w3cid: "68503"
2727
},
28+
{
29+
name: "Marcos Caceres",
30+
company: "Apple Inc.",
31+
companyURL: "https://www.apple.com/",
32+
w3cid: "39125"
33+
},
2834
{
2935
name: "Bryan Sullivan",
3036
company: "AT&T",
@@ -195,13 +201,17 @@

195201
subscriptiona> having the new keys as |newSubscription|.
196202
p>
197203
<p>
198-
To <dfn>create a push subscriptiondfn>, given an <a>PushSubscriptionOptionsa> object
199-
of |options|, the <a>user agenta> must run the following steps:
204+
To <dfn>create a push subscriptiondfn>, given an {{PushSubscriptionOptionsInit}}
205+
|optionsDictionary:PushSubscriptionOptionsInit|:
200206
p>
201-
<ol>
202-
<li>Let |subscription| be a new <a>push subscriptiona>.
207+
<ol class="algorithm">
208+
<li>Let |subscription:PushSubscription| be a new {{PushSubscription}}.
209+
li>
210+
<li>Let |options:PushSubscriptionOptions| be a newly created {{PushSubscriptionOptions}}
211+
object, initializing its attributes with the corresponding members and values of
212+
|optionsDictionary|.
203213
li>
204-
<li>Set the `options` attribute of |subscription| to be a copy of |options|.
214+
<li>Set |subscription|'s {{PushSubscription/options}} attribute to |options|.
205215
li>
206216
<li>Generate a new P-256 <a>ECDHa> key pair [[ANSI-X9-62]]. Store the private key in an
207217
internal slot on |subscription|; this value MUST NOT be made available to applications.
@@ -214,11 +224,21 @@

214224
key can be retrieved by calling the {{PushSubscription/getKey()}} method of the
215225
{{PushSubscription}} with an argument of {{PushEncryptionKeyName/"auth"}}.
216226
li>
217-
<li>Make a request to the <a>push servicea> to create a new <a>push subscriptiona>.
218-
Include the {{PushSubscriptionOptions/applicationServerKey}} attribute of |options| when
219-
it has been set.
227+
<li>Request a new <a>push subscriptiona>. Include the
228+
{{PushSubscriptionOptions/applicationServerKey}} attribute of |options| when it has been
229+
set. Rethrow any [=exceptions=].
230+
li>
231+
<li>When the <a>push subscriptiona> request has completed successfully:
232+
<ol>
233+
<li>Set |subscription|'s {{PushSubscription/endpoint}} attribute to the [=URL=]
234+
provided by the <a>push subscriptiona>.
235+
li>
236+
<li>If provided by the <a>push subscriptiona>, set |subscription|'s
237+
{{PushSubscription/expirationTime}}.
238+
li>
239+
ol>
220240
li>
221-
<li>When the request has completed, return |subscription|.
241+
<li>Return |subscription|.
222242
li>
223243
ol>
224244
<section>
@@ -548,73 +568,104 @@

548568
MAY support content codings defined in previous versions of the draft for compatibility
549569
reasons.
550570
p>
571+
<h3>
572+
`subscribe()` method
573+
h3>
551574
<p>
552-
The <dfn>subscribedfn> method when invoked MUST run the following steps:
575+
The <dfn>subscribe()dfn> method when invoked MUST run the following steps:
553576
p>
554-
<ol>
555-
<li>Let |promise| be <a>a new promisea>.
577+
<ol class="algorithm">
578+
<li>Let |promise| be [=a new promise=].
556579
li>
557-
<li>Return |promise| and continue the following steps asynchronously.
580+
<li>Let |global| be [=this=]' [=relevant global object=].
581+
li>
582+
<li>Return |promise| and continue [=in parallel=].
583+
<aside class="note" title="Validation order can vary across user agents">
584+
<p>
585+
Because of implementation-specific reasons, user agents are known to do some of the
586+
following checks in different order (e.g., some check if
587+
{{PushSubscriptionOptionsInit/userVisibleOnly}} is allowed after validating the
588+
{{PushSubscriptionOptionsInit/applicationServerKey}}, and vice versa). However, we
589+
don't believe this affects interoperability of implementations or web applications.
590+
p>
591+
aside>
592+
li>
593+
<li>If the |options| argument has a {{PushSubscriptionOptionsInit/userVisibleOnly}} value
594+
set to `false` and the user agent requires it to be `true`, [=queue a global task=] on the
595+
[=networking task source=] using |global| to [=reject=] |promise| {{"NotAllowedError"}}
596+
{{DOMException}}
597+
li>
598+
<li>If the |options| argument does not include a non-null value for the
599+
{{PushSubscriptionOptionsInit/applicationServerKey}} member, and the <a>push servicea>
600+
requires one to be given, [=queue a global task=] on the [=networking task source=] using
601+
|global| to [=reject=] |promise| with a {{"NotSupportedError"}} {{DOMException}}.
558602
li>
559603
<li>If the |options| argument includes a non-null value for the
560604
{{PushSubscriptionOptions/applicationServerKey}} attribute, run the following sub-steps:
561605
<ol>
562-
<li>If the |applicationServerKey| is provided as a {{DOMString}}, set its value to an
563-
{{ArrayBuffer}} containing the sequence of octets that result from decoding
564-
|applicationServerKey| using the base64url encoding [[RFC7515]]. If decoding fails,
565-
reject promise with a {{DOMException}} whose name is {{"InvalidCharacterError"}} and
566-
terminate these steps.
606+
<li>If |options|'s {{PushSubscriptionOptionsInit/applicationServerKey}} is a
607+
{{DOMString}}, set its value to an {{ArrayBuffer}} containing the sequence of octets
608+
that result from decoding |options|'s
609+
{{PushSubscriptionOptionsInit/applicationServerKey}} using the base64url encoding
610+
[[RFC7515]].
611+
li>
612+
<li>If decoding fails, [=queue a global task=] on the [=networking task source=] using
613+
|global| to [=reject=] |promise| with an {{"InvalidCharacterError"}} {{DOMException}}
614+
and terminate these steps.
567615
li>
568-
<li>Ensure that |applicationServerKey| describes a valid point on the P-256 curve. If
569-
the |applicationServerKey| value is invalid, reject |promise| with a {{DOMException}}
570-
whose name is {{"InvalidAccessError"}} and terminate these steps.
616+
<li>Ensure that |options|'s {{PushSubscriptionOptionsInit/applicationServerKey}}
617+
describes a valid point on the P-256 curve. If its value is invalid, [=queue a global
618+
task=] on the [=networking task source=] using |global| to [=reject=] |promise| with an
619+
{{"InvalidAccessError"}} {{DOMException}} and terminate these steps.
571620
li>
572621
ol>
573622
li>
574-
<li>If the |options| argument does not include a non-null value for the
575-
{{PushSubscriptionOptions/applicationServerKey}} attribute, and the <a>push servicea>
576-
requires one to be given, reject |promise| with a {{DOMException}} whose name is
577-
{{"NotSupportedError"}} and terminate these steps.
578-
li>
579-
<li>Let |registration| be the {{PushManager}}'s associated <a>service worker
623+
<li>Let |registration:ServiceWorkerRegistration| be [=this=]'s associated <a>service worker
580624
registrationa>.
581625
li>
582-
<li>If |registration|'s [=service worker registration/active worker=] is null, reject
583-
|promise| with a {{DOMException}} whose name is {{"InvalidStateError"}} and terminate these
584-
steps.
626+
<li>If |registration|'s [=service worker registration/active worker=] is null, [=queue a
627+
global task=] on the [=networking task source=] using |global| to [=reject=] |promise| with
628+
an {{"InvalidStateError"}} {{DOMException}} and terminate these steps.
629+
li>
630+
<li>Let |sw| be |registration|'s [=service worker registration/active worker=].
585631
li>
586632
<li>Let |permission| be [=request permission to use=] "push".
587633
li>
588-
<li>If |permission| is "denied", reject |promise| with a {{DOMException}} whose name is
589-
{{"NotAllowedError"}} and terminate these steps.
634+
<li>If |permission| is {{PermissionState/"denied"}}, [=queue a global task=] on the [=user
635+
interaction task source=] using |global| to [=reject=] |promise| with a
636+
{{"NotAllowedError"}} {{DOMException}} and terminate these steps.
590637
li>
591-
<li>If the <a>Service Workera> is already subscribed, run the following substeps:
638+
<li>If |sw| is already subscribed, run the following sub-steps:
592639
<ol>
593-
<li>Retrieve the <a>push subscriptiona> associated with the <a>Service Workera>.
640+
<li>Try to retrieve the <a>push subscriptiona> associated with the |sw|. If there is
641+
an error, [=queue a global task=] on the [=networking task source=] using |global| to
642+
[=reject=] |promise| with an {{"AbortError"}} {{DOMException}} and terminate these
643+
steps.
594644
li>
595-
<li>If there is an error, reject |promise| with a {{DOMException}} whose name is
596-
{{"AbortError"}} and terminate these steps.
645+
<li>Let |subscription| be the <a>push subscriptiona> associated with |sw|.
597646
li>
598-
<li>Let |subscription| be the retrieved subscription.
647+
<li>Compare the |options| argument with the `options` attribute of |subscription|. The
648+
contents of {{BufferSource}} values are compared for equality rather than
649+
[=ECMAScript/reference record|reference=].
599650
li>
600-
<li>Compare the |options| argument with the `options` attribute of |subscription|. If
601-
any attribute on |options| contains a different value to that stored for
602-
|subscription|, then reject |promise| with an {{InvalidStateError}} and terminate these
603-
steps. The contents of {{BufferSource}} values are compared for equality rather than
604-
<a href=
605-
"https://tc39.github.io/ecma262/#sec-reference-specification-type">referencesa>.
651+
<li>If any attribute on |options| contains a different value to that stored for
652+
|subscription|, then [=queue a global task=] on the [=networking task source=] using
653+
|global| to [=reject=] |promise| with an {{"InvalidStateError"}} {{DOMException}} and
654+
terminate these steps.
606655
li>
607-
<li>When the request has been completed, resolve |promise| with |subscription|.
656+
<li>When the request has been completed, [=queue a global task=] on the [=networking
657+
task source=] using |global| to [=resolve=] |promise| with |subscription| and terminate
658+
these steps.
608659
li>
609660
ol>
610661
li>
611-
<li>Let |subscription| be the result of running the <a>create a push subscriptiona> steps
612-
given |options|.
613-
li>
614-
<li>If there is an error, reject |promise| with a {{DOMException}} whose name is
615-
{{"AbortError"}} and terminate these steps.
662+
<li>Let |subscription| be the result of trying to [=create a push subscription=] with
663+
|options|. If creating the subscription [=exception/throws=] an [=exception=], [=queue a
664+
global task=] on the [=networking task source=] using |global| to [=reject=] |promise| with
665+
a that [=exception=] and terminate these these steps.
616666
li>
617-
<li>Resolve |promise| with a {{PushSubscription}} providing the details of the new
667+
<li>Otherwise, [=queue a global task=] on the [=networking task source=] using |global| to
668+
[=resolve=] |promise| with a {{PushSubscription}} providing the details of the new
618669
|subscription|.
619670
li>
620671
ol>

0 commit comments

Comments
 (0)