<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1096146
-->
<head>
  <meta charset="utf-8">
  <title>Test for Bug 1096146</title>
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="runTests();">
<a target="_blank"
   href="https://bugzilla.mozilla.org/show_bug.cgi?id=1096146">Mozilla Bug 1096146</a>
<div id="content" style="display: none;">
</div>
<pre id="test">
<script type="application/javascript">

const kKeydownEvent = 0x1;
const kScrollEvent  = 0x2;

var gCurrentTest = 0;
var gNumEvents = 0;
var kTests = [
  {
    description: "no preventDefault at 'mozbrowserbeforekeydown'",
    expectedEvents: kKeydownEvent | kScrollEvent,
    resultEvents: 0x0,
    doPreventDefault: false
  },
  {
    description: "do preventDefault at 'mozbrowserbeforekeydown'",
    expectedEvents: 0x0,
    resultEvents: 0x0,
    doPreventDefault: true
  }
]

function frameScript()
{
  function handler(e) {
    sendSyncMessage("forwardevent", { type: e.type });
  }
  addEventListener('keydown', handler);
  addEventListener('scroll', handler);
}


function waitAndVerifyResult(count) {
  if (gNumEvents >= 3 || count > 10) {
    is(kTests[gCurrentTest].resultEvents,
       kTests[gCurrentTest].expectedEvents,
       "verify result");
    runTests();
	} else {
    SimpleTest.requestFlakyTimeout("We must delay to wait for scroll/keydown events.");
    setTimeout(() => waitAndVerifyResult(count + 1), 100);
  }
}

function testDefaultAction()
{
  synthesizeKey('VK_END', {}, document.getElementById("embedded").contentWindow);
  waitAndVerifyResult(0);
}

function prepareTest()
{
  gNumEvents = 0;

  var handler;
  if (kTests[gCurrentTest].doPreventDefault) {
    handler = preventDefaultHandler;
  } else {
    handler = noPreventDefaultHandler;
  }
  window.addEventListener("mozbrowserbeforekeydown", handler);

  var iframe = document.createElement("iframe");
  iframe.id = "embedded";
  iframe.src = "bug1096146_embedded.html";
  iframe.setAttribute("remote", "false");
  SpecialPowers.wrap(iframe).mozbrowser = true;

  iframe.addEventListener("mozbrowserloadend", function onloadend() {
    iframe.removeEventListener("mozbrowserloadend", onloadend);
    iframe.focus();
    var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
    mm.addMessageListener("forwardevent", function(msg) {
      var value = 0;
      switch(msg.json.type) {
        case "scroll":
          ++gNumEvents;
          value = kScrollEvent;
          break;
        case "keydown":
          ++gNumEvents;
          value = kKeydownEvent;
          break;
        default:
          ok(false, "unexpected event");
      }

      kTests[gCurrentTest].resultEvents =
        kTests[gCurrentTest].resultEvents | value;
    });
    mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
    runTests();
    return;
  });

  document.body.appendChild(iframe);
}

function preventDefaultHandler(evt)
{
  ok(true, "receive " + evt.type + " and do preventDefault.");
	++gNumEvents;
  evt.preventDefault();
}

function noPreventDefaultHandler(evt)
{
  ok(true, "receive " + evt.type + ".");
	++gNumEvents;
}

function teardownHandler()
{
  var handler;
  if (kTests[gCurrentTest].doPreventDefault) {
    handler = preventDefaultHandler;
  } else {
    handler = noPreventDefaultHandler;
  }
  window.removeEventListener("mozbrowserbeforekeydown", handler);
  document.body.removeChild(document.getElementById("embedded"));

  runTests();
}

var tests = [
  function addPermissions() {
    SpecialPowers.pushPermissions(
      [{ type: "before-after-keyboard-event", allow: true, context: document },
       { type: "browser", allow: true, context: document }],
      runTests);
  },
  function addPreferences() {
    SpecialPowers.pushPrefEnv(
      { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
                ["dom.mozBrowserFramesEnabled", true],
                ["dom.ipc.tabs.disabled", false],
                ["network.disable.ipc.security", true]] },
      runTests);
  },

  prepareTest,
  testDefaultAction,
  teardownHandler,

  function() {
    gCurrentTest++;
    runTests();
  },
  prepareTest,
  testDefaultAction,
  teardownHandler
];

function runTests()
{
  if (!tests.length) {
    SimpleTest.finish();
    return;
  }

  var test = tests.shift();
  test();
}

</script>
</pre>
</body>
</html>