tor-browser

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

browser_pointerlock_popup.js (4698B)


      1 /**
      2 * Any copyright is dedicated to the Public Domain.
      3 * http://creativecommons.org/publicdomain/zero/1.0/
      4 */
      5 
      6 "use strict";
      7 
      8 const TEST_URL =
      9  "data:text/html,<body><div style='width: 100px; height: 100px; background-color: red;'></div></body>";
     10 
     11 function waitForEventRemote(aRemote, aEvent) {
     12  info(`Wait for ${aEvent} event`);
     13  return SpecialPowers.spawn(aRemote, [aEvent], function (aEvent) {
     14    return new Promise(resolve => {
     15      content.document.addEventListener(
     16        aEvent,
     17        _e => {
     18          info(`Received ${aEvent} event`);
     19          resolve();
     20        },
     21        { once: true }
     22      );
     23    });
     24  });
     25 }
     26 
     27 function executeSoonRemote(aRemote) {
     28  return SpecialPowers.spawn(aRemote, [], function () {
     29    return new Promise(resolve => {
     30      SpecialPowers.executeSoon(resolve);
     31    });
     32  });
     33 }
     34 
     35 function requestPointerLockRemote(aRemote) {
     36  info(`Request pointerlock`);
     37  return SpecialPowers.spawn(aRemote, [], function () {
     38    SpecialPowers.wrap(content.document).notifyUserGestureActivation();
     39    content.document.body.requestPointerLock();
     40  });
     41 }
     42 
     43 function exitPointerLockRemote(aRemote) {
     44  info(`Exit pointerlock`);
     45  return SpecialPowers.spawn(aRemote, [], function () {
     46    return new Promise(resolve => {
     47      if (!content.document.pointerLockElement) {
     48        resolve();
     49        return;
     50      }
     51 
     52      content.document.addEventListener(
     53        "pointerlockchange",
     54        _e => {
     55          info(`Received pointerlockchange event`);
     56          resolve();
     57        },
     58        { once: true }
     59      );
     60      content.document.exitPointerLock();
     61    });
     62  });
     63 }
     64 
     65 function isPointerLockedRemote(aRemote) {
     66  return SpecialPowers.spawn(aRemote, [], function () {
     67    return !!content.document.pointerLockElement;
     68  });
     69 }
     70 
     71 function getPopup(aDocument, aPopupType) {
     72  let popup = aDocument.getElementById(aPopupType);
     73  if (!popup) {
     74    let menuitem = aDocument.createXULElement("menuitem");
     75    menuitem.label = "This is a test popup";
     76 
     77    popup = aDocument.createXULElement(aPopupType);
     78    popup.id = aPopupType;
     79    popup.appendChild(menuitem);
     80    aDocument.documentElement.appendChild(popup);
     81  }
     82  return popup;
     83 }
     84 
     85 async function waitForPopupOpen(aDocument, aPopupType) {
     86  let popup = getPopup(aDocument, aPopupType);
     87  let promise = BrowserTestUtils.waitForPopupEvent(popup, "shown");
     88  popup.openPopup();
     89  await promise;
     90 
     91  return popup;
     92 }
     93 
     94 async function waitForPopupHide(aPopup) {
     95  let promise = BrowserTestUtils.waitForPopupEvent(aPopup, "hidden");
     96  aPopup.hidePopup(true);
     97  await promise;
     98 }
     99 
    100 function testPointerLockPopup(aPopupType, aShouldBlockPointerLock) {
    101  add_task(async function test_open_menu_popup_when_pointer_is_locked() {
    102    info(`Test ${aPopupType}`);
    103    await BrowserTestUtils.withNewTab(TEST_URL, async browser => {
    104      let promise = waitForEventRemote(browser, "pointerlockchange");
    105      await requestPointerLockRemote(browser);
    106      await promise;
    107      ok(await isPointerLockedRemote(browser), "pointer should be locked");
    108 
    109      if (aShouldBlockPointerLock) {
    110        promise = waitForEventRemote(browser, "pointerlockchange");
    111        // Wait for the event listener to get registered on the remote.
    112        await executeSoonRemote(browser);
    113      }
    114 
    115      info(`Open popup`);
    116      let popup = await waitForPopupOpen(document, aPopupType);
    117 
    118      if (!aShouldBlockPointerLock) {
    119        promise = executeSoonRemote(browser);
    120      }
    121 
    122      await promise;
    123      is(
    124        await isPointerLockedRemote(browser),
    125        !aShouldBlockPointerLock,
    126        "check if pointer is still locked"
    127      );
    128 
    129      await exitPointerLockRemote(browser);
    130 
    131      info(`Hide popup`);
    132      await waitForPopupHide(popup);
    133    });
    134  });
    135 
    136  add_task(async function test_request_pointerlock_when_popup_is_opened() {
    137    info(`Test ${aPopupType}`);
    138    await BrowserTestUtils.withNewTab(TEST_URL, async browser => {
    139      info(`Open popup`);
    140      let popup = await waitForPopupOpen(document, aPopupType);
    141 
    142      let promise = aShouldBlockPointerLock
    143        ? waitForEventRemote(browser, "pointerlockerror")
    144        : waitForEventRemote(browser, "pointerlockchange");
    145      // Wait for the event listener to get registered on the remote.
    146      await executeSoonRemote(browser);
    147      await requestPointerLockRemote(browser);
    148      await promise;
    149      is(
    150        await isPointerLockedRemote(browser),
    151        !aShouldBlockPointerLock,
    152        "check if pointer is still locked"
    153      );
    154 
    155      await exitPointerLockRemote(browser);
    156 
    157      info(`Hide popup`);
    158      await waitForPopupHide(popup);
    159    });
    160  });
    161 }
    162 
    163 testPointerLockPopup("menupopup", true);
    164 testPointerLockPopup("panel", true);
    165 testPointerLockPopup("tooltip", false);