author James Teh <>
Wed, 01 Feb 2023 05:02:01 +0000
changeset 651150 dd0fdd1daa69783be36acd5c50544f3694eaa8f9
parent 616557 918ef225713fa9fc188f42355a6cd4a2bfb3b64c
permissions -rw-r--r--
Bug 1813980: Check IsDoc before Parent in RemoteAccessibleBase::ApplyCrossDocOffset. r=morgan We call this function on every ancestor when calculating bounds. RemoteParent() currently requires a hash lookup, so it's more efficient to early return for !IsDoc() first. This is a micro-optimisation, but it might have some impact given that we call this on every ancestor, especially when hit testing, where we call Bounds() a lot. As a bit of drive-by cleanup, use RemoteParent() rather than calling Parent() and IsRemote/AsRemote(). Differential Revision:

  <meta charset="utf-8">
    A test to make sure checkerboard severity isn't reported for non-scrollable
    OOP iframe
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script src="/tests/SimpleTest/paint_listener.js"></script>
  <script src="helper_fission_utils.js"></script>
  <script src="apz_test_utils.js"></script>
  <script src="apz_test_native_event_utils.js"></script>


  .then(loadOOPIFrame("testframe", "helper_fission_empty.html"))
  .then(FissionTestHelper.subtestDone, FissionTestHelper.subtestFailed);

// The actual test

let code_for_oopif_to_run = function() {
  document.addEventListener("click", function(e) {
    dump(`OOPIF got click at ${e.clientX},${e.clientY}\n`);
    let result = { x: e.clientX, y: e.clientY };
    FissionTestHelper.fireEventInEmbedder("OOPIF:ClickData", result);
  dump("OOPIF registered click listener\n");
  return true;

async function getIframeDisplayport(iframe) {
  let oopif_displayport = function() {
    let result = getLastContentDisplayportFor("fission_empty_docelement", false);
    FissionTestHelper.fireEventInEmbedder("OOPIF:Displayport", result);
    return true;

  let iframePromise = promiseOneEvent(window, "OOPIF:Displayport", null);
  ok(await FissionTestHelper.sendToOopif(iframe, `(${oopif_displayport})()`));
  let iframeResponse = await iframePromise;
  dump("OOPIF response for Displayport: " +
       JSON.stringify( + "\n");


async function getIframeScrollMax(iframe) {
  let oopif_scroll_max = function() {
    let result = {
      scrollMaxX: window.scrollMaxX,
      scrollMaxY: window.scrollMaxY
    FissionTestHelper.fireEventInEmbedder("OOPIF:ScrollMax", result);
    return true;

  let iframePromise = promiseOneEvent(window, "OOPIF:ScrollMax", null);
  ok(await FissionTestHelper.sendToOopif(iframe, `(${oopif_scroll_max})()`));
  let iframeResponse = await iframePromise;
  dump("OOPIF response for ScrollMax: " +
       JSON.stringify( + "\n");


async function test() {
  await SpecialPowers.spawnChrome([], () => {

  const iframe = document.getElementById("testframe");

  // Make sure the iframe content is not scrollable.
  const { scrollMaxX, scrollMaxY } = await getIframeScrollMax(iframe);
  is(scrollMaxX, 0, "The iframe content should not be scrollable");
  is(scrollMaxY, 0, "The iframe content should not be scrollable");

  // Since bug 1709460 any visible OOP iframe initially has set the displayport.
  let displayport = await getIframeDisplayport(iframe);
  is(displayport.width, 400);
  is(displayport.height, 300);

  let iframeResponse =
    await FissionTestHelper.sendToOopif(iframe, `(${code_for_oopif_to_run})()`);
  dump("OOPIF response: " + JSON.stringify(iframeResponse) + "\n");
  ok(iframeResponse, "code_for_oopif_to_run successfully installed");

  // Click on the iframe via APZ so that it triggers a RequestContentRepaint
  // call then it sets zero display port margins for the iframe's root scroller,
  // thus as a result it will report a checkerboard event if there had been
  // checkerboarding.
  iframePromise = promiseOneEvent(window, "OOPIF:ClickData", null);
  await synthesizeNativeMouseEventWithAPZ(
    { type: "click", target: iframe, offsetX: 10, offsetY: 10 },
    () => dump("Finished synthesizing click, waiting for OOPIF message...\n")
  iframeResponse = await iframePromise;
  dump("OOPIF response: " + JSON.stringify( + "\n");

  // Now the displayport size should have been set.
  displayport = await getIframeDisplayport(iframe);
  is(displayport.width, 400, "The displayport size should be same as the iframe size");
  is(displayport.height, 300, "The displayport size should be same as the iframe size");

  // Wait 100ms to give a chance to deliver the checkerboard event.
  await new Promise(resolve => {
    setTimeout(resolve, 100);

  const hasCheckerboardSeverity = await SpecialPowers.spawnChrome([], () => {
    const histograms = Services.telemetry.getSnapshotForHistograms(
        true /* clear the histograms after taking this snapshot*/).parent;

    return histograms.hasOwnProperty("CHECKERBOARD_SEVERITY");
  ok(!hasCheckerboardSeverity, "there should be no checkerboard severity data");
    iframe {
        width: 400px;
        height: 300px;
        border: none;
<iframe id="testframe"></iframe>