From f86c078a173ea171ca5aa753e730a083d7588ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20J=C3=A4genstedt?= Date: Wed, 31 May 2017 10:57:39 +0200 Subject: [PATCH] Fullscreen/unfullscreen ASAP; fire events in animation frame tasks 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 https://github.com/whatwg/fullscreen/issues/74. --- fullscreen.bs | 164 +++++++++++++++++++++++--------------------------- 1 file changed, 76 insertions(+), 88 deletions(-) diff --git a/fullscreen.bs b/fullscreen.bs index 331b90e..2fa652f 100644 --- a/fullscreen.bs +++ b/fullscreen.bs @@ -247,68 +247,65 @@ these steps:
  • -

    As part of the next animation frame task, run these substeps: - -

      -
    1. -

      If any of the following conditions are false, then set error to true: - -

      + -
    2. Let fullscreenElements be an ordered set initially consisting of - pending. +

    3. +

      If error is true: -

    4. While the first element in fullscreenElements is in a - nested browsing context: prepend its browsing context container to - fullscreenElements. - +

        +
      1. Queue an animation frame task for pendingDoc to + fire a fullscreen event named fullscreenerror for (pending, + pendingDoc). -

      2. Let eventPairs be a new ordered set. +

      3. Reject promise with a TypeError exception and terminate these + steps. +

      -
    5. -

      For each element in fullscreenElements: +

    6. Let fullscreenElements be an ordered set initially consisting of + pending. -

        -
      1. Let doc be element's node document. +

      2. While the first element in fullscreenElements is in a + nested browsing context: append its browsing context container to + fullscreenElements. + -

      3. -

        If element is doc's fullscreen element, continue. +

      4. +

        For each element in fullscreenElements: -

        No need to notify observers when nothing has changed. +

          +
        1. Let doc be element's node document. -

        2. Otherwise, append (element, doc) to - eventPairs. +

        3. +

          If element is doc's fullscreen element, continue. -

        4. If element is pending and pending is an <{iframe}> - element, then set element's iframe fullscreen flag. +

          No need to notify observers when nothing has changed. -

        5. Fullscreen element within doc. -

        +
      5. If element is pending and pending is an <{iframe}> + element, then set element's iframe fullscreen flag. -

      6. For each (element, document) in eventPairs: - fire a fullscreen event named fullscreenchange for (element, - document). -

      +
    7. Fullscreen element within doc. -

    8. Resolve promise with undefined. +

    9. Queue an animation frame task for doc to fire a fullscreen event + named fullscreenchange for (element, document).

    -

    Animation frame task is not really defined yet, including relative order - within that task, see bug 26440. +

    The order in which elements are fullscreened + and animation frame tasks are queued is not observable, because the animation frame tasks will run + in tree order. -

    Implementations with out-of-process browsing contexts are left as an - exercise to the reader. Input welcome on potential improvements. +

  • Resolve promise with undefined. +

    Implementations with out-of-process browsing contexts are left as an +exercise to the reader. Input welcome on potential improvements. +

    The fullscreenEnabled attribute's getter must return true if the context object is allowed to use the feature indicated by attribute name allowfullscreen and fullscreen is supported, and false otherwise. @@ -394,66 +391,57 @@ could be an open <{dialog}> element.

  • If topLevelDoc is in docs, and it is a - simple fullscreen document, then set resize to true. + simple fullscreen document, then set doc to topLevelDoc and + resize to true.

  • Return promise, and run the remaining steps in parallel. -

  • If resize is true, resize topLevelDoc's viewport to its "normal" - dimensions. +

  • If resize is true, resize doc's viewport to its "normal" dimensions. -

  • -

    As part of the next animation frame task, run these substeps: - -

      -
    1. If doc's fullscreen element is null, then resolve promise - with undefined and terminate these steps. - -

    2. Let exitDocs be the result of - collecting documents to unfullscreen given - doc. - - -

    3. If resize is true and topLevelDoc is either not in - exitDocs, or not a simple fullscreen document, - fully exit fullscreen topLevelDoc, reject promise with a - TypeError exception, and terminate these steps. - +

    4. If doc's fullscreen element is null, then resolve promise with + undefined and terminate these steps. -

    5. Let eventPairs be a new ordered set. - -

    6. Let descendantDocs be an ordered set consisting of doc's - descendant browsing contexts' active documents whose fullscreen element is - non-null, if any, in reverse tree order. - +

    7. Let exitDocs be the result of + collecting documents to unfullscreen given + doc. + -

    8. -

      For each descendantDoc in descendantDocs: +

    9. Let descendantDocs be an ordered set consisting of doc's + descendant browsing contexts' active documents whose fullscreen element is + non-null, if any, in tree order. + -

        -
      1. Append (descendantDoc's fullscreen element, - descendantDoc) to eventPairs. +

      2. +

        For each exitDoc in exitDocs: -

      3. Unfullscreen descendantDoc. -

      +
        +
      1. Queue an animation frame task for exitDoc to + fire a fullscreen event named fullscreenchange for + (exitDoc's fullscreen element, exitDoc). -

      2. -

        For each exitDoc in exitDocs: +

      3. If resize is true, unfullscreen + exitDoc. -

          -
        1. Append (exitDoc's fullscreen element, - exitDoc) to eventPairs. +

        2. Otherwise, unfullscreen exitDoc's + fullscreen element. +

        -
      4. Unfullscreen exitDoc's fullscreen element. -

      +
    10. +

      For each descendantDoc in descendantDocs: -

    11. For each (element, document) in eventPairs: - fire a fullscreen event named fullscreenchange for (element, - document). +

        +
      1. Queue an animation frame task for descendantDoc to + fire a fullscreen event named fullscreenchange for + (descendantDoc's fullscreen element, descendantDoc). -

      2. Resolve promise with undefined. +

      3. Unfullscreen descendantDoc.

      -

      This results in events being fired from the innermost to the outermost document. +

      The order in which documents are unfullscreened + and animation frame tasks are queued is not observable, because the animation frame tasks will run + in tree order. + +

    12. Resolve promise with undefined.

    The exitFullscreen() method, when invoked, must