tor-browser

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

file_fullscreen-utils.js (3393B)


      1 // Keep track of how many fullscreenChange enters we've received, so that
      2 // we can balance them with the number of exits we receive. We reset this
      3 // to 0 when we load a test.
      4 var fullscreenChangeEnters = 0;
      5 
      6 addLoadEvent(function () {
      7  info(`Resetting fullscreen enter count.`);
      8  fullscreenChangeEnters = 0;
      9 });
     10 
     11 // This can be used to force a certain value for fullscreenChangeEnters
     12 // to handle unusual conditions -- such as exiting multiple levels of
     13 // fullscreen forcibly.
     14 function setFullscreenChangeEnters(enters) {
     15  info(`Setting fullscreen enter count to ${enters}.`);
     16  fullscreenChangeEnters = enters;
     17 }
     18 
     19 // Returns true if the window believes it is in fullscreen. This may be true even
     20 // before an asynchronous fullscreen transition is complete.
     21 function inFullscreenMode(win) {
     22  return win.document.fullscreenElement;
     23 }
     24 
     25 // Adds a listener that will be called once a fullscreen transition
     26 // is complete. When type==='enter', callback is called when we've
     27 // received a fullscreenchange event, and the fullscreen transition is
     28 // complete. When type==='exit', callback is called when we've
     29 // received a fullscreenchange event and the window is out of
     30 // fullscreen. inDoc is the document which the listeners are added on,
     31 // if absent, the listeners are added to the current document.
     32 // the current document.
     33 function addFullscreenChangeContinuation(type, callback, inDoc) {
     34  var doc = inDoc || document;
     35  var topWin = doc.defaultView.top;
     36  function checkCondition() {
     37    if (type == "enter") {
     38      fullscreenChangeEnters++;
     39      return inFullscreenMode(topWin);
     40    } else if (type == "exit") {
     41      fullscreenChangeEnters--;
     42      return fullscreenChangeEnters
     43        ? inFullscreenMode(topWin)
     44        : !inFullscreenMode(topWin);
     45    }
     46    throw new Error("'type' must be either 'enter', or 'exit'.");
     47  }
     48  function onFullscreenChange(event) {
     49    doc.removeEventListener("fullscreenchange", onFullscreenChange);
     50    ok(checkCondition(), `Should ${type} fullscreen.`);
     51    // Delay invocation so other listeners have a chance to respond before
     52    // we continue.
     53    requestAnimationFrame(() => setTimeout(() => callback(event), 0), 0);
     54  }
     55  doc.addEventListener("fullscreenchange", onFullscreenChange);
     56 }
     57 
     58 // Calls |callback| when the next fullscreenerror is dispatched to inDoc||document.
     59 function addFullscreenErrorContinuation(callback, inDoc) {
     60  let doc = inDoc || document;
     61  let listener = function (event) {
     62    doc.removeEventListener("fullscreenerror", listener);
     63    // Delay invocation so other listeners have a chance to respond before
     64    // we continue.
     65    requestAnimationFrame(() => setTimeout(() => callback(event), 0), 0);
     66  };
     67  doc.addEventListener("fullscreenerror", listener);
     68 }
     69 
     70 // Waits until the window has both the load event and a MozAfterPaint called on
     71 // it, and then invokes the callback
     72 function waitForLoadAndPaint(win, callback) {
     73  win.addEventListener(
     74    "MozAfterPaint",
     75    function () {
     76      // The load event may have fired before the MozAfterPaint, in which case
     77      // listening for it now will hang. Instead we check the readyState to see if
     78      // it already fired, and if so, invoke the callback right away.
     79      if (win.document.readyState == "complete") {
     80        callback();
     81      } else {
     82        win.addEventListener("load", callback, { once: true });
     83      }
     84    },
     85    { once: true }
     86  );
     87 }