dom/tests/mochitest/chrome/window_focus.xul

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/tests/mochitest/chrome/window_focus.xul	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1718 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
     1.6 +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
     1.7 +                 type="text/css"?>
     1.8 +<!--
     1.9 + This test checks focus in various ways
    1.10 +-->
    1.11 +<window id="outer-document" title="Focus Test" width="600" height="550"
    1.12 +        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    1.13 +  <script type="application/javascript"
    1.14 +          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
    1.15 +  <script type="application/javascript"
    1.16 +          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
    1.17 +
    1.18 +<body xmlns="http://www.w3.org/1999/xhtml"/>
    1.19 +
    1.20 +  <script type="application/javascript"><![CDATA[
    1.21 +
    1.22 +var fm = Components.classes["@mozilla.org/focus-manager;1"].
    1.23 +           getService(Components.interfaces.nsIFocusManager);
    1.24 +
    1.25 +const kChildDocumentRootIndex = 13;
    1.26 +const kBeforeTabboxIndex = 34;
    1.27 +const kTabbableSteps = 38;
    1.28 +const kFocusSteps = 26;
    1.29 +const kNoFocusSteps = 7;
    1.30 +const kOverflowElementIndex = 27;
    1.31 +
    1.32 +var gTestStarted = false;
    1.33 +var gPartialTabbing = false;
    1.34 +var gMoveToFocusFrame = false;
    1.35 +var gLastFocus = null;
    1.36 +var gLastFocusWindow = window;
    1.37 +var gLastFocusMethod = -1;
    1.38 +var gEvents = "";
    1.39 +var gExpectedEvents = "";
    1.40 +var gEventMatched = true;
    1.41 +var gShowOutput = false;
    1.42 +var gChildWindow = null;
    1.43 +
    1.44 +var gOldExpectedWindow = null;
    1.45 +var gNewExpectedWindow = null;
    1.46 +
    1.47 +function is(l, r, n) { window.opener.wrappedJSObject.SimpleTest.is(l,r,n); }
    1.48 +function ok(v, n) { window.opener.wrappedJSObject.SimpleTest.ok(v,n); }
    1.49 +
    1.50 +function initEvents(target)
    1.51 +{
    1.52 +  target.addEventListener("focus", eventOccured, true);
    1.53 +  target.addEventListener("blur", eventOccured, true);
    1.54 +  getTopWindow(target).addEventListener("activate", eventOccured, true);
    1.55 +  getTopWindow(target).addEventListener("deactivate", eventOccured, true);
    1.56 +}
    1.57 +
    1.58 +function eventOccured(event)
    1.59 +{
    1.60 +  // iframes should never receive focus or blur events directly
    1.61 +  if (event.target instanceof Element && event.target.localName == "iframe")
    1.62 +    ok(false, "iframe " + event.type + "occured");
    1.63 +
    1.64 +  var id;
    1.65 +  if (gOldExpectedWindow && event.type == "blur") {
    1.66 +    if (event.target instanceof Window)
    1.67 +      id = "frame-" + gOldExpectedWindow.document.documentElement.id + "-window";
    1.68 +    else if (event.target instanceof Document)
    1.69 +      id = "frame-" + gOldExpectedWindow.document.documentElement.id + "-document";
    1.70 +    else
    1.71 +      id = event.originalTarget.id;
    1.72 +  }
    1.73 +  else if (gNewExpectedWindow && event.type == "focus") {
    1.74 +    if (event.target instanceof Window)
    1.75 +      id = "frame-" + gNewExpectedWindow.document.documentElement.id + "-window";
    1.76 +    else if (event.target instanceof Document)
    1.77 +      id = "frame-" + gNewExpectedWindow.document.documentElement.id + "-document";
    1.78 +    else
    1.79 +      id = event.originalTarget.id;
    1.80 +  }
    1.81 +  else if (event.type == "activate" || event.type == "deactivate")
    1.82 +    id = event.target.document.documentElement.id + "-window";
    1.83 +  else if (event.target instanceof Window)
    1.84 +    id = (event.target == window) ? "outer-window" : "child-window";
    1.85 +  else if (event.target instanceof Document)
    1.86 +    id = (event.target == document) ? "outer-document" : "child-document";
    1.87 +  else
    1.88 +    id = event.originalTarget.id;
    1.89 +
    1.90 +  if (gEvents)
    1.91 +    gEvents += " ";
    1.92 +  gEvents += event.type + ": " + id;
    1.93 +}
    1.94 +
    1.95 +function expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid)
    1.96 +{
    1.97 +  if (expectedWindow == null)
    1.98 +    expectedWindow = expectedElement ?
    1.99 +                     expectedElement.ownerDocument.defaultView :
   1.100 +                     gLastFocusWindow;
   1.101 +
   1.102 +  var expectedEvents = "";
   1.103 +  if (focusChanged) {
   1.104 +    var id;
   1.105 +    if (getTopWindow(gLastFocusWindow) != getTopWindow(expectedWindow)) {
   1.106 +      id = getTopWindow(gLastFocusWindow).document.documentElement.id;
   1.107 +      expectedEvents += "deactivate: " + id + "-window";
   1.108 +    }
   1.109 +
   1.110 +    if (gLastFocus && gLastFocus.id != "t" + kChildDocumentRootIndex &&
   1.111 +        (!gOldExpectedWindow || gOldExpectedWindow.document.documentElement != gLastFocus)) {
   1.112 +      if (expectedEvents)
   1.113 +        expectedEvents += " ";
   1.114 +      if (!gOldExpectedWindow)
   1.115 +        expectedEvents += "commandupdate: cu ";
   1.116 +      expectedEvents += "blur: " + gLastFocus.id;
   1.117 +    }
   1.118 +
   1.119 +    if (gLastFocusWindow && gLastFocusWindow != expectedWindow) {
   1.120 +      if (!gMoveToFocusFrame) {
   1.121 +        if (gOldExpectedWindow)
   1.122 +          id = "frame-" + gOldExpectedWindow.document.documentElement.id;
   1.123 +        else
   1.124 +          id = (gLastFocusWindow == window) ? "outer" : "child";
   1.125 +        if (expectedEvents)
   1.126 +          expectedEvents += " ";
   1.127 +        expectedEvents += "blur: " + id + "-document " +
   1.128 +                          "blur: " + id + "-window";
   1.129 +      }
   1.130 +    }
   1.131 +
   1.132 +    if (getTopWindow(gLastFocusWindow) != getTopWindow(expectedWindow)) {
   1.133 +      id = getTopWindow(expectedWindow).document.documentElement.id;
   1.134 +      if (expectedEvents)
   1.135 +        expectedEvents += " ";
   1.136 +      expectedEvents += "activate: " + id + "-window";
   1.137 +    }
   1.138 +
   1.139 +    if (expectedWindow && gLastFocusWindow != expectedWindow) {
   1.140 +      if (gNewExpectedWindow)
   1.141 +        id = "frame-" + gNewExpectedWindow.document.documentElement.id;
   1.142 +      else
   1.143 +        id = (expectedWindow == window) ? "outer" : "child";
   1.144 +      if (expectedEvents)
   1.145 +        expectedEvents += " ";
   1.146 +      expectedEvents += "focus: " + id + "-document " +
   1.147 +                        "focus: " + id + "-window";
   1.148 +    }
   1.149 +
   1.150 +    // for this test which fires a mouse event on a label, the document will
   1.151 +    // be focused first and then the label code will focus the related
   1.152 +    // control. This doesn't result in different focus events, but a command
   1.153 +    // update will occur for the document and then a secon command update will
   1.154 +    // occur when the control is focused.
   1.155 +    if (testid == "mouse on html label with content inside")
   1.156 +      expectedEvents += " commandupdate: cu";
   1.157 +
   1.158 +    if (expectedElement &&
   1.159 +        (!gNewExpectedWindow || gNewExpectedWindow.document.documentElement != expectedElement)) {
   1.160 +      if (!gNewExpectedWindow) {
   1.161 +        if (expectedEvents)
   1.162 +          expectedEvents += " ";
   1.163 +        expectedEvents += "commandupdate: cu";
   1.164 +      }
   1.165 +      if (expectedElement.id != "t" + kChildDocumentRootIndex) {
   1.166 +        if (expectedEvents)
   1.167 +          expectedEvents += " ";
   1.168 +        expectedEvents += "focus: " + expectedElement.id;
   1.169 +      }
   1.170 +    }
   1.171 +    else if (expectedWindow && gLastFocusWindow != expectedWindow &&
   1.172 +             !expectedElement) {
   1.173 +      if (expectedEvents)
   1.174 +        expectedEvents += " ";
   1.175 +      expectedEvents += "commandupdate: cu";
   1.176 +    }
   1.177 +  }
   1.178 +
   1.179 +  gLastFocus = expectedElement;
   1.180 +  gLastFocusWindow = expectedWindow;
   1.181 +
   1.182 +  callback();
   1.183 +
   1.184 +  compareEvents(expectedEvents, expectedWindow, expectedElement, testid);
   1.185 +}
   1.186 +
   1.187 +function compareEvents(expectedEvents, expectedWindow, expectedElement, testid)
   1.188 +{
   1.189 +  if (!gShowOutput) {
   1.190 +    gEvents = "";
   1.191 +    return;
   1.192 +  }
   1.193 +
   1.194 +  is(gEvents, expectedEvents, testid + " events");
   1.195 +  gEvents = "";
   1.196 +
   1.197 +  var doc;
   1.198 +  if (expectedWindow == window)
   1.199 +    doc = "outer-document";
   1.200 +  else if (expectedWindow == gChildWindow)
   1.201 +    doc = "inner-document";
   1.202 +  else if (gNewExpectedWindow)
   1.203 +    doc = gNewExpectedWindow.document.body ? gNewExpectedWindow.document.body.id :
   1.204 +                                             gNewExpectedWindow.document.documentElement.id;
   1.205 +  else
   1.206 +    doc = "other-document";
   1.207 +
   1.208 +  var focusedElement = fm.focusedElement;
   1.209 +  is(focusedElement ? focusedElement.id : "none",
   1.210 +     expectedElement ? expectedElement.id : "none", testid + " focusedElement");
   1.211 +  is(fm.focusedWindow, expectedWindow, testid + " focusedWindow");
   1.212 +  var focusedWindow = {};
   1.213 +  is(fm.getFocusedElementForWindow(expectedWindow, false, focusedWindow),
   1.214 +     expectedElement, testid + " getFocusedElementForWindow");
   1.215 +  is(focusedWindow.value, expectedWindow, testid + " getFocusedElementForWindow frame");
   1.216 +  is(expectedWindow.document.hasFocus(), true, testid + " hasFocus");
   1.217 +  is(expectedWindow.document.activeElement ? expectedWindow.document.activeElement.id : "none",
   1.218 +     expectedElement ? expectedElement.id : doc, testid + " activeElement");
   1.219 +  var cdwindow = getTopWindow(expectedWindow);
   1.220 +  if (cdwindow.document.commandDispatcher) {
   1.221 +    is(cdwindow.document.commandDispatcher.focusedWindow, expectedWindow, testid + " commandDispatcher focusedWindow");
   1.222 +    is(cdwindow.document.commandDispatcher.focusedElement, focusedElement, testid + " commandDispatcher focusedElement");
   1.223 +  }
   1.224 +
   1.225 +  if (gLastFocusMethod != -1) {
   1.226 +    is(fm.getLastFocusMethod(null), gLastFocusMethod, testid + " lastFocusMethod null");
   1.227 +    is(fm.getLastFocusMethod(expectedWindow), gLastFocusMethod, testid + " lastFocusMethod window");
   1.228 +  }
   1.229 +
   1.230 +  // the parent should have the iframe focused
   1.231 +  if (doc == "inner-document") {
   1.232 +    is(document.hasFocus(), true, testid + " hasFocus");
   1.233 +    is(fm.getFocusedElementForWindow(window, false, focusedWindow),
   1.234 +       $("childframe"), testid + " getFocusedElementForWindow for parent");
   1.235 +    is(focusedWindow.value, window, testid + " getFocusedElementForWindow for parent frame");
   1.236 +    is(fm.getFocusedElementForWindow(window, true, focusedWindow),
   1.237 +       expectedElement, testid + " getFocusedElementForWindow deep for parent");
   1.238 +    is(focusedWindow.value, gChildWindow, testid + " getFocusedElementForWindow deep for parent frame");
   1.239 +    is(document.activeElement.id, "childframe", testid + " activeElement for parent");
   1.240 +  }
   1.241 +
   1.242 +  // compare the selection for the child window. Skip mouse tests as the caret
   1.243 +  // is adjusted by the selection code for mouse clicks, and not the focus code.
   1.244 +  if (expectedWindow == window) {
   1.245 +    var selection = window.getSelection();
   1.246 +    ok(selection.focusNode == null && selection.focusOffset == 0 &&
   1.247 +       selection.anchorNode == null && selection.anchorOffset == 0, testid + " selection");
   1.248 +  }
   1.249 +  else if ((expectedWindow == gChildWindow) && !testid.indexOf("mouse") == -1) {
   1.250 +    checkSelection(expectedElement, testid);
   1.251 +  }
   1.252 +}
   1.253 +
   1.254 +function checkSelection(node, testid)
   1.255 +{
   1.256 +  var selection = gChildWindow.getSelection();
   1.257 +
   1.258 +  var range = gChildWindow.document.createRange();
   1.259 +  range.selectNodeContents(node);
   1.260 +  if (!node.firstChild || node.localName == "input" ||
   1.261 +       node.localName == "select" || node.localName == "button") {
   1.262 +    range.setStartBefore(node);
   1.263 +    range.setEndBefore(node);
   1.264 +  }
   1.265 +
   1.266 +  if (node.firstChild)
   1.267 +    range.setEnd(range.startContainer, range.startOffset);
   1.268 +
   1.269 +  is(selection.focusNode, range.startContainer, testid + " selection focusNode");
   1.270 +  is(selection.focusOffset, range.startOffset, testid + " selection focusOffset");
   1.271 +  is(selection.anchorNode, range.endContainer, testid + " selection anchorNode");
   1.272 +  is(selection.anchorOffset, range.endOffset, testid + " selection anchorOffset");
   1.273 +}
   1.274 +
   1.275 +function getTopWindow(win)
   1.276 +{
   1.277 +  return win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
   1.278 +             getInterface(Components.interfaces.nsIWebNavigation).
   1.279 +             QueryInterface(Components.interfaces.nsIDocShellTreeItem).rootTreeItem.
   1.280 +             QueryInterface(Components.interfaces.nsIInterfaceRequestor).
   1.281 +             getInterface(Components.interfaces.nsIDOMWindow);
   1.282 +}
   1.283 +
   1.284 +function mouseOnElement(element, expectedElement, focusChanged, testid)
   1.285 +{
   1.286 +  var expectedWindow = (element.ownerDocument.defaultView == gChildWindow) ? gChildWindow : window;
   1.287 +  // on Mac, form elements are not focused when clicking, except for lists and textboxes.
   1.288 +  var noFocusOnMouse = (navigator.platform.indexOf("Mac") == 0);
   1.289 +  if (noFocusOnMouse) {
   1.290 +    if (element.namespaceURI == "http://www.w3.org/1999/xhtml") {
   1.291 +      // links are special. They can be focused but show no focus ring
   1.292 +      if (element.localName == "a" || element.localName == "div" ||
   1.293 +          element.localName == "select" ||
   1.294 +          element.localName == "input" && (element.type == "text" ||
   1.295 +                                           element.type == "password")) {
   1.296 +        noFocusOnMouse = false;
   1.297 +      }
   1.298 +    }
   1.299 +    else if (element.localName == "listbox") {
   1.300 +      noFocusOnMouse = false;
   1.301 +    }
   1.302 +  }
   1.303 +
   1.304 +  if (noFocusOnMouse) {
   1.305 +    // no focus so the last focus method will be 0
   1.306 +    gLastFocusMethod = 0;
   1.307 +    expectFocusShift(function () synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView),
   1.308 +                     expectedWindow, null, true, testid);
   1.309 +    gLastFocusMethod = fm.FLAG_BYMOUSE;
   1.310 +  }
   1.311 +  else {
   1.312 +    expectFocusShift(function () synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView),
   1.313 +                     element.ownerDocument.defaultView,
   1.314 +                     expectedElement, focusChanged, testid);
   1.315 +  }
   1.316 +}
   1.317 +
   1.318 +function done()
   1.319 +{
   1.320 +  var opener = window.opener;
   1.321 +  window.close();
   1.322 +  opener.wrappedJSObject.SimpleTest.finish();
   1.323 +}
   1.324 +
   1.325 +var pressTab = function () synthesizeKey("VK_TAB", { });
   1.326 +
   1.327 +function setFocusTo(id, fwindow)
   1.328 +{
   1.329 +  gLastFocus = getById(id);
   1.330 +  gLastFocusWindow = fwindow;
   1.331 +  if (gLastFocus)
   1.332 +    gLastFocus.focus();
   1.333 +  else
   1.334 +    fm.clearFocus(fwindow);
   1.335 +  gEvents = "";
   1.336 +}
   1.337 +
   1.338 +function getById(id)
   1.339 +{
   1.340 +  if (gNewExpectedWindow)
   1.341 +    return gNewExpectedWindow.document.getElementById(id);
   1.342 +  var element = $(id);
   1.343 +  if (!element)
   1.344 +    element = $("childframe").contentDocument.getElementById(id);
   1.345 +  return element;
   1.346 +}
   1.347 +
   1.348 +function startTest()
   1.349 +{
   1.350 +  if (gTestStarted)
   1.351 +    return;
   1.352 +  gTestStarted = true;
   1.353 +
   1.354 +  gChildWindow = $("childframe").contentWindow;
   1.355 +  gShowOutput = true;
   1.356 +
   1.357 +  // synthesize a mousemove over the image to ensure that the imagemap data is
   1.358 +  // created. Otherwise, the special imagemap frames might not exist, and
   1.359 +  // won't be focusable.
   1.360 +  synthesizeMouse(getById("image"), 4, 4, { type: "mousemove" }, gChildWindow);
   1.361 +
   1.362 +  initEvents(window);
   1.363 +
   1.364 +  is(fm.activeWindow, window, "activeWindow");
   1.365 +  is(gChildWindow.document.hasFocus(), false, " child document hasFocus");
   1.366 +
   1.367 +  // test to see if the Mac Full Keyboard Access setting is set. If t3 is
   1.368 +  // focused after tab is pressed, then it is set to textboxes and lists only.
   1.369 +  // Otherwise, all elements are in the tab order.
   1.370 +  pressTab();
   1.371 +
   1.372 +  if (fm.focusedElement.id == "t3")
   1.373 +    gPartialTabbing = true;
   1.374 +  else
   1.375 +    is(fm.focusedElement.id, "t1", "initial tab key");
   1.376 +
   1.377 +  is(fm.getLastFocusMethod(null), fm.FLAG_BYKEY, "last focus method null start");
   1.378 +  is(fm.getLastFocusMethod(window), fm.FLAG_BYKEY, "last focus method window start");
   1.379 +
   1.380 +  fm.clearFocus(window);
   1.381 +  gEvents = "";
   1.382 +
   1.383 +  gLastFocusMethod = fm.FLAG_BYKEY;
   1.384 +  if (gPartialTabbing) {
   1.385 +    var partialTabList = ["t3", "t5", "t9", "t10", "t11", "t12", "t13", "t14", "t15",
   1.386 +                          "t16", "t19", "t20", "t21", "t22", "t26", "t27", "t28", "t29", "t30"];
   1.387 +    for (var idx = 0; idx < partialTabList.length; idx++) {
   1.388 +      expectFocusShift(pressTab, null, getById(partialTabList[idx]), true, "partial tab key " + partialTabList[idx]);
   1.389 +    }
   1.390 +    setFocusTo("last", window);
   1.391 +    expectFocusShift(pressTab, null, getById(partialTabList[0]), true, "partial tab key wrap to start");
   1.392 +    expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
   1.393 +                     null, getById("last"), true, "partial shift tab key wrap to end");
   1.394 +    for (var idx = partialTabList.length - 1; idx >= 0; idx--) {
   1.395 +      expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
   1.396 +                       null, getById(partialTabList[idx]), true, "partial tab key " + partialTabList[idx]);
   1.397 +    }
   1.398 +  }
   1.399 +  else {
   1.400 +    // TAB key
   1.401 +    for (var idx = 1; idx <= kTabbableSteps; idx++) {
   1.402 +      expectFocusShift(pressTab, null, getById("t" + idx), true, "tab key t" + idx);
   1.403 +    }
   1.404 +
   1.405 +    // wrapping around at end with TAB key
   1.406 +    setFocusTo("last", window);
   1.407 +    expectFocusShift(pressTab, null, getById("t1"), true, "tab key wrap to start");
   1.408 +    expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
   1.409 +                     null, getById("last"), true, "shift tab key wrap to end");
   1.410 +
   1.411 +    // Shift+TAB key
   1.412 +    setFocusTo("o5", window);
   1.413 +    for (idx = kTabbableSteps; idx > 0; idx--) {
   1.414 +      expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
   1.415 +                       null, getById("t" + idx), true, "shift tab key t" + idx);
   1.416 +    }
   1.417 +  }
   1.418 +
   1.419 +  var t19 = getById("t19");
   1.420 +  is(t19.selectionStart, 0, "input focused from tab key selectionStart");
   1.421 +  is(t19.selectionEnd, 5, "input focused from tab key selectionEnd");
   1.422 +  t19.setSelectionRange(0, 0);
   1.423 +
   1.424 +  gLastFocusMethod = 0;
   1.425 +  var selectFired = false;
   1.426 +  function selectListener() { selectFired = true; }
   1.427 +  t19.addEventListener("select", selectListener, false); 
   1.428 +  expectFocusShift(function() t19.select(),
   1.429 +                   null, getById("t" + 19), true, "input.select()");
   1.430 +  t19.removeEventListener("select", selectListener, false); 
   1.431 +  ok(selectFired, "select event fires for input");
   1.432 +
   1.433 +  // mouse clicking
   1.434 +  gLastFocusMethod = fm.FLAG_BYMOUSE;
   1.435 +  for (idx = kTabbableSteps; idx >= 1; idx--) {
   1.436 +    // skip the document root and the overflow element
   1.437 +    if (idx == kChildDocumentRootIndex || idx == kOverflowElementIndex)
   1.438 +      continue;
   1.439 +    if ((navigator.platform.indexOf("Mac") == 0) && (idx == kBeforeTabboxIndex + 1))
   1.440 +      continue;
   1.441 +
   1.442 +    var element = getById("t" + idx);
   1.443 +    // skip area elements, as getBoundingClientRect doesn't return their actual coordinates
   1.444 +    if (element.localName == "area")
   1.445 +      continue;
   1.446 +
   1.447 +    mouseOnElement(element, getById("t" + idx), true, "mouse on element t" + idx);
   1.448 +    var expectedWindow = (element.ownerDocument.defaultView == gChildWindow) ? gChildWindow : window;
   1.449 +    if (element.localName == "listbox" && expectedWindow == window &&
   1.450 +        navigator.platform.indexOf("Mac") == 0) {
   1.451 +      // after focusing a listbox on Mac, clear the focus before continuing.
   1.452 +      setFocusTo(null, window);
   1.453 +    }
   1.454 +  }
   1.455 +
   1.456 +  is(t19.selectionStart, 0, "input focused from mouse selectionStart");
   1.457 +  is(t19.selectionEnd, 0, "input focused from mouse selectionEnd");
   1.458 +
   1.459 +  // mouse clicking on elements that are not tabbable 
   1.460 +  for (idx = 1; idx <= kFocusSteps; idx++) {
   1.461 +    var element = getById("o" + (idx % 2 ? idx : idx - 1));
   1.462 +
   1.463 +    mouseOnElement(element, element, idx % 2,
   1.464 +                   "mouse on non-tabbable element o" + idx);
   1.465 +  }
   1.466 +
   1.467 +  // mouse clicking on elements that are not tabbable and have user-focus: none
   1.468 +  // or are not focusable for other reasons (for instance, being disabled)
   1.469 +  // These elements will clear the focus when clicked.
   1.470 +  for (idx = 1; idx <= kNoFocusSteps; idx++) {
   1.471 +    var element = getById("n" + idx);
   1.472 +    gLastFocusMethod = idx % 2 ? 0 : fm.FLAG_BYMOUSE;
   1.473 +
   1.474 +    mouseOnElement(element, idx % 2 ? null: element, true, "mouse on unfocusable element n" + idx);
   1.475 +  }
   1.476 +
   1.477 +  if (idx == kOverflowElementIndex) {
   1.478 +    gLastFocusMethod = fm.FLAG_BYMOUSE;
   1.479 +    var element = getById("t" + idx);
   1.480 +    expectFocusShift(function () synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView),
   1.481 +                     window, null, true, "mouse on scrollable element");
   1.482 +  }
   1.483 +
   1.484 +  // focus() method
   1.485 +  gLastFocusMethod = 0;
   1.486 +  for (idx = kTabbableSteps; idx >= 1; idx--) {
   1.487 +    if ((navigator.platform.indexOf("Mac") == 0) && (idx == kBeforeTabboxIndex + 1))
   1.488 +      continue;
   1.489 +    expectFocusShift(function () getById("t" + idx).focus(),
   1.490 +                     null, getById("t" + idx), true, "focus method on element t" + idx);
   1.491 +  }
   1.492 +
   1.493 +  $("t1").focus();
   1.494 +  ok(gEvents === "", "focusing element that is already focused");
   1.495 +
   1.496 +  $("t2").blur();
   1.497 +  $("t7").blur();
   1.498 +  ok(gEvents === "", "blurring element that is not focused");
   1.499 +  is(document.activeElement, $("t1"), "old element still focused after blur() on another element");
   1.500 +
   1.501 +  // focus() method on elements that are not tabbable 
   1.502 +  for (idx = 1; idx <= kFocusSteps; idx++) {
   1.503 +    var expected = getById("o" + (idx % 2 ? idx : idx - 1));
   1.504 +    expectFocusShift(function () getById("o" + idx).focus(),
   1.505 +                     expected.ownerDocument.defaultView,
   1.506 +                     expected, idx % 2, "focus method on non-tabbable element o" + idx);
   1.507 +  }
   1.508 +
   1.509 +  // focus() method on elements that are not tabbable and have user-focus: none
   1.510 +  // or are not focusable for other reasons (for instance, being disabled)
   1.511 +  for (idx = 1; idx <= kNoFocusSteps; idx++) {
   1.512 +    var expected = getById("o" + (idx % 2 ? idx : idx - 1));
   1.513 +    expectFocusShift(function () getById("o" + idx).focus(),
   1.514 +                     expected.ownerDocument.defaultView,
   1.515 +                     expected, idx % 2, "focus method on unfocusable element n" + idx);
   1.516 +  }
   1.517 +
   1.518 +  // the focus() method on the legend element should focus the legend if it is
   1.519 +  // focusable, or the first element after the legend if it is not focusable.
   1.520 +  if (!gPartialTabbing) {
   1.521 +    gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
   1.522 +    var legend = getById("legend");
   1.523 +    expectFocusShift(function () legend.focus(),
   1.524 +                     null, getById("t28"), true, "focus method on unfocusable legend");
   1.525 +    gLastFocusMethod = 0;
   1.526 +    legend.tabIndex = "0";
   1.527 +    expectFocusShift(function () legend.focus(),
   1.528 +                     null, getById("legend"), true, "focus method on focusable legend");
   1.529 +    legend.tabIndex = "-1";
   1.530 +  }
   1.531 +
   1.532 +  var accessKeyDetails = (navigator.platform.indexOf("Mac") >= 0) ?
   1.533 +                         { ctrlKey : true } : { altKey : true };
   1.534 +
   1.535 +  // test accesskeys
   1.536 +  var keys = ["t26", "t19", "t22", "t29", "t15", "t17", "n6",
   1.537 +              "t4", "o1", "o9", "n4"];
   1.538 +  for (var k = 0; k < keys.length; k++) {
   1.539 +    var key = String.fromCharCode(65 + k);
   1.540 +
   1.541 +    // accesskeys D and G are for labels so get redirected
   1.542 +    gLastFocusMethod = (key == "D" || key == "G") ? fm.FLAG_BYMOVEFOCUS : fm.FLAG_BYKEY;
   1.543 +
   1.544 +    // on Windows and Linux, the shift key must be pressed for content area access keys
   1.545 +    // and on Mac, the alt key must be pressed for content area access keys
   1.546 +    var isContent = (getById(keys[k]).ownerDocument.defaultView == gChildWindow);
   1.547 +    if (navigator.platform.indexOf("Mac") == -1) {
   1.548 +      accessKeyDetails.shiftKey = isContent;
   1.549 +    } else {
   1.550 +      accessKeyDetails.altKey = isContent;
   1.551 +    }
   1.552 +
   1.553 +    expectFocusShift(function () synthesizeKey(key, accessKeyDetails),
   1.554 +                     null, getById(keys[k]), true, "accesskey " + key);
   1.555 +  }
   1.556 +
   1.557 +  // clicking on the labels
   1.558 +  gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
   1.559 +  expectFocusShift(function () synthesizeMouse(getById("ad"), 2, 2, { }, gChildWindow),
   1.560 +                   null, getById("t29"), true, "mouse on html label with content inside");
   1.561 +  expectFocusShift(function () synthesizeMouse(getById("ag"), 2, 2, { }, gChildWindow),
   1.562 +                   null, getById("n6"), true, "mouse on html label with for attribute");
   1.563 +  gLastFocusMethod = 0;
   1.564 +  expectFocusShift(function () synthesizeMouse(getById("aj"), 2, 2, { }),
   1.565 +                   null, getById("o9"), true, "mouse on xul label with content inside");
   1.566 +  expectFocusShift(function () synthesizeMouse(getById("ak"), 2, 2, { }),
   1.567 +                   null, getById("n4"), true, "mouse on xul label with control attribute");
   1.568 +
   1.569 +  // test accesskeys that shouldn't work
   1.570 +  k = "o".charCodeAt(0);
   1.571 +  while (k++ < "v".charCodeAt(0)) {
   1.572 +    var key = String.fromCharCode(k);
   1.573 +    expectFocusShift(function () synthesizeKey(key, accessKeyDetails),
   1.574 +                     window, getById("n4"), false, "non accesskey " + key);
   1.575 +  }
   1.576 +  gLastFocusMethod = -1;
   1.577 +
   1.578 +  // should focus the for element when using the focus method on a label as well
   1.579 +  expectFocusShift(function () getById("ad").focus(),
   1.580 +                   null, getById("t29"), true, "mouse on html label using focus method");
   1.581 +
   1.582 +  // make sure that the text is selected when clicking a label associated with an input
   1.583 +  getById("ag").htmlFor = "t19";
   1.584 +  expectFocusShift(function () synthesizeMouse(getById("ag"), 2, 2, { }, gChildWindow),
   1.585 +                   null, getById("t19"), true, "mouse on html label with for attribute changed");
   1.586 +  is(t19.selectionStart, 0, "input focused from label, selectionStart");
   1.587 +  is(t19.selectionEnd, 5, "input focused from label, selectionEnd");
   1.588 +
   1.589 +  // switch to another panel in a tabbox and ensure that tabbing moves between
   1.590 +  // elements on the new panel.
   1.591 +  $("tabbox").selectedIndex = 1;
   1.592 +  expectFocusShift(function () getById("t" + kBeforeTabboxIndex).focus(),
   1.593 +                   null, getById("t" + kBeforeTabboxIndex), true, "focus method on element before tabbox");
   1.594 +
   1.595 +  if (!gPartialTabbing) {
   1.596 +    expectFocusShift(pressTab, null, getById("tab2"), true, "focus method on tab");
   1.597 +    expectFocusShift(pressTab, null, getById("htab1"), true, "tab key switch tabpanel 1");
   1.598 +    expectFocusShift(pressTab, null, getById("htab2"), true, "tab key switch tabpanel 2");
   1.599 +    expectFocusShift(pressTab, null, getById("t" + (kBeforeTabboxIndex + 4)), true, "tab key switch tabpanel 3");
   1.600 +  }
   1.601 +  $("tabbox").selectedIndex = 0;
   1.602 +
   1.603 +  // ---- the following checks when the focus changes during a blur or focus event ----
   1.604 +
   1.605 +  var o5 = $("o5");
   1.606 +  var o9 = $("o9");
   1.607 +  var t3 = $("t3");
   1.608 +  var t17 = getById("t17");
   1.609 +  var t19 = getById("t19");
   1.610 +  var shiftFocusParentDocument = function() o9.focus();
   1.611 +  var shiftFocusChildDocument = function() t17.focus();
   1.612 +
   1.613 +  var trapBlur = function (element, eventListener, blurFunction)
   1.614 +  {
   1.615 +    element.focus();
   1.616 +    gEvents = "";
   1.617 +    element.addEventListener("blur", eventListener, false);
   1.618 +    blurFunction();
   1.619 +    element.removeEventListener("blur", eventListener, false);
   1.620 +  }
   1.621 +
   1.622 +  var functions = [
   1.623 +    function(element) element.focus(),
   1.624 +    function(element) synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView)
   1.625 +  ];
   1.626 +
   1.627 +  // first, check cases where the focus is adjusted during the blur event. Iterate twice,
   1.628 +  // once with the focus method and then focusing by mouse clicking
   1.629 +  for  (var l = 0; l < 2; l++) {
   1.630 +    var adjustFocus = functions[l];
   1.631 +    var mod = (l == 1) ? " with mouse" : "";
   1.632 +
   1.633 +    // an attempt is made to switch the focus from one element (o5) to another
   1.634 +    // element (t3) within the same document, yet the focus is shifted to a
   1.635 +    // third element (o9) in the same document during the blur event for the
   1.636 +    // first element.
   1.637 +    trapBlur(o5, shiftFocusParentDocument, function () adjustFocus(t3));
   1.638 +    compareEvents("commandupdate: cu blur: o5 commandupdate: cu focus: o9",
   1.639 +                  window, o9, "change focus to sibling during element blur, attempted sibling" + mod);
   1.640 +
   1.641 +    // similar, but the third element (t17) is in a child document
   1.642 +    trapBlur(o9, shiftFocusChildDocument, function () adjustFocus(t3));
   1.643 +    compareEvents("commandupdate: cu blur: o9 blur: outer-document blur: outer-window " +
   1.644 +                  "focus: child-document focus: child-window commandupdate: cu focus: t17",
   1.645 +                  gChildWindow, t17, "change focus to child document during element blur, attempted sibling" + mod);
   1.646 +
   1.647 +    // similar, but an attempt to switch focus within the same document, but the
   1.648 +    // third element (t17) is in a parent document
   1.649 +    trapBlur(t17, shiftFocusParentDocument, function () adjustFocus(t19));
   1.650 +    compareEvents("commandupdate: cu blur: t17 blur: child-document blur: child-window " +
   1.651 +                  "focus: outer-document focus: outer-window commandupdate: cu focus: o9",
   1.652 +                  window, o9, "change focus to parent document during element blur, attempted sibling" + mod);
   1.653 +
   1.654 +    // similar, but blur is called instead of switching focus
   1.655 +    trapBlur(t3, shiftFocusParentDocument, function () t3.blur());
   1.656 +    compareEvents("commandupdate: cu blur: t3 commandupdate: cu focus: o9",
   1.657 +                  window, o9, "change focus to same document during clear focus" + mod);
   1.658 +
   1.659 +    // check when an element in the same document is focused during the
   1.660 +    // element's blur event, but an attempt was made to focus an element in the
   1.661 +    // child document. In this case, the focus in the parent document should be
   1.662 +    // what was set during the blur event, but the actual focus should still
   1.663 +    // move to the child document.
   1.664 +    trapBlur(t3, shiftFocusParentDocument, function () adjustFocus(t17));
   1.665 +    compareEvents("commandupdate: cu blur: t3 commandupdate: cu focus: o9 " +
   1.666 +                  "blur: outer-document blur: outer-window " +
   1.667 +                  "focus: child-document focus: child-window commandupdate: cu focus: t17",
   1.668 +                  gChildWindow, t17, "change focus to sibling during element blur, attempted child" + mod);
   1.669 +    is(fm.getFocusedElementForWindow(window, false, {}), $("childframe"),
   1.670 +       "change focus to sibling during element blur, attempted child, focused in parent" + mod);
   1.671 +
   1.672 +    // similar, but with a parent
   1.673 +    trapBlur(t19, shiftFocusChildDocument, function () adjustFocus(t3));
   1.674 +    compareEvents("commandupdate: cu blur: t19 commandupdate: cu focus: t17 " +
   1.675 +                  "blur: child-document blur: child-window " +
   1.676 +                  "focus: outer-document focus: outer-window commandupdate: cu focus: t3",
   1.677 +                  window, t3, "change focus to sibling during element blur, attempted parent" + mod);
   1.678 +    is(fm.getFocusedElementForWindow(gChildWindow, false, {}), t17,
   1.679 +       "change focus to sibling during element blur, attempted child, focused in child" + mod);
   1.680 +
   1.681 +    // similar, with a child, but the blur event focuses a child element also
   1.682 +    trapBlur(t3, shiftFocusChildDocument, function () adjustFocus(t19));
   1.683 +    compareEvents("commandupdate: cu blur: t3 blur: outer-document blur: outer-window " +
   1.684 +                  "focus: child-document focus: child-window commandupdate: cu focus: t17",
   1.685 +                  gChildWindow, t17, "change focus to child during element blur, attempted child" + mod);
   1.686 +
   1.687 +    // similar, with a parent, where the blur event focuses a parent element also
   1.688 +    trapBlur(t17, shiftFocusParentDocument, function () adjustFocus(t3));
   1.689 +    compareEvents("commandupdate: cu blur: t17 blur: child-document blur: child-window " +
   1.690 +                  "focus: outer-document focus: outer-window commandupdate: cu focus: o9",
   1.691 +                  window, o9, "change focus to parent during element blur, attempted parent" + mod);
   1.692 +  }
   1.693 +
   1.694 +  var trapFocus = function (element, eventListener)
   1.695 +  {
   1.696 +    element.addEventListener("focus", eventListener, false);
   1.697 +    element.focus();
   1.698 +    element.removeEventListener("focus", eventListener, false);
   1.699 +  }
   1.700 +
   1.701 +  fm.clearFocus(window);
   1.702 +  gEvents = "";
   1.703 +
   1.704 +  // next, check cases where the focus is adjusted during the focus event
   1.705 +
   1.706 +  // switch focus to an element in the same document  
   1.707 +  trapFocus(o5, shiftFocusParentDocument);
   1.708 +  compareEvents("commandupdate: cu focus: o5 commandupdate: cu blur: o5 commandupdate: cu focus: o9",
   1.709 +                window, o9, "change focus to sibling during element focus");
   1.710 +
   1.711 +  // similar, but the new element (t17) is in a child document
   1.712 +  trapFocus(o5, shiftFocusChildDocument);
   1.713 +  compareEvents("commandupdate: cu blur: o9 " +
   1.714 +                "commandupdate: cu focus: o5 commandupdate: cu blur: o5 " +
   1.715 +                "blur: outer-document blur: outer-window " +
   1.716 +                "focus: child-document focus: child-window commandupdate: cu focus: t17",
   1.717 +                gChildWindow, t17, "change focus to child document during element focus");
   1.718 +
   1.719 +  // similar, but the new element (o9) is in a parent document.
   1.720 +  trapFocus(t19, shiftFocusParentDocument);
   1.721 +  compareEvents("commandupdate: cu blur: t17 " +
   1.722 +                "commandupdate: cu focus: t19 commandupdate: cu blur: t19 " +
   1.723 +                "blur: child-document blur: child-window " +
   1.724 +                "focus: outer-document focus: outer-window commandupdate: cu focus: o9",
   1.725 +                window, o9, "change focus to parent document during element focus");
   1.726 +
   1.727 +  // clear the focus during the focus event
   1.728 +  trapFocus(t3, function () fm.clearFocus(window));
   1.729 +  compareEvents("commandupdate: cu blur: o9 commandupdate: cu focus: t3 commandupdate: cu blur: t3",
   1.730 +                window, null, "clear focus during focus event");
   1.731 +
   1.732 +  if (!gPartialTabbing)
   1.733 +    doCommandDispatcherTests();
   1.734 +
   1.735 +  testMoveFocus();
   1.736 +
   1.737 +  doRemoveTests();
   1.738 +
   1.739 +  // tests various focus manager apis for null checks
   1.740 +  var exh = false;
   1.741 +  try {
   1.742 +    fm.clearFocus(null);
   1.743 +  }
   1.744 +  catch (ex) { exh = true; }
   1.745 +  is(exh, true, "clearFocus with null window causes exception");
   1.746 +
   1.747 +  var exh = false;
   1.748 +  try {
   1.749 +    fm.getFocusedElementForWindow(null, false, focusedWindow);
   1.750 +  }
   1.751 +  catch (ex) { exh = true; }
   1.752 +  is(exh, true, "getFocusedElementForWindow with null window causes exception");
   1.753 +
   1.754 +  // just make sure that this doesn't crash
   1.755 +  fm.moveCaretToFocus(null);
   1.756 +
   1.757 +  // ---- tests for the FLAG_NOSWITCHFRAME flag
   1.758 +  getById("o5").focus();
   1.759 +  gLastFocusMethod = 0;
   1.760 +  gEvents = "";
   1.761 +  // focus is being shifted in a child, so the focus should not change
   1.762 +  expectFocusShift(function () fm.setFocus(getById("t20"), fm.FLAG_NOSWITCHFRAME),
   1.763 +                   window, getById("o5"), false, "no switch frame focus to child");
   1.764 +  setFocusTo("t20", gChildWindow);
   1.765 +
   1.766 +  // here, however, focus is being shifted in a parent, which will have to blur
   1.767 +  // the child, so the focus will always change
   1.768 +  expectFocusShift(function () fm.setFocus(getById("o5"), fm.FLAG_NOSWITCHFRAME),
   1.769 +                   window, getById("o5"), true, "no switch frame focus to parent");
   1.770 +
   1.771 +  expectFocusShift(function () fm.setFocus(getById("t1"), fm.FLAG_NOSWITCHFRAME),
   1.772 +                   window, getById("t1"), true, "no switch frame focus to same window");
   1.773 +
   1.774 +  // ---- tests for focus and scrolling into view ----
   1.775 +  var inscroll = getById("inscroll");
   1.776 +  inscroll.tabIndex = 0;
   1.777 +  is(inscroll.parentNode.scrollTop, 0, "scroll position before focus");
   1.778 +  inscroll.focus();
   1.779 +  ok(inscroll.parentNode.scrollTop > 5, "scroll position after focus");
   1.780 +  inscroll.parentNode.scrollTop = 0;
   1.781 +  fm.setFocus(inscroll, fm.FLAG_NOSCROLL);
   1.782 +  is(inscroll.parentNode.scrollTop, 0, "scroll position after noscroll focus");
   1.783 +
   1.784 +  getById("t9").focus();
   1.785 +  getById("inpopup1").focus();
   1.786 +  is(fm.focusedElement, getById("t9"), "focus in closed popup");
   1.787 +
   1.788 +  // ---- tests to check if tabbing out of a textbox works
   1.789 +
   1.790 +  setFocusTo("t1", window);
   1.791 +
   1.792 +  var textbox1 = document.createElement("textbox");
   1.793 +  $("innerbox").appendChild(textbox1);
   1.794 +
   1.795 +  var textbox2 = document.createElement("textbox");
   1.796 +  $("innerbox").appendChild(textbox2);
   1.797 +
   1.798 +  gLastFocusMethod = 0;
   1.799 +  expectFocusShift(function () textbox2.focus(),
   1.800 +                   null, textbox2.inputField, true, "focus on textbox");
   1.801 +  gLastFocusMethod = fm.FLAG_BYKEY;
   1.802 +  expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
   1.803 +                   null, textbox1.inputField, true, "shift+tab on textbox");
   1.804 +
   1.805 +  textbox1.tabIndex = 2;
   1.806 +  textbox2.tabIndex = 2;
   1.807 +  gLastFocusMethod = 0;
   1.808 +  expectFocusShift(function () textbox2.focus(),
   1.809 +                   null, textbox2.inputField, true, "focus on textbox with tabindex set");
   1.810 +  gLastFocusMethod = fm.FLAG_BYKEY;
   1.811 +  expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
   1.812 +                   null, textbox1.inputField, true, "shift+tab on textbox with tabindex set");
   1.813 +
   1.814 +  // ---- test for bug 618907 which ensures that canceling the mousedown event still focuses the
   1.815 +  //      right frame
   1.816 +
   1.817 +  var childContentFrame = document.getElementById("ifa")
   1.818 +  childContentFrame.style.MozUserFocus = "";
   1.819 +
   1.820 +  var frab = childContentFrame.contentDocument.getElementById("fra-b");
   1.821 +  var mouseDownListener = function(event) event.preventDefault();
   1.822 +  frab.addEventListener("mousedown", mouseDownListener, false);
   1.823 +
   1.824 +  var childElementToFocus = childContentFrame.contentDocument.getElementById("fra");
   1.825 +  gLastFocus = childElementToFocus;
   1.826 +  gLastFocusWindow = childContentFrame.contentWindow;
   1.827 +  gLastFocus.focus();
   1.828 +  gEvents = "";
   1.829 +
   1.830 +  setFocusTo("t1", window);
   1.831 +
   1.832 +  gLastFocusMethod = -1;
   1.833 +  expectFocusShift(function () synthesizeMouse(frab, 5, 5, { }, childContentFrame.contentWindow),
   1.834 +                   null, childElementToFocus, true,
   1.835 +                   "mousedown event canceled - chrome to content");
   1.836 +
   1.837 +  frab.removeEventListener("mousedown", mouseDownListener, false);
   1.838 +
   1.839 +  var t5 = getById("t5");
   1.840 +  t5.addEventListener("mousedown", mouseDownListener, false);
   1.841 +  synthesizeMouse(t5, 10, 10, { })
   1.842 +  t5.removeEventListener("mousedown", mouseDownListener, false);
   1.843 +  is(fm.focusedElement, childElementToFocus,
   1.844 +     "mousedown event cancelled - content to chrome - element");
   1.845 +  is(fm.focusedWindow, childContentFrame.contentWindow, "mousedown event cancelled - content to chrome - window");
   1.846 +
   1.847 +  // ---- test to check that refocusing an element during a blur event doesn't succeed
   1.848 +
   1.849 +  var t1 = getById("t1");
   1.850 +  t1.addEventListener("blur", function() t1.focus(), true);
   1.851 +  t1.focus();
   1.852 +  var t3 = getById("t3");
   1.853 +  synthesizeMouse(t3, 2, 2, { });
   1.854 +  is(fm.focusedElement, t3, "focus during blur");
   1.855 +
   1.856 +  setFocusTo("t9", window);
   1.857 +  gLastFocusMethod = -1;
   1.858 +  window.openDialog("focus_window2.xul", "_blank", "chrome", otherWindowFocused);
   1.859 +}
   1.860 +
   1.861 +function doCommandDispatcherTests()
   1.862 +{
   1.863 +  var t19 = getById("t19");
   1.864 +  t19.focus();
   1.865 +  gLastFocusWindow = gChildWindow;
   1.866 +  gLastFocus = t19;
   1.867 +  gEvents = "";
   1.868 +
   1.869 +  expectFocusShift(function () document.commandDispatcher.focusedElement = getById("o9"),
   1.870 +                   null, getById("o9"), true, "command dispatcher set focusedElement");
   1.871 +  expectFocusShift(function () document.commandDispatcher.advanceFocus(),
   1.872 +                   null, getById("o13"), true, "command dispatcher advanceFocus");
   1.873 +  expectFocusShift(function () document.commandDispatcher.rewindFocus(),
   1.874 +                   null, getById("o9"), true, "command dispatcher rewindFocus");
   1.875 +  expectFocusShift(function () document.commandDispatcher.focusedElement = null,
   1.876 +                   null, null, true, "command dispatcher set focusedElement to null");
   1.877 +  expectFocusShift(function () document.commandDispatcher.focusedWindow = gChildWindow,
   1.878 +                   null, getById("t19"), true, "command dispatcher set focusedElement to null");
   1.879 +  expectFocusShift(function () document.commandDispatcher.focusedElement = null,
   1.880 +                   gChildWindow, null, true, "command dispatcher set focusedElement to null in child");
   1.881 +  expectFocusShift(function () document.commandDispatcher.advanceFocusIntoSubtree(getById("t19")),
   1.882 +                   null, getById("t20"), true, "command dispatcher advanceFocusIntoSubtree child");
   1.883 +  expectFocusShift(function () document.commandDispatcher.advanceFocusIntoSubtree(null),
   1.884 +                   null, getById("t21"), true, "command dispatcher advanceFocusIntoSubtree null child");
   1.885 +  expectFocusShift(function () document.commandDispatcher.advanceFocusIntoSubtree(getById("o9").parentNode),
   1.886 +                   null, getById("o9"), true, "command dispatcher advanceFocusIntoSubtree parent");
   1.887 +}
   1.888 +
   1.889 +function doRemoveTests()
   1.890 +{
   1.891 +  // next, some tests which remove elements
   1.892 +  var t19 = getById("t19");
   1.893 +  t19.focus();
   1.894 +  t19.parentNode.removeChild(t19);
   1.895 +
   1.896 +  is(fm.focusedElement, null, "removed element focusedElement");
   1.897 +  is(fm.focusedWindow, gChildWindow, "removed element focusedWindow");
   1.898 +  is(gChildWindow.document.hasFocus(), true, "removed element hasFocus");
   1.899 +  is(gChildWindow.document.activeElement, getById("inner-document"), "removed element activeElement");
   1.900 +
   1.901 +  getById("t15").focus();
   1.902 +  var abs = getById("abs");
   1.903 +  abs.parentNode.removeChild(abs);
   1.904 +
   1.905 +  is(fm.focusedElement, null, "removed ancestor focusedElement");
   1.906 +  is(fm.focusedWindow, gChildWindow, "removed ancestor focusedWindow");
   1.907 +  is(gChildWindow.document.hasFocus(), true, "removed ancestor hasFocus");
   1.908 +  is(gChildWindow.document.activeElement, getById("inner-document"), "removed ancestor activeElement");
   1.909 +}
   1.910 +
   1.911 +// tests for the FocusManager moveFocus method
   1.912 +function testMoveFocus()
   1.913 +{
   1.914 +  setFocusTo("t6", window);
   1.915 +
   1.916 +  // moving focus while an element is already focused
   1.917 +  var newFocus;
   1.918 +  gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
   1.919 +  var expectedFirst = getById(gPartialTabbing ? "t3" : "t1");
   1.920 +  expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FIRST, 0),
   1.921 +                   window, expectedFirst, true, "moveFocus to first null window null content");
   1.922 +  is(newFocus, fm.focusedElement, "moveFocus to first null window null content return value");
   1.923 +
   1.924 +  expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_LAST, 0),
   1.925 +                   window, getById("last"), true, "moveFocus to last null window null content");
   1.926 +  is(newFocus, fm.focusedElement, "moveFocus to last null window null content return value");
   1.927 +
   1.928 +  gLastFocusMethod = 0;
   1.929 +  newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_ROOT, 0);
   1.930 +  is(newFocus, null, "moveFocus to root null window null content return value");
   1.931 +  is(fm.focusedWindow, window, "moveFocus to root null window null content focusedWindow");
   1.932 +  is(fm.focusedElement, null, "moveFocus to root null window null content focusedElement");
   1.933 +
   1.934 +  // moving focus while no element is focused
   1.935 +  fm.clearFocus(window);
   1.936 +  gEvents = "";
   1.937 +  gLastFocus = null;
   1.938 +  gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
   1.939 +  expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FIRST, 0),
   1.940 +                   window, expectedFirst, true, "moveFocus to first null window null content no focus");
   1.941 +  is(newFocus, fm.focusedElement, "moveFocus to first null window null content no focus return value");
   1.942 +  fm.clearFocus(window);
   1.943 +  gEvents = "";
   1.944 +  gLastFocus = null;
   1.945 +  expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_LAST, 0),
   1.946 +                   window, getById("last"), true, "moveFocus to last null window null content no focus");
   1.947 +  is(newFocus, fm.focusedElement, "moveFocus to last null window null content no focus return value");
   1.948 +  fm.clearFocus(window);
   1.949 +  gEvents = "";
   1.950 +  gLastFocusMethod = 0;
   1.951 +  newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_ROOT, 0);
   1.952 +  is(newFocus, null, "moveFocus to root null window null content no focus return value");
   1.953 +  is(fm.focusedWindow, window, "moveFocus to root null window null content no focus focusedWindow");
   1.954 +  is(fm.focusedElement, null, "moveFocus to root null window null content no focus focusedElement");
   1.955 +
   1.956 +  // moving focus from a specified element
   1.957 +  setFocusTo("t6", window);
   1.958 +  gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
   1.959 +  expectFocusShift(function () newFocus = fm.moveFocus(null, getById("specialroot"), fm.MOVEFOCUS_FIRST, 0),
   1.960 +                   window, getById("t3"), true, "moveFocus to first null window with content");
   1.961 +// XXXndeakin P3 this doesn't work
   1.962 +//  expectFocusShift(function () newFocus = fm.moveFocus(null, getById("specialroot"), fm.MOVEFOCUS_LAST, 0),
   1.963 +//                   window, getById("o3"), true, "moveFocus to last null window with content");
   1.964 +
   1.965 +  // move focus to first in child window
   1.966 +  expectFocusShift(function () newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_FIRST, 0),
   1.967 +                   gChildWindow, getById("t" + (kChildDocumentRootIndex + 1)), true,
   1.968 +                   "moveFocus to first child window null content");
   1.969 +  is(newFocus, getById("t" + (kChildDocumentRootIndex + 1)),
   1.970 +     "moveFocus to first child window null content return value");
   1.971 +
   1.972 +  // move focus to last in child window
   1.973 +  setFocusTo("t6", window);
   1.974 +  var expectedLast = getById(gPartialTabbing ? "t30" : "t" + (kBeforeTabboxIndex - 1));
   1.975 +  expectFocusShift(function () newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_LAST, 0),
   1.976 +                   gChildWindow, expectedLast, true,
   1.977 +                   "moveFocus to last child window null content");
   1.978 +  is(newFocus, getById(expectedLast),
   1.979 +     "moveFocus to last child window null content return value");
   1.980 +
   1.981 +  // move focus to root in child window
   1.982 +  setFocusTo("t6", window);
   1.983 +  var childroot = getById("t" + kChildDocumentRootIndex);
   1.984 +  gLastFocusMethod = 0;
   1.985 +  newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_ROOT, 0),
   1.986 +  is(newFocus, childroot, "moveFocus to root child window null content return value");
   1.987 +  is(fm.focusedWindow, gChildWindow, "moveFocus to root child window null content focusedWindow");
   1.988 +  is(fm.focusedElement, childroot, "moveFocus to root child window null content focusedElement");
   1.989 +
   1.990 +  // MOVEFOCUS_CARET tests
   1.991 +  getById("t20").focus();
   1.992 +  gEvents = "";
   1.993 +
   1.994 +  var selection = gChildWindow.getSelection();
   1.995 +  selection.removeAllRanges();
   1.996 +
   1.997 +  newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
   1.998 +  is(newFocus, null, "move caret when at document root");
   1.999 +  is(fm.focusedElement, null, "move caret when at document root");
  1.1000 +
  1.1001 +  var node = getById("t16").firstChild;
  1.1002 +  var range = gChildWindow.document.createRange();
  1.1003 +  range.setStart(node, 3);
  1.1004 +  range.setEnd(node, 3);
  1.1005 +  selection.addRange(range);
  1.1006 +
  1.1007 +  newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
  1.1008 +  is(newFocus, null, "move caret to non-link return value");
  1.1009 +  is(fm.focusedElement, null, "move caret to non-link");
  1.1010 +
  1.1011 +  var t25 = getById("t25");
  1.1012 +  var node = t25.firstChild;
  1.1013 +  range.setStart(node, 1);
  1.1014 +  range.setEnd(node, 1);
  1.1015 +  newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
  1.1016 +
  1.1017 +  is(newFocus, t25, "move caret to link return value");
  1.1018 +  is(fm.focusedElement, t25, "move caret to link focusedElement");
  1.1019 +
  1.1020 +  // enable caret browsing temporarily to test caret movement
  1.1021 +  var prefs = Components.classes["@mozilla.org/preferences-service;1"].
  1.1022 +                getService(Components.interfaces.nsIPrefBranch);
  1.1023 +  prefs.setBoolPref("accessibility.browsewithcaret", true);
  1.1024 +
  1.1025 +  synthesizeKey("VK_LEFT", { }, gChildWindow);
  1.1026 +  synthesizeKey("VK_LEFT", { }, gChildWindow);
  1.1027 +  is(fm.focusedElement, null, "move caret away from link");
  1.1028 +
  1.1029 +  synthesizeKey("VK_LEFT", { }, gChildWindow);
  1.1030 +  is(fm.focusedElement, getById("t24"), "move caret away onto link");
  1.1031 +
  1.1032 +  prefs.setBoolPref("accessibility.browsewithcaret", false);
  1.1033 +
  1.1034 +  // cases where focus in on a content node with no frame
  1.1035 +
  1.1036 +  if (!gPartialTabbing) {
  1.1037 +    getById("t24").blur();
  1.1038 +    gEvents = "";
  1.1039 +    gLastFocus = null;
  1.1040 +    gLastFocusWindow = gChildWindow;
  1.1041 +    gLastFocusMethod = fm.FLAG_BYKEY;
  1.1042 +
  1.1043 +    selection.selectAllChildren(getById("hiddenspan"));
  1.1044 +    expectFocusShift(function () synthesizeKey("VK_TAB", { }),
  1.1045 +                     gChildWindow, getById("t26"), true, "tab with selection on hidden content");
  1.1046 +
  1.1047 +    setFocusTo($("o15"), window);
  1.1048 +    $("o15").hidden = true;
  1.1049 +    document.documentElement.getBoundingClientRect(); // flush after hiding
  1.1050 +    expectFocusShift(function () synthesizeKey("VK_TAB", { }),
  1.1051 +                     window, $("o17"), true, "tab with focus on hidden content");
  1.1052 +
  1.1053 +    $("o17").hidden = true;
  1.1054 +    document.documentElement.getBoundingClientRect();
  1.1055 +    expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
  1.1056 +                     window, $("o13"), true, "shift+tab with focus on hidden content");
  1.1057 +  }
  1.1058 +
  1.1059 +  // cases with selection in an <input>
  1.1060 +
  1.1061 +  var t19 = getById("t19");
  1.1062 +  t19.setSelectionRange(0, 0);
  1.1063 +  setFocusTo("t18", gChildWindow);
  1.1064 +
  1.1065 +  gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
  1.1066 +  expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FORWARD, 0),
  1.1067 +                   gChildWindow, t19, true, "moveFocus to next textbox");
  1.1068 +  is(t19.selectionStart, 0, "input focused after moveFocus selectionStart");
  1.1069 +  is(t19.selectionEnd, 5, "input focused after moveFocus selectionEnd");
  1.1070 +
  1.1071 +  t19.setSelectionRange(0, 0);
  1.1072 +  setFocusTo("t18", gChildWindow);
  1.1073 +  gLastFocusMethod = fm.FLAG_BYKEY;
  1.1074 +  expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FORWARD, fm.FLAG_BYKEY),
  1.1075 +                   gChildWindow, t19, true, "moveFocus to next textbox by key");
  1.1076 +  is(t19.selectionStart, 0, "input focused after moveFocus by key selectionStart");
  1.1077 +  is(t19.selectionEnd, 5, "input focused after moveFocus by key selectionEnd");
  1.1078 +}
  1.1079 +
  1.1080 +function otherWindowFocused(otherWindow)
  1.1081 +{
  1.1082 +  var expectedElement = getById("t9");
  1.1083 +
  1.1084 +  is(fm.activeWindow, otherWindow, "other activeWindow");
  1.1085 +  is(fm.focusedWindow, otherWindow, "other focusedWindow");
  1.1086 +  is(window.document.hasFocus(), false, "when lowered document hasFocus");
  1.1087 +  var focusedWindow = {};
  1.1088 +  is(fm.getFocusedElementForWindow(window, false, focusedWindow),
  1.1089 +     expectedElement, "when lowered getFocusedElementForWindow");
  1.1090 +  is(focusedWindow.value, window, "when lowered getFocusedElementForWindow frame");
  1.1091 +  is(document.activeElement.id, expectedElement.id, "when lowered activeElement");
  1.1092 +  is(window.document.commandDispatcher.focusedWindow, window, " commandDispatcher in other window focusedWindow");
  1.1093 +  is(window.document.commandDispatcher.focusedElement, expectedElement, " commandDispatcher in other window focusedElement");
  1.1094 +
  1.1095 +  compareEvents("deactivate: outer-document-window blur: t9 blur: outer-document blur: outer-window",
  1.1096 +                otherWindow, null, "other window opened");
  1.1097 +
  1.1098 +  otherWindow.document.getElementById("other").focus();
  1.1099 +
  1.1100 +  for (var idx = kTabbableSteps; idx >= 1; idx--) {
  1.1101 +    expectedElement = getById("t" + idx);
  1.1102 +    if (!expectedElement) // skip elements that were removed in doRemoveTests()
  1.1103 +      continue;
  1.1104 +    if ((navigator.platform.indexOf("Mac") == 0) && (idx == kBeforeTabboxIndex + 1))
  1.1105 +      continue;
  1.1106 +
  1.1107 +    expectedElement.focus();
  1.1108 +
  1.1109 +    is(fm.focusedElement.id, "other", "when lowered focusedElement t" + idx);
  1.1110 +    is(fm.focusedWindow, otherWindow, "when lowered focusedWindow t" + idx);
  1.1111 +
  1.1112 +    var checkWindow = expectedElement.ownerDocument.defaultView;
  1.1113 +    is(fm.getFocusedElementForWindow(checkWindow, false, {}).id, expectedElement.id,
  1.1114 +       "when lowered getFocusedElementForWindow t" + idx);
  1.1115 +    is(checkWindow.document.activeElement.id, expectedElement.id, "when lowered activeElement t" + idx);
  1.1116 +    if (checkWindow != window) {
  1.1117 +      is(fm.getFocusedElementForWindow(window, false, {}), $("childframe"),
  1.1118 +         "when lowered parent getFocusedElementForWindow t" + idx);
  1.1119 +      is(document.activeElement.id, "childframe",
  1.1120 +         "when lowered parent activeElement t" + idx);
  1.1121 +    }
  1.1122 +  }
  1.1123 +
  1.1124 +  gEvents = gEvents.replace(/commandupdate: cu\s?/g, "");
  1.1125 +  is(gEvents, "", "when lowered no events fired");
  1.1126 +
  1.1127 +  var other = otherWindow.document.getElementById("other");
  1.1128 +  other.focus();
  1.1129 +  is(fm.focusedElement, other, "focus method in second window");
  1.1130 +
  1.1131 +  otherWindow.close();
  1.1132 +
  1.1133 +  getById("n2").focus();
  1.1134 +
  1.1135 +  // next, check modal dialogs
  1.1136 +  // XXXndeakin Bug 621399 - the modal dialog test as well as later tests sometime fail
  1.1137 +  // on Windows 8 so just end the test here.
  1.1138 +  if (navigator.userAgent.indexOf("Windows NT 6.2") >= 0) {
  1.1139 +    done();
  1.1140 +  }
  1.1141 +  else {
  1.1142 +    window.openDialog("focus_window2.xul", "_blank", "chrome,modal", modalWindowOpened);
  1.1143 +  }
  1.1144 +}
  1.1145 +
  1.1146 +function modalWindowOpened(modalWindow)
  1.1147 +{
  1.1148 +  var elem = modalWindow.document.getElementById("other");
  1.1149 +  if (gPartialTabbing)
  1.1150 +    elem.focus();
  1.1151 +  else
  1.1152 +    synthesizeKey("VK_TAB", { }, modalWindow);
  1.1153 +  is(fm.activeWindow, modalWindow, "modal activeWindow");
  1.1154 +  is(fm.focusedElement, elem, "modal focusedElement");
  1.1155 +
  1.1156 +  modalWindow.close();
  1.1157 +  SimpleTest.waitForFocus(modalWindowClosed);
  1.1158 +}
  1.1159 +
  1.1160 +function modalWindowClosed()
  1.1161 +{
  1.1162 +  is(fm.activeWindow, window, "modal window closed activeWindow");
  1.1163 +  is(fm.focusedElement, getById("n2"), "modal window closed focusedElement");
  1.1164 +
  1.1165 +  window.open("focus_frameset.html", "_blank", "width=400,height=400,toolbar=no");
  1.1166 +}
  1.1167 +
  1.1168 +function framesetWindowLoaded(framesetWindow)
  1.1169 +{
  1.1170 +  gLastFocus = null;
  1.1171 +  gLastFocusWindow = framesetWindow;
  1.1172 +  gEvents = "";
  1.1173 +
  1.1174 +  is(fm.activeWindow, getTopWindow(framesetWindow), "frameset window active");
  1.1175 +  gOldExpectedWindow = getTopWindow(framesetWindow);
  1.1176 +
  1.1177 +  gMoveToFocusFrame = true;
  1.1178 +  for (var idx = 1; idx <= 8; idx++) {
  1.1179 +    gNewExpectedWindow = framesetWindow.frames[(idx - 1) >> 1];
  1.1180 +    if (idx % 2)
  1.1181 +      initEvents(gNewExpectedWindow);
  1.1182 +    expectFocusShift(function () synthesizeKey("VK_TAB", { }, framesetWindow),
  1.1183 +                     gNewExpectedWindow, getById("f" + idx), true, "frameset tab key f" + idx);
  1.1184 +    gMoveToFocusFrame = false;
  1.1185 +    gOldExpectedWindow = gNewExpectedWindow;
  1.1186 +  }
  1.1187 +
  1.1188 +  gNewExpectedWindow = framesetWindow.frames[0];
  1.1189 +  expectFocusShift(function () synthesizeKey("VK_TAB", { }, framesetWindow),
  1.1190 +                   gNewExpectedWindow, getById("f1"), true, "frameset tab key wrap to start");
  1.1191 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1192 +  gNewExpectedWindow = framesetWindow.frames[3];
  1.1193 +  expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }, framesetWindow),
  1.1194 +                   gNewExpectedWindow, getById("f8"), true, "frameset shift tab key wrap to end");
  1.1195 +
  1.1196 +  for (idx = 7; idx >= 1; idx--) {
  1.1197 +    gOldExpectedWindow = gNewExpectedWindow;
  1.1198 +    gNewExpectedWindow = framesetWindow.frames[(idx - 1) >> 1];
  1.1199 +    expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }, framesetWindow),
  1.1200 +                     gNewExpectedWindow, getById("f" + idx), true, "frameset shift tab key f" + idx);
  1.1201 +  }
  1.1202 +
  1.1203 +  // document shifting
  1.1204 +  // XXXndeakin P3 ctrl+tab doesn't seem to be testable currently for some reason
  1.1205 +  gNewExpectedWindow = framesetWindow.frames[1];
  1.1206 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true }, framesetWindow),
  1.1207 +                   gNewExpectedWindow, getById("f3"), true, "switch document forward with f6");
  1.1208 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1209 +  gNewExpectedWindow = framesetWindow.frames[2];
  1.1210 +  expectFocusShift(function () synthesizeKey("VK_F6", { }, framesetWindow),
  1.1211 +                   gNewExpectedWindow, getById("f5"), true, "switch document forward with ctrl+tab");
  1.1212 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1213 +  gNewExpectedWindow = framesetWindow.frames[3];
  1.1214 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true }, framesetWindow),
  1.1215 +                   gNewExpectedWindow, getById("f7"), true, "switch document forward with ctrl+f6");
  1.1216 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1217 +  gNewExpectedWindow = framesetWindow.frames[0];
  1.1218 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true }, framesetWindow),
  1.1219 +                   gNewExpectedWindow, getById("f1"), true, "switch document forward and wrap");
  1.1220 +
  1.1221 +// going backwards by document and wrapping doesn't currently work, but didn't work
  1.1222 +// before the focus reworking either
  1.1223 +
  1.1224 +/*
  1.1225 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1226 +  gNewExpectedWindow = framesetWindow.frames[3];
  1.1227 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
  1.1228 +                   gNewExpectedWindow, getById("f7"), true, "switch document backward and wrap");
  1.1229 + */
  1.1230 +
  1.1231 +  fm.moveFocus(framesetWindow.frames[3], null, fm.MOVEFOCUS_ROOT, 0);
  1.1232 +  gEvents = "";
  1.1233 +
  1.1234 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1235 +  gNewExpectedWindow = framesetWindow.frames[2];
  1.1236 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
  1.1237 +                   gNewExpectedWindow, getById("f5"), true, "switch document backward with f6");
  1.1238 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1239 +  gNewExpectedWindow = framesetWindow.frames[1];
  1.1240 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
  1.1241 +                   gNewExpectedWindow, getById("f3"), true, "switch document backward with ctrl+tab");
  1.1242 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1243 +  gNewExpectedWindow = framesetWindow.frames[0];
  1.1244 +  expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
  1.1245 +                   gNewExpectedWindow, getById("f1"), true, "switch document backward with ctrl+f6");
  1.1246 +
  1.1247 +  // skip the window switching tests for now on Linux, as raising and lowering
  1.1248 +  // a window is asynchronous there
  1.1249 +  if (navigator.platform.indexOf("Linux") == -1) {
  1.1250 +    window.openDialog("focus_window2.xul", "_blank", "chrome", switchWindowTest, framesetWindow);
  1.1251 +  }
  1.1252 +  else {
  1.1253 +    gOldExpectedWindow = null;
  1.1254 +    gNewExpectedWindow = null;
  1.1255 +    framesetWindow.close();
  1.1256 +    SimpleTest.waitForFocus(doWindowNoRootTest);
  1.1257 +  }
  1.1258 +}
  1.1259 +
  1.1260 +// test switching between two windows
  1.1261 +function switchWindowTest(otherWindow, framesetWindow)
  1.1262 +{
  1.1263 +  initEvents(otherWindow);
  1.1264 +  var otherElement = otherWindow.document.getElementById("other");
  1.1265 +  otherElement.focus();
  1.1266 +
  1.1267 +  framesetWindow.frames[1].document.getElementById("f4").focus();
  1.1268 +
  1.1269 +  is(fm.focusedElement, otherElement, "focus after inactive window focus");
  1.1270 +
  1.1271 +  gLastFocus = otherElement;
  1.1272 +  gLastFocusWindow = otherWindow;
  1.1273 +  gEvents = "";
  1.1274 +  gOldExpectedWindow = otherWindow;
  1.1275 +  gNewExpectedWindow = framesetWindow.frames[1];
  1.1276 +
  1.1277 +  expectFocusShift(function () gNewExpectedWindow.focus(),
  1.1278 +                   gNewExpectedWindow, getById("f4"), true, "switch to frame in another window");
  1.1279 +  is(fm.getFocusedElementForWindow(otherWindow, false, {}).id, "other", "inactive window has focused element");
  1.1280 +
  1.1281 +  gOldExpectedWindow = framesetWindow.frames[1];
  1.1282 +  gNewExpectedWindow = otherWindow;
  1.1283 +  expectFocusShift(function () otherWindow.focus(),
  1.1284 +                   gNewExpectedWindow, getById("other"), true, "switch to another window");
  1.1285 +
  1.1286 +  var exh = false;
  1.1287 +  try {
  1.1288 +    fm.activeWindow = framesetWindow.frames[0];
  1.1289 +  }
  1.1290 +  catch (ex) { exh = true; }
  1.1291 +  is(exh, true, "activeWindow set to non top-level window");
  1.1292 +
  1.1293 +  exh = false;
  1.1294 +  try {
  1.1295 +    fm.activeWindow = null;
  1.1296 +  }
  1.1297 +  catch (ex) { exh = true; }
  1.1298 +  is(exh, true, "activeWindow set to null");
  1.1299 +  is(fm.activeWindow, otherWindow, "window not changed when activeWindow set to null");
  1.1300 +
  1.1301 +  var topWindow = getTopWindow(framesetWindow);
  1.1302 +
  1.1303 +  ok(topWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
  1.1304 +     "getControllerForCommand for focused window set");
  1.1305 +  ok(otherWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
  1.1306 +     "getControllerForCommand for non-focused window set");
  1.1307 +  ok(topWindow.document.commandDispatcher.getControllerForCommand("cmd_copy") !=
  1.1308 +     otherWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
  1.1309 +     "getControllerForCommand for two windows different");
  1.1310 +  ok(topWindow.document.commandDispatcher.getControllers() !=
  1.1311 +     otherWindow.document.commandDispatcher.getControllers(),
  1.1312 +     "getControllers for two windows different");
  1.1313 +
  1.1314 +  gOldExpectedWindow = otherWindow;
  1.1315 +  gNewExpectedWindow = framesetWindow.frames[1];
  1.1316 +  expectFocusShift(function () fm.activeWindow = topWindow,
  1.1317 +                   gNewExpectedWindow, getById("f4"), true, "switch to frame activeWindow");
  1.1318 +
  1.1319 +  fm.clearFocus(otherWindow);
  1.1320 +  gOldExpectedWindow = gNewExpectedWindow;
  1.1321 +  gNewExpectedWindow = otherWindow;
  1.1322 +  expectFocusShift(function () fm.setFocus(otherElement, fm.FLAG_RAISE),
  1.1323 +                   gNewExpectedWindow, getById("other"), true, "switch to window with raise");
  1.1324 +
  1.1325 +  getTopWindow(framesetWindow).document.commandDispatcher.focusedWindow = gOldExpectedWindow;
  1.1326 +  is(fm.activeWindow, gNewExpectedWindow, "setting commandDispatcher focusedWindow doesn't raise window");
  1.1327 +
  1.1328 +  fm.moveFocus(otherWindow, null, fm.MOVEFOCUS_FORWARD, 0);
  1.1329 +  var otherTextbox = otherWindow.document.getElementById("other-textbox");
  1.1330 +  otherTextbox.setSelectionRange(2, 3);
  1.1331 +  fm.activeWindow = topWindow;
  1.1332 +  fm.activeWindow = otherWindow;
  1.1333 +  is(otherTextbox.selectionStart, 2, "selectionStart after textbox focus and window raise");
  1.1334 +  is(otherTextbox.selectionEnd, 3, "selectionEnd after textbox focus and window raise");
  1.1335 +  is(fm.getLastFocusMethod(null), fm.FLAG_BYMOVEFOCUS, "last focus method after textbox focus and window raise");
  1.1336 +
  1.1337 +  fm.clearFocus(otherWindow);
  1.1338 +
  1.1339 +  // test to ensure that a synthetic event works
  1.1340 +  var synevent = document.createEvent("Event");
  1.1341 +  synevent.initEvent("focus", false, false);
  1.1342 +  otherTextbox.inputField.dispatchEvent(synevent);
  1.1343 +  is(synevent.type, "focus", "event.type after synthetic focus event");
  1.1344 +  is(synevent.target, otherTextbox, "event.target after synthetic focus event");
  1.1345 +  is(fm.focusedElement, null, "focusedElement after synthetic focus event");
  1.1346 +  is(otherWindow.document.activeElement, otherWindow.document.documentElement,
  1.1347 +     "document.activeElement after synthetic focus event");
  1.1348 +
  1.1349 +  // check accessing a focus event after the event has finishing firing
  1.1350 +  function continueTest(event) {
  1.1351 +    is(event.type, "focus", "event.type after accessing focus event in timeout");
  1.1352 +    is(event.target, otherTextbox, "event.target after accessing focus event in timeout");
  1.1353 +
  1.1354 +    gOldExpectedWindow = null;
  1.1355 +    gNewExpectedWindow = null;
  1.1356 +    otherWindow.close();
  1.1357 +    framesetWindow.close();
  1.1358 +
  1.1359 +    SimpleTest.waitForFocus(doWindowNoRootTest);
  1.1360 +  }
  1.1361 +
  1.1362 +  function textboxFocused(event) {
  1.1363 +    otherTextbox.removeEventListener("focus", textboxFocused, true);
  1.1364 +    setTimeout(continueTest, 0, event);
  1.1365 +  }
  1.1366 +
  1.1367 +  otherTextbox.addEventListener("focus", textboxFocused, true);
  1.1368 +  otherTextbox.focus();
  1.1369 +}
  1.1370 +
  1.1371 +// open a window with no root element
  1.1372 +var noRootWindow = null;
  1.1373 +function doWindowNoRootTest()
  1.1374 +{
  1.1375 +  var data = "data:application/vnd.mozilla.xul+xml," + unescape(
  1.1376 +             "<window onfocus='dostuff()' xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
  1.1377 +             "        style='-moz-user-focus: normal;'>" +
  1.1378 +             "<script>function dostuff() { setTimeout(function() { " +
  1.1379 +             "document.documentElement.focus(); document.removeChild(document.documentElement);" +
  1.1380 +             "window.opener.focus(); }, 100); }</script></window>");
  1.1381 +
  1.1382 +  addEventListener("focus", doFrameSwitchingTests, true);
  1.1383 +  noRootWindow = window.open(data, "_blank", "chrome,width=100,height=100");
  1.1384 +}
  1.1385 +
  1.1386 +// these tests check when focus is moved between a tree of frames to ensure
  1.1387 +// that the focus is in the right place at each event step.
  1.1388 +function doFrameSwitchingTests()
  1.1389 +{
  1.1390 +  removeEventListener("focus", doFrameSwitchingTests, true);
  1.1391 +  noRootWindow.close();
  1.1392 +
  1.1393 +  var framea = document.getElementById("ifa");
  1.1394 +  var frameb = document.getElementById("ifb");
  1.1395 +  framea.style.MozUserFocus = "";
  1.1396 +  frameb.style.MozUserFocus = "";
  1.1397 +
  1.1398 +  window.removeEventListener("focus", eventOccured, true);
  1.1399 +  window.removeEventListener("blur", eventOccured, true);
  1.1400 +
  1.1401 +  var inputa = framea.contentDocument.body.firstChild;
  1.1402 +  inputa.focus();
  1.1403 +
  1.1404 +  addFrameSwitchingListeners(framea);
  1.1405 +  addFrameSwitchingListeners(frameb);
  1.1406 +  var framec = framea.contentDocument.body.lastChild;
  1.1407 +  addFrameSwitchingListeners(framec);
  1.1408 +
  1.1409 +  var framed = framec.contentDocument.body.lastChild;
  1.1410 +  addFrameSwitchingListeners(framed);
  1.1411 +
  1.1412 +  var inputc = framec.contentDocument.body.firstChild;
  1.1413 +
  1.1414 +  var expectedMainWindowFocus = framea;
  1.1415 +
  1.1416 +  // An element in the immediate parent frame is focused. Focus an element in
  1.1417 +  // the child. The child should be focused and the parent's current focus should
  1.1418 +  // be the child iframe.
  1.1419 +  gEventMatched = true;
  1.1420 +  is(fm.getFocusedElementForWindow(window, false, {}), expectedMainWindowFocus,
  1.1421 +     "parent of framea has iframe focused");
  1.1422 +  gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea],
  1.1423 +                     [framea.contentDocument, "blur", null, null, window, framea],
  1.1424 +                     [framea.contentWindow, "blur", null, null, window, framea],
  1.1425 +                     [framec.contentDocument, "focus", null, framec.contentWindow, window, framea],
  1.1426 +                     [framec.contentWindow, "focus", null, framec.contentWindow, window, framea],
  1.1427 +                     [inputc, "focus", inputc, framec.contentWindow, window, framea]];
  1.1428 +  inputc.focus();
  1.1429 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from parent input to child input" + gExpectedEvents);
  1.1430 +
  1.1431 +  // An element in a child is focused. Focus an element in the immediate
  1.1432 +  // parent.
  1.1433 +  gEventMatched = true;
  1.1434 +  gExpectedEvents = [[inputc, "blur", null, framec.contentWindow, window, framea],
  1.1435 +                     [framec.contentDocument, "blur", null, null, window, framea],
  1.1436 +                     [framec.contentWindow, "blur", null, null, window, framea],
  1.1437 +                     [framea.contentDocument, "focus", null, framea.contentWindow, window, framea],
  1.1438 +                     [framea.contentWindow, "focus", null, framea.contentWindow, window, framea],
  1.1439 +                     [inputa, "focus", inputa, framea.contentWindow, window, framea]];
  1.1440 +  inputa.focus();
  1.1441 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to parent input");
  1.1442 +
  1.1443 +  // An element in a frame is focused. Focus an element in a sibling frame.
  1.1444 +  // The common ancestor of the two frames should have its focused node
  1.1445 +  // cleared after the element is blurred.
  1.1446 +  var inputb = frameb.contentDocument.body.firstChild;
  1.1447 +
  1.1448 +  gEventMatched = true;
  1.1449 +  gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea],
  1.1450 +                     [framea.contentDocument, "blur", null, null, window, null],
  1.1451 +                     [framea.contentWindow, "blur", null, null, window, null],
  1.1452 +                     [frameb.contentDocument, "focus", null, frameb.contentWindow, window, frameb],
  1.1453 +                     [frameb.contentWindow, "focus", null, frameb.contentWindow, window, frameb],
  1.1454 +                     [inputb, "focus", inputb, frameb.contentWindow, window, frameb]];
  1.1455 +  inputb.focus();
  1.1456 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from input to sibling frame");
  1.1457 +  is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), inputa, 
  1.1458 +     "blurred frame still has input as focus");
  1.1459 +
  1.1460 +  // focus a descendant in a sibling
  1.1461 +  var inputd = framed.contentDocument.body.firstChild;
  1.1462 +  gEventMatched = true;
  1.1463 +  gExpectedEvents = [[inputb, "blur", null, frameb.contentWindow, window, frameb],
  1.1464 +                     [frameb.contentDocument, "blur", null, null, window, null],
  1.1465 +                     [frameb.contentWindow, "blur", null, null, window, null],
  1.1466 +                     [framed.contentDocument, "focus", null, framed.contentWindow, window, framea],
  1.1467 +                     [framed.contentWindow, "focus", null, framed.contentWindow, window, framea],
  1.1468 +                     [inputd, "focus", inputd, framed.contentWindow, window, framea]];
  1.1469 +  inputd.focus();
  1.1470 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from input to sibling descendant");
  1.1471 +  is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec,
  1.1472 +     "sibling parent focus has shifted to frame");
  1.1473 +
  1.1474 +  // focus an ancestor
  1.1475 +  gEventMatched = true;
  1.1476 +  gExpectedEvents = [[inputd, "blur", null, framed.contentWindow, window, framea],
  1.1477 +                     [framed.contentDocument, "blur", null, null, window, framea],
  1.1478 +                     [framed.contentWindow, "blur", null, null, window, framea],
  1.1479 +                     [framea.contentDocument, "focus", null, framea.contentWindow, window, framea],
  1.1480 +                     [framea.contentWindow, "focus", null, framea.contentWindow, window, framea],
  1.1481 +                     [inputa, "focus", inputa, framea.contentWindow, window, framea]];
  1.1482 +  inputa.focus();
  1.1483 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to ancestor");
  1.1484 +
  1.1485 +  // focus a descendant
  1.1486 +  gEventMatched = true;
  1.1487 +  gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea],
  1.1488 +                     [framea.contentDocument, "blur", null, null, window, framea],
  1.1489 +                     [framea.contentWindow, "blur", null, null, window, framea],
  1.1490 +                     [framed.contentDocument, "focus", null, framed.contentWindow, window, framea],
  1.1491 +                     [framed.contentWindow, "focus", null, framed.contentWindow, window, framea],
  1.1492 +                     [inputd, "focus", inputd, framed.contentWindow, window, framea]];
  1.1493 +  inputd.focus();
  1.1494 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to ancestor");
  1.1495 +  is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec,
  1.1496 +     "parent focus has shifted to frame");
  1.1497 +
  1.1498 +  // focus a sibling frame by setting focusedWindow
  1.1499 +  gEventMatched = true;
  1.1500 +  gExpectedEvents = [[inputd, "blur", null, framed.contentWindow, window, framea],
  1.1501 +                     [framed.contentDocument, "blur", null, null, window, null],
  1.1502 +                     [framed.contentWindow, "blur", null, null, window, null],
  1.1503 +                     [frameb.contentDocument, "focus", null, frameb.contentWindow, window, frameb],
  1.1504 +                     [frameb.contentWindow, "focus", null, frameb.contentWindow, window, frameb],
  1.1505 +                     [inputb, "focus", inputb, frameb.contentWindow, window, frameb]];
  1.1506 +  fm.focusedWindow = frameb.contentWindow;
  1.1507 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch using focusedWindow");
  1.1508 +
  1.1509 +  // clear the focus in an unfocused frame
  1.1510 +  gEventMatched = true;
  1.1511 +  gExpectedEvents = [];
  1.1512 +  fm.clearFocus(framec.contentWindow);
  1.1513 +  ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in unfocused frame");
  1.1514 +
  1.1515 +  // focus a sibling frame by setting focusedWindow when no element is focused in that frame
  1.1516 +  gEventMatched = true;
  1.1517 +  gExpectedEvents = [[inputb, "blur", null, frameb.contentWindow, window, frameb],
  1.1518 +                     [frameb.contentDocument, "blur", null, null, window, null],
  1.1519 +                     [frameb.contentWindow, "blur", null, null, window, null],
  1.1520 +                     [framec.contentDocument, "focus", null, framec.contentWindow, window, framea],
  1.1521 +                     [framec.contentWindow, "focus", null, framec.contentWindow, window, framea]];
  1.1522 +  fm.focusedWindow = framec.contentWindow;
  1.1523 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch using focusedWindow with no element focused");
  1.1524 +  is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec,
  1.1525 +     "parent focus has shifted to frame using focusedWindow");
  1.1526 +
  1.1527 +  // focus the parent frame by setting focusedWindow. This should have no effect.
  1.1528 +  gEventMatched = true;
  1.1529 +  gExpectedEvents = [];
  1.1530 +  fm.focusedWindow = framea.contentWindow;
  1.1531 +  ok(gEventMatched && gExpectedEvents.length == 0, "frame switch to parent using focusedWindow");
  1.1532 +
  1.1533 +  // clear the focus in the parent frame
  1.1534 +  gEventMatched = true;
  1.1535 +  gExpectedEvents = [[framec.contentDocument, "blur", null, null, window, framea],
  1.1536 +                     [framec.contentWindow, "blur", null, null, window, framea],
  1.1537 +                     [framea.contentDocument, "focus", null, framea.contentWindow, window, framea],
  1.1538 +                     [framea.contentWindow, "focus", null, framea.contentWindow, window, framea]];
  1.1539 +  fm.clearFocus(framea.contentWindow);
  1.1540 +  ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in parent frame");
  1.1541 +
  1.1542 +  // clear the focus in an unfocused child frame
  1.1543 +  gEventMatched = true;
  1.1544 +  gExpectedEvents = [];
  1.1545 +  fm.clearFocus(framed.contentWindow);
  1.1546 +  ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in unfocused child frame");
  1.1547 +
  1.1548 +  var exh = false;
  1.1549 +  try {
  1.1550 +    fm.focusedWindow = null;
  1.1551 +  }
  1.1552 +  catch (ex) { exh = true; }
  1.1553 +  is(exh, true, "focusedWindow set to null");
  1.1554 +  is(fm.focusedWindow, framea.contentWindow, "window not changed when focusedWindow set to null");
  1.1555 +
  1.1556 +  doFrameHistoryTests()
  1.1557 +}
  1.1558 +
  1.1559 +function doFrameHistoryTests()
  1.1560 +{
  1.1561 +  var t20 = getById("t20");
  1.1562 +  t20.focus();
  1.1563 +
  1.1564 +  gChildWindow.addEventListener("focus",
  1.1565 +    function(event) {
  1.1566 +      if (event.target == t20) {
  1.1567 +        is(fm.focusedElement, t20, "focus restored after history back"); done();
  1.1568 +    }
  1.1569 +  }, true);
  1.1570 +
  1.1571 +  // make sure that loading a new page and then going back maintains the focus
  1.1572 +  gChildWindow.location = "data:text/html,<script>window.onload=function() {setTimeout(function () {window.back();}, 0);}</script>";
  1.1573 +}
  1.1574 +
  1.1575 +function addFrameSwitchingListeners(frame)
  1.1576 +{
  1.1577 +  frame.contentWindow.addEventListener("focus", frameSwitchingEventOccured, false);
  1.1578 +  frame.contentWindow.addEventListener("blur", frameSwitchingEventOccured, false);
  1.1579 +  frame.contentDocument.addEventListener("focus", frameSwitchingEventOccured, false);
  1.1580 +  frame.contentDocument.addEventListener("blur", frameSwitchingEventOccured, false);
  1.1581 +
  1.1582 +  var node = frame.contentDocument.body.firstChild;
  1.1583 +  node.addEventListener("focus", frameSwitchingEventOccured, false);
  1.1584 +  node.addEventListener("blur", frameSwitchingEventOccured, false);
  1.1585 +}
  1.1586 +
  1.1587 +function frameSwitchingEventOccured(event)
  1.1588 +{
  1.1589 +  if (!gExpectedEvents.length) {
  1.1590 +    gEventMatched = false;
  1.1591 +    return;
  1.1592 +  }
  1.1593 +
  1.1594 +  try {
  1.1595 +    var events = gExpectedEvents.shift();
  1.1596 +    is(event.target, events[0], "event target");
  1.1597 +    is(event.type, events[1], "event type");
  1.1598 +    is(fm.focusedElement, events[2], "focused element");
  1.1599 +    is(fm.focusedWindow, events[3], "focused frame");
  1.1600 +    if (events[4])
  1.1601 +      is(fm.getFocusedElementForWindow(events[4], false, {}), events[5], "focused element in frame");
  1.1602 +
  1.1603 +    if (gEventMatched && event.target == events[0] && event.type == events[1] &&
  1.1604 +        fm.focusedElement == events[2] && fm.focusedWindow == events[3]) {
  1.1605 +      if (!events[4] || fm.getFocusedElementForWindow(events[4], false, {}) == events[5])
  1.1606 +        return;
  1.1607 +    }
  1.1608 +  } catch (ex) { ok(ex, "exception"); }
  1.1609 +
  1.1610 +  gEventMatched = false;
  1.1611 +}
  1.1612 +
  1.1613 +SimpleTest.waitForExplicitFinish();
  1.1614 +SimpleTest.waitForFocus(startTest);
  1.1615 +
  1.1616 +]]>
  1.1617 +</script>
  1.1618 +
  1.1619 +<commandset id="cu"
  1.1620 +            commandupdater="true"
  1.1621 +            events="focus"
  1.1622 +            oncommandupdate="eventOccured(event)"/>
  1.1623 +
  1.1624 +<!--
  1.1625 + The elements with ids starting with t are focusable and in the taborder.
  1.1626 + The elements with ids starting with o are:
  1.1627 +   odd numbered ids - focusable but not part of the tab order
  1.1628 +   even numbered ids - not focusable with -moz-user-focus: ignore or disabled
  1.1629 + The elements with ids starting with n are:
  1.1630 +   odd numbered ids - not focusable with -moz-user-focus: none
  1.1631 +   even numbered ids - focusable but not part of the tab order
  1.1632 + -->
  1.1633 +<vbox id="buttonbox">
  1.1634 +<hbox id="innerbox">
  1.1635 +  <button id="t4" accesskey="h" label="no tabindex"/>
  1.1636 +  <button id="o1" accesskey="i" label="tabindex = -1" tabindex="-1"/>
  1.1637 +  <listbox id="t5" label="tabindex = 0" tabindex="0" rows="1">
  1.1638 +    <listitem/>
  1.1639 +  </listbox>
  1.1640 +  <button id="t1" label="tabindex = 2" tabindex="2"/>
  1.1641 +</hbox>
  1.1642 +<hbox>
  1.1643 +  <button id="o2" accesskey="o" style="-moz-user-focus: ignore;" label="no tabindex"/>
  1.1644 +  <button id="o4" style="-moz-user-focus: ignore;" label="tabindex = -1" tabindex="-1"/>
  1.1645 +  <button id="t6" style="-moz-user-focus: ignore;" label="tabindex = 0" tabindex="0"/>
  1.1646 +  <button id="t2" style="-moz-user-focus: ignore;" label="tabindex = 2" tabindex="2"/>
  1.1647 +</hbox>
  1.1648 +<hbox id="specialroot">
  1.1649 +  <button id="t7" style="-moz-user-focus: normal;" label="no tabindex"/>
  1.1650 +  <button id="o3" style="-moz-user-focus: normal;" label="tabindex = -1" tabindex="-1"/>
  1.1651 +  <button id="t8" style="-moz-user-focus: normal;" label="tabindex = 0" tabindex="0"/>
  1.1652 +  <listbox id="t3" style="-moz-user-focus: normal;" label="tabindex = 2" tabindex="2" rows="1">
  1.1653 +    <listitem/>
  1.1654 +  </listbox>
  1.1655 +</hbox>
  1.1656 +<hbox>
  1.1657 +  <button accesskey="p" style="display: none;"/> <button accesskey="q" style="visibility: collapse;"/>
  1.1658 +  <button style="display: none;" tabindex="2"/> <button style="visibility: collapse;" tabindex="2"/>
  1.1659 +</hbox>
  1.1660 +<hbox>
  1.1661 +  <button id="o20" accesskey="s" label="no tabindex" disabled="true"/>
  1.1662 +  <button id="o22" label="tabindex = -1" tabindex="-1" disabled="true"/>
  1.1663 +  <button id="o24" label="tabindex = 0" tabindex="0" disabled="true"/>
  1.1664 +  <button id="o26" label="tabindex = 2" tabindex="2" disabled="true"/>
  1.1665 +</hbox>
  1.1666 +</vbox>
  1.1667 +<vbox>
  1.1668 +<hbox>
  1.1669 +  <dropmarker id="o6" value="no tabindex"/>
  1.1670 +  <dropmarker id="o8" value="tabindex = -1" tabindex="-1"/>
  1.1671 +  <dropmarker id="o10" value="tabindex = 0" tabindex="0"/>
  1.1672 +  <dropmarker id="o12" value="tabindex = 2" tabindex="2"/>
  1.1673 +  <dropmarker id="t9" accesskey="r" style="-moz-user-focus: normal;" value="no tabindex" />
  1.1674 +  <dropmarker id="t10" style="-moz-user-focus: normal;" value="tabindex = -1" tabindex="-1" />
  1.1675 +  <dropmarker id="t11" style="-moz-user-focus: normal;" value="tabindex = 0" tabindex="0" />
  1.1676 +  <dropmarker id="t12" style="-moz-user-focus: normal;" value="tabindex = 2" tabindex="2" />
  1.1677 +  <dropmarker id="o14" style="-moz-user-focus: ignore;" value="no tabindex"/>
  1.1678 +  <dropmarker id="o16" style="-moz-user-focus: ignore;" value="tabindex = -1" tabindex="-1"/>
  1.1679 +  <dropmarker id="n1" style="-moz-user-focus: none;" value="tabindex = 0" tabindex="0"/>
  1.1680 +  <dropmarker id="n3" style="-moz-user-focus: none;" value="tabindex = 2" tabindex="2"/>
  1.1681 +</hbox>
  1.1682 +</vbox>
  1.1683 +<browser id="childframe" type="content" src="child_focus_frame.html" width="300" height="195"/>
  1.1684 +<button id="t34"/>
  1.1685 +<tabbox id="tabbox">
  1.1686 +  <tabs><tab id="t35" label="One"/><tab id="tab2" label="Two"/></tabs>
  1.1687 +  <tabpanels>
  1.1688 +    <tabpanel>
  1.1689 +      <checkbox id="t36"/>
  1.1690 +      <button id="t37"/>
  1.1691 +    </tabpanel>
  1.1692 +    <tabpanel>
  1.1693 +      <checkbox id="htab1"/>
  1.1694 +      <button id="nohtab2" tabindex="7"/>
  1.1695 +      <checkbox id="htab2" tabindex="0"/>
  1.1696 +    </tabpanel>
  1.1697 +  </tabpanels>
  1.1698 +</tabbox>
  1.1699 +<hbox>
  1.1700 +<panel>
  1.1701 +  <button id="inpopup1" label="One"/>
  1.1702 +  <textbox label="Two"/>
  1.1703 +</panel>
  1.1704 +<description label="o" accesskey="v"/>
  1.1705 +<button id="t38"/>
  1.1706 +<!-- The 't' element tests end here so it doesn't matter that these elements are tabbable -->
  1.1707 +<label id="aj" value="j" accesskey="j" control="o9"/>
  1.1708 +<label id="ak" accesskey="k" control="n4">k</label>
  1.1709 +<checkbox id="o5"/><checkbox id="o7"/><hbox><checkbox id="o9"/></hbox>
  1.1710 +<checkbox id="o13"/><checkbox id="o15"/><checkbox id="o17"/><checkbox id="o19"/><checkbox id="o21"/><checkbox id="o23"/><checkbox id="o25"/>
  1.1711 +<checkbox id="n2"/><checkbox id="n4"/>
  1.1712 +<listbox id="last" width="20" rows="1"/>
  1.1713 +
  1.1714 +<iframe id="ifa" width="40" height="60" style="-moz-user-focus: ignore;" type="content"
  1.1715 +        src="data:text/html,&lt;input id=fra size='2'&gt;&lt;input id='fra-b' size='2'&gt;
  1.1716 +        &lt;iframe src='data:text/html,&lt;input id=frc&gt;&lt;iframe src=&quot;data:text/html,&lt;input id=frd&gt;&quot;&gt;&lt;/iframe&gt;'&gt;&lt;/iframe&gt;"/>
  1.1717 +<iframe id="ifb" width="20" height="20" style="-moz-user-focus: ignore;"
  1.1718 +        src="data:text/html,&lt;input id=frd&gt;&lt;/iframe&gt;"/>
  1.1719 +
  1.1720 +</hbox>
  1.1721 +</window>

mercurial