<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                 type="text/css"?>

<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        title="Accessibility Loading Document Events Test.">

  <script type="application/javascript"
          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
  <script type="application/javascript"
          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>

  <script type="application/javascript"
          src="../common.js"></script>
  <script type="application/javascript"
          src="../role.js"></script>
  <script type="application/javascript"
          src="../states.js"></script>
  <script type="application/javascript"
          src="../events.js"></script>
  <script type="application/javascript"
          src="../browser.js"></script>

  <script type="application/javascript">
  <![CDATA[
    ////////////////////////////////////////////////////////////////////////////
    // Invoker checkers.
    function stateBusyChecker(aIsEnabled)
    {
      this.type = EVENT_STATE_CHANGE;
      this.__defineGetter__("target", currentTabDocument);

      this.check = function stateBusyChecker_check(aEvent)
      {
        var event = null;
        try {
          var event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
        } catch (e) {
          ok(false, "State change event was expected");
        }

        if (!event)
          return;

        is(event.state, STATE_BUSY, "Wrong state of statechange event.");
        is(event.isEnabled, aIsEnabled,
           "Wrong value of state of statechange event");

        testStates(event.accessible, (aIsEnabled ? STATE_BUSY : 0), 0,
                   (aIsEnabled ? 0 : STATE_BUSY), 0);
      }
    }

    function documentReloadChecker(aIsFromUserInput)
    {
      this.type = EVENT_DOCUMENT_RELOAD;
      this.__defineGetter__("target", currentTabDocument);

      this.check = function documentReloadChecker_check(aEvent)
      {
        is(aEvent.isFromUserInput, aIsFromUserInput,
           "Wrong value of isFromUserInput");
      }
    }

    ////////////////////////////////////////////////////////////////////////////
    // Invokers.

    /**
     * Load URI.
     */
    function loadURIInvoker(aURI)
    {
      this.invoke = function loadURIInvoker_invoke()
      {
        tabBrowser().loadURI(aURI);
      }

      this.eventSeq = [
        // We don't expect state change event for busy true since things happen
        // quickly and it's coalesced.
        new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
        new stateBusyChecker(false)
      ];

      this.getID = function loadURIInvoker_getID()
      {
        return "load uri " + aURI;
      }
    }

    /**
     * Load the document having sub document. No document loading events for
     * nested document.
     */
    function loadNestedDocURIInvoker(aNestedDocURI)
    {
      this.__proto__ = new loadURIInvoker(aNestedDocURI);

      // Remove reorder event checker since the event is likely coalesced by
      // reorder event on Firefox UI (refer to bug 759670 for details).
      this.eventSeq.shift();

      this.unexpectedEventSeq = [
        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getNestedDoc),
        new invokerChecker(EVENT_STATE_CHANGE, getNestedDoc)
      ];

      function getNestedDoc()
      {
        var iframeNodes = currentTabDocument().getElementsByTagName("iframe");
        return iframeNodes && iframeNodes.length > 0 ?
          iframeNodes[0].firstChild : null;
      }
    }

    /**
     * Reload the page by F5 (isFromUserInput flag is true).
     */
    function userReloadInvoker()
    {
      this.invoke = function userReloadInvoker_invoke()
      {
        synthesizeKey("VK_F5", {}, browserWindow());
      }

      this.eventSeq = [
        new documentReloadChecker(true),
        new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
        new stateBusyChecker(false)
      ];

      this.getID = function userReloadInvoker_getID()
      {
        return "user reload page";
      }
    }

    /**
     * Reload the page (isFromUserInput flag is false).
     */
    function reloadInvoker()
    {
      this.invoke = function reloadInvoker_invoke()
      {
        tabBrowser().reload();
      }

      this.eventSeq = [
        new documentReloadChecker(false),
        new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
        new stateBusyChecker(false)
      ];

      this.getID = function reloadInvoker_getID()
      {
        return "reload page";
      }
    }

    /**
     * Load wrong URI what results in error page loading.
     */
    function loadErrorPageInvoker(aURL, aURLDescr)
    {
      this.invoke = function loadErrorPageInvoker_invoke()
      {
        tabBrowser().loadURI(aURL);
      }

      this.eventSeq = [
        // We don't expect state change for busy true, load stopped events since
        // things happen quickly and it's coalesced.
        new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
        new stateBusyChecker(false)
      ];

      this.getID = function loadErrorPageInvoker_getID()
      {
        return "load error page: '" + aURLDescr + "'";
      }
    }

    ////////////////////////////////////////////////////////////////////////////
    // Tests

    //gA11yEventDumpToConsole = true; // debug
    //gA11yEventDumpFeature = "parentchain:reorder";

    var gQueue = null;
    function doTests()
    {
      gQueue = new eventQueue();

      var dataURL =
        "data:text/html,<html><body><iframe src='http://example.com'></iframe></body></html>";
      gQueue.push(new loadNestedDocURIInvoker(dataURL));

      gQueue.push(new loadURIInvoker("about:"));
      gQueue.push(new userReloadInvoker());
      gQueue.push(new loadURIInvoker("about:mozilla"));
      gQueue.push(new reloadInvoker());
      gQueue.push(new loadErrorPageInvoker("www.wronguri.wronguri",
                                           "Server not found"));
      gQueue.push(new loadErrorPageInvoker("https://nocert.example.com:443",
                                          "Untrusted Connection"));

      gQueue.onFinish = function() { closeBrowserWindow(); }
      gQueue.invoke();
    }

    SimpleTest.waitForExplicitFinish();
    openBrowserWindow(doTests);
  ]]>
  </script>

  <vbox flex="1" style="overflow: auto;">
  <body xmlns="http://www.w3.org/1999/xhtml">
    <a target="_blank"
       href="https://bugzilla.mozilla.org/show_bug.cgi?id=566103"
       title=" reorganize accessible document handling">
      Mozilla Bug 566103
    </a>
    <a target="_blank"
       href="https://bugzilla.mozilla.org/show_bug.cgi?id=754165"
       title="Fire document load events on iframes too">
      Mozilla Bug 754165
    </a>
    <p id="display"></p>
    <div id="content" style="display: none">
    </div>
    <pre id="test">
    </pre>
  </body>

  <vbox id="eventdump"></vbox>
  </vbox>
</window>