tor-browser

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

element-request-fullscreen-cross-origin.sub.html (4653B)


      1 <!DOCTYPE html>
      2 <title>
      3  Element#requestFullscreen() works properly with a tree of cross-origin iframes
      4 </title>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="/resources/testdriver.js"></script>
      8 <script src="/resources/testdriver-vendor.js"></script>
      9 
     10 <body>
     11  <script>
     12    function waitFor(action, frameName) {
     13      return new Promise((resolve) => {
     14        window.addEventListener("message", function listener(e) {
     15          if (e.data.action === action && e.data.name === frameName) {
     16            window.removeEventListener("message", listener);
     17            resolve(event.data);
     18          }
     19        });
     20      });
     21    }
     22 
     23    function compare_report(report, expectedEvents) {
     24      assert_equals(
     25        report.events.length,
     26        expectedEvents.length,
     27        `Expected report for iframe "${report.frame}" to have ${expectedEvents.length} events: [${expectedEvents}]`
     28      );
     29      report.events.forEach((value, i) => {
     30        assert_equals(
     31          value,
     32          expectedEvents[i],
     33          "Event type matches in order expected"
     34        );
     35      });
     36 
     37      report.events.length
     38        ? assert_false(
     39            report.fullscreenElementIsNull,
     40            "Event fired, fullscreenElement is set"
     41          )
     42        : assert_true(
     43            report.fullscreenElementIsNull,
     44            "No event fired, fullscreenElement is null"
     45          );
     46    }
     47 
     48    const iframes = [
     49      {
     50        name: "A",
     51        src: "http://{{hosts[][]}}:{{ports[http][0]}}/fullscreen/api/resources/recursive-iframe-fullscreen.html?a",
     52        allow_fullscreen: true,
     53        expectedEvents: ["fullscreenchange"],
     54      },
     55      {
     56        name: "B",
     57        src: "http://{{hosts[][]}}:{{ports[http][1]}}/fullscreen/api/resources/recursive-iframe-fullscreen.html?b",
     58        allow_fullscreen: true,
     59        expectedEvents: ["fullscreenchange"],
     60      },
     61      {
     62        name: "C",
     63        src: "http://{{hosts[alt][]}}:{{ports[http][0]}}/fullscreen/api/resources/recursive-iframe-fullscreen.html?c",
     64        allow_fullscreen: true,
     65        expectedEvents: ["fullscreenchange"],
     66      },
     67      {
     68        name: "D",
     69        src: "http://{{hosts[alt][]}}:{{ports[http][1]}}/fullscreen/api/resources/recursive-iframe-fullscreen.html?d",
     70        allow_fullscreen: true,
     71        expectedEvents: ["fullscreenchange"],
     72      },
     73      {
     74        name: "E",
     75        src: "http://{{hosts[][]}}:{{ports[http][0]}}/fullscreen/api/resources/recursive-iframe-fullscreen.html?e",
     76        allow_fullscreen: true,
     77        expectedEvents: [],
     78      },
     79    ];
     80 
     81    promise_setup(async () => {
     82      // Add the first iframe.
     83      const iframeDetails = iframes[0];
     84      const child_frame = document.createElement("iframe");
     85      child_frame.allow = iframeDetails.allow_fullscreen ? "fullscreen" : "";
     86      child_frame.name = iframeDetails.name;
     87      child_frame.style.width = "100%";
     88      child_frame.style.height = "100%";
     89      child_frame.src = iframeDetails.src;
     90      await new Promise((resolve) => {
     91        child_frame.onload = resolve;
     92        document.body.appendChild(child_frame);
     93      });
     94 
     95      // Create the nested iframes.
     96      for (let i = 1; i < iframes.length; i++) {
     97        const parentName = iframes[i - 1].name;
     98        const details = iframes[i];
     99        child_frame.contentWindow.postMessage(
    100          { action: "addIframe", iframe: details, name: parentName },
    101          "*"
    102        );
    103        await waitFor("load", details.name);
    104      }
    105    });
    106 
    107    promise_test(async (t) => {
    108      t.add_cleanup(() => {
    109        if (document.fullscreenElement) {
    110          return document.exitFullscreen();
    111        }
    112      });
    113      document.onfullscreenerror = t.unreached_func(
    114        "fullscreenerror event fired"
    115      );
    116      const fsChangeFiredPromise = new Promise((resolve) => {
    117        document.onfullscreenchange = resolve;
    118      });
    119 
    120      const child_frame = document.querySelector("iframe[name=A]");
    121      child_frame.contentWindow.postMessage(
    122        {
    123          action: "requestFullscreen",
    124          name: "D",
    125        },
    126        "*"
    127      );
    128 
    129      await waitFor("requestFullscreen", "D");
    130 
    131      for (const frame of iframes.slice(1)) {
    132        const data = {
    133          action: "requestReport",
    134          name: frame.name,
    135        };
    136        child_frame.contentWindow.postMessage(data, "*");
    137        const { report } = await waitFor("report", frame.name);
    138        compare_report(report, frame.expectedEvents);
    139      }
    140      await fsChangeFiredPromise;
    141    }, "Element#requestFullscreen() works properly with a tree of cross-origin iframes");
    142  </script>
    143 </body>