<!DOCTYPE html>
<html>
  <head>
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/resources/testdriver.js"></script>
    <script src="/resources/testdriver-vendor.js"></script>
    <script src="resources/utils.js"></script>
  </head>
  <body>
    <h1>Check that cross origin iframes don't get activated</h1>
    <p>
      Tests that activating a same-origin navigable doesn't activate a cross
      origin navigable.
    </p>
    <ol id="instructions">
      <li>Click inside the yellow area.</li>
    </ol>
    <h1>Same origin</h1>
    <iframe id="so-child" width="200" height="50"></iframe>
    <h1>Cross origin</h1>
    <iframe id="xo-child" width="200" height="50"></iframe>
  </body>
  <script>
    const soChild = document.getElementById("so-child");
    const xoChild = document.getElementById("xo-child");

    function receiveMessage(type) {
      return new Promise((resolve) => {
        window.addEventListener("message", function listener(event) {
          if (typeof event.data !== "string") {
            return;
          }
          const data = JSON.parse(event.data);
          if (data.type === type) {
            window.removeEventListener("message", listener);
            resolve(data);
          }
        });
      });
    }

    function requestXOReport() {
      xoChild.contentWindow.postMessage(
        JSON.stringify({ type: "report" }),
        "*"
      );
      return receiveMessage(`child-two-report`);
    }

    promise_test(async (t) => {
      soChild.src = "./resources/child-one.html";
      xoChild.src =
        "http://{{hosts[alt][]}}:{{ports[http][0]}}/html/user-activation/resources/child-two.html";
      const [, unclickedCrossOrigin] = await Promise.all([
        receiveMessage("child-one-loaded"),
        receiveMessage("child-two-loaded"),
      ]);
      const soActivation = soChild.contentWindow.navigator.userActivation;
      assert_false(
        navigator.userActivation.isActive,
        "navigator.userActivation.isActive must be false"
      );
      assert_false(
        navigator.userActivation.hasBeenActive,
        "navigator.userActivation.hasBeenActive must be false"
      );

      assert_false(soActivation.isActive, "child-one isActive must be false");
      assert_false(
        soActivation.hasBeenActive,
        "child-one hasBeenActive must be false"
      );
      assert_false(
        unclickedCrossOrigin.isActive,
        "child-two isActive must be false"
      );
      assert_false(
        unclickedCrossOrigin.hasBeenActive,
        "child-two hasBeenActive must be false"
      );
    }, "Check Initial states of user activation are all false");

    promise_test(async (t) => {
      await test_driver.click(soChild);
      const xoActivation = await requestXOReport();
      const soActivation = soChild.contentWindow.navigator.userActivation;
      assert_true(
        navigator.userActivation.isActive,
        "navigator.userActivation.isActive must be true"
      );
      assert_true(
        navigator.userActivation.hasBeenActive,
        "navigator.userActivation.hasBeenActive must be true"
      );
      assert_true(soActivation.isActive, "child-one isActive must be true");
      assert_true(
        soActivation.hasBeenActive,
        "child-one hasBeenActive must be true"
      );
      assert_false(xoActivation.isActive, "child-two isActive must be false");
      assert_false(
        xoActivation.hasBeenActive,
        "child-two hasBeenActive must be false"
      );
    }, "Check that activating a same-origin navigable doesn't activate a cross origin navigable");

    promise_test(async (t) => {
      await consumeTransientActivation();
      const soActivation = soChild.contentWindow.navigator.userActivation;
      assert_false(
        navigator.userActivation.isActive,
        "navigator.userActivation.isActive must be false"
      );
      assert_true(
        navigator.userActivation.hasBeenActive,
        "navigator.userActivation.hasBeenActive must be true"
      );
      assert_false(soActivation.isActive, "child-one isActive must be false");
      assert_true(
        soActivation.hasBeenActive,
        "child-one hasBeenActive must be true"
      );
      const [, xoActivation] = await Promise.all([
        test_driver.click(xoChild),
        receiveMessage("child-two-clicked"),
      ]);
      assert_true(
        navigator.userActivation.isActive,
        "navigator.userActivation.isActive must be true"
      );
      assert_true(
        navigator.userActivation.hasBeenActive,
        "navigator.userActivation.hasBeenActive must remain true"
      );
      assert_true(xoActivation.isActive, "child-two isActive must be true");
      assert_true(
        xoActivation.hasBeenActive,
        "child-two hasBeenActive must be true"
      );
      assert_false(soActivation.isActive, "child-one isActive must be false");
      assert_true(
        soActivation.hasBeenActive,
        "child-one hasBeenActive must remain true"
      );
    }, "Clicking on the cross-origin navigable activates parent navigable.");
  </script>
</html>
