<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1277475
html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1277475 - html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1277475">Mozilla Bug 1277475</a>
<p id="display"></p>
<div id="content">Tests for Bug 1277475</div>

<iframe id="if1" name="if1" src="file_marquee_event_handlers.html"
   sandbox="allow-same-origin allow-forms allow-top-navigation allow-pointer-lock allow-orientation-lock allow-popups allow-modals allow-popups-to-escape-sandbox">
</iframe>

<iframe id="if2" name="if2" src="file_marquee_event_handlers.html"
   sandbox="allow-scripts"></iframe>

<script>
  SimpleTest.waitForExplicitFinish();

  var expectedMessages = new Set();
  var numberOfMessagesExpected = 4;
  var unexpectedMessages = new Set();

  window.onmessage = function(event) {
    info(event.data + " message received");
    if (event.data.startsWith("if2") || event.data == "if1 chaser") {
      expectedMessages.add(event.data);
      if (expectedMessages.size == numberOfMessagesExpected) {
        checkRecievedMessages();
      }
    } else {
      unexpectedMessages.add(event.data);
    }
  };

  function checkRecievedMessages() {
    // Check the expected messages explicitly as a cross-check.
    ok(expectedMessages.has("if1 chaser"),
       "if1 chaser message should have been received");
    ok(expectedMessages.has("if2 marquee onstart"),
       "if2 marquee onstart should have run in iframe sandbox with allow-scripts");
    ok(expectedMessages.has("if2 marquee onbounce"),
       "if2 marquee onbounce should have run in iframe sandbox with allow-scripts");
    ok(expectedMessages.has("if2 marquee onfinish"),
       "if2 marquee onfinish should have run in iframe sandbox with allow-scripts");

    unexpectedMessages.forEach(
      (v) => {
        ok(false, v + " should NOT have run in iframe sandbox without allow-scripts");
      }
    );

    SimpleTest.finish();
  }

  // If things are working properly the attribute event handlers won't run on
  // the marquee in if1, so add our own capturing listeners on its window, so we
  // know when they have fired. (These will run as we are not sandboxed.)
  var if1FiredEvents = new Set();
  var if1NumberOfEventsExpected = 3;
  var if1Win = document.getElementById("if1").contentWindow;
  if1Win.addEventListener("start", () => { checkMarqueeEvent("start"); }, true);
  if1Win.addEventListener("bounce", () => { checkMarqueeEvent("bounce"); }, true);
  if1Win.addEventListener("finish", () => { checkMarqueeEvent("finish"); }, true);

  function checkMarqueeEvent(eventType) {
    info("if1 event " + eventType + " fired");
    if1FiredEvents.add(eventType);
    if (if1FiredEvents.size == if1NumberOfEventsExpected) {
      // Only send the chasing message after a tick of the event loop to allow
      // event handlers on the marquee to process.
      SimpleTest.executeSoon(sendChasingMessage);
    }
  }

  function sendChasingMessage() {
    // Add our own message listener to if1's window and echo back a chasing
    // message to make sure that any messages from incorrectly run marquee
    // attribute event handlers should have arrived before it.
    if1Win.addEventListener("message",
                            (e) => { if1Win.parent.postMessage(e.data, "*"); });
    if1Win.postMessage("if1 chaser", "*");
    info("if1 chaser message sent");
  }
</script>
</body>
</html>
