/
index.html
3468 lines (3457 loc) · 140 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
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
Web App Manifest
</title>
<script src="https://www.w3.org/Tools/respec/respec-w3c-common" class=
"remove">
</script>
<script class='remove'>
//make tidy happy
var respecConfig = {
doRDFa: false,
previousPublishDate: "2013-12-17",
specStatus: 'WD',
shortName: 'appmanifest',
subtitle: 'Living Document',
prevVersion: 'FPWD',
previousMaturity: "WD",
editors: [{
name: "Marcos Caceres",
company: "Mozilla Corporation",
companyURL: "https://mozilla.org/",
w3cid: 39125
}, {
name: "Kenneth Rohde Christiansen",
company: "Intel Corporation",
companyURL: "http://intel.com",
w3cid: 57705
}, {
name: "Mounir Lamouri",
company: "Google Inc.",
companyURL: "https://google.com",
w3cid: 45389
}, {
name: "Anssi Kostiainen",
company: "Intel Corporation",
companyURL: "http://intel.com",
w3cid: 41974
}],
wg: 'Web Platform Working Group',
wgURI: 'https://www.w3.org/WebPlatform/WG/',
license: 'w3c-software-doc',
wgPublicList: 'public-webapps',
wgPatentURI: 'https://www.w3.org/2004/01/pp-impl/83482/status',
noLegacyStyle: true,
otherLinks: [{
key: 'Repository',
data: [{
value: 'We are on Github.',
href: 'https://github.com/w3c/manifest'
}, {
value: 'File a bug.',
href: 'https://github.com/w3c/manifest/issues'
}, {
value: 'Commit history.',
href: 'https://github.com/w3c/manifest/commits/gh-pages'
}, {
value: 'Mailing list.',
href: 'https://lists.w3.org/Archives/Public/public-webapps/'
}]
}, {
key: "Implementation status",
data: [{
value: "Gecko",
href: "https://bugzilla.mozilla.org/show_bug.cgi?id=997779"
}, {
value: "Blink",
href: "https://code.google.com/p/chromium/issues/detail?id=366145"
}]
}],
issueBase: "https://www.github.com/w3c/manifest/issues/",
githubAPI: "https://api.github.com/repos/w3c/manifest",
license: "w3c-software-doc",
};
</script>
</head>
<body>
<section id='abstract'>
<p>
This specification defines a JSON-based manifest file that provides
developers with a centralized place to put metadata associated with a
web application. This metadata includes, but is not limited to, the web
application's name, links to icons, as well as the preferred URL to
open when a user launches the web application. The manifest also allows
developers to declare a default orientation for their web application,
as well as providing the ability to set the display mode for the
application (e.g., in fullscreen). Additionally, the manifest allows a
developer to "scope" a web application to a URL. This restricts the
URLs to which the manifest is applied and provides a means to "deep
link" into a web application from other applications.
</p>
<p>
Using this metadata, user agents can provide developers with means to
create user experiences that are more comparable to that of a native
application.
</p>
<p>
To associate documents of a web application with a manifest, this
specification defines the <code>manifest</code> link type as a
declarative means for a document to be associated with a manifest.
</p>
</section>
<section id="sotd">
<div class="warning">
<p>
Implementors need to be aware that this specification is not stable.
However, aspects of this specification are shipping in at least one
browser (see links to implementation status at the top of this
document). <strong>Implementors who are not taking part in the
discussions will find the specification changing out from under them
in incompatible ways.</strong> Vendors interested in implementing
this specification before it eventually reaches the Candidate
Recommendation phase should <a href=
"https://github.com/w3c/manifest/issues">subscribe to the repository
on GitHub</a> and take part in the discussions.
</p>
</div>
</section>
<section class="informative">
<h2>
Usage Examples
</h2>
<p>
This section shows how developers can make use of the various features
of this specification.
</p>
<section class="informative">
<h3>
Example manifest
</h3>
<p>
The following shows a typical <a>manifest</a>.
</p>
<pre class="example json" title="typical manifest">
{
"lang": "en",
"dir": "ltr",
"name": "Super Racer 3000",
"description": "The ultimate futuristic racing game from the future!",
"short_name": "Racer3K",
"icons": [{
"src": "icon/lowres.webp",
"sizes": "64x64",
"type": "image/webp"
},{
"src": "icon/lowres.png",
"sizes": "64x64"
}, {
"src": "icon/hd_hi",
"sizes": "128x128"
}],
"scope": "/racer/",
"start_url": "/racer/start.html",
"display": "fullscreen",
"orientation": "landscape",
"theme_color": "aliceblue",
"background_color": "red",
"screenshots": [{
"src": "screenshots/in-game-1x.jpg",
"sizes": "640x480",
"type": "image/jpeg"
},{
"src": "screenshots/in-game-2x.jpg",
"sizes": "1280x920",
"type": "image/jpeg"
}]
}
</pre>
</section>
<section class="informative">
<h3>
Using a <code>link</code> element to link to a manifest
</h3>
<p>
Example of using a <code>link</code> element to associate a website
with a <a>manifest</a>. The example also shows how to use [[!HTML]]'s
<code>link</code> and <code>meta</code> elements to give the web
application a fallback name and set of icons.
</p>
<pre class="example html" title="linking to a manifest">
<!doctype>
<html>
<title>Super Racer 3000</title>
<!-- Startup configuration -->
<link rel="manifest" href="manifest.webmanifest">
<!-- Fallback application metadata for legacy browsers -->
<meta name="application-name" content="Racer3K">
<link rel="icon" sizes="16x16 32x32 48x48" href="lo_def.ico">
<link rel="icon" sizes="512x512" href="hi_def.png">
</pre>
</section>
</section>
<section>
<h2>
Installable web applications
</h2>
<p>
A common use case of a manifest is for a user agent to <dfn data-lt=
"installing|installed|installation">install</dfn> a web application;
whereby the user agent provides the end-user with a means of
instantiating a new <a>top-level browsing context</a> that has the
manifest's members applied to it. That is, the manifest's members, or
their defaults, are in effect on the <a>top-level browsing context</a>.
This distinguishes an installed web application from a traditional
bookmark, as opening a web page from a traditional bookmark will not
have the manifest's properties <a>applied</a> to it.
</p>
<p>
For example, on user agents that support installation, a web
application could be presented and launched in a way that, to the
end-user, is indistinguishable from native applications: such as
appearing as a labeled icon on the home screen, launcher, or start
menu. When launched, the manifest is <a>applied</a> by the user agent
to the <a>top-level browsing context</a> prior to the <a>start URL</a>
being loaded. This gives the user agent time to apply the relevant
values of the manifest, possibly changing the <a>display mode</a> and
screen orientation of the web application. Alternatively, and again as
an example, the user agent could <a>install</a> the web application
into a list of bookmarks within the user agent itself.
</p>
<p>
An end-user can <dfn data-lt="manual installation">manually</dfn>
trigger the <a>installation process</a> through the browser's
<abbr>UI</abbr>. Alternatively, the <a>installation process</a> can
occur through an <dfn>automated install prompt</dfn>: that is, a
<abbr>UI</abbr> that the user agent presents to the user when, for
instance, there are sufficient <a>installability signals</a> to warrant
<a>installation</a> of the web application.
</p>
<section>
<h3>
Authority of the manifest's metadata
</h3>
<p>
When a <a>manifest</a> is linked from a <code>Document</code>, it
indicates to the user agent that the metadata is
<dfn>authoritative</dfn>: that is, the user agent SHOULD use the
metadata of the manifest instead of the one in the
<code>Document</code>. However, in cases where metadata is missing,
or in error, a user agent MAY fallback to the <code>Document</code>
to find suitable replacements for missing manifest members (e.g.,
using <code>application-name</code> in place of
<code>short_name</code>).
</p>
</section>
<section>
<h3>
Application's name
</h3>
<p>
The <dfn>application's name</dfn> is derived from either the
<a><code>name</code> member</a> or <a><code>short_name</code>
member</a> (if either is present) - otherwise, it is generated by the
user agent or provided by the end-user.
</p>
<p>
When either member is missing from the manifest, a user agent MAY use
the <a><code>name</code> member</a> as a fallback for the
<a><code>short_name</code> member</a> or vice versa.
</p>
<p>
If the <a data-lt="name member"><code>name</code></a> and <a data-lt=
"short_name member"><code>short_name</code></a> members are
undefined, the user agent SHOULD assign a default name (e.g.,
"Untitled"). Alternatively, a user agent MAY allow the end-user to
input some text that can serve as the <a>application's name</a>.
</p>
<p>
When both the <a data-lt="name member"><code>name</code></a> and
<a data-lt="short_name member"><code>short_name</code></a> members
are present, it is left up to implementations to decide which member
is best suited for the space available (e.g., the
<a><code>short_name</code> member</a> might be better suited for the
space available underneath an icon).
</p>
</section>
<section>
<h3>
Installation process
</h3>
<p>
An <dfn>installation process</dfn> is an attempt by the user agent to
<a>install</a> a web application. The details of such a process
(i.e., the display of an install <abbr>UI</abbr>, and any resulting
<abbr>IO</abbr> operations of the host <abbr>OS</abbr>) are left up
to implementers. Implementers need to be aware that there are
<a href="#installation-sec">privacy and security considerations</a>
that directly relate to the <a>installation process</a>.
</p>
<p>
For the purpose of this specification, the <dfn>installation
succeeded</dfn> once the <a>installation process</a> succeeds in
<a>installing</a> the web application (e.g., an icon was successfully
placed onto the device's homescreen). If the end-user cancels the
installation process (even if they <a>manually</a> triggered it, and
then changed their minds), then the <dfn>installation was
canceled</dfn>. Otherwise, the <dfn>installation failed</dfn>.
Reasons for installation failure can include, for example, the OS
denying permission to the user agent to add an icon to the homescreen
of the device and the end-user rejecting the installation.
</p>
</section>
<section>
<h3>
Installation
</h3>
<p>
The <dfn>steps to install the web application</dfn> are given by the
following algorithm:
</p>
<ol>
<li>Let <var>window</var> be the <code>Window</code> object of the
<a>top-level browsing context</a> for which the user agent will
attempt installation.
</li>
<li>Then, <a>in parallel</a>:
<ol>
<li>Instantiate an <a>installation process</a>.
</li>
<li>Let <a>manifest</a> be the result of <a>obtaining the
manifest</a>.
</li>
<li>If <a>obtaining the manifest</a> results in an error, a user
agent can, at this point, fall back to using the <a>top-level
browsing context</a>' <code>Document</code>'s metadata to
populate an <a>installation process</a>' UI.
</li>
<li>If the <a>installation succeeded</a>, <a>queue a task</a> on
the the <dfn>application life-cycle task source</dfn> to <a>fire
an event</a> named <code>install</code> at the <var>window</var>
object.
</li>
</ol>
</li>
</ol>
</section>
<section>
<h3 id="installation-sec">
Privacy and security considerations
</h3>
<p>
During the <a>installation process</a>, it is RECOMMENDED that the
user agent allow the end-user to inspect the icon, name, <a>start
URL</a>, origin, etc. pertaining to a web application. This is to
give a end-user an opportunity to make a conscious decision to
approve, and possibly modify, the information pertaining to the web
application before installing it. This also gives the end-user an
opportunity to discern if the user agent is spoofing another web
application, by, for example, using an unexpected icon or name.
</p>
<p>
It is RECOMMENDED that user agents prevent other applications from
determining which applications are installed on the system (e.g., via
a timing attack on the user agent's cache). This could be done by,
for example, invalidating from the user agent's cache the resources
linked to from the manifest (for example, icons) after a web
application is <a>installed</a> - or by using an entirely different
cache from that used for regular web browsing.
</p>
</section>
<section class="informative">
<h3>
Installability signals
</h3>
<p>
By design, this specification does not provide developers with an
explicit API to "install" a web application. Instead, a
<a>manifest</a> can serve as an <dfn data-lt=
"installability signals">installability signal</dfn> to a user agent
that a web application can be <a>installed</a>.
</p>
<p>
Examples of <a>installability signals</a> for a web application:
</p>
<ul>
<li>is <a>associated with a manifest</a> with at least a
<code>name</code> member and a suitable icon.
</li>
<li>is served over a secure network connection.
</li>
<li>has a sensible content security policy.
</li>
<li>is able to responsibly adapt to display on a variety of screen
sizes, catering for both mobile and desktop.
</li>
<li>is able to function without a network connection.
</li>
<li>is repeatedly used by the end-user over some extended period of
time.
</li>
<li>has been explicitly marked by the user as one that they value and
trust (e.g., by bookmarking or "starring" it).
</li>
</ul>
<p>
This list is not exhaustive and some <a>installability signals</a>
might not apply to all user agents. How a user agent makes use of
these <a>installability signals</a> to determine if a web application
can be <a>installed</a> is left to implementers.
</p>
</section>
</section>
<section>
<h2>
Installation Events
</h2>
<section>
<h3>
Extensions to the <code>Window</code> object
</h3>
<p>
The following extensions to the <code>Window</code> object specify
the <a>event handler attributes</a> on which events relating to the
<a>installation</a> of a web application are fired.
</p>
<pre class="idl">
partial interface Window {
attribute EventHandler oninstall;
};
</pre>
<div class="example">
<p>
This example shows two ways of handling the install event.
</p>
<pre>
function handleInstall(ev){
const date = new Date(ev.timeStamp / 1000);
console.log(`Yay! Our app got installed at ${date.toTimeString()}`);
}
// Using the event handler IDL attribute
window.oninstall = handleInstall;
// Using .addEventListener()
window.addEventListener("install", handleInstall);
</pre>
</div>
<section>
<h4>
<code>oninstall</code> attribute
</h4>
<p>
<dfn for="Window">oninstall</dfn> is an <a>event handler IDL
attribute</a> for the "<a>install</a>" event type. The interface
used for these events is the <a><code>Event</code> interface</a>
[[!WHATWG-DOM]]. This event is dispatched as a result of a
<a>manual installation</a> or an <a>automated install prompt</a>,
which cause the <a>steps to install the web application</a> to run.
</p>
</section>
</section>
</section>
<section>
<h2>
Navigation scope
</h2>
<p>
A <dfn>navigation scope</dfn> is a [[!WHATWG-URL]] that represents the
set of URLs to which an <a>application context</a> can be navigated
while the manifest is <a>applied</a>. To determine if a URL is within
the <a>navigation scope</a>, the user agent MUST run the <a>within
scope</a> algorithm.
</p>
<p>
A string <var>targetURL</var> is said the be <dfn>within scope</dfn> of
<a>navigation scope</a> <var>scopeURL</var> if the following algorithm
returns <code>true</code>:
</p>
<ol>
<li>If <var>scopeURL</var> is <code>undefined</code> (i.e., it is
<a>unbounded</a> because of an error or it was not declared in the
manifest), return <code>true</code>.
</li>
<li>Let <var>target</var> be a new URL using <var>targetURL</var> as
input. If <var>target</var> is failure, return <code>false</code>.
</li>
<li>If <var>target</var> is <a>same origin</a> as <var>scope</var> and
<var>target</var>'s <code>pathname</code> starts with
<var>scope</var>'s <code>pathname</code>, return <code>true</code>.
</li>
<li>Otherwise, return <code>false</code>.
</li>
</ol>
<div class="issue" title="🐒 Monkey patch">
<p>
Enforcing the navigation scope depends on [[!HTML]]'s navigate
algorithm. As such, the following algorithm monkey patches [[!HTML]].
<a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=27653">Bug
27653</a> has been filed to address this.
</p>
</div>
<p>
The user agent MUST navigate the application context as per [[!HTML]]'s
<a>navigate algorithm</a> with exceptions enabled. If the URL of the
resource being loaded in the navigation is not <a>within scope</a> of
the navigation scope, then the user agent MUST behave as if the
application context is not <a>allowed to navigate</a> (this provides
the ability for the user agent to perform the navigation in a different
browsing context, or in a different user agent entirely). If during the
handle redirects step of HTML's <a>navigate algorithm</a> the redirect
URL is not <a>within scope</a>, abort HTML's navigation algorithm with
a <code>SecurityError</code>.
</p>
<p>
A developer specifies the navigation scope via the
<a><code>scope</code> member</a>. In the case where the
<a><code>scope</code> member</a> is missing or in error, the navigation
scope is treated as <dfn>unbounded</dfn> (represented as the value
<code>undefined</code>). In such a case, the manifest is applied to all
URLs the application context is <a>navigated</a> to (see related
<a href="#navigation-scope-security-considerations">security
considerations</a>).
</p>
<section>
<h3 id="navigation-scope-security-considerations">
Security considerations
</h3>
<p>
When the navigation scope is <a>unbounded</a> and a <a>display
mode</a> other than <code>browser</code> is being applied, it is
RECOMMENDED that user agents signal to the end-user when security
and/or privacy sensitive navigations occur. The manner of signaling
is left up to implementers, but can include things like showing the
URL of the application context, dropping out of fullscreen to the
<a>browser</a> <a>display mode</a>. Examples of security and/or
privacy sensitive navigations include, but are not limited to:
</p>
<ul>
<li>the application context being <a>navigated</a> from a secure
connection to an insecure connection (or vice versa).
</li>
<li>the application context being <a>navigated</a> to a different
origin.
</li>
</ul>
<p>
This specification distinguishes between behavior in first-party and
third-party contexts. In particular, if a <code>scope</code> member
is declared in the manifest, it is not possible to navigate the
<a>top-level browsing context</a> to somewhere outside the scope
while the <a>manifest</a> is <a>applied</a> to the <a>top-level
browsing context</a>. That's not to say that the web application
cannot be navigated: just that the set of URLs to which the manifest
applies is restricted by the <a>navigation scope</a>.
</p>
</section>
<section>
<h3>
Deep links
</h3>
<div class="issue" data-number="363"></div>
<p>
A <dfn>deep link</dfn> is a URL that is <a>within scope</a> of an
<a>installed</a> web application.
</p>
<p>
An <a>application context</a> can be instantiated through a <a>deep
link</a> (a URL that is within scope of the installed web
application); in which case, the manifest is applied and the <a>deep
link</a> is loaded within the context of a web application.
</p>
<div class="note">
<p>
The concept of a <a>deep link</a> is useful in that it allows
hyperlinking from one installed application to another. This can be
from a native application to an <a>installed</a> web application
(and possibly vice versa!). Theoretically, this can provide
seamless context switching between native and web applications
through standard hyperlinks. And in the case where a particular web
application is not <a>installed</a>, the OS can just open the link
in the user's preferred web browser.
</p>
<p>
Implementers are encouraged make such context switching obvious to
the user, for example, by adhering to the human interface
guidelines of the underlying platform with respect to application
switching.
</p>
</div>
</section>
</section>
<section>
<h2>
Display modes
</h2>
<p>
A <dfn>display mode</dfn> represents how the web application is being
presented within the context of an OS (e.g., in fullscreen, etc.).
Display modes correspond to user interface (UI) metaphors and
functionality in use on a given platform. The UI conventions of the
display modes are purely advisory and implementers are free to
interpret them how they best see fit.
</p>
<p>
Once a user agent applies a particular <a>display mode</a> to an
<a>application context</a>, it becomes the <dfn>default display
mode</dfn> for the <a>top-level browsing context</a> (i.e., it is used
as the display mode when the window is <a>navigated</a>). The user
agent MAY override the <a>default display mode</a> for security reasons
(e.g., the <a>top-level browsing context</a> is <a>navigated</a> to
another origin) and/or the user agent MAY provide the user with a means
of switching to another <a>display mode</a>.
</p>
<p>
When the <code>display</code> member is missing, or if there is no
valid <code>display</code> member, the user agent uses the
<code>browser</code> <a>display mode</a> as the <a>default display
mode</a>. As such, the user agent is REQUIRED to support the
<code>browser</code> <a>display mode</a>.
</p>
<p>
Each <a>display mode</a>, except <code>browser</code>, has a
<dfn data-lt="fallback display modes">fallback display mode</dfn>,
which is the <a>display mode</a> that the user agent can try to use if
it doesn't support a particular <a>display mode</a>. If the user agent
does support a <a>fallback display mode</a>, then it checks to see if
it can use that <a>display mode</a>'s <a>fallback display mode</a>.
This creates a fallback chain, with the <a>default display mode</a>
(<code>browser</code>) being the last item in the chain.
</p>
<div class="example">
<p>
For example, Awesome Browser only supports the
<code>minimal-ui</code> and <code>browser</code> display modes, but a
developer declares that she wants <code>fullscreen</code> in the
manifest. In this case, the user agent will first check if it
supports <code>fullscreen</code> (it doesn't), so it falls back to
<code>standalone</code> (which it also doesn't support), and
ultimately falls back to <code>minimal-ui</code>.
</p>
</div>
<p>
The <dfn>display modes values</dfn> and their corresponding <a>fallback
display modes</a> are as follows:
</p>
<dl>
<dt>
<dfn id="dm-fullscreen">fullscreen</dfn>
</dt>
<dd>
Opens the web application without any user agent chrome and takes up
the entirety of the available display area.
</dd>
<dd>
The <a>fallback display mode</a> for <code>fullscreen</code> is
<code>standalone</code>.
</dd>
<dt>
<dfn id="dm-standalone">standalone</dfn>
</dt>
<dd>
Opens the web application to look and feel like a standalone native
application. This can include the application having a different
window, its own icon in the application launcher, etc. In this mode,
the user agent will exclude UI elements for controlling navigation,
but can include other UI elements such as a status bar.
</dd>
<dd>
The <a>fallback display mode</a> for <code>standalone</code> is
<code>minimal-ui</code>.
</dd>
<dt>
<dfn id="dm-minimal-ui">minimal-ui</dfn>
</dt>
<dd>
This mode is similar to <a>fullscreen</a>, but provides the end-user
with some means to access a minimal set of UI elements for
controlling navigation (i.e., back, forward, reload, and perhaps some
way of viewing the document's address). A user agent can include
other platform specific UI elements, such as "share" and "print"
buttons or whatever is customary on the platform and user agent.
</dd>
<dd>
The <a>fallback display mode</a> for <code>minimal-ui</code> is
<code>browser</code>.
</dd>
<dt>
<dfn id="dm-browser">browser</dfn>
</dt>
<dd>
Opens the web application using the platform-specific convention for
opening hyperlinks in the user agent (e.g., in a browser tab or a new
window).
</dd>
<dd>
The <code>browser</code> <a>display mode</a> doesn't have a
<a>fallback display mode</a> (conforming user agents are required to
support the <code>browser</code> <a>display mode</a>).
</dd>
</dl>
<p class="note">
The <a>fullscreen</a> <a>display mode</a> is orthogonal to, and works
independently of, the [[WHATWG-FULLSCREEN]] API. The
<a><code>fullscreen</code></a> <a>display mode</a> affects the
fullscreen state of the browser window, while the [[WHATWG-FULLSCREEN]]
API operates on an element contained within the viewport. As such, a
web application can have its <a>display mode</a> set to
<a><code>fullscreen</code></a>, while
<code>document.fullScreenElement</code> returns <code>null</code>, and
<code>fullscreenEnabled</code> returns <code>false</code>.
</p>
<section>
<h3>
Privacy and security considerations
</h3>
<p>
When the <a>fullscreen</a> <a>display mode</a> is applied, it is
RECOMMENDED that the user agent provides the end-user a means to
consult common information about the web application, such as the
origin, start and/or current URL, granted permissions, and associated
icon. How such information is exposed to end-users is left up to
implementers.
</p>
<p>
Additionally, when applying a manifest that sets the <a>display
mode</a> to anything except "<a>browser</a>", it is RECOMMENDED that
the user agent clearly indicate to the end-user that their are
leaving the normal browsing context of a web browser. Ideally,
launching or switching to a web application is performed in a manner
that is consistent with launching or switching to other applications
in the host platform. For example, a long and obvious animated
transition, or speaking the text "Launching application X".
</p>
</section>
<section>
<h3>
The <code>'display-mode'</code> media feature
</h3>
<p>
The <code><dfn>display-mode</dfn></code> media feature represents,
via a CSS media query [[!MEDIAQ]], the <a>display mode</a> of the web
application. This media feature applies to the top-level browsing
context and any child browsing contexts. Child browsing contexts
reflect the <a>display mode</a> of the <a>top-level browsing
context</a>.
</p>
<p>
A user agent MUST expose the '<code>display-mode</code>' media
feature irrespective of whether a manifest is being applied to a
browsing context. For example, if the end-user puts the whole user
agent into fullscreen, then the user agent would reflect this change
to CSS and scripts via the '<code>display-mode</code>' media feature.
</p>
<div class="note">
<p>
Please note that the <code>fullscreen</code> <a>display mode</a> is
not directly related to the CSS <code>:fullscreen</code>
pseudo-class specified in the [[WHATWG-FULLSCREEN]] API. The
<code>:fullscreen</code> pseudo-class matches exclusively when a
[[!HTML]] element is put into the fullscreen element stack.
However, a side effect of calling the
<code>requestFullscreen()</code> method on an element using the
[[WHATWG-FULLSCREEN]] API is that the browser window can enter a
fullscreen mode at the OS-level. In such a case, both
<code>:fullscreen</code> and <code>(display-mode:
fullscreen)</code> will match.
</p>
<p>
On some platforms, it is possible for a user to put a browser
window into fullscreen without the aid of the [[WHATWG-FULLSCREEN]]
API. When this happens, the <code>:fullscreen</code> pseudo class
will not match, but <code>(display-mode: fullscreen)</code> will
match. This is exemplified in CSS code below.
</p>
<pre class='example'>
/* applies when the window is fullscreen */
@media all and (display-mode: fullscreen) {
...
}
/* applies when an element goes fullscreen */
#game:fullsceen{
...
}
</pre>
</div>
<dl>
<dt>
Value:
</dt>
<dd>
<a>fullscreen</a> | <a>standalone</a> | <a>minimal-ui</a> |
<a>browser</a>
</dd>
<dt>
Applies to:
</dt>
<dd>
visual media types
</dd>
<dt>
Accepts min/max prefixes:
</dt>
<dd>
No
</dd>
</dl>
<p>
A user agent MUST reflect the applied <a>display mode</a> of the web
application via a CSS media query [[!MEDIAQ]].
</p>
<section>
<h4>
Examples
</h4>
<p>
An example in CSS:
</p>
<pre class='example'>
@media all and (display-mode: minimal-ui) {
/* ... */
}
@media all and (display-mode: standalone) {
/* ... */
}
</pre>
<p>
Accessing the display-mode media feature in ECMAScript through
<code>matchMedia()</code> of [[cssom-view]]:
</p>
<pre class="example">
const standalone = matchMedia( '(display-mode: standalone)' );
standalone.onchange = (e) => {
/* handle changes to display mode */
}
if (standalone.matches) {
/* do standalone things */
}
</pre>
</section>
<section>
<h3>
Security and privacy considerations
</h3>
<p>
The <code>'display-mode'</code> media feature allows an origin
access to aspects of a user’s local computing environment and,
together with the <code>display</code> member, allows an origin
some measure of control over a user agent’s native UI: Through a
CSS media query, a script can know the display mode of a web
application. An attacker could, in such a case, exploit the fact
that an application is being displayed in fullscreen to mimic the
user interface of another application.
</p>
<p>
Furthermore, by neglecting to define a scope member in the
manifest, it's possible to put a web application into a <a>display
mode</a> that persists cross-origin (for legacy reasons, this is
the default behavior). In case where the navigation scope is
unbounded, it is left to the user agent to either stop applying the
manifest when a cross-origin navigation occurs or to show some sort
of security warning to the user.
</p>
</section>
</section>
</section>
<section>
<h3>
Associating a resource with a manifest
</h3>
<p>
A resource is said to be <dfn>associated with a manifest</dfn> if the
resource representation, an HTML document, has a <a href=
"#linking"><code>manifest</code> link relationship</a>.
</p>
<section id="linking">
<h3>
Linking to a manifest
</h3>
<p>
The <code>manifest</code> keyword can be used with a [[!HTML]]
<a><code>link</code> element</a>. This keyword creates an <a>external
resource link</a>.
</p>
<table border="1">
<tr>
<th rowspan="2">
Link type
</th>
<th colspan="2">
Effect on...
</th>
<th rowspan="2">
Brief description
</th>
</tr>
<tr>
<th>
<code><a>link</a></code>
</th>
<th>
<code><a>a</a></code> and <code><a>area</a></code>
</th>
</tr>
<tr>
<td>
<code>manifest</code>
</td>
<td>
<a>External Resource</a>
</td>
<td>
not allowed
</td>
<td>
Imports or links to a <a>manifest</a>.
</td>
</tr>
</table>
<p>
The <a>media type for a manifest</a> serves as the default media type
for resources associated with the <code><a href=
"#rel-manifest">manifest</a></code> <a>link type</a>.
</p>
<p class="note">
In cases where more than one <a><code>link</code> element</a> with a
<code>manifest</code> link type appears in a <code>Document</code>,
the user agent uses the first <a><code>link</code> element</a> in
tree order and ignores all subsequent <a><code>link</code>
element</a> with a <code>manifest</code> link type (even if the first
element was erroneous). See the <a>steps for obtaining a
manifest</a>.
</p>
<p>
To obtain a manifest, the user agent MUST run the <a data-lt=
"obtaining the manifest">steps for obtaining a manifest</a>. The
appropriate time to obtain the manifest is left up to
implementations. A user agent MAY opt to delay fetching a manifest
until after the document and its other resources have been fully
loaded (i.e., to not delay the availability of content and scripts
required by the <code>document</code>).
</p>
<p>
A <a>manifest</a> is obtained and applied regardless of the
<a><code>media</code></a> attribute of the <a><code>link</code>
element</a> matches the environment or not.
</p>
</section>
</section>
<section>
<h2>
Manifest life-cycle
</h2>
<p>
This section defines algorithms for <a href="#obtaining">obtaining</a>,
<a href="#processing">processing</a>, and <a>applying</a> a
<a>manifest</a>.
</p>
<section id="obtaining">
<h3>
Obtaining a manifest
</h3>
<p>
The <dfn data-lt="obtaining the manifest|obtaining a manifest">steps
for obtaining a manifest</dfn> are given by the following algorithm.
The algorithm, if successful, returns a <a>processed manifest</a> and
the <var>manifest URL</var>; otherwise, it terminates prematurely and
returns nothing. In the case of nothing being returned, the user
agent MUST ignore the manifest declaration. In running these steps, a
user agent MUST NOT <a>delay the load event</a>.
</p>
<ol>
<li>From the <code>Document</code> of the <a>top-level browsing
context</a>, let <var>manifest link</var> be the first
<a><code>link</code> element</a> in <a>tree order</a> whose <a><code>
rel</code> attribute</a> contains the token <code>manifest</code>.
</li>
<li>If <var>manifest link</var> is <code>null</code>, terminate this
algorithm.
</li>
<li>If <var>manifest link</var>'s <code>href</code> attribute's value
is the empty string, then abort these steps.
</li>
<li>Let <var>manifest URL</var> be the result of <a>parsing</a> the
value of the <code>href</code> attribute, relative to <a>the
element's base URL</a>. If parsing fails, then abort these steps.
</li>
<li>Let <var>request</var> be a new [[!FETCH]] <a>request</a>, whose
URL is <var>manifest URL</var>, and whose <a>context</a> is
"<code>manifest</code>".
</li>
<li>If the <var>manifest link</var>'s <code>crossOrigin</code>
attribute's value is '<code>use-credentials</code>', then set
<var>request</var>'s credentials to '<code>include</code>'.
</li>
<li>Await the result of performing a <a>fetch</a> with
<var>request</var>, letting <var>response</var> be the result.
</li>
<li>If <var>response</var> is a <a>network error</a>, terminate this
algorithm.
</li>
<li>Let <var>manifest</var> be the result of running the <a>steps for
processing a manifest</a> with <var>response</var>'s <a href=
"https://fetch.spec.whatwg.org/#concept-request-body">body</a> as the