tor-browser

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

head.js (5105B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 ChromeUtils.defineESModuleGetters(this, {
      5  EnterprisePolicyTesting:
      6    "resource://testing-common/EnterprisePolicyTesting.sys.mjs",
      7  ExtensionCommon: "resource://gre/modules/ExtensionCommon.sys.mjs",
      8  PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
      9  TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs",
     10  sinon: "resource://testing-common/Sinon.sys.mjs",
     11 });
     12 
     13 async function promisePageActionPanelOpen(win = window, eventDict = {}) {
     14  await BrowserTestUtils.waitForCondition(() => {
     15    // Wait for the main page action button to become visible.  It's hidden for
     16    // some URIs, so depending on when this is called, it may not yet be quite
     17    // visible.  It's up to the caller to make sure it will be visible.
     18    info("Waiting for main page action button to have non-0 size");
     19    let bounds = win.windowUtils.getBoundsWithoutFlushing(
     20      win.BrowserPageActions.mainButtonNode
     21    );
     22    return bounds.width > 0 && bounds.height > 0;
     23  });
     24 
     25  // Wait for the panel to become open, by clicking the button if necessary.
     26  info("Waiting for main page action panel to be open");
     27  if (win.BrowserPageActions.panelNode.state == "open") {
     28    return;
     29  }
     30  let shownPromise = promisePageActionPanelShown(win);
     31  EventUtils.synthesizeMouseAtCenter(
     32    win.BrowserPageActions.mainButtonNode,
     33    eventDict,
     34    win
     35  );
     36  await shownPromise;
     37  info("Wait for items in the panel to become visible.");
     38  await promisePageActionViewChildrenVisible(
     39    win.BrowserPageActions.mainViewNode,
     40    win
     41  );
     42 }
     43 
     44 function promisePageActionPanelShown(win = window) {
     45  return promisePanelShown(win.BrowserPageActions.panelNode, win);
     46 }
     47 
     48 function promisePageActionPanelHidden(win = window) {
     49  return promisePanelHidden(win.BrowserPageActions.panelNode, win);
     50 }
     51 
     52 function promisePanelShown(panelIDOrNode, win = window) {
     53  return promisePanelEvent(panelIDOrNode, "popupshown", win);
     54 }
     55 
     56 function promisePanelHidden(panelIDOrNode, win = window) {
     57  return promisePanelEvent(panelIDOrNode, "popuphidden", win);
     58 }
     59 
     60 function promisePanelEvent(panelIDOrNode, eventType, win = window) {
     61  return new Promise(resolve => {
     62    let panel = panelIDOrNode;
     63    if (typeof panel == "string") {
     64      panel = win.document.getElementById(panelIDOrNode);
     65      if (!panel) {
     66        throw new Error(`Panel with ID "${panelIDOrNode}" does not exist.`);
     67      }
     68    }
     69    if (
     70      (eventType == "popupshown" && panel.state == "open") ||
     71      (eventType == "popuphidden" && panel.state == "closed")
     72    ) {
     73      executeSoon(() => resolve(panel));
     74      return;
     75    }
     76    panel.addEventListener(
     77      eventType,
     78      () => {
     79        executeSoon(() => resolve(panel));
     80      },
     81      { once: true }
     82    );
     83  });
     84 }
     85 
     86 async function promisePageActionViewChildrenVisible(
     87  panelViewNode,
     88  win = window
     89 ) {
     90  info(
     91    "promisePageActionViewChildrenVisible waiting for a child node to be visible"
     92  );
     93  await new Promise(win.requestAnimationFrame);
     94  let dwu = win.windowUtils;
     95  return TestUtils.waitForCondition(() => {
     96    let bodyNode = panelViewNode.firstElementChild;
     97    for (let childNode of bodyNode.children) {
     98      let bounds = dwu.getBoundsWithoutFlushing(childNode);
     99      if (bounds.width > 0 && bounds.height > 0) {
    100        return true;
    101      }
    102    }
    103    return false;
    104  });
    105 }
    106 
    107 function promiseAddonUninstalled(addonId) {
    108  return new Promise(resolve => {
    109    let listener = {};
    110    listener.onUninstalled = addon => {
    111      if (addon.id == addonId) {
    112        AddonManager.removeAddonListener(listener);
    113        resolve();
    114      }
    115    };
    116    AddonManager.addAddonListener(listener);
    117  });
    118 }
    119 
    120 async function promiseAnimationFrame(win = window) {
    121  await new Promise(resolve => win.requestAnimationFrame(resolve));
    122  await win.promiseDocumentFlushed(() => {});
    123 }
    124 
    125 async function promisePopupNotShown(id, win = window) {
    126  let deferred = Promise.withResolvers();
    127  function listener() {
    128    deferred.reject("Unexpected popupshown");
    129  }
    130  let panel = win.document.getElementById(id);
    131  panel.addEventListener("popupshown", listener);
    132  try {
    133    await Promise.race([
    134      deferred.promise,
    135      new Promise(resolve => {
    136        /* eslint-disable mozilla/no-arbitrary-setTimeout */
    137        win.setTimeout(resolve, 300);
    138      }),
    139    ]);
    140  } finally {
    141    panel.removeEventListener("popupshown", listener);
    142  }
    143 }
    144 
    145 // TODO (Bug 1700780): Why is this necessary? Without this trick the test
    146 // fails intermittently on Ubuntu.
    147 function promiseStableResize(expectedWidth, win = window) {
    148  let deferred = Promise.withResolvers();
    149  let id;
    150  function listener() {
    151    win.clearTimeout(id);
    152    info(`Got resize event: ${win.innerWidth} x ${win.innerHeight}`);
    153    if (win.innerWidth <= expectedWidth) {
    154      id = win.setTimeout(() => {
    155        win.removeEventListener("resize", listener);
    156        deferred.resolve();
    157      }, 100);
    158    }
    159  }
    160  win.addEventListener("resize", listener);
    161  win.resizeTo(expectedWidth, win.outerHeight);
    162  return deferred.promise;
    163 }