tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

fullscreen_helpers.js (6172B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const TEST_URLS = [
      7  // all frames are in different process.
      8  `data:text/html,
      9    <div name="div" id="div" style="width: 100px; height: 100px; background: red;">
     10    <iframe id="iframe" allowfullscreen="yes"
     11     src="https://example.com/browser/dom/base/test/fullscreen/file_fullscreen-iframe-middle.html"></iframe>
     12    </div>`,
     13  // toplevel and inner most iframe are in same process, and middle iframe is
     14  // in a different process.
     15  `https://example.org/browser/dom/base/test/fullscreen/file_fullscreen-iframe-top.html`,
     16  // toplevel and middle iframe are in same process, and inner most iframe is
     17  // in a different process.
     18  `https://example.com/browser/dom/base/test/fullscreen/file_fullscreen-iframe-top.html`,
     19 ];
     20 
     21 function waitRemoteFullscreenEnterEvents(aBrowsingContexts) {
     22  let promises = [];
     23  aBrowsingContexts.forEach(([aBrowsingContext, aName]) => {
     24    promises.push(
     25      SpecialPowers.spawn(aBrowsingContext, [aName], async name => {
     26        return new Promise(resolve => {
     27          let document = content.document;
     28          document.addEventListener(
     29            "fullscreenchange",
     30            function changeHandler() {
     31              info(`received fullscreenchange event on ${name}`);
     32              ok(
     33                !!document.fullscreenElement,
     34                `check remote DOM fullscreen event`
     35              );
     36              document.removeEventListener("fullscreenchange", changeHandler);
     37              resolve();
     38            }
     39          );
     40        });
     41      })
     42    );
     43  });
     44  return Promise.all(promises);
     45 }
     46 
     47 function waitRemoteFullscreenExitEvents(aBrowsingContexts) {
     48  let promises = [];
     49  aBrowsingContexts.forEach(([aBrowsingContext, aName]) => {
     50    promises.push(
     51      SpecialPowers.spawn(aBrowsingContext, [aName], async name => {
     52        return new Promise(resolve => {
     53          let document = content.document;
     54          document.addEventListener(
     55            "fullscreenchange",
     56            function changeHandler() {
     57              if (document.fullscreenElement) {
     58                return;
     59              }
     60 
     61              info(`received fullscreenchange event on ${name}`);
     62              ok(true, `check remote DOM fullscreen event (${name})`);
     63              document.removeEventListener("fullscreenchange", changeHandler);
     64              resolve();
     65            }
     66          );
     67        });
     68      })
     69    );
     70  });
     71  return Promise.all(promises);
     72 }
     73 
     74 function waitDOMFullscreenEvent(
     75  aDocument,
     76  aIsInFullscreen,
     77  aWaitUntil = false
     78 ) {
     79  return new Promise(resolve => {
     80    function errorHandler() {
     81      ok(false, "should not get fullscreenerror event");
     82      aDocument.removeEventListener("fullscreenchange", changeHandler);
     83      aDocument.removeEventListener("fullscreenerror", errorHandler);
     84      resolve();
     85    }
     86 
     87    function changeHandler() {
     88      if (aWaitUntil && aIsInFullscreen != !!aDocument.fullscreenElement) {
     89        return;
     90      }
     91 
     92      is(
     93        aIsInFullscreen,
     94        !!aDocument.fullscreenElement,
     95        "check DOM fullscreen (event)"
     96      );
     97      aDocument.removeEventListener("fullscreenchange", changeHandler);
     98      aDocument.removeEventListener("fullscreenerror", errorHandler);
     99      resolve();
    100    }
    101 
    102    aDocument.addEventListener("fullscreenchange", changeHandler);
    103    aDocument.addEventListener("fullscreenerror", errorHandler);
    104  });
    105 }
    106 
    107 function waitWidgetFullscreenEvent(
    108  aWindow,
    109  aIsInFullscreen,
    110  aWaitUntil = false
    111 ) {
    112  return BrowserTestUtils.waitForEvent(aWindow, "fullscreen", false, () => {
    113    if (
    114      aWaitUntil &&
    115      aIsInFullscreen !=
    116        aWindow.document.documentElement.hasAttribute("inFullscreen")
    117    ) {
    118      return false;
    119    }
    120 
    121    is(
    122      aIsInFullscreen,
    123      aWindow.document.documentElement.hasAttribute("inFullscreen"),
    124      "check widget fullscreen (event)"
    125    );
    126    return true;
    127  });
    128 }
    129 
    130 function waitForFullScreenObserver(
    131  aDocument,
    132  aIsInFullscreen,
    133  aWaitUntil = false
    134 ) {
    135  return TestUtils.topicObserved("fullscreen-painted", () => {
    136    if (
    137      aWaitUntil &&
    138      aIsInFullscreen !=
    139        aDocument.documentElement.hasAttribute("inDOMFullscreen")
    140    ) {
    141      return false;
    142    }
    143 
    144    is(
    145      aIsInFullscreen,
    146      aDocument.documentElement.hasAttribute("inDOMFullscreen"),
    147      "check fullscreen (observer)"
    148    );
    149    return true;
    150  });
    151 }
    152 
    153 function waitForFullscreenState(
    154  aDocument,
    155  aIsInFullscreen,
    156  aWaitUntil = false
    157 ) {
    158  return Promise.all([
    159    waitWidgetFullscreenEvent(
    160      aDocument.defaultView,
    161      aIsInFullscreen,
    162      aWaitUntil
    163    ),
    164    waitDOMFullscreenEvent(aDocument, aIsInFullscreen, aWaitUntil),
    165    waitForFullScreenObserver(aDocument, aIsInFullscreen, aWaitUntil),
    166  ]);
    167 }
    168 
    169 // Wait for fullscreenchange event for fullscreen exit. And wait for
    170 // fullscreen-painted observed conditionally.
    171 async function waitForFullscreenExit(aDocument) {
    172  info(`waitForFullscreenExit`);
    173  let promiseFsObserver = null;
    174  let observer = function () {
    175    if (aDocument.documentElement.hasAttribute("inDOMFullscreen")) {
    176      info(`waitForFullscreenExit, fullscreen-painted, inDOMFullscreen`);
    177      Services.obs.removeObserver(observer, "fullscreen-painted");
    178      promiseFsObserver = waitForFullScreenObserver(aDocument, false);
    179    }
    180  };
    181  Services.obs.addObserver(observer, "fullscreen-painted");
    182 
    183  await waitDOMFullscreenEvent(aDocument, false, true);
    184  // If there is a fullscreen-painted observer notified for inDOMFullscreen set,
    185  // we expect to have a subsequent fullscreen-painted observer notified with
    186  // inDOMFullscreen unset.
    187  if (promiseFsObserver) {
    188    info(`waitForFullscreenExit, promiseFsObserver`);
    189    await promiseFsObserver;
    190    return;
    191  }
    192 
    193  Services.obs.removeObserver(observer, "fullscreen-painted");
    194  // If inDOMFullscreen is set we expect to have a subsequent fullscreen-painted
    195  // observer notified with inDOMFullscreen unset.
    196  if (aDocument.documentElement.hasAttribute("inDOMFullscreen")) {
    197    info(`waitForFullscreenExit, inDOMFullscreen`);
    198    await waitForFullScreenObserver(aDocument, false, true);
    199  }
    200 }