tor-browser

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

helper_fission_utils.js (3013B)


      1 /**
      2 * This is similar to the hitTest function in apz_test_utils.js, in that it
      3 * does a hit-test for a point and returns the result. The difference is that
      4 * in the fission world, the hit-test may land on an OOPIF, which means the
      5 * result information will be in the APZ test data for the OOPIF process. This
      6 * function checks both the current process and OOPIF process to see which one
      7 * got a hit result, and returns the result regardless of which process got it.
      8 * The caller is expected to check the layers id which will allow distinguishing
      9 * the two cases.
     10 */
     11 async function hitTestOOPIF(point, iframeElement) {
     12  let getIframeCompositorTestData = async iframe => {
     13    let data = await SpecialPowers.spawn(iframe, [], () => {
     14      let utils = SpecialPowers.getDOMWindowUtils(content.window);
     15      return JSON.stringify(utils.getCompositorAPZTestData());
     16    });
     17 
     18    return JSON.parse(data);
     19  };
     20 
     21  let utils = SpecialPowers.getDOMWindowUtils(window);
     22 
     23  // Get the test data before doing the actual hit-test, to get a baseline
     24  // of what we can ignore.
     25  let oldParentTestData = utils.getCompositorAPZTestData();
     26  let oldIframeTestData = await getIframeCompositorTestData(iframeElement);
     27 
     28  let hittestPromise = SpecialPowers.spawnChrome([], () => {
     29    return new Promise(resolve => {
     30      browsingContext.topChromeWindow.addEventListener(
     31        "MozMouseHittest",
     32        () => {
     33          resolve();
     34        },
     35        { once: true }
     36      );
     37    });
     38  });
     39  await SpecialPowers.executeAfterFlushingMessageQueue();
     40 
     41  // Now do the hit-test
     42  dump(`Hit-testing point (${point.x}, ${point.y}) in fission context\n`);
     43  SpecialPowers.wrap(window).synthesizeMouseEvent(
     44    "MozMouseHittest",
     45    point.x,
     46    point.y,
     47    {},
     48    { ignoreRootScrollFrame: true }
     49  );
     50 
     51  await hittestPromise;
     52 
     53  // Collect the new test data
     54  let newParentTestData = utils.getCompositorAPZTestData();
     55  let newIframeTestData = await getIframeCompositorTestData(iframeElement);
     56 
     57  // See which test data has new hit results
     58  let hitResultCount = testData => {
     59    return Object.keys(testData.hitResults).length;
     60  };
     61 
     62  let hitIframe =
     63    hitResultCount(newIframeTestData) > hitResultCount(oldIframeTestData);
     64  let hitParent =
     65    hitResultCount(newParentTestData) > hitResultCount(oldParentTestData);
     66 
     67  // Extract the results from the appropriate test data
     68  let lastHitResult = testData => {
     69    let lastHit =
     70      testData.hitResults[Object.keys(testData.hitResults).length - 1];
     71    return {
     72      hitInfo: lastHit.hitResult,
     73      scrollId: lastHit.scrollId,
     74      layersId: lastHit.layersId,
     75    };
     76  };
     77  if (hitIframe && hitParent) {
     78    throw new Error(
     79      "Both iframe and parent got hit-results, that is unexpected!"
     80    );
     81  } else if (hitIframe) {
     82    return lastHitResult(newIframeTestData);
     83  } else if (hitParent) {
     84    return lastHitResult(newParentTestData);
     85  } else {
     86    throw new Error(
     87      "Neither iframe nor parent got the hit-result, that is unexpected!"
     88    );
     89  }
     90 }