forked from w3c/push-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
802 lines (795 loc) · 35.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
<!DOCTYPE html>
<html>
<head>
<title>
Push API
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src='https://www.w3.org/Tools/respec/respec-w3c-common' class='remove'>
</script>
<script class="remove">
// (this is to make tidy happy)
// See http://www.w3.org/respec/ for ReSpec documentation.
var respecConfig = {
specStatus: "ED",
shortName: "push-api",
previousPublishDate: "2013-08-15",
previousMaturity: "WD",
edDraftURI: "https://w3c.github.io/push-api/",
editors: [
{
name: "Bryan Sullivan",
company: "AT&T",
companyURL: "http://www.att.com/"
},
{
name: "Eduardo Fullea",
company: "Telefonica",
companyURL: "http://www.telefonica.com/"
},
{
name: "Michaël van Ouwerkerk",
company: "Google",
companyURL: "https://www.google.com/"
},
],
wg: "Web Applications Working Group",
wgURI: "http://www.w3.org/2008/webapps/",
wgPublicList: "public-webapps",
subjectPrefix: "[Push API]",
// This is important for Rec-track documents, do not copy a patent URI
// from a random document unless you know what you're doing. If in
// doubt ask your friendly neighbourhood Team Contact.
wgPatentURI: "http://www.w3.org/2004/01/pp-impl/42538/status",
noLegacyStyle: true,
otherLinks: [
{
key: "Participate",
data: [
{
value: "Mailing list",
href: "http://lists.w3.org/Archives/Public/public-webapps/"
},
{
value: "Browse open issues",
href: "https://github.com/w3c/push-api/issues"
},
{
value: "File a bug",
href: "https://github.com/w3c/push-api/issues/new"
},
]
},
],
};
</script>
</head>
<body>
<section id='abstract'>
<p>
The <cite>Push API</cite> provides <a title="webapp">webapps</a> with scripted access to
server-sent messages, for simplicity referred to here as <a title="push message">push
messages</a>, as delivered by <a title="push service">push services</a>. A <a>push
service</a> allows a <a>webapp server</a> to send messages to a <a>webapp</a>, regardless
of whether the <a>webapp</a> is currently active on the <a>user agent</a>. The <a>push
message</a> will be delivered to a <a>Service Worker</a>, which could then store the
message's data or display a notification to the user.
</p>
<p>
This specification is designed to promote compatibility with any delivery method for
<a title="push message">push messages</a> from <a title="push service">push services</a> to
<a title="user agent">user agents</a>.
</p>
</section>
<section id='sotd'></section>
<section class='informative' id="introduction">
<h2>
Introduction
</h2>
<p>
As defined here, <a title="push service">push services</a> support delivery of <a>webapp
server</a> messages in the following contexts and related use cases:
</p>
<ul>
<li>the user is actively involved in the use of a <a>webapp</a>: this relates to any normal
use case in which a <a>webapp</a> user may benefit from <a title="push message">push
messages</a> while the user is actively using the <a>webapp</a>
</li>
<li>the user is not actively involved in the use of a <a>webapp</a>, but the <a>webapp</a>
is active in a window of the browser or executing as a web worker: this relates to use
cases such as social networking, messaging, web feed readers, etc in which the user may not
be actively using a <a>webapp</a> but still benefits from <a title="push message">push
messages</a> being sent to (or via) the <a>webapp</a>, to keep the user up-to-date
</li>
<li>the <a>webapp</a> is not currently active in a browser window: this relates to use
cases in which the user may close the <a>webapp</a>, but still benefits from the
<a>webapp</a> being able to be restarted when a <a>push message</a> is received, e.g. the
WebRTC use case in which an incoming call can invoke the WebRTC <a>webapp</a>
</li>
<li>multiple <a title="webapp">webapps</a> are running, but <a title="push message">push
messages</a> are delivered only to the <a>webapp</a> that requested them, e.g. any normal
use case in which multiple <a title="webapp">webapps</a> are active in the browser and
utilizing <a title="push service">push services</a>
</li>
<li>multiple instances of the same <a>webapp</a> are active in the browser, and <a title=
"push message">push messages</a> specific to each instance of the <a>webapp</a> are
delivered only to the specific instance, e.g. when a mail <a>webapp</a> is active in two
windows using different mail accounts
</li>
<li>multiple instances of the same <a>webapp</a> are active in different browsers, and push
messages are delivered to a set of instances of the <a>webapp</a>, e.g. when a mail
<a>webapp</a> is active in two browsers using the same email account
</li>
<li>multiple instances of the same <a>webapp</a> are active in different browsers, and push
messages are delivered to all instances of the <a>webapp</a>, e.g. when a message is to be
broadcasted to all users of the <a>webapp</a>
</li>
</ul>
</section>
<section id="conformance">
<p>
This specification defines conformance criteria that apply to a single product: the
<dfn>user agent</dfn> that implements the interfaces that it contains.
</p>
<p>
Implementations that use ECMAScript to implement the APIs defined in this specification
MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web
IDL specification [[!WEBIDL]].
</p>
</section>
<section>
<h2>
Terminology
</h2>
<p>
The terms <dfn><a href="http://www.w3.org/TR/html5/webappapis.html#event-handlers">event
handler</a></dfn>, <dfn><a href=
"http://www.w3.org/TR/html5/webappapis.html#event-handler-event-type">event handler event
type</a></dfn>, <dfn><a href=
"http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a></dfn>, and
<dfn><a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple
event</a></dfn> are defined in [[!HTML5]].
</p>
<p>
<code><a href=
'http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects'><dfn>Promise</dfn></a></code>
is defined in [[!ECMASCRIPT]].
</p>
<p>
<code><a href="http://www.w3.org/TR/dom/#eventinit"><dfn>EventInit</dfn></a></code>,
<code><a href="http://www.w3.org/TR/dom/#domexception"><dfn>DOMException</dfn></a></code>,
<code><a href="http://www.w3.org/TR/dom/#aborterror"><dfn>AbortError</dfn></a></code>,
<code><a href=
"http://www.w3.org/TR/dom/#notfounderror"><dfn>NotFoundError</dfn></a></code>, and
<code><a href="http://www.w3.org/TR/dom/#securityerror"><dfn>SecurityError</dfn></a></code>
are defined in [[!DOM]].
</p>
<p>
<dfn>Service Worker</dfn>, <dfn>ServiceWorkerRegistration</dfn>,
<dfn>ServiceWorkerGlobalScope</dfn>, and <dfn>ExtendableEvent</dfn> are defined in
[[!SERVICE-WORKERS]].
</p>
<p>
The term <dfn>webapp</dfn> refers to a Web application, i.e. an application implemented
using Web technologies, and executing within the context of a Web <a>user agent</a>, e.g. a
Web browser or other Web runtime environment.
</p>
<p>
The term <dfn>webapp server</dfn> refers to server-side components of a <a>webapp</a>.
</p>
<p>
The term <dfn>push message</dfn> refers to an indication to a <a>webapp</a> that there is
new information for it from the <a>webapp server</a>, all or part of which MAY be contained
in the <a>push message</a> itself.
</p>
<p>
The term <dfn>push registration</dfn> refers to each logical channel aimed at delivering
<a title="push message">push messages</a> from an <a>webapp server</a> to a <a>webapp</a>,
which is created by a distinct registration of such <a>webapp</a> via this Push API.
</p>
<p>
The term <dfn>push service</dfn> refers to an overall end-to-end system that allows
<a title="webapp server">webapp servers</a> to send <a title="push message">push
messages</a> to a <a>webapp</a>.
</p>
<p>
The term <dfn>push server</dfn> refers to the <a>push service</a> access point via which
<a title="webapp server">webapp-servers</a> can initiate <a>push message</a> delivery. Push
servers typically expose APIs specific to the <a>push service</a>, e.g. for <a>push
message</a> delivery initiation.
</p>
<p>
The term <dfn>express permission</dfn> refers to an act by the user, e.g. via user
interface or host device platform features, via which the user approves the permission of a
<a>webapp</a> to access the Push API.
</p>
</section>
<section>
<h2>
Security and privacy considerations
</h2>
<p>
<a title="user agent">User agents</a> MUST NOT provide Push API access to <a title=
"webapp">webapps</a> without the <a>express permission</a> of the user. <a title=
"user agent">User agents</a> MUST acquire consent for permission through a user interface
for each call to the <code>register()</code> method, unless a prearranged trust
relationship applies.
</p>
<p>
<a title="user agent">User agents</a> MAY support prearranged trust relationships that do
not require such per-request user interfaces.
</p>
<p>
<a title="user agent">User agents</a> MUST implement the Push API to be HTTPS-only.
SSL-only support provides better protection for the user against man-in-the-middle attacks
intended to obtain push registration data. Browsers may ignore this rule for development
purposes only.
</p>
<p>
Permissions that are preserved beyond the current browsing session MUST be revocable.
</p>
</section>
<section class='informative' id="pushframework">
<h2>
Push Framework
</h2>
<p>
Although <a title="push service">push services</a> are expected to differ in deployment, a
typical deployment is expected to have the following general entities and example operation
for delivery of <a title="push message">push messages</a>:
</p>
<ul>
<li>
<a title="webapp server">Webapp servers</a> request delivery of a <a>push message</a> to
a <a>webapp</a> via a RESTful API exposed by a <a>push server</a>
</li>
<li>The <a>push server</a> delivers the message to a specific <a>user agent</a>
</li>
<li>The <a>user agent</a> delivers the <a>push message</a> to the specific <a>webapp</a>
intended to receive it.
</li>
</ul>
<p>
This overall framework allows <a title="webapp server">webapp servers</a> to inform
<a title="webapp">webapps</a> that new data is available at the <a title=
"webapp server">webapp server</a>, or pass the new data directly to the <a>webapp</a> in
the <a>push message</a>.
</p>
<p>
The push API enables delivery of arbitrary application data to <a title=
"webapp">webapps</a>, and makes no assumptions about the over-the-air/wire protocol used by
<a title="push service">push services</a>. As such, the details of what types of data flow
through a <a title="push service">push services</a> for a particular <a>webapp</a> are
specific to the <a>push service</a> and <a>webapp</a>. As needed, clarification about what
data flows over-the-air/wire should be sought from <a>push service</a> operators or
<a>webapp</a> developers.
</p>
<p>
The following code and diagram illustrate a hypothetical use of the push API.
</p>
<section class="informative">
<h2>
Example
</h2>
<pre class="example highlight">
// https://example.com/serviceworker.js
this.onpush = function(event) {
console.log(event.data);
// From here we can write the data to IndexedDB, send it to any open windows,
// display a notification, etc.
}
// https://example.com/webapp.js
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushRegistrationManager.register().then(
function(pushRegistration) {
console.log(pushRegistration.registrationId);
console.log(pushRegistration.endpoint);
// The push registration details needed by the application server to push
// messages to the push service are now available, and can be sent to the
// application server using, for example, an XMLHttpRequest.
}, function(error) {
// During development it often helps to log errors to the console. In a
// production environment it might make sense to also report information
// about errors back to the application server.
console.log(error);
}
});
});
</pre>
</section>
<section class="informative">
<h2>
Sequence diagram
</h2>
<figure>
<a href="sequence_diagram.png"><img src="sequence_diagram.png" width="800" alt=
"Example flow of events for registration, message delivery, and unregistration"></a>
<figcaption>
Example flow of events for registration, message delivery, and unregistration
</figcaption>
</figure>
</section>
<section>
<h3>
Push Server Discovery and API Use
</h3>
<p>
This specification does not define either specific normative methods via which webapps
can determine the applicable push system, or initiate push requests through that system
via a push server API. While these limitations add complexity for webapp developers, they
reflect the current reality of a diversity of push systems, for which convergence at
least in push server APIs, is not expected to be a short-term possibility. While a
converged push server API is a worthwhile goal and may be addressed in a different
specification, the Push API defined here has been designed to enable the current variety
of push systems to be used as appropriate for the webapp host device or software
platform. This section provides examples of how a webapp can be designed to work with a
variety of hypothetical push systems as needed.
</p>
<p>
The Push API provides several interface parameters and attributes that can enable a
webapp to deliver and obtain the necessary push system specific data enabling use of that
particular push system. These parameters and attributes include:
</p>
<ul>
<li>The <code>registrationId</code> of a <code>PushRegistration</code>, as an opaque
string to the Push API, may be used by push systems to provide meaningful data to the <a>
webapp server</a> through the webapp. For example, the <code>registrationId</code> may
be used as a push server API request parameter or request body element for specific
push systems.
</li>
<li>As a URI, the <code>endpoint</code> of a <code>PushRegistration</code> provides a
flexible means for push systems to deliver webapp-specific registration and/or push
server API parameters to the <a>webapp server</a>, through the webapp.
</li>
</ul>
<p>
Push systems that are compatible with the Push API will be expected to clarify how these
data are used in the push server APIs of the specific system, e.g. through their
developer programs. Examples of considerations include:
</p>
<ul>
<li>The URI used by the <a>webapp server</a> to issue push server API requests, which may
be based upon the <code>endpoint</code>, and for a particular push server API request
require additional parameters e.g. the <code>registrationId</code>.
</li>
<li>The push server API request body, which may require that the <code>endpoint</code> or
<code>registrationId</code> be present in some body element.
</li>
<li>The <code>pushRegistration</code> attributes may only be used by the <a>webapp
server</a> to associate the webapp to a specific push service registration, with the
details of the push server API relying upon other pre-configured data.
</li>
</ul>
<p>
The Push API does not provide any <code>pushRegistration</code> attributes that
normatively identify the particular push system that applies to the registration. Webapps
that are designed to work with a single push system are assumed to know inherently how to
use the push server API of that system. For such webapps, a key consideration is ensuring
that if the webapp is used on a device or browser that does not support the necessary
push system, that either the user is informed that the push-dependent webapp functions
will not work, or the webapp must use alternate methods e.g. [[websockets]] or [[SSE]] to
deliver the server-initiated data.
</p>
<p>
Prior to use of a push server API, <a title="webapp server">webapp servers</a> that are
designed to work with multiple push systems may need to determine the applicable system
by parsing the <code>endpoint</code> to detect the push system from the URI domain.
</p>
</section>
</section>
<section>
<h2>
Extensions to the <a>ServiceWorkerRegistration</a> interface
</h2>
<p>
The Service Worker specification defines a <code>ServiceWorkerRegistration</code> interface
[[!SERVICE-WORKERS]], which this specification extends.
</p>
<dl title="partial interface ServiceWorkerRegistration" class="idl">
<dt>
readonly attribute PushRegistrationManager pushRegistrationManager
</dt>
</dl>
<p>
The <code><dfn id=
"widl-ServiceWorkerRegistration-pushRegistrationManager">pushRegistrationManager</dfn></code>
attribute exposes the <code>PushRegistrationManager</code> for the <a>Service Worker</a>
identified by the <code>ServiceWorkerRegistration</code>.
</p>
</section>
<section>
<h2>
<a>PushRegistrationManager</a> interface
</h2>
<p>
The <a>PushRegistrationManager</a> interface defines the operations that enable <a title=
"webapp">webapps</a> to establish access to <a title="push service">push services</a>. Note
that just a single <a>push registration</a> is allowed per <a>webapp</a>.
</p>
<dl title="interface PushRegistrationManager" class="idl">
<dt>
Promise<PushRegistration> register ()
</dt>
<dt>
Promise<PushRegistration> unregister ()
</dt>
<dt>
Promise<PushRegistration> getRegistration ()
</dt>
<dt>
Promise<PushPermissionStatus> hasPermission ()
</dt>
</dl>
<p>
The <code><dfn id=
"widl-PushRegistrationManager-register-Promise-PushRegistration">register</dfn></code>
method when invoked MUST run the following steps:
</p>
<ol>
<li>Let <var>promise</var> be a new <a><code>Promise</code></a>.
</li>
<li>Return <var>promise</var> and continue the following steps asynchronously.
</li>
<li>If the scheme of the document url is not <code>https</code>, reject <var>promise</var>
with a <code><a>DOMException</a></code> whose name is "<code><a>SecurityError</a></code>"
and terminate these steps.
</li>
<li>Ask the user whether they allow the <a>webapp</a> to receive <a title=
"push message">push messages</a>, unless a prearranged trust relationship applies or the
user has already granted or denied permission explicitly for this <a>webapp</a>.
</li>
<li>If not granted, reject <var>promise</var> with a <code><a>DOMException</a></code> whose
name is "<a href=
"https://www.w3.org/Bugs/Public/show_bug.cgi?id=23033"><code>PermissionDeniedError</code></a>"
and terminate these steps.
</li>
<li>If the <a>webapp</a> is already registered, run the following substeps:
<ol>
<li>Retrieve the <a>push registration</a> associated with the <a>webapp</a>.
</li>
<li>If there is an error, reject <var>promise</var> with a
<code><a>DOMException</a></code> whose name is "<code><a>AbortError</a></code>" and
terminate these steps.
</li>
<li>When the request has been completed, resolve <var>promise</var> with a
<a><code>PushRegistration</code></a> providing the details of the retrieved <a>push
registration</a>.
</li>
</ol>
</li>
<li>Make a request to the system to create a new <a>push registration</a> for the
<a>webapp</a>.
</li>
<li>If there is an error, reject <var>promise</var> with a <code><a>DOMException</a></code>
whose name is "<code><a>AbortError</a></code>" and terminate these steps.
</li>
<li>When the request has been completed, resolve <var>promise</var> with a
<a><code>PushRegistration</code></a> providing the details of the new <a>push
registration</a>.
</li>
</ol>
<p class="note">
<a href=
"https://www.w3.org/Bugs/Public/show_bug.cgi?id=23033"><code>PermissionDeniedError</code></a>
has not yet been defined in a specification, this document currently links to the bug for
defining it.
</p>
<p>
The <code><dfn id=
"widl-PushRegistrationManager-unregister-Promise-PushRegistration">unregister</dfn></code>
method when invoked MUST run the following steps:
</p>
<ol>
<li>Let <var>promise</var> be a new <a><code>Promise</code></a>.
</li>
<li>Return <var>promise</var> and continue the following steps asynchronously.
</li>
<li>If the <a>webapp</a> is not registered, reject <var>promise</var> with a
<code><a>DOMException</a></code> whose name is "<code><a>NotFoundError</a></code>" and
terminate these steps.
</li>
<li>Make a request to the system to deactivate the <a>push registration</a> associated with
the <a>webapp</a>.
</li>
<li>If there is an error, reject <var>promise</var> with a <code><a>DOMException</a></code>
whose name is "<code><a>AbortError</a></code>" and terminate these steps.
</li>
<li>When the request has been completed, resolve <var>promise</var> with a
<a><code>PushRegistration</code></a> providing the details of the <a>push registration</a>
which has been unregistered.
</li>
</ol>
<p>
The <code><dfn id=
"widl-PushRegistrationManager-getRegistration-Promise-PushRegistration">getRegistration</dfn></code>
method when invoked MUST run the following steps:
</p>
<ol>
<li>Let <var>promise</var> be a new <a><code>Promise</code></a>.
</li>
<li>Return <var>promise</var> and continue the following steps asynchronously.
</li>
<li>If the <a>webapp</a> is not registered, reject <var>promise</var> with a
<code><a>DOMException</a></code> whose name is "<code><a>NotFoundError</a></code>" and
terminate these steps.
</li>
<li>Retrieve the <a>push registration</a> associated with the <a>webapp</a>.
</li>
<li>If there is an error, reject <var>promise</var> with a <code><a>DOMException</a></code>
whose name is "<code><a>AbortError</a></code>" and terminate these steps.
</li>
<li>When the request has been completed, resolve <var>promise</var> with a
<a><code>PushRegistration</code></a> providing the details of the retrieved <a>push
registration</a>.
</li>
</ol>
<p>
The <code><dfn id=
"widl-PushRegistrationManager-hasPermission-Promise-PushPermissionStatus">hasPermission</dfn></code>
method when invoked MUST run the following steps:
</p>
<ol>
<li>Let <var>promise</var> be a new <a><code>Promise</code></a>.
</li>
<li>Return <var>promise</var> and continue the following steps asynchronously.
</li>
<li>Retrieve the push permission status (<a><code>PushPermissionStatus</code></a>) of the
requesting <a>webapp</a>
</li>
<li>If there is an error, reject <var>promise</var> with no arguments and terminate these
steps.
</li>
<li>When the request has been completed, resolve <var>promise</var> with
<a><code>PushPermissionStatus</code></a> providing the push permission status.
</li>
</ol>
<p>
Permission to use the push service can be persistent, that is, it does not need to be
reconfirmed for subsequent registrations if a valid permission exists.
</p>
<p>
If there is a need to ask for permission, it needs to be done by invoking the
<a><code>register</code></a> method.
</p>
<section>
<h3>
Push Registration Persistence
</h3>
<p>
To facilitate persistence of push registrations when a <a>webapp</a> is closed, it can
use a <a>Service Worker</a> to register for and receive push events. In that case, even
if the <a>webapp</a> parent window is closed, the <code>pushRegistration</code> object
will still enable delivery of <a title="push message">push messages</a>, through the
<a>Service Worker</a>. The <a title="push message">push messages</a>, can then be
processed by the <a>Service Worker</a>, e.g. including one or more of the following
actions:
</p>
<ul>
<li>store the <a title="push message">push messages</a> for later access by the
<a>webapp</a> when reinvoked by the user
</li>
<li>invoke/reconstruct the <a>webapp</a>, a process that is not described here (expected
to be clarified in [[!SERVICE-WORKERS]])
</li>
<li>delivery of the <a title="push message">push messages</a> data to the to the
<a>webapp</a> as necessary through other means, e.g. [[webmessaging]].
</li>
</ul>
<p>
If a <a>webapp</a> creates a <a>push registration</a> without using a <a>Service
Worker</a>, the <code>pushRegistration</code> object will persist only as long as the
<a>webapp</a> window is open.
</p>
</section>
<section>
<h3>
Push Registration Uniqueness
</h3>
<p>
Each <a>push registration</a> is unique, i.e. a single instance specific to each
<a>webapp</a> and call to the <code>register</code> interface.
</p>
<p>
<a title="webapp">webapps</a> that create multiple <a title="push registration">push
registrations</a> are responsible for mapping the individual registrations to specific
app functions as necessary. For example, the <a>webapp</a> or <a>webapp server</a> can
associate a specific <code>pushRegistration</code> to a particular function of the app
through JavaScript.
</p>
</section>
</section>
<section>
<h2>
<a>PushRegistration</a> interface
</h2>
<p>
The <a>PushRegistration</a> interface contains information about a specific channel used by
a <a>webapp</a> to receive <a title="push message">push messages</a>.
</p>
<dl title="interface PushRegistration" class="idl">
<dt>
readonly attribute DOMString endpoint
</dt>
<dt>
readonly attribute DOMString registrationId
</dt>
</dl>
<p>
When getting the <code><dfn id="widl-PushRegistration-endpoint">endpoint</dfn></code>
attribute, the <a>user agent</a> MUST return the absolute URL exposed by the <a>push
server</a> where the <a>webapp server</a> can send <a title="push message">push
messages</a> to this <a>webapp</a>. The value of <code>endpoint</code> may be the same for
multiple <a title="webapp">webapps</a> / <a>webapp</a> instances running on multiple
devices.
</p>
<p>
When getting the <code><dfn id=
"widl-PushRegistration-registrationId">registrationId</dfn></code> attribute, the <a>user
agent</a> MUST return a univocal identifier of this <a>push registration</a> in the <a>push
server</a>. It is used by the <a>webapp server</a> to indicate the target of the <a title=
"push message">push messages</a> that it submits to the <a>push server</a>. Each pair of
<code>registrationId</code> and <code>endpoint</code> is expected to be unique and specific
to a particular <a>webapp</a> instance running on a specific device.
</p>
</section>
<section>
<h2>
Events
</h2>
<p>
The Service Worker specification defines a <code>ServiceWorkerGlobalScope</code> interface
[[!SERVICE-WORKERS]], which this specification extends.
</p>
<dl title="partial interface ServiceWorkerGlobalScope" class="idl">
<dt>
attribute EventHandler onpush
</dt>
<dt>
attribute EventHandler onpushregistrationlost
</dt>
</dl>
<p>
The <code><dfn id="widl-ServiceWorkerGlobalScope-onpush">onpush</dfn></code> attribute is
an <a>event handler</a> whose corresponding <a>event handler event type</a> is
<code>push</code>.
</p>
<p>
The <code><dfn id=
"widl-ServiceWorkerGlobalScope-onpushregistrationlost">onpushregistrationlost</dfn></code>
attribute is an <a>event handler</a> whose corresponding <a>event handler event type</a> is
<code>pushregistrationlost</code>.
</p>
<section>
<h2>
The <code>push</code> event
</h2>
<p>
The <a>PushEvent</a> interface represents a received <a>push message</a>.
</p>
<dl title=
"[Constructor(DOMString type, optional PushEventInit eventInitDict), Exposed=ServiceWorker] interface PushEvent : ExtendableEvent"
class="idl" data-merge="PushEventInit">
<dt>
readonly attribute DOMString? data
</dt>
</dl>
<p>
When getting the <code id="widl-PushEventInit-data">data</code> attribute of a
<code>PushEventInit</code> object, the <a>user agent</a> MUST return the message data
received by the <a>user agent</a> in the <a>push message</a>, or null if no data was
received.
</p>
<p>
When getting the <code id="widl-PushEvent-data">data</code> attribute of a
<code>PushEvent</code>, the <a>user agent</a> MUST return the message data received by
the <a>user agent</a> in the <a>push message</a>, or null if no data was received.
</p>
<dl title="dictionary PushEventInit : EventInit" class="idl">
<dt>
DOMString? data
</dt>
</dl>
<p>
Upon receiving a <a>push message</a> for a <a>webapp</a> from the <a>push service</a> the
<a>user agent</a> MUST run the following steps:
</p>
<ol>
<li>If the <a>Service Worker</a> associated with the <a>webapp</a> is not running, start
it.
</li>
<li>Let <var>scope</var> be the <code>ServiceWorkerGlobalScope</code> of the <a>Service
Worker</a> associated with the <a>webapp</a>.
</li>
<li>Let <var>event</var> be a new <a><code>PushEvent</code></a> whose <code>data</code>
attribute is the message data received by the <a>user agent</a> in the <a>push
message</a>, or null if no data was received.
</li>
<li>
<a>Queue a task</a> to <a title="fire a simple event">fire <var>event</var> as a simple
event</a> named <code>push</code> at <var>scope</var>.
</li>
</ol>
</section>
<section>
<h2>
The <code>pushregistrationlost</code> event
</h2>
<p>
Upon any event that makes a <a>push registration</a> no longer valid, e.g. <a>push
server</a> database failure, the <a>user agent</a> MUST run the following steps:
</p>
<ol>
<li>If the <a>Service Worker</a> associated with the <a>webapp</a> is not running, start
it.
</li>
<li>Let <var>scope</var> be the <code>ServiceWorkerGlobalScope</code> of the <a>Service
Worker</a> associated with the <a>webapp</a>.
</li>
<li>
<a>Queue a task</a> to <a>fire a simple event</a> named
<code>pushregistrationlost</code> at <var>scope</var>.
</li>
</ol>
</section>
</section>
<section>
<h2>
Enumerations
</h2>
<dl class="idl" title="enum PushPermissionStatus">
<dt>
granted
</dt>
<dt>
denied
</dt>
<dt>
default
</dt>
</dl>
<table class="simple">
<tr>
<th colspan="2">
Enumeration description
</th>
</tr>
<tr>
<td>
<code id="idl-def-PushPermissionStatus.granted">granted</code>
</td>
<td>
The <a>webapp</a> has permission to use Push API.
</td>
</tr>
<tr>
<td>
<code id="idl-def-PushPermissionStatus.denied">denied</code>
</td>
<td>
The <a>webapp</a> has been denied permission to use Push API.
</td>
</tr>
<tr>
<td>
<code id="idl-def-PushPermissionStatus.default">default</code>
</td>
<td>
The <a>webapp</a> needs to ask for permission in order to use Push API.
</td>
</tr>
</table>
</section>
<section class="appendix">
<h2>
Acknowledgements
</h2>
<p>
The editors would like to express their gratitude to the Mozilla and Telefónica Digital
teams implementing the Firefox OS Push message solution and specially to Doug Turner,
Nikhil Marathe, Fernando R. Sela, Guillermo López, Antonio Amaya, José Manuel Cantera and
Albert Crespell, for their technical guidance, implementation work and support.
</p>
</section>
</body>
</html>