forked from w3c/screen-orientation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1199 lines (1189 loc) · 47.4 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>
The Screen Orientation API
</title>
<script src='https://www.w3.org/Tools/respec/respec-w3c-common' class=
'remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "ED",
shortName: "screen-orientation",
previousPublishDate: "2019-05-30",
previousMaturity: "WD",
editors: [
{
name: "Mounir Lamouri",
company: "Google Inc.",
w3cid: 45389,
},
{
name: "Marcos Cáceres",
company: "Mozilla",
w3cid: 39125,
},
{
name: "Johanna Herman",
company: "Invited Expert",
w3cid: 111724,
}
],
testSuiteURI:
"https://w3c-test.org/screen-orientation/",
github: "w3c/screen-orientation",
wg: "Web Applications Working Group",
wgURI: "https://www.w3.org/2019/webapps/",
wgPatentURI: "https://www.w3.org/2004/01/pp-impl/114929/status",
caniuse: "screen-orientation",
xref: "web-platform",
};
</script>
</head>
<body>
<section id='abstract'>
<p>
The <cite>Screen Orientation API</cite> provides the ability to read
the screen orientation type and angle, to be informed when the screen
orientation changes, and to lock the screen to a specific orientation.
</p>
</section>
<section id='sotd'>
<p>
This document is a work in progress.
</p>
</section>
<section class="informative">
<h2>
Introduction
</h2>
<p>
For web applications, the <cite>Screen Orientation API</cite> exposes
the type and angle of a device's current screen orientation, and can
provide notification if the device's orientation changes. This allows
web applications to programmatically adapt the user experience for many
possible screen orientations (in concert with CSS). The API also allows
locking the screen to a particular orientation. This is useful in
applications such as computer games where users physically rotate the
device but the screen orientation itself mustn't change.
</p>
<section>
<h2>
Goals
</h2>
<ul>
<li>Allow a web application to have control over screen orientation
where needed and without being intrusive to end users.
</li>
<li>Support a better user experience by providing developers with
information on screen orientation changes so web applications can
update correspondingly.
</li>
</ul>
</section>
<section class='informative'>
<h2>
Examples
</h2>
<section>
<h2>
Locking to a specific orientation and unlocking
</h2>
<p>
In this example, clicking the "Lock" button makes a request to go
into fullscreen and then lock the screen to the opposite
orientation. Pressing the "Unlock" button unlocks the screen so it
rotates if the user turns the device.
</p>
<p>
The developer console logs the change in orientation type and
angle.
</p>
<pre class='example html'>
<script>
function fullScreenCheck() {
if (document.fullscreenElement) return;
return document.documentElement.requestFullscreen();
}
function updateDetails(lockButton) {
const buttonOrientation = getOppositeOrientation();
lockButton.textContent = `Lock to ${buttonOrientation}`;
}
function getOppositeOrientation() {
const { type } = screen.orientation;
return type.startsWith("portrait") ? "landscape" : "portrait";
}
async function rotate(lockButton) {
try {
await fullScreenCheck();
} catch (err) {
console.error(err);
}
const newOrientation = getOppositeOrientation();
await screen.orientation.lock(newOrientation);
updateDetails(lockButton);
}
function show() {
const { type, angle } = screen.orientation;
console.log(`Orientation type is ${type} & angle is ${angle}.`);
}
screen.orientation.addEventListener("change", () => {
show();
updateDetails(document.getElementById("button"));
});
window.addEventListener("load", () => {
show();
updateDetails(document.getElementById("button"));
});
</script>
<button onclick="rotate(this)" id="button">
Lock
</button>
<button onclick="screen.orientation.unlock()">
Unlock
</button>
</pre>
</section>
<section>
<h2>
Locking the screen before calling a function
</h2>
<p>
This example waits to go into fullscreen, then locks to landscape
before calling `ready()`.
</p>
<pre class='example html'>
<script>
function ready() {
const { type } = screen.orientation;
console.log(`Fullscreen and locked to ${type}. Ready!`);
}
async function start() {
await document.body.requestFullscreen();
await screen.orientation.lock("landscape");
ready();
}
</script>
<button onclick="start()">
Start
</button>
</pre>
</section>
<section>
<h2>
Alerting the user if the API is not supported
</h2>
<p data-link-for="ScreenOrientation">
In this example, if the <cite>Screen Orientation API</cite> is not
supported, or the screen orientation {{lock()}} rejects, the user
is alerted to rotate their screen manually to landscape.
</p>
<pre class='example html'>
<script>
function start() {
/* Start application when in correct orientation */
}
async function rotate() {
try {
await screen.orientation.lock("landscape");
start();
} catch (err) {
console.error(err);
}
const matchLandscape = matchMedia("(orientation: landscape)");
if (matchLandscape.matches) return start();
addEventListener("orientationchange", function listener() {
matchLandscape.addListener(function mediaChange(e) {
if (!e.matches) return;
removeEventListener("orientationchange", listener);
matchLandscape.removeListener(mediaChange);
start();
});
});
alert("To start, please rotate your screen to landscape.");
}
</script>
<button onclick="start()">
Start
</button>
</pre>
</section>
</section>
</section>
<section data-dfn-for='Screen'>
<h2>
Extensions to the `Screen` interface
</h2>
<p>
The [[[CSSOM-View]]] specification defines the <code><dfn data-cite=
"CSSOM-View#screen">Screen</dfn></code> interface, which this
specification extends:
</p>
<pre class='idl'>
partial interface Screen {
[SameObject] readonly attribute ScreenOrientation orientation;
};
</pre>
<section>
<h2>
<dfn>orientation</dfn> attribute
</h2>
<p>
The {{Screen.orientation}} attribute is an instance of
{{ScreenOrientation}}. This attribute provides the current
orientation, current angle and whether there was an onchange event.
The <a>user agent</a> MUST run the <a>update the orientation
information</a> algorithm steps to initialize the values and return
the {{Screen.orientation}} attribute.
</p>
</section>
</section>
<section data-dfn-for='ScreenOrientation' data-link-for=
'ScreenOrientation'>
<h2>
<dfn>ScreenOrientation</dfn> interface
</h2>
<pre class='idl' data-cite="DOM HTML">
[Exposed=Window]
interface ScreenOrientation : EventTarget {
Promise<void> lock(OrientationLockType orientation);
void unlock();
readonly attribute OrientationType type;
readonly attribute unsigned short angle;
attribute EventHandler onchange;
};
enum OrientationLockType {
"any",
"natural",
"landscape",
"portrait",
"portrait-primary",
"portrait-secondary",
"landscape-primary",
"landscape-secondary"
};
enum OrientationType {
"portrait-primary",
"portrait-secondary",
"landscape-primary",
"landscape-secondary"
};
</pre>
<p data-dfn-for="OrientationLockType">
The <dfn>OrientationLockType</dfn> enum represents the screen
orientations to which a screen can be locked: the "<dfn>any</dfn>" enum
value represents the <a>any</a> orientation, the "<dfn>natural</dfn>"
enum represents the <a>natural</a> orientation, the
"<dfn>landscape</dfn>" enum represents the <a>landscape</a>
orientation, the "<dfn>portrait</dfn>" enum represents the
<a>portrait</a> orientation, the "<dfn>portrait-primary</dfn>" enum
represents the <a>portrait-primary</a> orientation, the
"<dfn>portrait-secondary</dfn>" enum represents the
<a>portrait-secondary</a> orientation, the
"<dfn>landscape-primary</dfn>" enum represents the
<a>landscape-primary</a> orientation, and the
"<dfn>landscape-secondary</dfn>" enum represents the
<a>landscape-secondary</a> orientation.
</p>
<p data-dfn-for="OrientationType">
The <dfn>OrientationType</dfn> enum represents the actual current
screen orientation that the screen is in irrespective of which lock is
applied: the "<dfn>portrait-primary</dfn>" enum represents the
<a>portrait-primary</a> orientation, the
"<dfn>portrait-secondary</dfn>" enum represents the
<a>portrait-secondary</a> orientation, the
"<dfn>landscape-primary</dfn>" enum represents the
<a>landscape-primary</a> orientation, and the
"<dfn>landscape-secondary</dfn>" enum represents the
<a>landscape-secondary</a> orientation.
</p>
<section>
<h2>
<dfn>lock()</dfn> method: Lock screen to a specific orientation
</h2>
<p data-tests="lock-bad-argument.html, lock-basic.html">
When the {{lock()}} method is invoked, the <a>user agent</a> MUST run
the <a>apply an orientation lock</a> steps to the [=environment
settings object / responsible document=] using |orientation|.
</p>
</section>
<section>
<h2>
<dfn>unlock()</dfn> method: Unlock screen to default orientation
</h2>
<p>
When the {{unlock()}} method is invoked, the <a>user agent</a> MUST
run the steps to <a>lock the orientation</a> of the [=environment
settings object / responsible document=] to its <a>default
orientation</a>.
</p>
<p class='note' title="Why does unlock() not return a promise?">
{{unlock()}} does not return a promise because it is equivalent to
locking to the <a>default orientation</a> which might or might not be
known by the <a>user agent</a>. Hence, the <a>user agent</a> can not
predict what the new orientation is going to be and even if it is
going to change at all.
</p>
<div class="issue" data-number="104"></div>
</section>
<section>
<h2>
<dfn>type</dfn> attribute: Get current orientation
</h2>
<p>
When getting the {{type}} attribute, the <a>user agent</a> MUST
return the [=environment settings object / responsible document=]'s
<a>current orientation type</a>.
</p>
</section>
<section>
<h2>
<dfn>angle</dfn> attribute: Get orientation angle
</h2>
<p>
When getting the {{angle}} attribute, the <a>user agent</a> MUST
return the [=environment settings object / responsible document=]'s
<a>current orientation angle</a>.
</p>
<div class='note' title=
"What does the value given for angle represent?">
<p>
{{angle}} represents how far the user has turned the device
counterclockwise from the natural orientation. When the device is
rotated 90° counterclockwise, the screen compensates by rotating
90° clockwise, so {{angle}} returns `90`.
</p>
<p>
The <a>screen orientation values table</a> shows how the angle
changes depending on the how the device is rotated.
</p>
<p>
The value returned by this property is always in the range 0-359.
It never returns negative values.
</p>
</div>
</section>
<section>
<h2>
<dfn>onchange</dfn> attribute: Handle orientation changes
</h2>
</section>
<p>
The {{onchange}} attribute is an <a>event handler</a> whose
corresponding <a>event handler event type</a> is `"change"`.
</p>
</section>
<section>
<h2>
Extensions to the `Document` interface
</h2>
<section>
<h2>
Internal Slots
</h2>
<table class="simple">
<thead>
<tr>
<th>
Internal Slot
</th>
<th>
Description
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<dfn>[[\orientationLock]]</dfn>
</td>
<td>
The {{[[orientationLock]]}} represents a <a>document</a>'s
<a>orientation lock</a> as an <a>ordered set</a> of
{{OrientationType}}.
</td>
</tr>
<tr>
<td>
<dfn>[[\defaultOrientation]]</dfn>
</td>
<td>
An <a>ordered set</a> of orientations to which the screen
orientation is locked when not explicitly locked by this API or
any other means.
</td>
</tr>
<tr>
<td>
<dfn>[[\orientationPendingPromise]]</dfn>
</td>
<td>
Either `null` or a {{Promise}}. When assigned a {{Promise}},
that promise represents a request to lock the screen to one of
the supported orientations. The promise resolves after locking
the orientation succeeds or rejects if locking fails.
</td>
</tr>
</tbody>
</table>
</section>
</section>
<section>
<h2>
Concepts
</h2>
<p>
The term <dfn data-lt="screen concept" data-lt-nodefault=
"">screen</dfn> is equivalent to the screen of the output device
associated to the {{Window}}, as per [[CSSOM-VIEW]].
</p>
<p>
Algorithms defined in this specification assume that for each
<a>document</a> there is an {{[[orientationPendingPromise]]}}.
</p>
<section>
<h2>
Screen orientation types and locks
</h2>
<p>
<dfn>Landscape-primary</dfn> is an orientation where the screen width
is greater than the screen height. If the device's natural
orientation is landscape, then it is in landscape-primary when held
in that position. If the device's natural orientation is portrait,
the <a>user agent</a> sets landscape-primary from the two options as
shown in the <a>screen orientation values table</a>.
</p>
<p>
<dfn>Landscape-secondary</dfn> is an orientation where the screen
width is greater than the screen height. If the device's natural
orientation is landscape, it is in landscape-secondary when rotated
180º from its natural orientation. If the device's natural
orientation is portrait, the <a>user agent</a> sets
landscape-secondary from the two options as shown in the <a>screen
orientation values table</a>.
</p>
<p>
<dfn>Portrait-primary</dfn> is an orientation where the screen width
is less than or equal to the screen height. If the device's natural
orientation is portrait, then it is in portrait-primary when held in
that position. If the device's natural orientation is landscape, the
<a>user agent</a> sets portrait-primary from the two options as shown
in the <a>screen orientation values table</a>.
</p>
<p>
<dfn>Portrait-secondary</dfn> is an orientation where the screen
width is less than or equal to the screen height. If the device's
natural orientation is portrait, then it is in portrait-secondary
when rotated 180º from its natural position. If the device's natural
orientation is landscape, the <a>user agent</a> sets
portrait-secondary from the two options as shown in the <a>screen
orientation values table</a>.
</p>
<p>
<dfn>Portrait</dfn> is an orientation where the screen width is less
than or equal to the screen height and depending on platform
convention locking the screen to portrait can represent
portrait-primary, portrait-secondary or both.
</p>
<p>
<dfn>Landscape</dfn> is an orientation where the screen width is
greater than the screen height and depending on platform convention
locking the screen to landscape can represent landscape-primary,
landscape-secondary or both.
</p>
<p>
<dfn>Natural</dfn> is an orientation that refers to either
portrait-primary or landscape-primary depending on the device's usual
orientation. This orientation is usually provided by the underlying
operating system.
</p>
<p>
<dfn>Any</dfn> is an orientation that means the screen can be locked
to any one of portrait-primary, portrait-secondary, landscape-primary
and landscape-secondary.
</p>
<p>
The <dfn>default orientation</dfn> is the set of orientations to
which the screen is locked when there is no current <a>orientation
lock</a>. This orientation is determined by the device's operating
system, or the user agent (e.g., <a href=
"#interaction-with-web-application-manifest"></a>), or controlled by
the end-user.
</p>
<div class="issue" data-number="150"></div>
</section>
<section data-dfn-for='OrientationType' data-link-for="OrientationType">
<h2>
Reading the screen orientation
</h2>
<p>
All <a>documents</a> have a <dfn>current orientation type</dfn> and a
<dfn>current orientation angle</dfn>. Both of them SHOULD be
initialized when the <a>document</a> is created, otherwise they MUST
be initialized the first time they are accessed and before their
value is read. The <a>user agent</a> MUST <a>update the orientation
information</a> of the <a>document</a> to initialize them.
</p>
<p>
For a given <a>document</a>, the <a>current orientation type</a> and
the <a>current orientation angle</a> are strongly linked in the sense
that for any given type, there will be a specific angle associated.
</p>
<p>
One primary orientation will always be determined by the
<a>natural</a> orientation of the device and this will then determine
the secondary value of its related orientation.
</p>
<p>
For example a device held in its natural <a>portrait</a> orientation
would have a current orientation of <a>portrait-primary</a> and its
<a>portrait-secondary</a> orientation would be its position when
rotated 180°.
</p>
<p>
The <a>user agent</a> can associate the other `*-primary` and
`*-secondary` values at will. For example, it can be based on the
device preferred angles, the user's preferred orientations or the
current orientation when the application starts.
</p>
<p>
The <a>screen orientation values table</a> presents the possible
orientation types: <a>portrait-primary</a>,
<a>portrait-secondary</a>, <a>landscape-primary</a> and
<a>landscape-secondary</a>. The table shows the primary and secondary
values that are determined by the device's <a>natural</a> orientation
and the possibilities available to the <a>user agent</a> for setting
the other primary and secondary orientation values.
</p>
<table class="simple">
<caption>
The <dfn>screen orientation values table</dfn>
</caption>
<thead>
<tr>
<th>
Natural Orientation
</th>
<th>
Primary Orientation 1
</th>
<th>
Secondary Orientation 1
</th>
<th>
Primary Orientation 2
</th>
<th>
Secondary Orientation 2
</th>
</tr>
</thead>
<tbody data-link-for="ScreenOrientation">
<tr>
<td>
<a>Portrait</a>
</td>
<td>
<a>portrait-primary</a><br>
{{angle}} `0`
</td>
<td>
<a>portrait-secondary</a><br>
{{angle}} `180`
</td>
<td>
<a>landscape-primary</a><br>
<a>User agent</a> to set at either {{angle}} `90` or {{angle}}
`270`
</td>
<td>
<a>landscape-secondary</a><br>
Set at the angle not used for landscape-primary
</td>
</tr>
<tr>
<td>
<a>Landscape</a>
</td>
<td>
<a>landscape-primary</a><br>
{{angle}} `0`
</td>
<td>
<a>landscape-secondary</a><br>
{{angle}} `180`
</td>
<td>
<a>portrait-primary</a><br>
<a>User agent</a> to set at either {{angle}} `90` or {{angle}}
`270`
</td>
<td>
<a>portrait-secondary</a><br>
Set at the angle not used for portrait-primary
</td>
</tr>
</tbody>
</table>
<p>
Once the <a>user agent</a> has set the primary and secondary values
from the options in the <a>screen orientation values table</a>, the
<a>current orientation type</a> and the <a>current orientation
angle</a> relation MUST be kept consistent for any given
<a>document</a>.
</p>
<div class='practice'>
<p class='practicedesc'>
<span class='practicelab'>{{ScreenOrientation.angle}} and
{{ScreenOrientation.type}} relationship</span> Never assume any
cross-devices relationship between the screen orientation type and
the screen orientation angle. Any assumption would be wrong given
that a device might have `90` and `270` as the angles for
`landscape` types but another device will have `0` and `180`,
depending on its <a>natural</a> orientation. Instead, it is
recommended to check during runtime the relationship between angle
and type.
</p>
</div>
</section>
<section data-dfn-for='OrientationLockType'>
<h2>
Locking the screen orientation
</h2>
<p>
The <a>user agent</a> MAY require a <a>document</a> and its
associated [=Document/browsing context=] to meet one or more
<dfn>pre-lock conditions</dfn> in order to lock the screen
orientation. For example, a <a>user agent</a> might require a
<a>document</a>'s <a>top-level browsing context</a> to be fullscreen
(see <a href='#interaction-with-fullscreen-api'></a>) in order to
allow an <a>orientation lock</a>.
</p>
<p>
The <a>user agent</a> MAY reject all attempts to lock the screen
orientation if the platform conventions do not expect applications to
be able to change the screen orientation. For example, on most
desktop platforms, applications can not change the screen
orientation.
</p>
<p>
If the <a>user agent</a> supports locking the screen orientation, it
MUST allow the screen to be locked to all of the states of the
{{OrientationLockType}} enum.
</p>
<p>
The {{[[orientationLock]]}} internal slot represents the
<a>document</a>'s <a>orientation lock</a>.
</p>
<p>
An <dfn>orientation lock</dfn> is in place when the screen has
successfully been locked to a specific orientation.
</p>
<section>
<h2>
Locking to the default orientation
</h2>
<p>
From the perspective of a <a>document</a>, locking to the
<a>default orientation</a> is equivalent to unlocking because it
means that it no longer has a lock applied.
</p>
<p class="note" title="Who controls the default orientation?">
This does not mean that the {{[[defaultOrientation]]}} will only
contain the item <a>any</a>. The <a>default orientation</a> is
likely device-specific and {{[[defaultOrientation]]}} could for
example contain <a>portrait-primary</a> and/or
<a>landscape-primary</a>. Alternatively, the user could restrict
the default orientation to a specific orientation via some OS or
browser level preference for accessibility reasons. The user agent
can also set the default orientation e.g., <a href=
"#interaction-with-web-application-manifest"></a>.
</p>
</section>
</section>
</section>
<section>
<h2>
Interactions with other specifications
</h2>
<p>
This section explains how this specification interacts with other
related specifications of the platform.
</p>
<section>
<h2>
Interaction with Fullscreen API
</h2>
<p>
As a <a>pre-lock condition</a>, a user agent MAY restrict locking the
screen orientation exclusively to when the <a>top-level browsing
context</a>'s <a>document</a>'s is full screen. When that <a>pre-lock
condition</a> applies, whenever the <a>document</a>'s <a>fullscreen
element</a> is empty and a screen <a>orientation lock</a> is applied,
the <a>user agent</a> MUST <a>lock the orientation</a> of the
<a>document</a> to the <a>document</a>'s <a>default orientation</a>.
</p>
<div class='issue'>
This section could be improved if the [[FULLSCREEN]] specification
had a hook for when the document is no longer fullscreen. See
<a href='https://github.com/w3c/screen-orientation/issues/62'>issue
62</a>.
</div>
</section>
<section class='informative'>
<h2>
Interaction with Web Application Manifest
</h2>
<p>
The [[[appmanifest]]] allows web applications to set the
<a>document</a>'s <a>default orientation</a>.
</p>
</section>
<section class='informative'>
<h2>
Interaction with CSS Device Adaptation
</h2>
<p>
The [[[CSS-ADAPTATION]]] specification defines, independently of this
document, a way to lock the screen orientation for a web page using
CSS.
</p>
</section>
<section class='informative'>
<h2>
Interaction with Web Content Accessibility Guidelines
</h2>
<p>
The [[[WCAG21]]] includes a <a data-cite="WCAG21#orientation">Success
Criterion related to screen orientation</a>.
</p>
<p>
The intent of this Success Criterion is to ensure that all
<a data-cite="WCAG21#dfn-essential">essential</a> content and
functionality is available regardless of the display orientation
(portrait or landscape). Some websites and applications automatically
set the screen to a particular display orientation and expect that
users will respond by rotating their device to match.
</p>
<p>
However, some users may have their devices mounted in a fixed
orientation (e.g. on the arm of a power wheelchair). Therefore,
websites and applications need to support both orientations by making
sure <a data-cite="WCAG21#dfn-essential">essential</a> content and
functionality is available in each orientation. While the order of
content and method of functionality may have differences the content
and functionality must always be available. When a particular
orientation is <a data-cite="WCAG21#dfn-essential">essential</a>, the
user needs to be advised of the orientation requirements.
</p>
</section>
</section>
<section>
<h2>
Algorithms
</h2>
<section data-link-for="OrientationType">
<h2>
Updating the orientation information
</h2>
<p data-tests="orientation-reading.html">
The steps to <dfn>update the orientation information</dfn> of a
<a>document</a> are as follows:
</p>
<ol class="algorithm">
<li>If the screen width is greater than the screen height, set the
<a>document</a>'s <a>current orientation type</a> to
<a>landscape-primary</a> or <a>landscape-secondary</a>.
</li>
<li>Otherwise, if the screen width is less than or equal to the
screen height, set the <a>document</a>'s <a>current orientation
type</a> to <a>portrait-primary</a> or <a>portrait-secondary</a>.
</li>
<li data-tests="orientation-reading.html">Set the <a>document</a>'s
<a>current orientation angle</a> to the clockwise angle in degrees
between the orientation of the viewport as it is drawn and the
<a>natural</a> orientation of the device (i.e., the top of the
physical screen). This is the opposite of the physical rotation. In
other words, if a device is turned 90 degrees on the right, the
<a>current orientation angle</a> would be 270 degrees. The <a>screen
orientation values table</a> gives the options for each orientation
and possible associated angles.
</li>
</ol>
</section>
<section data-link-for="OrientationType">
<h2>
Apply an orientation lock
</h2>
<p class="algorithm">
The steps to <dfn>apply an orientation lock</dfn> to a
<a>document</a> using |orientation| are as follows:
</p>
<ol class="algorithm">
<li>If the <a>user agent</a> does not support locking the screen
orientation, return a promise rejected with a `"NotSupportedError"`
{{DOMException}} and abort these steps.
</li>
<li data-tests="lock-sandboxed-iframe.html">If the <a>document</a>'s
has the <a>sandboxed orientation lock browsing context flag</a> set,
or <a>user agent</a> doesn't meet the <a>pre-lock conditions</a> to
perform an orientation change, return a promise rejected with a
`"SecurityError"` {{DOMException}} and abort these steps.
</li>
<li data-tests="lock-basic.html">Set |doc|'s
{{[[orientationPendingPromise]]}} to a newly-created promise.
</li>
<li>Return |doc|'s {{[[orientationPendingPromise]]}} and <a>in
parallel</a>:
<ol>
<li>Let |browsing contexts| be the <a>list of the descendant
browsing contexts</a> of the <a>top-level browsing context</a>'s
<a>document</a>.
</li>
<li>If one of the |browsing contexts|'s <a>document</a>'s
{{[[orientationPendingPromise]]}} is not `null`:
<ol>
<li>Let |doc| be the <a>document</a> which has a not `null`
{{[[orientationPendingPromise]]}}.
</li>
<li>Reject |doc|'s {{[[orientationPendingPromise]]}} with
`"AbortError"` {{DOMException}}.
</li>
<li>Set |doc|'s {{[[orientationPendingPromise]]}} to `null` .
</li>
</ol>
</li>
<li data-tests="lock-basic.html">Let |orientations| be an empty
<a>list</a>.
</li>
<li>Depending on |orientation| value, do the following:
<dl>
<dt>
<a>portrait-primary</a> or <a>portrait-secondary</a> or
<a>landscape-primary</a> or <a>landscape-secondary</a>
</dt>
<dd>
Append |orientation| to |orientations|.
</dd>
<dt>
<a data-link-for='OrientationLockType'>landscape</a>
</dt>
<dd>
Depending on platform convention, append
`landscape-primary`, or `landscape-secondary`, or both to
|orientations|.
</dd>
<dt>
<a data-link-for='OrientationLockType'>portrait</a>
</dt>
<dd>
Depending on platform convention, append
`portrait-primary`, or `portrait-secondary`, or both to
|orientations|.
</dd>
<dt>
<a data-link-for='OrientationLockType'>natural</a>
</dt>
<dd>
Append `portrait-primary` or `landscape-primary` to
|orientations| such as the associated <a>current
orientation angle</a> is 0.
</dd>
<dt>
`any`
</dt>
<dd>
Append `portrait-primary`, `portrait-secondary`,
`landscape-primary` and `landscape-secondary` to
|orientations|.
</dd>
</dl>
</li>
<li>
<a>Lock the orientation</a> of the <a>document</a> to
|orientations|.
</li>
<li>If locking the orientation did not result in a change of
orientation, as part of the next <a>animation frame task</a>,
resolve {{[[orientationPendingPromise]]}} with `undefined` and
set {{[[orientationPendingPromise]]}} to `null`.
</li>
</ol>
</li>
</ol>
<div class='note'>
If locking the orientation results in an orientation change, the
promise will be resolved when the orientation will change as
described in the <a href="#Screen-orientation-change"></a> section.
</div>
</section>
<section>
<h2>
Locking the orientation
</h2>
<p>
The steps to <dfn>lock the orientation</dfn> to |orientation| are as
follows.
</p>
<ol class="algorithm">
<li class="algorithm" data-tests="lock-basic.html">Set the <a>document</a>'s
{{[[orientationLock]]}} to |orientations|.
</li>
<li>If the <a>active orientation lock</a> is not the
<a>document</a>'s {{[[orientationLock]]}}, abort these steps.
</li>
<li>If the <a>active orientation lock</a> value is equal to
|orientations| value, abort these steps.
</li>
<li>If |orientations| contains only one value, run the following
sub-steps:
<ol>
<li>Let |orientation| be the value contained in |orientations|.
</li>
<li>Change how the viewport is drawn so that the
<a>document</a>'s <a>current orientation type</a> will be equal
to |orientation|.
</li>
<li>After the change has happened, prevent the <a>document</a>'s
<a>top-level browsing context</a>'s screen orientation from
changing until those steps are run again.
</li>
<li>Abort these steps.
</li>
</ol>
</li>
<li>If the <a>document</a>'s <a>current orientation type</a> is not
part of |orientations|, change how the viewport is drawn such as the
<a>document</a>'s <a>current orientation type</a> will be equal to
one of |orientations|' values.
</li>
<li>Otherwise, depending on platform conventions, change how the
viewport is drawn in order to make it match another screen
orientation type. However, it has to be part of |orientations|.
</li>
<li>Allow the user to change the screen orientation to any value part
of |orientations| and only those values until those steps are run
again. The method to define the current screen orientation has to
match the platform conventions.
</li>
</ol>
</section>
<section>
<h2>
Determining the active orientation lock
</h2>
<p>
The steps to determine the <dfn>active orientation lock</dfn> are as
follows:
</p>
<ol class="algorithm">
<li>If there is only one <a>top-level browsing context</a> with a <a>
document</a> that is visible per [[PAGE-VISIBILITY]], the <a>active
orientation lock</a> is the <a>document</a>'s
{{[[orientationLock]]}}.
</li>
<li>Otherwise, if there are more than one <a>top-level browsing
context</a> with a <a>document</a> that is visible per
[[PAGE-VISIBILITY]] but only one of those <a>document</a>s is
focused, the <a>active orientation lock</a> is the focused
<a>document</a>'s {{[[orientationLock]]}}.