<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<meta http-equiv="Content-Security-Policy" content="img-src http://{{hosts[][www]}}:{{ports[http][0]}}">
<body>
  <script>
    let message_from = w => {
      return new Promise(resolve => {
        window.addEventListener('message', msg => {
          if (msg.source == w) {
            resolve(msg.data);
          }
        });
      });
    };

    // `iframe_a` and `iframe_b` are two helper iframes with different
    // CSPs.
    let iframe_a, iframe_b;

    // Setup `iframe_a` and `iframe_b`.
    promise_setup(async () => {
      iframe_a = document.createElement('iframe');
      iframe_a.src = "./support/iframe-do.sub.html?" +
        "img-src=http://{{hosts[][www1]}}:{{ports[http][0]}}";
      document.body.appendChild(iframe_a);
      await message_from(iframe_a.contentWindow);

      iframe_b = document.createElement('iframe');
      iframe_b.id = 'iframe_b';
      iframe_b.src = "./support/iframe-do.sub.html?" +
        "img-src=http://{{hosts[][www2]}}:{{ports[http][0]}}";
      document.body.appendChild(iframe_b);
      await message_from(iframe_b.contentWindow);
    });

    let test_iframe_id_counter = 0;

    // Helper function to create the target iframe of a navigation.
    let create_test_iframe = async () => {
      let test_iframe = document.createElement('iframe');
      test_iframe.id = "test_iframe_" + test_iframe_id_counter++;
      test_iframe.name = test_iframe.id;
      document.body.appendChild(test_iframe);
      return test_iframe;
    }

    // The following code will try loading several images and check
    // whether CSP has been inherited by the parent ("p"), `iframe_a`
    // ("a") or `iframe_b` ("b"). It will post a message to the top
    // with the result.
    let data_payload = `
      <body><script>
        new Promise(async (resolve, reject) => {
          const img_path = "/content-security-policy/support/pass.png";

          let img_loaded = (origin) => new Promise(resolve => {
            let img = document.createElement('img');
            img.onerror = () => resolve(false);
            img.onload = () => resolve(true);
            img.src = origin + img_path;
            document.body.appendChild(img);
          });

          inherited_from_p = await img_loaded(
            "http://{{hosts[][www]}}:{{ports[http][0]}}");
          inherited_from_a = await img_loaded(
            "http://{{hosts[][www1]}}:{{ports[http][0]}}");
          inherited_from_b = await img_loaded(
            "http://{{hosts[][www2]}}:{{ports[http][0]}}");

          if (inherited_from_a + inherited_from_b +
               inherited_from_p !== 1) {
            reject("Exactly one CSP should be inherited");
          }
          if (inherited_from_a) resolve("a");
          if (inherited_from_b) resolve("b");
          if (inherited_from_p) resolve("p");
        }).then(from => top.postMessage(from, '*'),
                error => top.postMessage(error, '*'));
      </scr`+`ipt></body>
    `;

    let data_url = "data:text/html;base64," + btoa(data_payload);

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      iframe_a.contentWindow.postMessage(
        `parent.document.getElementById('${test_iframe.id}').src = '${data_url}'`);

      assert_equals(await message_from(test_iframe.contentWindow), "p");
    }, "Setting src inherits from parent.");

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      iframe_a.contentWindow.postMessage(
        `parent.document.getElementById('${test_iframe.id}').contentWindow.location = '${data_url}'`);

      assert_equals(await message_from(test_iframe.contentWindow), "a");
    }, "Changing contentWindow.location inherits from who changed it.");

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      window.navigate_test_iframe = () => {
        test_iframe.contentWindow.location = data_url;
      };
      iframe_a.contentWindow.postMessage(`parent.navigate_test_iframe();`);
      assert_equals(await message_from(test_iframe.contentWindow), "p");
    }, "Changing contentWindow.location indirectly inherits from who changed it directly.");

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      iframe_a.contentWindow.postMessage(
        `window.open('${data_url}', "${test_iframe.name}")`);

      assert_equals(await message_from(test_iframe.contentWindow), "a");
    }, "window.open() inherits from caller.");

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      let a = iframe_b.contentDocument.createElement('a');
      a.id = 'a';
      a.href = data_url;
      a.target = test_iframe.name;
      iframe_b.contentDocument.body.appendChild(a);

      iframe_a.contentWindow.postMessage(
        `parent.document.getElementById('iframe_b').contentDocument.getElementById('a').click();`);

      assert_equals(await message_from(test_iframe.contentWindow), "b");
      iframe_b.contentDocument.body.removeChild(a);
    }, "Click on anchor inherits from owner of the anchor.");

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      let form = iframe_b.contentDocument.createElement('form');
      form.id = 'form';
      form.action = data_url;
      form.target = test_iframe.name;
      form.method = "POST";
      iframe_b.contentDocument.body.appendChild(form);

      iframe_a.contentWindow.postMessage(
        `parent.document.getElementById('iframe_b').contentDocument.getElementById('form').submit();`);

      assert_equals(await message_from(test_iframe.contentWindow), "b");
      iframe_b.contentDocument.body.removeChild(form);
    }, "Form submission through submit() inherits from owner of form.");

    promise_test(async t => {
      let test_iframe = await create_test_iframe();
      let form = iframe_b.contentDocument.createElement('form');
      form.id = 'form';
      form.action = data_url;
      form.target = test_iframe.name;
      form.method = "POST";
      iframe_b.contentDocument.body.appendChild(form);
      let button = iframe_b.contentDocument.createElement('button');
      button.type = "submit";
      button.value = "submit";
      button.id = "button";
      form.appendChild(button);

      iframe_a.contentWindow.postMessage(
        `parent.document.getElementById('iframe_b').contentDocument.getElementById('button').click();`);

      assert_equals(await message_from(test_iframe.contentWindow), "b");
      iframe_b.contentDocument.body.removeChild(form);
    }, "Form submission through button click inherits from owner of form.");

  </script>
</body>
