<!DOCTYPE html><!-- webkit-test-runner [ TabsToLinks=true SpatialNavigationEnabled=true ] -->
<html>
  <!--
    This test ensures the correctness of Spatial Navigation (SNav) algorithm over multiple select element.

    * Pre-conditions:
    1) TestRunner support for SNav enable/disable.

    * Navigation steps:
    1) Loads this page, focus goes to "start" automatically.
    2) Focus moves away from select in 4 different directions to neighbor nodes and back.
  -->
  <head>
    <script src="../../resources/js-test-pre.js"></script>
    <script src="resources/spatial-navigation-utils.js"></script>
    <script type="application/javascript">

    var resultMap = [
      ["Down", "start"],
      ["Down", "start"],
      ["Down", "start"],
      ["Down", "8"],
      ["Up", "start"],
      ["Up", "start"],
      ["Up", "start"],
      ["Up", "2"],
      ["Down", "start"],
      ["Right", "6"],
      ["Left", "start"],
      ["Left", "4"],
      ["Right", "start"],
      ["DONE", "DONE"]
    ];

    if (window.testRunner) {
      testRunner.dumpAsText();
      testRunner.waitUntilDone();
    }

    function runTest()
    {
      // starting the test itself: get to a known place.
      document.getElementById("start").focus();

      initTest(resultMap, additionalTest);
    }

    function sendKeyAndCheckOptions(option0, option1, option2, option3)
    {
      shouldBe("gFocusedDocument.getElementById(\"start\").options[0].selected", option0);
      shouldBe("gFocusedDocument.getElementById(\"start\").options[1].selected", option1);
      shouldBe("gFocusedDocument.getElementById(\"start\").options[2].selected", option2);
      shouldBe("gFocusedDocument.getElementById(\"start\").options[3].selected", option3);
    }

    function additionalTest()
    {
      document.getElementById("start").focus();         //move to 1st item
      sendKeyAndCheckOptions("false", "false", "false", "false");
      eventSender.keyDown("downArrow");                 //move to 2nd item
      sendKeyAndCheckOptions("false", "false", "false", "false");
      eventSender.keyDown(" ");                         //nothing should change
      sendKeyAndCheckOptions("false", "true", "false", "false");
      eventSender.keyDown("downArrow");                 //move to 4th item (3rd item is disabled) 
      sendKeyAndCheckOptions("false", "true", "false", "false");
      eventSender.keyDown(" ");                         //nothing should change
      sendKeyAndCheckOptions("false", "true", "false", "true");
      eventSender.keyDown("upArrow");                   //move back to 2nd item
      sendKeyAndCheckOptions("false", "true", "false", "true");
      eventSender.keyDown(" ");                         //noting should change
      sendKeyAndCheckOptions("false", "false", "false", "true");
      eventSender.keyDown("upArrow");                   //move back to 1st item
      sendKeyAndCheckOptions("false", "false", "false", "true");
      eventSender.keyDown("downArrow", ["shiftKey"]);   //shift-down to 2nd item
      sendKeyAndCheckOptions("false", "true", "false", "true");

      testCompleted();
    }

    function testCompleted()
    {
      if (window.testRunner)
        testRunner.notifyDone();
    }

    window.onload = runTest;

    </script>
    <script src="../resources/js-test-post.js"></script>
  </head>
  <body id="some-content" xmlns="http://www.w3.org/1999/xhtml">
    <table style="text-align: left; width: 100%; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="1">
      <tbody>
        <tr>
          <td style="vertical-align: top; text-align: center;"></td>
          <td style="vertical-align: top; text-align: center;"><a id="2" href="a">2</a></td>
          <td style="vertical-align: top; text-align: center;"></td>
        </tr>
        <tr>
          <td style="vertical-align: top; text-align: center;"><a id="4" href="a">4</a></td>
          <td style="vertical-align: top; text-align: center;">
		  <select id="start" multiple><optgroup label="o1"><option>1</option></optgroup><optgroup label="o2"><option>2</option></optgroup><optgroup label="o3"><option disabled>3</option></optgroup><optgroup label="o4"><option>4</option></optgroup>
		  </select></td>
          <td style="vertical-align: top; text-align: center;"><a id="6" href="a">6</a></td>
        </tr>
        <tr>
          <td style="vertical-align: top; text-align: center;"></td>
          <td style="vertical-align: top; text-align: center;"><a id="8" href="a">8</a></td>
          <td style="vertical-align: top; text-align: center;"></td>
        </tr>
      </tbody>
    </table>
    <div id="console"></div>
  </body>
</html>

