Skip to content

Commit 4208e5a

Browse files
committed
Fullscreen/unfullscreen ASAP; fire events at animation frame timing
This means that changes to document.fullscreenElement and other state will be observable as soon as the resize itself is (e.g. via window.innerWidth) and before resize or scroll events are fired. The fullscreenchange event is still delayed to animation frame timing. This also includes a slight change when /resize/ is true in "exit fullscreen". By changing /doc/ to /topLevelDoc/ in this case, we can make sure that we always fully unfullscreen all documents in this case. This makes a "fully exit fullscreen" corner case unnecessary. Fixes #74.
1 parent aaa10c1 commit 4208e5a

File tree

1 file changed

+96
-95
lines changed

1 file changed

+96
-95
lines changed

fullscreen.bs

Lines changed: 96 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ spec:dom
2626
type:interface; text:Document
2727
spec:infra
2828
type:dfn; for:set; text:for each
29+
type:dfn; text:string
2930
</pre>
3031

3132
<pre class=anchors>
@@ -72,6 +73,9 @@ stated otherwise it is unset.
7273
<a>fullscreen element</a> is the topmost <a>element</a> in the <a for=/>document</a>'s
7374
<a>top layer</a> whose <a>fullscreen flag</a> is set, if any, and null otherwise.
7475

76+
<p>All <a for=/>documents</a> have an associated <dfn>list of pending fullscreen events</dfn>, which
77+
is an <a>ordered set</a> of (<a>string</a>, <a>element</a>) <a>pairs</a>. It is initially empty.
78+
7579
<p>To <dfn>fullscreen an <var>element</var></dfn>, set <var>element</var>'s <a>fullscreen flag</a>
7680
and <a for="top layer">add</a> it to its <a>node document</a>'s <a>top layer</a>.
7781

@@ -135,16 +139,25 @@ security risk, or platform limitation.
135139

136140
<hr>
137141

138-
<p>To <dfn>fire a fullscreen event</dfn> named <var>e</var> for an (<var>element</var>,
139-
<var>document</var>) <a>pair</a>, run these steps:
142+
<p>To <dfn>run the fullscreen rendering steps</dfn> for a <a>document</a> <var>document</var>, run
143+
these steps:
140144

141145
<ol>
142-
<li><p>Let <var>target</var> be <var>element</var> if <var>element</var> is <a>connected</a>
143-
and its <a>node document</a> is <var>document</var>, and otherwise let <var>target</var> be
144-
<var>document</var>.
146+
<li><p>Let <var>pairs</var> be <var>document</var>'s <a>list of pending fullscreen events</a>.
147+
148+
<li><p><a for=set>Empty</a> <var>document</var>'s <a>list of pending fullscreen events</a>.
145149

146-
<li><p><a>Fire an event</a> named <var>e</var>, with its {{Event/bubbles}} and {{Event/composed}}
147-
attributes set to true, at <var>target</var>.
150+
<li>
151+
<p><a>For each</a> (<var>type</var>, <var>element</var>) in <var>pairs</var>:
152+
153+
<ol>
154+
<li><p>Let <var>target</var> be <var>element</var> if <var>element</var> is <a>connected</a>
155+
and its <a>node document</a> is <var>document</var>, and otherwise let <var>target</var> be
156+
<var>document</var>.
157+
158+
<li><p><a>Fire an event</a> named <var>type</var>, with its {{Event/bubbles}} and
159+
{{Event/composed}} attributes set to true, at <var>target</var>.
160+
</ol>
148161
</ol>
149162

150163

@@ -247,68 +260,65 @@ these steps:
247260
<!-- cross-process -->
248261

249262
<li>
250-
<p>As part of the next <a>animation frame task</a>, run these substeps:
251-
252-
<ol>
253-
<li>
254-
<p>If any of the following conditions are false, then set <var>error</var> to true:
255-
256-
<ul>
257-
<li><p><var>pending</var>'s <a>node document</a> is <var>pendingDoc</var>.
263+
<p>If any of the following conditions are false, then set <var>error</var> to true:
258264

259-
<li><p>The <a>fullscreen element ready check</a> for <var>pending</var> returns true.
260-
<!-- cross-process; check is only needed on pending as it is recursive already -->
261-
</ul>
265+
<ul>
266+
<li><p><var>pending</var>'s <a>node document</a> is <var>pendingDoc</var>.
262267

263-
<li><p>If <var>error</var> is true, <a>fire a fullscreen event</a> named
264-
<code>fullscreenerror</code> for (<var>pending</var>, <var>pendingDoc</var>), reject
265-
<var>promise</var> with a <code>TypeError</code> exception, and terminate these steps.
268+
<li><p>The <a>fullscreen element ready check</a> for <var>pending</var> returns true.
269+
<!-- cross-process; check is only needed on pending as it is recursive already -->
270+
</ul>
266271

267-
<li><p>Let <var>fullscreenElements</var> be an <a>ordered set</a> initially consisting of
268-
<var>pending</var>.
272+
<li>
273+
<p>If <var>error</var> is true:
269274

270-
<li><p><a>While</a> the first element in <var>fullscreenElements</var> is in a
271-
<a>nested browsing context</a>: <a for=set>prepend</a> its <a>browsing context container</a> to
272-
<var>fullscreenElements</var>.
273-
<!-- cross-process -->
275+
<ol>
276+
<li><p><a for=set>Append</a> (<code>fullscreenerror</code>, <var>pending</var>) to
277+
<var>pendingDoc</var>'s <a>list of pending fullscreen events</a>.
274278

275-
<li><p>Let <var>eventPairs</var> be a new <a>ordered set</a>.
279+
<li><p>Reject <var>promise</var> with a <code>TypeError</code> exception and terminate these
280+
steps.
281+
</ol>
276282

277-
<li>
278-
<p><a>For each</a> <var>element</var> in <var>fullscreenElements</var>:
283+
<li><p>Let <var>fullscreenElements</var> be an <a>ordered set</a> initially consisting of
284+
<var>pending</var>.
279285

280-
<ol>
281-
<li><p>Let <var>doc</var> be <var>element</var>'s <a>node document</a>.
286+
<li><p><a>While</a> the first element in <var>fullscreenElements</var> is in a
287+
<a>nested browsing context</a>: <a for=set>append</a> its <a>browsing context container</a> to
288+
<var>fullscreenElements</var>.
289+
<!-- cross-process -->
282290

283-
<li>
284-
<p>If <var>element</var> is <var>doc</var>'s <a>fullscreen element</a>, <a>continue</a>.
291+
<li>
292+
<p><a>For each</a> <var>element</var> in <var>fullscreenElements</var>:
285293

286-
<p class=note>No need to notify observers when nothing has changed.
294+
<ol>
295+
<li><p>Let <var>doc</var> be <var>element</var>'s <a>node document</a>.
287296

288-
<li><p>Otherwise, <a for=set>append</a> (<var>element</var>, <var>doc</var>) to
289-
<var>eventPairs</var>.
297+
<li>
298+
<p>If <var>element</var> is <var>doc</var>'s <a>fullscreen element</a>, <a>continue</a>.
290299

291-
<li><p>If <var>element</var> is <var>pending</var> and <var>pending</var> is an <{iframe}>
292-
<a>element</a>, then set <var>element</var>'s <a>iframe fullscreen flag</a>.
300+
<p class=note>No need to notify observers when nothing has changed.
293301

294-
<li><p><a lt="fullscreen an element">Fullscreen <var>element</var></a> within <var>doc</var>.
295-
</ol>
302+
<li><p>If <var>element</var> is <var>pending</var> and <var>pending</var> is an <{iframe}>
303+
<a>element</a>, then set <var>element</var>'s <a>iframe fullscreen flag</a>.
296304

297-
<li><p><a>For each</a> (<var>element</var>, <var>document</var>) in <var>eventPairs</var>:
298-
<a>fire a fullscreen event</a> named <code>fullscreenchange</code> for (<var>element</var>,
299-
<var>document</var>).
300-
</ol>
305+
<li><p><a lt="fullscreen an element">Fullscreen <var>element</var></a> within <var>doc</var>.
301306

302-
<li><p>Resolve <var>promise</var> with undefined.
307+
<li><p><a for=set>Append</a> (<code>fullscreenchange</code>, <var>element</var>) to
308+
<var>doc</var>'s <a>list of pending fullscreen events</a>.
303309
</ol>
304310

305-
<p class=XXX><dfn>Animation frame task</dfn> is not really defined yet, including relative order
306-
within that task, see <a href=https://www.w3.org/Bugs/Public/show_bug.cgi?id=26440>bug 26440</a>.
311+
<p class=note>The order in which elements are <a lt="fullscreen an element">fullscreened</a>
312+
is not observable, because the
313+
<a lt="run the fullscreen rendering steps">fullscreen rendering steps</a> will run in
314+
<a>tree order</a>.
307315

308-
<p class=note>Implementations with out-of-process <a for=/>browsing contexts</a> are left as an
309-
exercise to the reader. Input welcome on potential improvements.
316+
<li><p>Resolve <var>promise</var> with undefined.
310317
</ol>
311318

319+
<p class=note>Implementations with out-of-process <a for=/>browsing contexts</a> are left as an
320+
exercise to the reader. Input welcome on potential improvements.
321+
312322
<p>The <dfn attribute for=Document><code>fullscreenEnabled</code></dfn> attribute's getter must
313323
return true if the <a>context object</a> is <a>allowed to use</a> the feature indicated by attribute
314324
name <code>allowfullscreen</code> and <a>fullscreen is supported</a>, and false otherwise.
@@ -394,66 +404,57 @@ could be an open <{dialog}> element.
394404
<!-- cross-process -->
395405

396406
<li><p>If <var>topLevelDoc</var> is in <var>docs</var>, and it is a
397-
<a>simple fullscreen document</a>, then set <var>resize</var> to true.
407+
<a>simple fullscreen document</a>, then set <var>doc</var> to <var>topLevelDoc</var> and
408+
<var>resize</var> to true.
398409

399410
<li><p>Return <var>promise</var>, and run the remaining steps <a>in parallel</a>.
400411

401-
<li><p>If <var>resize</var> is true, resize <var>topLevelDoc</var>'s viewport to its "normal"
402-
dimensions.
412+
<li><p>If <var>resize</var> is true, resize <var>doc</var>'s viewport to its "normal" dimensions.
403413

404-
<li>
405-
<p>As part of the next <a>animation frame task</a>, run these substeps:
414+
<li><p>If <var>doc</var>'s <a>fullscreen element</a> is null, then resolve <var>promise</var> with
415+
undefined and terminate these steps.
406416

407-
<ol>
408-
<li><p>If <var>doc</var>'s <a>fullscreen element</a> is null, then resolve <var>promise</var>
409-
with undefined and terminate these steps.
410-
411-
<li><p>Let <var>exitDocs</var> be the result of
412-
<a lt="collect documents to unfullscreen">collecting documents to unfullscreen</a> given
413-
<var>doc</var>.
414-
<!-- cross-process -->
415-
416-
<li><p>If <var>resize</var> is true and <var>topLevelDoc</var> is either not in
417-
<var>exitDocs</var>, or not a <a>simple fullscreen document</a>,
418-
<a>fully exit fullscreen</a> <var>topLevelDoc</var>, reject <var>promise</var> with a
419-
<code>TypeError</code> exception, and terminate these steps.
420-
<!-- cross-process -->
421-
422-
<li><p>Let <var>eventPairs</var> be a new <a>ordered set</a>.
423-
424-
<li><p>Let <var>descendantDocs</var> be an <a>ordered set</a> consisting of <var>doc</var>'s
425-
<a>descendant browsing contexts</a>' <a>active documents</a> whose <a>fullscreen element</a> is
426-
non-null, if any, in <em>reverse</em> <a>tree order</a>.
427-
<!-- cross-process -->
417+
<li><p>Let <var>exitDocs</var> be the result of
418+
<a lt="collect documents to unfullscreen">collecting documents to unfullscreen</a> given
419+
<var>doc</var>.
420+
<!-- cross-process -->
428421

429-
<li>
430-
<p><a>For each</a> <var>descendantDoc</var> in <var>descendantDocs</var>:
422+
<li><p>Let <var>descendantDocs</var> be an <a>ordered set</a> consisting of <var>doc</var>'s
423+
<a>descendant browsing contexts</a>' <a>active documents</a> whose <a>fullscreen element</a> is
424+
non-null, if any, in <a>tree order</a>.
425+
<!-- cross-process -->
431426

432-
<ol>
433-
<li><p><a for=set>Append</a> (<var>descendantDoc</var>'s <a>fullscreen element</a>,
434-
<var>descendantDoc</var>) to <var>eventPairs</var>.
427+
<li>
428+
<p><a>For each</a> <var>exitDoc</var> in <var>exitDocs</var>:
435429

436-
<li><p><a lt="unfullscreen a document">Unfullscreen <var>descendantDoc</var></a>.
437-
</ol>
430+
<ol>
431+
<li><p><a for=set>Append</a> (<code>fullscreenchange</code>, <var>exitDoc</var>'s
432+
<a>fullscreen element</a>) to <var>exitDoc</var>'s <a>list of pending fullscreen events</a>.
438433

439-
<li>
440-
<p><a>For each</a> <var>exitDoc</var> in <var>exitDocs</var>:
434+
<li><p>If <var>resize</var> is true, <a lt="unfullscreen a document">unfullscreen
435+
<var>exitDoc</var></a>.
441436

442-
<ol>
443-
<li><p><a for=set>Append</a> (<var>exitDoc</var>'s <a>fullscreen element</a>,
444-
<var>exitDoc</var>) to <var>eventPairs</var>.
437+
<li><p>Otherwise, <a lt="unfullscreen an element">unfullscreen</a> <var>exitDoc</var>'s
438+
<a>fullscreen element</a>.
439+
</ol>
445440

446-
<li><p><a lt="unfullscreen an element">Unfullscreen</a> <var>exitDoc</var>'s <a>fullscreen element</a>.
447-
</ol>
441+
<li>
442+
<p><a>For each</a> <var>descendantDoc</var> in <var>descendantDocs</var>:
448443

449-
<li><p><a>For each</a> (<var>element</var>, <var>document</var>) in <var>eventPairs</var>:
450-
<a>fire a fullscreen event</a> named <code>fullscreenchange</code> for (<var>element</var>,
451-
<var>document</var>).
444+
<ol>
445+
<li><p><a for=set>Append</a> (<code>fullscreenchange</code>, <var>descendantDoc</var>'s
446+
<a>fullscreen element</a>) to <var>descendantDoc</var>'s
447+
<a>list of pending fullscreen events</a>.
452448

453-
<li><p>Resolve <var>promise</var> with undefined.
449+
<li><p><a lt="unfullscreen a document">Unfullscreen <var>descendantDoc</var></a>.
454450
</ol>
455451

456-
<p class=note>This results in events being fired from the innermost to the outermost document.
452+
<p class=note>The order in which documents are <a lt="unfullscreen a document">unfullscreened</a>
453+
is not observable, because the
454+
<a lt="run the fullscreen rendering steps">fullscreen rendering steps</a> will run in
455+
<a>tree order</a>.
456+
457+
<li><p>Resolve <var>promise</var> with undefined.
457458
</ol>
458459

459460
<p>The <dfn method for=Document><code>exitFullscreen()</code></dfn> method, when invoked, must

0 commit comments

Comments
 (0)