<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=795785
-->
<head>
  <title>Test for Bug 795785</title>
  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.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=795785">Mozilla Bug 795785</a>
<div id="display">
  <textarea id="textarea" style="overflow: hidden; height: 3em; width: 5em; word-wrap: normal;"></textarea>
  <div id="div" contenteditable style="overflow: hidden; height: 3em; width: 5em;"></div>
</div>
<div id="content" style="display: none">
  
</div>
<pre id="test">
</pre>

<script class="testbody" type="application/javascript">


SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("This test uses setTimeouts in order to fix an intermittent failure.");

// Turn off spatial navigation because it hijacks arrow key events and VK_RETURN
// events.
SimpleTest.waitForFocus(function() {
  SpecialPowers.pushPrefEnv({"set":[["snav.enabled", false]]}, runTests);
});
var textarea = document.getElementById("textarea");
var div = document.getElementById("div");

function hitEventLoop(aFunc, aTimes)
{
  if (--aTimes) {
    setTimeout(hitEventLoop, 0, aFunc, aTimes);
  } else {
    setTimeout(aFunc, 100);
  }
}

function doKeyEventTest(aElement, aElementDescription, aCallback)
{
  aElement.focus();
  aElement.scrollTop = 0;
  hitEventLoop(function () {
    is(aElement.scrollTop, 0,
       aElementDescription + "'s scrollTop isn't 0");
    synthesizeKey("VK_RETURN", { });
    synthesizeKey("VK_RETURN", { });
    synthesizeKey("VK_RETURN", { });
    synthesizeKey("VK_RETURN", { });
    synthesizeKey("VK_RETURN", { });
    synthesizeKey("VK_RETURN", { });
    hitEventLoop(function () {
      isnot(aElement.scrollTop, 0,
            aElementDescription + " was not scrolled by inserting line breaks");
      var scrollTop = aElement.scrollTop;
      synthesizeKey("VK_UP", { });
      synthesizeKey("VK_UP", { });
      synthesizeKey("VK_UP", { });
      synthesizeKey("VK_UP", { });
      synthesizeKey("VK_UP", { });
      hitEventLoop(function () {
        isnot(aElement.scrollTop, scrollTop,
              aElementDescription + " was not scrolled by up key events");
        synthesizeKey("VK_DOWN", { });
        synthesizeKey("VK_DOWN", { });
        synthesizeKey("VK_DOWN", { });
        synthesizeKey("VK_DOWN", { });
        synthesizeKey("VK_DOWN", { });
        hitEventLoop(function () {
          is(aElement.scrollTop, scrollTop,
             aElementDescription + " was not scrolled by down key events");
          var longWord = "aaaaaaaaaaaaaaaaaaaa";
          sendString(longWord);
          hitEventLoop(function () {
            isnot(aElement.scrollLeft, 0,
                  aElementDescription + " was not scrolled by typing long word");
            var scrollLeft = aElement.scrollLeft;
            var i;
            for (i = 0; i < longWord.length; i++) {
              synthesizeKey("VK_LEFT", { });
            }
            hitEventLoop(function () {
              isnot(aElement.scrollLeft, scrollLeft,
                    aElementDescription + " was not scrolled by left key events");
              for (i = 0; i < longWord.length; i++) {
                synthesizeKey("VK_RIGHT", { });
              }
              hitEventLoop(function () {
                is(aElement.scrollLeft, scrollLeft,
                   aElementDescription + " was not scrolled by right key events");
                aCallback();
              }, 20);
            }, 20);
          }, 20);
        }, 20);
      }, 20);
    }, 20);
  }, 20);
}

function doCompositionTest(aElement, aElementDescription, aCallback)
{
  aElement.focus();
  aElement.scrollTop = 0;
  hitEventLoop(function () {
    is(aElement.scrollTop, 0,
       aElementDescription + "'s scrollTop isn't 0");
    var str = "Web \u958b\u767a\u8005\u306e\u7686\u3055\u3093\u306f\u3001" +
              "Firefox \u306b\u5b9f\u88c5\u3055\u308c\u3066\u3044\u308b HTML5" +
              " \u3084 CSS \u306e\u65b0\u6a5f\u80fd\u3092\u6d3b\u7528\u3059" +
              "\u308b\u3053\u3068\u3067\u3001\u9b45\u529b\u3042\u308b Web " +
              "\u30b5\u30a4\u30c8\u3084\u9769\u65b0\u7684\u306a Web \u30a2" +
              "\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u3088\u308a" +
              "\u77ed\u6642\u9593\u3067\u7c21\u5358\u306b\u4f5c\u6210\u3067" +
              "\u304d\u307e\u3059\u3002";
    synthesizeCompositionChange({
        composition: {
          string: str,
          clauses: [
            { length: str.length, attr: COMPOSITION_ATTR_RAW_CLAUSE }
          ]
        },
        caret: { start: str.length, length: 0 }
      });
    hitEventLoop(function () {
      isnot(aElement.scrollTop, 0,
            aElementDescription + " was not scrolled by composition");
      synthesizeComposition({ type: "compositioncommit", data: "" });
      hitEventLoop(function () {
        is(aElement.scrollTop, 0,
           aElementDescription + " was not scrolled back to the top by canceling composition");
        aCallback();
      }, 20);
    }, 20);
  }, 20);
}

function runTests()
{
  doKeyEventTest(textarea, "textarea",
    function () {
      textarea.value = "";
      doKeyEventTest(div, "div (contenteditable)",
        function () {
          div.innerHTML = "";
          doCompositionTest(textarea, "textarea",
            function () {
              doCompositionTest(div, "div (contenteditable)",
                function () {
                  SimpleTest.finish();
                });
            });
        });
    });
}

</script>
</body>

</html>