dom/tests/mochitest/chrome/window_focus.xul

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <?xml version="1.0"?>
michael@0 2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
michael@0 3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
michael@0 4 type="text/css"?>
michael@0 5 <!--
michael@0 6 This test checks focus in various ways
michael@0 7 -->
michael@0 8 <window id="outer-document" title="Focus Test" width="600" height="550"
michael@0 9 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
michael@0 10 <script type="application/javascript"
michael@0 11 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
michael@0 12 <script type="application/javascript"
michael@0 13 src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
michael@0 14
michael@0 15 <body xmlns="http://www.w3.org/1999/xhtml"/>
michael@0 16
michael@0 17 <script type="application/javascript"><![CDATA[
michael@0 18
michael@0 19 var fm = Components.classes["@mozilla.org/focus-manager;1"].
michael@0 20 getService(Components.interfaces.nsIFocusManager);
michael@0 21
michael@0 22 const kChildDocumentRootIndex = 13;
michael@0 23 const kBeforeTabboxIndex = 34;
michael@0 24 const kTabbableSteps = 38;
michael@0 25 const kFocusSteps = 26;
michael@0 26 const kNoFocusSteps = 7;
michael@0 27 const kOverflowElementIndex = 27;
michael@0 28
michael@0 29 var gTestStarted = false;
michael@0 30 var gPartialTabbing = false;
michael@0 31 var gMoveToFocusFrame = false;
michael@0 32 var gLastFocus = null;
michael@0 33 var gLastFocusWindow = window;
michael@0 34 var gLastFocusMethod = -1;
michael@0 35 var gEvents = "";
michael@0 36 var gExpectedEvents = "";
michael@0 37 var gEventMatched = true;
michael@0 38 var gShowOutput = false;
michael@0 39 var gChildWindow = null;
michael@0 40
michael@0 41 var gOldExpectedWindow = null;
michael@0 42 var gNewExpectedWindow = null;
michael@0 43
michael@0 44 function is(l, r, n) { window.opener.wrappedJSObject.SimpleTest.is(l,r,n); }
michael@0 45 function ok(v, n) { window.opener.wrappedJSObject.SimpleTest.ok(v,n); }
michael@0 46
michael@0 47 function initEvents(target)
michael@0 48 {
michael@0 49 target.addEventListener("focus", eventOccured, true);
michael@0 50 target.addEventListener("blur", eventOccured, true);
michael@0 51 getTopWindow(target).addEventListener("activate", eventOccured, true);
michael@0 52 getTopWindow(target).addEventListener("deactivate", eventOccured, true);
michael@0 53 }
michael@0 54
michael@0 55 function eventOccured(event)
michael@0 56 {
michael@0 57 // iframes should never receive focus or blur events directly
michael@0 58 if (event.target instanceof Element && event.target.localName == "iframe")
michael@0 59 ok(false, "iframe " + event.type + "occured");
michael@0 60
michael@0 61 var id;
michael@0 62 if (gOldExpectedWindow && event.type == "blur") {
michael@0 63 if (event.target instanceof Window)
michael@0 64 id = "frame-" + gOldExpectedWindow.document.documentElement.id + "-window";
michael@0 65 else if (event.target instanceof Document)
michael@0 66 id = "frame-" + gOldExpectedWindow.document.documentElement.id + "-document";
michael@0 67 else
michael@0 68 id = event.originalTarget.id;
michael@0 69 }
michael@0 70 else if (gNewExpectedWindow && event.type == "focus") {
michael@0 71 if (event.target instanceof Window)
michael@0 72 id = "frame-" + gNewExpectedWindow.document.documentElement.id + "-window";
michael@0 73 else if (event.target instanceof Document)
michael@0 74 id = "frame-" + gNewExpectedWindow.document.documentElement.id + "-document";
michael@0 75 else
michael@0 76 id = event.originalTarget.id;
michael@0 77 }
michael@0 78 else if (event.type == "activate" || event.type == "deactivate")
michael@0 79 id = event.target.document.documentElement.id + "-window";
michael@0 80 else if (event.target instanceof Window)
michael@0 81 id = (event.target == window) ? "outer-window" : "child-window";
michael@0 82 else if (event.target instanceof Document)
michael@0 83 id = (event.target == document) ? "outer-document" : "child-document";
michael@0 84 else
michael@0 85 id = event.originalTarget.id;
michael@0 86
michael@0 87 if (gEvents)
michael@0 88 gEvents += " ";
michael@0 89 gEvents += event.type + ": " + id;
michael@0 90 }
michael@0 91
michael@0 92 function expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid)
michael@0 93 {
michael@0 94 if (expectedWindow == null)
michael@0 95 expectedWindow = expectedElement ?
michael@0 96 expectedElement.ownerDocument.defaultView :
michael@0 97 gLastFocusWindow;
michael@0 98
michael@0 99 var expectedEvents = "";
michael@0 100 if (focusChanged) {
michael@0 101 var id;
michael@0 102 if (getTopWindow(gLastFocusWindow) != getTopWindow(expectedWindow)) {
michael@0 103 id = getTopWindow(gLastFocusWindow).document.documentElement.id;
michael@0 104 expectedEvents += "deactivate: " + id + "-window";
michael@0 105 }
michael@0 106
michael@0 107 if (gLastFocus && gLastFocus.id != "t" + kChildDocumentRootIndex &&
michael@0 108 (!gOldExpectedWindow || gOldExpectedWindow.document.documentElement != gLastFocus)) {
michael@0 109 if (expectedEvents)
michael@0 110 expectedEvents += " ";
michael@0 111 if (!gOldExpectedWindow)
michael@0 112 expectedEvents += "commandupdate: cu ";
michael@0 113 expectedEvents += "blur: " + gLastFocus.id;
michael@0 114 }
michael@0 115
michael@0 116 if (gLastFocusWindow && gLastFocusWindow != expectedWindow) {
michael@0 117 if (!gMoveToFocusFrame) {
michael@0 118 if (gOldExpectedWindow)
michael@0 119 id = "frame-" + gOldExpectedWindow.document.documentElement.id;
michael@0 120 else
michael@0 121 id = (gLastFocusWindow == window) ? "outer" : "child";
michael@0 122 if (expectedEvents)
michael@0 123 expectedEvents += " ";
michael@0 124 expectedEvents += "blur: " + id + "-document " +
michael@0 125 "blur: " + id + "-window";
michael@0 126 }
michael@0 127 }
michael@0 128
michael@0 129 if (getTopWindow(gLastFocusWindow) != getTopWindow(expectedWindow)) {
michael@0 130 id = getTopWindow(expectedWindow).document.documentElement.id;
michael@0 131 if (expectedEvents)
michael@0 132 expectedEvents += " ";
michael@0 133 expectedEvents += "activate: " + id + "-window";
michael@0 134 }
michael@0 135
michael@0 136 if (expectedWindow && gLastFocusWindow != expectedWindow) {
michael@0 137 if (gNewExpectedWindow)
michael@0 138 id = "frame-" + gNewExpectedWindow.document.documentElement.id;
michael@0 139 else
michael@0 140 id = (expectedWindow == window) ? "outer" : "child";
michael@0 141 if (expectedEvents)
michael@0 142 expectedEvents += " ";
michael@0 143 expectedEvents += "focus: " + id + "-document " +
michael@0 144 "focus: " + id + "-window";
michael@0 145 }
michael@0 146
michael@0 147 // for this test which fires a mouse event on a label, the document will
michael@0 148 // be focused first and then the label code will focus the related
michael@0 149 // control. This doesn't result in different focus events, but a command
michael@0 150 // update will occur for the document and then a secon command update will
michael@0 151 // occur when the control is focused.
michael@0 152 if (testid == "mouse on html label with content inside")
michael@0 153 expectedEvents += " commandupdate: cu";
michael@0 154
michael@0 155 if (expectedElement &&
michael@0 156 (!gNewExpectedWindow || gNewExpectedWindow.document.documentElement != expectedElement)) {
michael@0 157 if (!gNewExpectedWindow) {
michael@0 158 if (expectedEvents)
michael@0 159 expectedEvents += " ";
michael@0 160 expectedEvents += "commandupdate: cu";
michael@0 161 }
michael@0 162 if (expectedElement.id != "t" + kChildDocumentRootIndex) {
michael@0 163 if (expectedEvents)
michael@0 164 expectedEvents += " ";
michael@0 165 expectedEvents += "focus: " + expectedElement.id;
michael@0 166 }
michael@0 167 }
michael@0 168 else if (expectedWindow && gLastFocusWindow != expectedWindow &&
michael@0 169 !expectedElement) {
michael@0 170 if (expectedEvents)
michael@0 171 expectedEvents += " ";
michael@0 172 expectedEvents += "commandupdate: cu";
michael@0 173 }
michael@0 174 }
michael@0 175
michael@0 176 gLastFocus = expectedElement;
michael@0 177 gLastFocusWindow = expectedWindow;
michael@0 178
michael@0 179 callback();
michael@0 180
michael@0 181 compareEvents(expectedEvents, expectedWindow, expectedElement, testid);
michael@0 182 }
michael@0 183
michael@0 184 function compareEvents(expectedEvents, expectedWindow, expectedElement, testid)
michael@0 185 {
michael@0 186 if (!gShowOutput) {
michael@0 187 gEvents = "";
michael@0 188 return;
michael@0 189 }
michael@0 190
michael@0 191 is(gEvents, expectedEvents, testid + " events");
michael@0 192 gEvents = "";
michael@0 193
michael@0 194 var doc;
michael@0 195 if (expectedWindow == window)
michael@0 196 doc = "outer-document";
michael@0 197 else if (expectedWindow == gChildWindow)
michael@0 198 doc = "inner-document";
michael@0 199 else if (gNewExpectedWindow)
michael@0 200 doc = gNewExpectedWindow.document.body ? gNewExpectedWindow.document.body.id :
michael@0 201 gNewExpectedWindow.document.documentElement.id;
michael@0 202 else
michael@0 203 doc = "other-document";
michael@0 204
michael@0 205 var focusedElement = fm.focusedElement;
michael@0 206 is(focusedElement ? focusedElement.id : "none",
michael@0 207 expectedElement ? expectedElement.id : "none", testid + " focusedElement");
michael@0 208 is(fm.focusedWindow, expectedWindow, testid + " focusedWindow");
michael@0 209 var focusedWindow = {};
michael@0 210 is(fm.getFocusedElementForWindow(expectedWindow, false, focusedWindow),
michael@0 211 expectedElement, testid + " getFocusedElementForWindow");
michael@0 212 is(focusedWindow.value, expectedWindow, testid + " getFocusedElementForWindow frame");
michael@0 213 is(expectedWindow.document.hasFocus(), true, testid + " hasFocus");
michael@0 214 is(expectedWindow.document.activeElement ? expectedWindow.document.activeElement.id : "none",
michael@0 215 expectedElement ? expectedElement.id : doc, testid + " activeElement");
michael@0 216 var cdwindow = getTopWindow(expectedWindow);
michael@0 217 if (cdwindow.document.commandDispatcher) {
michael@0 218 is(cdwindow.document.commandDispatcher.focusedWindow, expectedWindow, testid + " commandDispatcher focusedWindow");
michael@0 219 is(cdwindow.document.commandDispatcher.focusedElement, focusedElement, testid + " commandDispatcher focusedElement");
michael@0 220 }
michael@0 221
michael@0 222 if (gLastFocusMethod != -1) {
michael@0 223 is(fm.getLastFocusMethod(null), gLastFocusMethod, testid + " lastFocusMethod null");
michael@0 224 is(fm.getLastFocusMethod(expectedWindow), gLastFocusMethod, testid + " lastFocusMethod window");
michael@0 225 }
michael@0 226
michael@0 227 // the parent should have the iframe focused
michael@0 228 if (doc == "inner-document") {
michael@0 229 is(document.hasFocus(), true, testid + " hasFocus");
michael@0 230 is(fm.getFocusedElementForWindow(window, false, focusedWindow),
michael@0 231 $("childframe"), testid + " getFocusedElementForWindow for parent");
michael@0 232 is(focusedWindow.value, window, testid + " getFocusedElementForWindow for parent frame");
michael@0 233 is(fm.getFocusedElementForWindow(window, true, focusedWindow),
michael@0 234 expectedElement, testid + " getFocusedElementForWindow deep for parent");
michael@0 235 is(focusedWindow.value, gChildWindow, testid + " getFocusedElementForWindow deep for parent frame");
michael@0 236 is(document.activeElement.id, "childframe", testid + " activeElement for parent");
michael@0 237 }
michael@0 238
michael@0 239 // compare the selection for the child window. Skip mouse tests as the caret
michael@0 240 // is adjusted by the selection code for mouse clicks, and not the focus code.
michael@0 241 if (expectedWindow == window) {
michael@0 242 var selection = window.getSelection();
michael@0 243 ok(selection.focusNode == null && selection.focusOffset == 0 &&
michael@0 244 selection.anchorNode == null && selection.anchorOffset == 0, testid + " selection");
michael@0 245 }
michael@0 246 else if ((expectedWindow == gChildWindow) && !testid.indexOf("mouse") == -1) {
michael@0 247 checkSelection(expectedElement, testid);
michael@0 248 }
michael@0 249 }
michael@0 250
michael@0 251 function checkSelection(node, testid)
michael@0 252 {
michael@0 253 var selection = gChildWindow.getSelection();
michael@0 254
michael@0 255 var range = gChildWindow.document.createRange();
michael@0 256 range.selectNodeContents(node);
michael@0 257 if (!node.firstChild || node.localName == "input" ||
michael@0 258 node.localName == "select" || node.localName == "button") {
michael@0 259 range.setStartBefore(node);
michael@0 260 range.setEndBefore(node);
michael@0 261 }
michael@0 262
michael@0 263 if (node.firstChild)
michael@0 264 range.setEnd(range.startContainer, range.startOffset);
michael@0 265
michael@0 266 is(selection.focusNode, range.startContainer, testid + " selection focusNode");
michael@0 267 is(selection.focusOffset, range.startOffset, testid + " selection focusOffset");
michael@0 268 is(selection.anchorNode, range.endContainer, testid + " selection anchorNode");
michael@0 269 is(selection.anchorOffset, range.endOffset, testid + " selection anchorOffset");
michael@0 270 }
michael@0 271
michael@0 272 function getTopWindow(win)
michael@0 273 {
michael@0 274 return win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
michael@0 275 getInterface(Components.interfaces.nsIWebNavigation).
michael@0 276 QueryInterface(Components.interfaces.nsIDocShellTreeItem).rootTreeItem.
michael@0 277 QueryInterface(Components.interfaces.nsIInterfaceRequestor).
michael@0 278 getInterface(Components.interfaces.nsIDOMWindow);
michael@0 279 }
michael@0 280
michael@0 281 function mouseOnElement(element, expectedElement, focusChanged, testid)
michael@0 282 {
michael@0 283 var expectedWindow = (element.ownerDocument.defaultView == gChildWindow) ? gChildWindow : window;
michael@0 284 // on Mac, form elements are not focused when clicking, except for lists and textboxes.
michael@0 285 var noFocusOnMouse = (navigator.platform.indexOf("Mac") == 0);
michael@0 286 if (noFocusOnMouse) {
michael@0 287 if (element.namespaceURI == "http://www.w3.org/1999/xhtml") {
michael@0 288 // links are special. They can be focused but show no focus ring
michael@0 289 if (element.localName == "a" || element.localName == "div" ||
michael@0 290 element.localName == "select" ||
michael@0 291 element.localName == "input" && (element.type == "text" ||
michael@0 292 element.type == "password")) {
michael@0 293 noFocusOnMouse = false;
michael@0 294 }
michael@0 295 }
michael@0 296 else if (element.localName == "listbox") {
michael@0 297 noFocusOnMouse = false;
michael@0 298 }
michael@0 299 }
michael@0 300
michael@0 301 if (noFocusOnMouse) {
michael@0 302 // no focus so the last focus method will be 0
michael@0 303 gLastFocusMethod = 0;
michael@0 304 expectFocusShift(function () synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView),
michael@0 305 expectedWindow, null, true, testid);
michael@0 306 gLastFocusMethod = fm.FLAG_BYMOUSE;
michael@0 307 }
michael@0 308 else {
michael@0 309 expectFocusShift(function () synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView),
michael@0 310 element.ownerDocument.defaultView,
michael@0 311 expectedElement, focusChanged, testid);
michael@0 312 }
michael@0 313 }
michael@0 314
michael@0 315 function done()
michael@0 316 {
michael@0 317 var opener = window.opener;
michael@0 318 window.close();
michael@0 319 opener.wrappedJSObject.SimpleTest.finish();
michael@0 320 }
michael@0 321
michael@0 322 var pressTab = function () synthesizeKey("VK_TAB", { });
michael@0 323
michael@0 324 function setFocusTo(id, fwindow)
michael@0 325 {
michael@0 326 gLastFocus = getById(id);
michael@0 327 gLastFocusWindow = fwindow;
michael@0 328 if (gLastFocus)
michael@0 329 gLastFocus.focus();
michael@0 330 else
michael@0 331 fm.clearFocus(fwindow);
michael@0 332 gEvents = "";
michael@0 333 }
michael@0 334
michael@0 335 function getById(id)
michael@0 336 {
michael@0 337 if (gNewExpectedWindow)
michael@0 338 return gNewExpectedWindow.document.getElementById(id);
michael@0 339 var element = $(id);
michael@0 340 if (!element)
michael@0 341 element = $("childframe").contentDocument.getElementById(id);
michael@0 342 return element;
michael@0 343 }
michael@0 344
michael@0 345 function startTest()
michael@0 346 {
michael@0 347 if (gTestStarted)
michael@0 348 return;
michael@0 349 gTestStarted = true;
michael@0 350
michael@0 351 gChildWindow = $("childframe").contentWindow;
michael@0 352 gShowOutput = true;
michael@0 353
michael@0 354 // synthesize a mousemove over the image to ensure that the imagemap data is
michael@0 355 // created. Otherwise, the special imagemap frames might not exist, and
michael@0 356 // won't be focusable.
michael@0 357 synthesizeMouse(getById("image"), 4, 4, { type: "mousemove" }, gChildWindow);
michael@0 358
michael@0 359 initEvents(window);
michael@0 360
michael@0 361 is(fm.activeWindow, window, "activeWindow");
michael@0 362 is(gChildWindow.document.hasFocus(), false, " child document hasFocus");
michael@0 363
michael@0 364 // test to see if the Mac Full Keyboard Access setting is set. If t3 is
michael@0 365 // focused after tab is pressed, then it is set to textboxes and lists only.
michael@0 366 // Otherwise, all elements are in the tab order.
michael@0 367 pressTab();
michael@0 368
michael@0 369 if (fm.focusedElement.id == "t3")
michael@0 370 gPartialTabbing = true;
michael@0 371 else
michael@0 372 is(fm.focusedElement.id, "t1", "initial tab key");
michael@0 373
michael@0 374 is(fm.getLastFocusMethod(null), fm.FLAG_BYKEY, "last focus method null start");
michael@0 375 is(fm.getLastFocusMethod(window), fm.FLAG_BYKEY, "last focus method window start");
michael@0 376
michael@0 377 fm.clearFocus(window);
michael@0 378 gEvents = "";
michael@0 379
michael@0 380 gLastFocusMethod = fm.FLAG_BYKEY;
michael@0 381 if (gPartialTabbing) {
michael@0 382 var partialTabList = ["t3", "t5", "t9", "t10", "t11", "t12", "t13", "t14", "t15",
michael@0 383 "t16", "t19", "t20", "t21", "t22", "t26", "t27", "t28", "t29", "t30"];
michael@0 384 for (var idx = 0; idx < partialTabList.length; idx++) {
michael@0 385 expectFocusShift(pressTab, null, getById(partialTabList[idx]), true, "partial tab key " + partialTabList[idx]);
michael@0 386 }
michael@0 387 setFocusTo("last", window);
michael@0 388 expectFocusShift(pressTab, null, getById(partialTabList[0]), true, "partial tab key wrap to start");
michael@0 389 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 390 null, getById("last"), true, "partial shift tab key wrap to end");
michael@0 391 for (var idx = partialTabList.length - 1; idx >= 0; idx--) {
michael@0 392 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 393 null, getById(partialTabList[idx]), true, "partial tab key " + partialTabList[idx]);
michael@0 394 }
michael@0 395 }
michael@0 396 else {
michael@0 397 // TAB key
michael@0 398 for (var idx = 1; idx <= kTabbableSteps; idx++) {
michael@0 399 expectFocusShift(pressTab, null, getById("t" + idx), true, "tab key t" + idx);
michael@0 400 }
michael@0 401
michael@0 402 // wrapping around at end with TAB key
michael@0 403 setFocusTo("last", window);
michael@0 404 expectFocusShift(pressTab, null, getById("t1"), true, "tab key wrap to start");
michael@0 405 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 406 null, getById("last"), true, "shift tab key wrap to end");
michael@0 407
michael@0 408 // Shift+TAB key
michael@0 409 setFocusTo("o5", window);
michael@0 410 for (idx = kTabbableSteps; idx > 0; idx--) {
michael@0 411 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 412 null, getById("t" + idx), true, "shift tab key t" + idx);
michael@0 413 }
michael@0 414 }
michael@0 415
michael@0 416 var t19 = getById("t19");
michael@0 417 is(t19.selectionStart, 0, "input focused from tab key selectionStart");
michael@0 418 is(t19.selectionEnd, 5, "input focused from tab key selectionEnd");
michael@0 419 t19.setSelectionRange(0, 0);
michael@0 420
michael@0 421 gLastFocusMethod = 0;
michael@0 422 var selectFired = false;
michael@0 423 function selectListener() { selectFired = true; }
michael@0 424 t19.addEventListener("select", selectListener, false);
michael@0 425 expectFocusShift(function() t19.select(),
michael@0 426 null, getById("t" + 19), true, "input.select()");
michael@0 427 t19.removeEventListener("select", selectListener, false);
michael@0 428 ok(selectFired, "select event fires for input");
michael@0 429
michael@0 430 // mouse clicking
michael@0 431 gLastFocusMethod = fm.FLAG_BYMOUSE;
michael@0 432 for (idx = kTabbableSteps; idx >= 1; idx--) {
michael@0 433 // skip the document root and the overflow element
michael@0 434 if (idx == kChildDocumentRootIndex || idx == kOverflowElementIndex)
michael@0 435 continue;
michael@0 436 if ((navigator.platform.indexOf("Mac") == 0) && (idx == kBeforeTabboxIndex + 1))
michael@0 437 continue;
michael@0 438
michael@0 439 var element = getById("t" + idx);
michael@0 440 // skip area elements, as getBoundingClientRect doesn't return their actual coordinates
michael@0 441 if (element.localName == "area")
michael@0 442 continue;
michael@0 443
michael@0 444 mouseOnElement(element, getById("t" + idx), true, "mouse on element t" + idx);
michael@0 445 var expectedWindow = (element.ownerDocument.defaultView == gChildWindow) ? gChildWindow : window;
michael@0 446 if (element.localName == "listbox" && expectedWindow == window &&
michael@0 447 navigator.platform.indexOf("Mac") == 0) {
michael@0 448 // after focusing a listbox on Mac, clear the focus before continuing.
michael@0 449 setFocusTo(null, window);
michael@0 450 }
michael@0 451 }
michael@0 452
michael@0 453 is(t19.selectionStart, 0, "input focused from mouse selectionStart");
michael@0 454 is(t19.selectionEnd, 0, "input focused from mouse selectionEnd");
michael@0 455
michael@0 456 // mouse clicking on elements that are not tabbable
michael@0 457 for (idx = 1; idx <= kFocusSteps; idx++) {
michael@0 458 var element = getById("o" + (idx % 2 ? idx : idx - 1));
michael@0 459
michael@0 460 mouseOnElement(element, element, idx % 2,
michael@0 461 "mouse on non-tabbable element o" + idx);
michael@0 462 }
michael@0 463
michael@0 464 // mouse clicking on elements that are not tabbable and have user-focus: none
michael@0 465 // or are not focusable for other reasons (for instance, being disabled)
michael@0 466 // These elements will clear the focus when clicked.
michael@0 467 for (idx = 1; idx <= kNoFocusSteps; idx++) {
michael@0 468 var element = getById("n" + idx);
michael@0 469 gLastFocusMethod = idx % 2 ? 0 : fm.FLAG_BYMOUSE;
michael@0 470
michael@0 471 mouseOnElement(element, idx % 2 ? null: element, true, "mouse on unfocusable element n" + idx);
michael@0 472 }
michael@0 473
michael@0 474 if (idx == kOverflowElementIndex) {
michael@0 475 gLastFocusMethod = fm.FLAG_BYMOUSE;
michael@0 476 var element = getById("t" + idx);
michael@0 477 expectFocusShift(function () synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView),
michael@0 478 window, null, true, "mouse on scrollable element");
michael@0 479 }
michael@0 480
michael@0 481 // focus() method
michael@0 482 gLastFocusMethod = 0;
michael@0 483 for (idx = kTabbableSteps; idx >= 1; idx--) {
michael@0 484 if ((navigator.platform.indexOf("Mac") == 0) && (idx == kBeforeTabboxIndex + 1))
michael@0 485 continue;
michael@0 486 expectFocusShift(function () getById("t" + idx).focus(),
michael@0 487 null, getById("t" + idx), true, "focus method on element t" + idx);
michael@0 488 }
michael@0 489
michael@0 490 $("t1").focus();
michael@0 491 ok(gEvents === "", "focusing element that is already focused");
michael@0 492
michael@0 493 $("t2").blur();
michael@0 494 $("t7").blur();
michael@0 495 ok(gEvents === "", "blurring element that is not focused");
michael@0 496 is(document.activeElement, $("t1"), "old element still focused after blur() on another element");
michael@0 497
michael@0 498 // focus() method on elements that are not tabbable
michael@0 499 for (idx = 1; idx <= kFocusSteps; idx++) {
michael@0 500 var expected = getById("o" + (idx % 2 ? idx : idx - 1));
michael@0 501 expectFocusShift(function () getById("o" + idx).focus(),
michael@0 502 expected.ownerDocument.defaultView,
michael@0 503 expected, idx % 2, "focus method on non-tabbable element o" + idx);
michael@0 504 }
michael@0 505
michael@0 506 // focus() method on elements that are not tabbable and have user-focus: none
michael@0 507 // or are not focusable for other reasons (for instance, being disabled)
michael@0 508 for (idx = 1; idx <= kNoFocusSteps; idx++) {
michael@0 509 var expected = getById("o" + (idx % 2 ? idx : idx - 1));
michael@0 510 expectFocusShift(function () getById("o" + idx).focus(),
michael@0 511 expected.ownerDocument.defaultView,
michael@0 512 expected, idx % 2, "focus method on unfocusable element n" + idx);
michael@0 513 }
michael@0 514
michael@0 515 // the focus() method on the legend element should focus the legend if it is
michael@0 516 // focusable, or the first element after the legend if it is not focusable.
michael@0 517 if (!gPartialTabbing) {
michael@0 518 gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
michael@0 519 var legend = getById("legend");
michael@0 520 expectFocusShift(function () legend.focus(),
michael@0 521 null, getById("t28"), true, "focus method on unfocusable legend");
michael@0 522 gLastFocusMethod = 0;
michael@0 523 legend.tabIndex = "0";
michael@0 524 expectFocusShift(function () legend.focus(),
michael@0 525 null, getById("legend"), true, "focus method on focusable legend");
michael@0 526 legend.tabIndex = "-1";
michael@0 527 }
michael@0 528
michael@0 529 var accessKeyDetails = (navigator.platform.indexOf("Mac") >= 0) ?
michael@0 530 { ctrlKey : true } : { altKey : true };
michael@0 531
michael@0 532 // test accesskeys
michael@0 533 var keys = ["t26", "t19", "t22", "t29", "t15", "t17", "n6",
michael@0 534 "t4", "o1", "o9", "n4"];
michael@0 535 for (var k = 0; k < keys.length; k++) {
michael@0 536 var key = String.fromCharCode(65 + k);
michael@0 537
michael@0 538 // accesskeys D and G are for labels so get redirected
michael@0 539 gLastFocusMethod = (key == "D" || key == "G") ? fm.FLAG_BYMOVEFOCUS : fm.FLAG_BYKEY;
michael@0 540
michael@0 541 // on Windows and Linux, the shift key must be pressed for content area access keys
michael@0 542 // and on Mac, the alt key must be pressed for content area access keys
michael@0 543 var isContent = (getById(keys[k]).ownerDocument.defaultView == gChildWindow);
michael@0 544 if (navigator.platform.indexOf("Mac") == -1) {
michael@0 545 accessKeyDetails.shiftKey = isContent;
michael@0 546 } else {
michael@0 547 accessKeyDetails.altKey = isContent;
michael@0 548 }
michael@0 549
michael@0 550 expectFocusShift(function () synthesizeKey(key, accessKeyDetails),
michael@0 551 null, getById(keys[k]), true, "accesskey " + key);
michael@0 552 }
michael@0 553
michael@0 554 // clicking on the labels
michael@0 555 gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
michael@0 556 expectFocusShift(function () synthesizeMouse(getById("ad"), 2, 2, { }, gChildWindow),
michael@0 557 null, getById("t29"), true, "mouse on html label with content inside");
michael@0 558 expectFocusShift(function () synthesizeMouse(getById("ag"), 2, 2, { }, gChildWindow),
michael@0 559 null, getById("n6"), true, "mouse on html label with for attribute");
michael@0 560 gLastFocusMethod = 0;
michael@0 561 expectFocusShift(function () synthesizeMouse(getById("aj"), 2, 2, { }),
michael@0 562 null, getById("o9"), true, "mouse on xul label with content inside");
michael@0 563 expectFocusShift(function () synthesizeMouse(getById("ak"), 2, 2, { }),
michael@0 564 null, getById("n4"), true, "mouse on xul label with control attribute");
michael@0 565
michael@0 566 // test accesskeys that shouldn't work
michael@0 567 k = "o".charCodeAt(0);
michael@0 568 while (k++ < "v".charCodeAt(0)) {
michael@0 569 var key = String.fromCharCode(k);
michael@0 570 expectFocusShift(function () synthesizeKey(key, accessKeyDetails),
michael@0 571 window, getById("n4"), false, "non accesskey " + key);
michael@0 572 }
michael@0 573 gLastFocusMethod = -1;
michael@0 574
michael@0 575 // should focus the for element when using the focus method on a label as well
michael@0 576 expectFocusShift(function () getById("ad").focus(),
michael@0 577 null, getById("t29"), true, "mouse on html label using focus method");
michael@0 578
michael@0 579 // make sure that the text is selected when clicking a label associated with an input
michael@0 580 getById("ag").htmlFor = "t19";
michael@0 581 expectFocusShift(function () synthesizeMouse(getById("ag"), 2, 2, { }, gChildWindow),
michael@0 582 null, getById("t19"), true, "mouse on html label with for attribute changed");
michael@0 583 is(t19.selectionStart, 0, "input focused from label, selectionStart");
michael@0 584 is(t19.selectionEnd, 5, "input focused from label, selectionEnd");
michael@0 585
michael@0 586 // switch to another panel in a tabbox and ensure that tabbing moves between
michael@0 587 // elements on the new panel.
michael@0 588 $("tabbox").selectedIndex = 1;
michael@0 589 expectFocusShift(function () getById("t" + kBeforeTabboxIndex).focus(),
michael@0 590 null, getById("t" + kBeforeTabboxIndex), true, "focus method on element before tabbox");
michael@0 591
michael@0 592 if (!gPartialTabbing) {
michael@0 593 expectFocusShift(pressTab, null, getById("tab2"), true, "focus method on tab");
michael@0 594 expectFocusShift(pressTab, null, getById("htab1"), true, "tab key switch tabpanel 1");
michael@0 595 expectFocusShift(pressTab, null, getById("htab2"), true, "tab key switch tabpanel 2");
michael@0 596 expectFocusShift(pressTab, null, getById("t" + (kBeforeTabboxIndex + 4)), true, "tab key switch tabpanel 3");
michael@0 597 }
michael@0 598 $("tabbox").selectedIndex = 0;
michael@0 599
michael@0 600 // ---- the following checks when the focus changes during a blur or focus event ----
michael@0 601
michael@0 602 var o5 = $("o5");
michael@0 603 var o9 = $("o9");
michael@0 604 var t3 = $("t3");
michael@0 605 var t17 = getById("t17");
michael@0 606 var t19 = getById("t19");
michael@0 607 var shiftFocusParentDocument = function() o9.focus();
michael@0 608 var shiftFocusChildDocument = function() t17.focus();
michael@0 609
michael@0 610 var trapBlur = function (element, eventListener, blurFunction)
michael@0 611 {
michael@0 612 element.focus();
michael@0 613 gEvents = "";
michael@0 614 element.addEventListener("blur", eventListener, false);
michael@0 615 blurFunction();
michael@0 616 element.removeEventListener("blur", eventListener, false);
michael@0 617 }
michael@0 618
michael@0 619 var functions = [
michael@0 620 function(element) element.focus(),
michael@0 621 function(element) synthesizeMouse(element, 4, 4, { }, element.ownerDocument.defaultView)
michael@0 622 ];
michael@0 623
michael@0 624 // first, check cases where the focus is adjusted during the blur event. Iterate twice,
michael@0 625 // once with the focus method and then focusing by mouse clicking
michael@0 626 for (var l = 0; l < 2; l++) {
michael@0 627 var adjustFocus = functions[l];
michael@0 628 var mod = (l == 1) ? " with mouse" : "";
michael@0 629
michael@0 630 // an attempt is made to switch the focus from one element (o5) to another
michael@0 631 // element (t3) within the same document, yet the focus is shifted to a
michael@0 632 // third element (o9) in the same document during the blur event for the
michael@0 633 // first element.
michael@0 634 trapBlur(o5, shiftFocusParentDocument, function () adjustFocus(t3));
michael@0 635 compareEvents("commandupdate: cu blur: o5 commandupdate: cu focus: o9",
michael@0 636 window, o9, "change focus to sibling during element blur, attempted sibling" + mod);
michael@0 637
michael@0 638 // similar, but the third element (t17) is in a child document
michael@0 639 trapBlur(o9, shiftFocusChildDocument, function () adjustFocus(t3));
michael@0 640 compareEvents("commandupdate: cu blur: o9 blur: outer-document blur: outer-window " +
michael@0 641 "focus: child-document focus: child-window commandupdate: cu focus: t17",
michael@0 642 gChildWindow, t17, "change focus to child document during element blur, attempted sibling" + mod);
michael@0 643
michael@0 644 // similar, but an attempt to switch focus within the same document, but the
michael@0 645 // third element (t17) is in a parent document
michael@0 646 trapBlur(t17, shiftFocusParentDocument, function () adjustFocus(t19));
michael@0 647 compareEvents("commandupdate: cu blur: t17 blur: child-document blur: child-window " +
michael@0 648 "focus: outer-document focus: outer-window commandupdate: cu focus: o9",
michael@0 649 window, o9, "change focus to parent document during element blur, attempted sibling" + mod);
michael@0 650
michael@0 651 // similar, but blur is called instead of switching focus
michael@0 652 trapBlur(t3, shiftFocusParentDocument, function () t3.blur());
michael@0 653 compareEvents("commandupdate: cu blur: t3 commandupdate: cu focus: o9",
michael@0 654 window, o9, "change focus to same document during clear focus" + mod);
michael@0 655
michael@0 656 // check when an element in the same document is focused during the
michael@0 657 // element's blur event, but an attempt was made to focus an element in the
michael@0 658 // child document. In this case, the focus in the parent document should be
michael@0 659 // what was set during the blur event, but the actual focus should still
michael@0 660 // move to the child document.
michael@0 661 trapBlur(t3, shiftFocusParentDocument, function () adjustFocus(t17));
michael@0 662 compareEvents("commandupdate: cu blur: t3 commandupdate: cu focus: o9 " +
michael@0 663 "blur: outer-document blur: outer-window " +
michael@0 664 "focus: child-document focus: child-window commandupdate: cu focus: t17",
michael@0 665 gChildWindow, t17, "change focus to sibling during element blur, attempted child" + mod);
michael@0 666 is(fm.getFocusedElementForWindow(window, false, {}), $("childframe"),
michael@0 667 "change focus to sibling during element blur, attempted child, focused in parent" + mod);
michael@0 668
michael@0 669 // similar, but with a parent
michael@0 670 trapBlur(t19, shiftFocusChildDocument, function () adjustFocus(t3));
michael@0 671 compareEvents("commandupdate: cu blur: t19 commandupdate: cu focus: t17 " +
michael@0 672 "blur: child-document blur: child-window " +
michael@0 673 "focus: outer-document focus: outer-window commandupdate: cu focus: t3",
michael@0 674 window, t3, "change focus to sibling during element blur, attempted parent" + mod);
michael@0 675 is(fm.getFocusedElementForWindow(gChildWindow, false, {}), t17,
michael@0 676 "change focus to sibling during element blur, attempted child, focused in child" + mod);
michael@0 677
michael@0 678 // similar, with a child, but the blur event focuses a child element also
michael@0 679 trapBlur(t3, shiftFocusChildDocument, function () adjustFocus(t19));
michael@0 680 compareEvents("commandupdate: cu blur: t3 blur: outer-document blur: outer-window " +
michael@0 681 "focus: child-document focus: child-window commandupdate: cu focus: t17",
michael@0 682 gChildWindow, t17, "change focus to child during element blur, attempted child" + mod);
michael@0 683
michael@0 684 // similar, with a parent, where the blur event focuses a parent element also
michael@0 685 trapBlur(t17, shiftFocusParentDocument, function () adjustFocus(t3));
michael@0 686 compareEvents("commandupdate: cu blur: t17 blur: child-document blur: child-window " +
michael@0 687 "focus: outer-document focus: outer-window commandupdate: cu focus: o9",
michael@0 688 window, o9, "change focus to parent during element blur, attempted parent" + mod);
michael@0 689 }
michael@0 690
michael@0 691 var trapFocus = function (element, eventListener)
michael@0 692 {
michael@0 693 element.addEventListener("focus", eventListener, false);
michael@0 694 element.focus();
michael@0 695 element.removeEventListener("focus", eventListener, false);
michael@0 696 }
michael@0 697
michael@0 698 fm.clearFocus(window);
michael@0 699 gEvents = "";
michael@0 700
michael@0 701 // next, check cases where the focus is adjusted during the focus event
michael@0 702
michael@0 703 // switch focus to an element in the same document
michael@0 704 trapFocus(o5, shiftFocusParentDocument);
michael@0 705 compareEvents("commandupdate: cu focus: o5 commandupdate: cu blur: o5 commandupdate: cu focus: o9",
michael@0 706 window, o9, "change focus to sibling during element focus");
michael@0 707
michael@0 708 // similar, but the new element (t17) is in a child document
michael@0 709 trapFocus(o5, shiftFocusChildDocument);
michael@0 710 compareEvents("commandupdate: cu blur: o9 " +
michael@0 711 "commandupdate: cu focus: o5 commandupdate: cu blur: o5 " +
michael@0 712 "blur: outer-document blur: outer-window " +
michael@0 713 "focus: child-document focus: child-window commandupdate: cu focus: t17",
michael@0 714 gChildWindow, t17, "change focus to child document during element focus");
michael@0 715
michael@0 716 // similar, but the new element (o9) is in a parent document.
michael@0 717 trapFocus(t19, shiftFocusParentDocument);
michael@0 718 compareEvents("commandupdate: cu blur: t17 " +
michael@0 719 "commandupdate: cu focus: t19 commandupdate: cu blur: t19 " +
michael@0 720 "blur: child-document blur: child-window " +
michael@0 721 "focus: outer-document focus: outer-window commandupdate: cu focus: o9",
michael@0 722 window, o9, "change focus to parent document during element focus");
michael@0 723
michael@0 724 // clear the focus during the focus event
michael@0 725 trapFocus(t3, function () fm.clearFocus(window));
michael@0 726 compareEvents("commandupdate: cu blur: o9 commandupdate: cu focus: t3 commandupdate: cu blur: t3",
michael@0 727 window, null, "clear focus during focus event");
michael@0 728
michael@0 729 if (!gPartialTabbing)
michael@0 730 doCommandDispatcherTests();
michael@0 731
michael@0 732 testMoveFocus();
michael@0 733
michael@0 734 doRemoveTests();
michael@0 735
michael@0 736 // tests various focus manager apis for null checks
michael@0 737 var exh = false;
michael@0 738 try {
michael@0 739 fm.clearFocus(null);
michael@0 740 }
michael@0 741 catch (ex) { exh = true; }
michael@0 742 is(exh, true, "clearFocus with null window causes exception");
michael@0 743
michael@0 744 var exh = false;
michael@0 745 try {
michael@0 746 fm.getFocusedElementForWindow(null, false, focusedWindow);
michael@0 747 }
michael@0 748 catch (ex) { exh = true; }
michael@0 749 is(exh, true, "getFocusedElementForWindow with null window causes exception");
michael@0 750
michael@0 751 // just make sure that this doesn't crash
michael@0 752 fm.moveCaretToFocus(null);
michael@0 753
michael@0 754 // ---- tests for the FLAG_NOSWITCHFRAME flag
michael@0 755 getById("o5").focus();
michael@0 756 gLastFocusMethod = 0;
michael@0 757 gEvents = "";
michael@0 758 // focus is being shifted in a child, so the focus should not change
michael@0 759 expectFocusShift(function () fm.setFocus(getById("t20"), fm.FLAG_NOSWITCHFRAME),
michael@0 760 window, getById("o5"), false, "no switch frame focus to child");
michael@0 761 setFocusTo("t20", gChildWindow);
michael@0 762
michael@0 763 // here, however, focus is being shifted in a parent, which will have to blur
michael@0 764 // the child, so the focus will always change
michael@0 765 expectFocusShift(function () fm.setFocus(getById("o5"), fm.FLAG_NOSWITCHFRAME),
michael@0 766 window, getById("o5"), true, "no switch frame focus to parent");
michael@0 767
michael@0 768 expectFocusShift(function () fm.setFocus(getById("t1"), fm.FLAG_NOSWITCHFRAME),
michael@0 769 window, getById("t1"), true, "no switch frame focus to same window");
michael@0 770
michael@0 771 // ---- tests for focus and scrolling into view ----
michael@0 772 var inscroll = getById("inscroll");
michael@0 773 inscroll.tabIndex = 0;
michael@0 774 is(inscroll.parentNode.scrollTop, 0, "scroll position before focus");
michael@0 775 inscroll.focus();
michael@0 776 ok(inscroll.parentNode.scrollTop > 5, "scroll position after focus");
michael@0 777 inscroll.parentNode.scrollTop = 0;
michael@0 778 fm.setFocus(inscroll, fm.FLAG_NOSCROLL);
michael@0 779 is(inscroll.parentNode.scrollTop, 0, "scroll position after noscroll focus");
michael@0 780
michael@0 781 getById("t9").focus();
michael@0 782 getById("inpopup1").focus();
michael@0 783 is(fm.focusedElement, getById("t9"), "focus in closed popup");
michael@0 784
michael@0 785 // ---- tests to check if tabbing out of a textbox works
michael@0 786
michael@0 787 setFocusTo("t1", window);
michael@0 788
michael@0 789 var textbox1 = document.createElement("textbox");
michael@0 790 $("innerbox").appendChild(textbox1);
michael@0 791
michael@0 792 var textbox2 = document.createElement("textbox");
michael@0 793 $("innerbox").appendChild(textbox2);
michael@0 794
michael@0 795 gLastFocusMethod = 0;
michael@0 796 expectFocusShift(function () textbox2.focus(),
michael@0 797 null, textbox2.inputField, true, "focus on textbox");
michael@0 798 gLastFocusMethod = fm.FLAG_BYKEY;
michael@0 799 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 800 null, textbox1.inputField, true, "shift+tab on textbox");
michael@0 801
michael@0 802 textbox1.tabIndex = 2;
michael@0 803 textbox2.tabIndex = 2;
michael@0 804 gLastFocusMethod = 0;
michael@0 805 expectFocusShift(function () textbox2.focus(),
michael@0 806 null, textbox2.inputField, true, "focus on textbox with tabindex set");
michael@0 807 gLastFocusMethod = fm.FLAG_BYKEY;
michael@0 808 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 809 null, textbox1.inputField, true, "shift+tab on textbox with tabindex set");
michael@0 810
michael@0 811 // ---- test for bug 618907 which ensures that canceling the mousedown event still focuses the
michael@0 812 // right frame
michael@0 813
michael@0 814 var childContentFrame = document.getElementById("ifa")
michael@0 815 childContentFrame.style.MozUserFocus = "";
michael@0 816
michael@0 817 var frab = childContentFrame.contentDocument.getElementById("fra-b");
michael@0 818 var mouseDownListener = function(event) event.preventDefault();
michael@0 819 frab.addEventListener("mousedown", mouseDownListener, false);
michael@0 820
michael@0 821 var childElementToFocus = childContentFrame.contentDocument.getElementById("fra");
michael@0 822 gLastFocus = childElementToFocus;
michael@0 823 gLastFocusWindow = childContentFrame.contentWindow;
michael@0 824 gLastFocus.focus();
michael@0 825 gEvents = "";
michael@0 826
michael@0 827 setFocusTo("t1", window);
michael@0 828
michael@0 829 gLastFocusMethod = -1;
michael@0 830 expectFocusShift(function () synthesizeMouse(frab, 5, 5, { }, childContentFrame.contentWindow),
michael@0 831 null, childElementToFocus, true,
michael@0 832 "mousedown event canceled - chrome to content");
michael@0 833
michael@0 834 frab.removeEventListener("mousedown", mouseDownListener, false);
michael@0 835
michael@0 836 var t5 = getById("t5");
michael@0 837 t5.addEventListener("mousedown", mouseDownListener, false);
michael@0 838 synthesizeMouse(t5, 10, 10, { })
michael@0 839 t5.removeEventListener("mousedown", mouseDownListener, false);
michael@0 840 is(fm.focusedElement, childElementToFocus,
michael@0 841 "mousedown event cancelled - content to chrome - element");
michael@0 842 is(fm.focusedWindow, childContentFrame.contentWindow, "mousedown event cancelled - content to chrome - window");
michael@0 843
michael@0 844 // ---- test to check that refocusing an element during a blur event doesn't succeed
michael@0 845
michael@0 846 var t1 = getById("t1");
michael@0 847 t1.addEventListener("blur", function() t1.focus(), true);
michael@0 848 t1.focus();
michael@0 849 var t3 = getById("t3");
michael@0 850 synthesizeMouse(t3, 2, 2, { });
michael@0 851 is(fm.focusedElement, t3, "focus during blur");
michael@0 852
michael@0 853 setFocusTo("t9", window);
michael@0 854 gLastFocusMethod = -1;
michael@0 855 window.openDialog("focus_window2.xul", "_blank", "chrome", otherWindowFocused);
michael@0 856 }
michael@0 857
michael@0 858 function doCommandDispatcherTests()
michael@0 859 {
michael@0 860 var t19 = getById("t19");
michael@0 861 t19.focus();
michael@0 862 gLastFocusWindow = gChildWindow;
michael@0 863 gLastFocus = t19;
michael@0 864 gEvents = "";
michael@0 865
michael@0 866 expectFocusShift(function () document.commandDispatcher.focusedElement = getById("o9"),
michael@0 867 null, getById("o9"), true, "command dispatcher set focusedElement");
michael@0 868 expectFocusShift(function () document.commandDispatcher.advanceFocus(),
michael@0 869 null, getById("o13"), true, "command dispatcher advanceFocus");
michael@0 870 expectFocusShift(function () document.commandDispatcher.rewindFocus(),
michael@0 871 null, getById("o9"), true, "command dispatcher rewindFocus");
michael@0 872 expectFocusShift(function () document.commandDispatcher.focusedElement = null,
michael@0 873 null, null, true, "command dispatcher set focusedElement to null");
michael@0 874 expectFocusShift(function () document.commandDispatcher.focusedWindow = gChildWindow,
michael@0 875 null, getById("t19"), true, "command dispatcher set focusedElement to null");
michael@0 876 expectFocusShift(function () document.commandDispatcher.focusedElement = null,
michael@0 877 gChildWindow, null, true, "command dispatcher set focusedElement to null in child");
michael@0 878 expectFocusShift(function () document.commandDispatcher.advanceFocusIntoSubtree(getById("t19")),
michael@0 879 null, getById("t20"), true, "command dispatcher advanceFocusIntoSubtree child");
michael@0 880 expectFocusShift(function () document.commandDispatcher.advanceFocusIntoSubtree(null),
michael@0 881 null, getById("t21"), true, "command dispatcher advanceFocusIntoSubtree null child");
michael@0 882 expectFocusShift(function () document.commandDispatcher.advanceFocusIntoSubtree(getById("o9").parentNode),
michael@0 883 null, getById("o9"), true, "command dispatcher advanceFocusIntoSubtree parent");
michael@0 884 }
michael@0 885
michael@0 886 function doRemoveTests()
michael@0 887 {
michael@0 888 // next, some tests which remove elements
michael@0 889 var t19 = getById("t19");
michael@0 890 t19.focus();
michael@0 891 t19.parentNode.removeChild(t19);
michael@0 892
michael@0 893 is(fm.focusedElement, null, "removed element focusedElement");
michael@0 894 is(fm.focusedWindow, gChildWindow, "removed element focusedWindow");
michael@0 895 is(gChildWindow.document.hasFocus(), true, "removed element hasFocus");
michael@0 896 is(gChildWindow.document.activeElement, getById("inner-document"), "removed element activeElement");
michael@0 897
michael@0 898 getById("t15").focus();
michael@0 899 var abs = getById("abs");
michael@0 900 abs.parentNode.removeChild(abs);
michael@0 901
michael@0 902 is(fm.focusedElement, null, "removed ancestor focusedElement");
michael@0 903 is(fm.focusedWindow, gChildWindow, "removed ancestor focusedWindow");
michael@0 904 is(gChildWindow.document.hasFocus(), true, "removed ancestor hasFocus");
michael@0 905 is(gChildWindow.document.activeElement, getById("inner-document"), "removed ancestor activeElement");
michael@0 906 }
michael@0 907
michael@0 908 // tests for the FocusManager moveFocus method
michael@0 909 function testMoveFocus()
michael@0 910 {
michael@0 911 setFocusTo("t6", window);
michael@0 912
michael@0 913 // moving focus while an element is already focused
michael@0 914 var newFocus;
michael@0 915 gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
michael@0 916 var expectedFirst = getById(gPartialTabbing ? "t3" : "t1");
michael@0 917 expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FIRST, 0),
michael@0 918 window, expectedFirst, true, "moveFocus to first null window null content");
michael@0 919 is(newFocus, fm.focusedElement, "moveFocus to first null window null content return value");
michael@0 920
michael@0 921 expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_LAST, 0),
michael@0 922 window, getById("last"), true, "moveFocus to last null window null content");
michael@0 923 is(newFocus, fm.focusedElement, "moveFocus to last null window null content return value");
michael@0 924
michael@0 925 gLastFocusMethod = 0;
michael@0 926 newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_ROOT, 0);
michael@0 927 is(newFocus, null, "moveFocus to root null window null content return value");
michael@0 928 is(fm.focusedWindow, window, "moveFocus to root null window null content focusedWindow");
michael@0 929 is(fm.focusedElement, null, "moveFocus to root null window null content focusedElement");
michael@0 930
michael@0 931 // moving focus while no element is focused
michael@0 932 fm.clearFocus(window);
michael@0 933 gEvents = "";
michael@0 934 gLastFocus = null;
michael@0 935 gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
michael@0 936 expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FIRST, 0),
michael@0 937 window, expectedFirst, true, "moveFocus to first null window null content no focus");
michael@0 938 is(newFocus, fm.focusedElement, "moveFocus to first null window null content no focus return value");
michael@0 939 fm.clearFocus(window);
michael@0 940 gEvents = "";
michael@0 941 gLastFocus = null;
michael@0 942 expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_LAST, 0),
michael@0 943 window, getById("last"), true, "moveFocus to last null window null content no focus");
michael@0 944 is(newFocus, fm.focusedElement, "moveFocus to last null window null content no focus return value");
michael@0 945 fm.clearFocus(window);
michael@0 946 gEvents = "";
michael@0 947 gLastFocusMethod = 0;
michael@0 948 newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_ROOT, 0);
michael@0 949 is(newFocus, null, "moveFocus to root null window null content no focus return value");
michael@0 950 is(fm.focusedWindow, window, "moveFocus to root null window null content no focus focusedWindow");
michael@0 951 is(fm.focusedElement, null, "moveFocus to root null window null content no focus focusedElement");
michael@0 952
michael@0 953 // moving focus from a specified element
michael@0 954 setFocusTo("t6", window);
michael@0 955 gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
michael@0 956 expectFocusShift(function () newFocus = fm.moveFocus(null, getById("specialroot"), fm.MOVEFOCUS_FIRST, 0),
michael@0 957 window, getById("t3"), true, "moveFocus to first null window with content");
michael@0 958 // XXXndeakin P3 this doesn't work
michael@0 959 // expectFocusShift(function () newFocus = fm.moveFocus(null, getById("specialroot"), fm.MOVEFOCUS_LAST, 0),
michael@0 960 // window, getById("o3"), true, "moveFocus to last null window with content");
michael@0 961
michael@0 962 // move focus to first in child window
michael@0 963 expectFocusShift(function () newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_FIRST, 0),
michael@0 964 gChildWindow, getById("t" + (kChildDocumentRootIndex + 1)), true,
michael@0 965 "moveFocus to first child window null content");
michael@0 966 is(newFocus, getById("t" + (kChildDocumentRootIndex + 1)),
michael@0 967 "moveFocus to first child window null content return value");
michael@0 968
michael@0 969 // move focus to last in child window
michael@0 970 setFocusTo("t6", window);
michael@0 971 var expectedLast = getById(gPartialTabbing ? "t30" : "t" + (kBeforeTabboxIndex - 1));
michael@0 972 expectFocusShift(function () newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_LAST, 0),
michael@0 973 gChildWindow, expectedLast, true,
michael@0 974 "moveFocus to last child window null content");
michael@0 975 is(newFocus, getById(expectedLast),
michael@0 976 "moveFocus to last child window null content return value");
michael@0 977
michael@0 978 // move focus to root in child window
michael@0 979 setFocusTo("t6", window);
michael@0 980 var childroot = getById("t" + kChildDocumentRootIndex);
michael@0 981 gLastFocusMethod = 0;
michael@0 982 newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_ROOT, 0),
michael@0 983 is(newFocus, childroot, "moveFocus to root child window null content return value");
michael@0 984 is(fm.focusedWindow, gChildWindow, "moveFocus to root child window null content focusedWindow");
michael@0 985 is(fm.focusedElement, childroot, "moveFocus to root child window null content focusedElement");
michael@0 986
michael@0 987 // MOVEFOCUS_CARET tests
michael@0 988 getById("t20").focus();
michael@0 989 gEvents = "";
michael@0 990
michael@0 991 var selection = gChildWindow.getSelection();
michael@0 992 selection.removeAllRanges();
michael@0 993
michael@0 994 newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
michael@0 995 is(newFocus, null, "move caret when at document root");
michael@0 996 is(fm.focusedElement, null, "move caret when at document root");
michael@0 997
michael@0 998 var node = getById("t16").firstChild;
michael@0 999 var range = gChildWindow.document.createRange();
michael@0 1000 range.setStart(node, 3);
michael@0 1001 range.setEnd(node, 3);
michael@0 1002 selection.addRange(range);
michael@0 1003
michael@0 1004 newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
michael@0 1005 is(newFocus, null, "move caret to non-link return value");
michael@0 1006 is(fm.focusedElement, null, "move caret to non-link");
michael@0 1007
michael@0 1008 var t25 = getById("t25");
michael@0 1009 var node = t25.firstChild;
michael@0 1010 range.setStart(node, 1);
michael@0 1011 range.setEnd(node, 1);
michael@0 1012 newFocus = fm.moveFocus(gChildWindow, null, fm.MOVEFOCUS_CARET, 0);
michael@0 1013
michael@0 1014 is(newFocus, t25, "move caret to link return value");
michael@0 1015 is(fm.focusedElement, t25, "move caret to link focusedElement");
michael@0 1016
michael@0 1017 // enable caret browsing temporarily to test caret movement
michael@0 1018 var prefs = Components.classes["@mozilla.org/preferences-service;1"].
michael@0 1019 getService(Components.interfaces.nsIPrefBranch);
michael@0 1020 prefs.setBoolPref("accessibility.browsewithcaret", true);
michael@0 1021
michael@0 1022 synthesizeKey("VK_LEFT", { }, gChildWindow);
michael@0 1023 synthesizeKey("VK_LEFT", { }, gChildWindow);
michael@0 1024 is(fm.focusedElement, null, "move caret away from link");
michael@0 1025
michael@0 1026 synthesizeKey("VK_LEFT", { }, gChildWindow);
michael@0 1027 is(fm.focusedElement, getById("t24"), "move caret away onto link");
michael@0 1028
michael@0 1029 prefs.setBoolPref("accessibility.browsewithcaret", false);
michael@0 1030
michael@0 1031 // cases where focus in on a content node with no frame
michael@0 1032
michael@0 1033 if (!gPartialTabbing) {
michael@0 1034 getById("t24").blur();
michael@0 1035 gEvents = "";
michael@0 1036 gLastFocus = null;
michael@0 1037 gLastFocusWindow = gChildWindow;
michael@0 1038 gLastFocusMethod = fm.FLAG_BYKEY;
michael@0 1039
michael@0 1040 selection.selectAllChildren(getById("hiddenspan"));
michael@0 1041 expectFocusShift(function () synthesizeKey("VK_TAB", { }),
michael@0 1042 gChildWindow, getById("t26"), true, "tab with selection on hidden content");
michael@0 1043
michael@0 1044 setFocusTo($("o15"), window);
michael@0 1045 $("o15").hidden = true;
michael@0 1046 document.documentElement.getBoundingClientRect(); // flush after hiding
michael@0 1047 expectFocusShift(function () synthesizeKey("VK_TAB", { }),
michael@0 1048 window, $("o17"), true, "tab with focus on hidden content");
michael@0 1049
michael@0 1050 $("o17").hidden = true;
michael@0 1051 document.documentElement.getBoundingClientRect();
michael@0 1052 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
michael@0 1053 window, $("o13"), true, "shift+tab with focus on hidden content");
michael@0 1054 }
michael@0 1055
michael@0 1056 // cases with selection in an <input>
michael@0 1057
michael@0 1058 var t19 = getById("t19");
michael@0 1059 t19.setSelectionRange(0, 0);
michael@0 1060 setFocusTo("t18", gChildWindow);
michael@0 1061
michael@0 1062 gLastFocusMethod = fm.FLAG_BYMOVEFOCUS;
michael@0 1063 expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FORWARD, 0),
michael@0 1064 gChildWindow, t19, true, "moveFocus to next textbox");
michael@0 1065 is(t19.selectionStart, 0, "input focused after moveFocus selectionStart");
michael@0 1066 is(t19.selectionEnd, 5, "input focused after moveFocus selectionEnd");
michael@0 1067
michael@0 1068 t19.setSelectionRange(0, 0);
michael@0 1069 setFocusTo("t18", gChildWindow);
michael@0 1070 gLastFocusMethod = fm.FLAG_BYKEY;
michael@0 1071 expectFocusShift(function () newFocus = fm.moveFocus(null, null, fm.MOVEFOCUS_FORWARD, fm.FLAG_BYKEY),
michael@0 1072 gChildWindow, t19, true, "moveFocus to next textbox by key");
michael@0 1073 is(t19.selectionStart, 0, "input focused after moveFocus by key selectionStart");
michael@0 1074 is(t19.selectionEnd, 5, "input focused after moveFocus by key selectionEnd");
michael@0 1075 }
michael@0 1076
michael@0 1077 function otherWindowFocused(otherWindow)
michael@0 1078 {
michael@0 1079 var expectedElement = getById("t9");
michael@0 1080
michael@0 1081 is(fm.activeWindow, otherWindow, "other activeWindow");
michael@0 1082 is(fm.focusedWindow, otherWindow, "other focusedWindow");
michael@0 1083 is(window.document.hasFocus(), false, "when lowered document hasFocus");
michael@0 1084 var focusedWindow = {};
michael@0 1085 is(fm.getFocusedElementForWindow(window, false, focusedWindow),
michael@0 1086 expectedElement, "when lowered getFocusedElementForWindow");
michael@0 1087 is(focusedWindow.value, window, "when lowered getFocusedElementForWindow frame");
michael@0 1088 is(document.activeElement.id, expectedElement.id, "when lowered activeElement");
michael@0 1089 is(window.document.commandDispatcher.focusedWindow, window, " commandDispatcher in other window focusedWindow");
michael@0 1090 is(window.document.commandDispatcher.focusedElement, expectedElement, " commandDispatcher in other window focusedElement");
michael@0 1091
michael@0 1092 compareEvents("deactivate: outer-document-window blur: t9 blur: outer-document blur: outer-window",
michael@0 1093 otherWindow, null, "other window opened");
michael@0 1094
michael@0 1095 otherWindow.document.getElementById("other").focus();
michael@0 1096
michael@0 1097 for (var idx = kTabbableSteps; idx >= 1; idx--) {
michael@0 1098 expectedElement = getById("t" + idx);
michael@0 1099 if (!expectedElement) // skip elements that were removed in doRemoveTests()
michael@0 1100 continue;
michael@0 1101 if ((navigator.platform.indexOf("Mac") == 0) && (idx == kBeforeTabboxIndex + 1))
michael@0 1102 continue;
michael@0 1103
michael@0 1104 expectedElement.focus();
michael@0 1105
michael@0 1106 is(fm.focusedElement.id, "other", "when lowered focusedElement t" + idx);
michael@0 1107 is(fm.focusedWindow, otherWindow, "when lowered focusedWindow t" + idx);
michael@0 1108
michael@0 1109 var checkWindow = expectedElement.ownerDocument.defaultView;
michael@0 1110 is(fm.getFocusedElementForWindow(checkWindow, false, {}).id, expectedElement.id,
michael@0 1111 "when lowered getFocusedElementForWindow t" + idx);
michael@0 1112 is(checkWindow.document.activeElement.id, expectedElement.id, "when lowered activeElement t" + idx);
michael@0 1113 if (checkWindow != window) {
michael@0 1114 is(fm.getFocusedElementForWindow(window, false, {}), $("childframe"),
michael@0 1115 "when lowered parent getFocusedElementForWindow t" + idx);
michael@0 1116 is(document.activeElement.id, "childframe",
michael@0 1117 "when lowered parent activeElement t" + idx);
michael@0 1118 }
michael@0 1119 }
michael@0 1120
michael@0 1121 gEvents = gEvents.replace(/commandupdate: cu\s?/g, "");
michael@0 1122 is(gEvents, "", "when lowered no events fired");
michael@0 1123
michael@0 1124 var other = otherWindow.document.getElementById("other");
michael@0 1125 other.focus();
michael@0 1126 is(fm.focusedElement, other, "focus method in second window");
michael@0 1127
michael@0 1128 otherWindow.close();
michael@0 1129
michael@0 1130 getById("n2").focus();
michael@0 1131
michael@0 1132 // next, check modal dialogs
michael@0 1133 // XXXndeakin Bug 621399 - the modal dialog test as well as later tests sometime fail
michael@0 1134 // on Windows 8 so just end the test here.
michael@0 1135 if (navigator.userAgent.indexOf("Windows NT 6.2") >= 0) {
michael@0 1136 done();
michael@0 1137 }
michael@0 1138 else {
michael@0 1139 window.openDialog("focus_window2.xul", "_blank", "chrome,modal", modalWindowOpened);
michael@0 1140 }
michael@0 1141 }
michael@0 1142
michael@0 1143 function modalWindowOpened(modalWindow)
michael@0 1144 {
michael@0 1145 var elem = modalWindow.document.getElementById("other");
michael@0 1146 if (gPartialTabbing)
michael@0 1147 elem.focus();
michael@0 1148 else
michael@0 1149 synthesizeKey("VK_TAB", { }, modalWindow);
michael@0 1150 is(fm.activeWindow, modalWindow, "modal activeWindow");
michael@0 1151 is(fm.focusedElement, elem, "modal focusedElement");
michael@0 1152
michael@0 1153 modalWindow.close();
michael@0 1154 SimpleTest.waitForFocus(modalWindowClosed);
michael@0 1155 }
michael@0 1156
michael@0 1157 function modalWindowClosed()
michael@0 1158 {
michael@0 1159 is(fm.activeWindow, window, "modal window closed activeWindow");
michael@0 1160 is(fm.focusedElement, getById("n2"), "modal window closed focusedElement");
michael@0 1161
michael@0 1162 window.open("focus_frameset.html", "_blank", "width=400,height=400,toolbar=no");
michael@0 1163 }
michael@0 1164
michael@0 1165 function framesetWindowLoaded(framesetWindow)
michael@0 1166 {
michael@0 1167 gLastFocus = null;
michael@0 1168 gLastFocusWindow = framesetWindow;
michael@0 1169 gEvents = "";
michael@0 1170
michael@0 1171 is(fm.activeWindow, getTopWindow(framesetWindow), "frameset window active");
michael@0 1172 gOldExpectedWindow = getTopWindow(framesetWindow);
michael@0 1173
michael@0 1174 gMoveToFocusFrame = true;
michael@0 1175 for (var idx = 1; idx <= 8; idx++) {
michael@0 1176 gNewExpectedWindow = framesetWindow.frames[(idx - 1) >> 1];
michael@0 1177 if (idx % 2)
michael@0 1178 initEvents(gNewExpectedWindow);
michael@0 1179 expectFocusShift(function () synthesizeKey("VK_TAB", { }, framesetWindow),
michael@0 1180 gNewExpectedWindow, getById("f" + idx), true, "frameset tab key f" + idx);
michael@0 1181 gMoveToFocusFrame = false;
michael@0 1182 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1183 }
michael@0 1184
michael@0 1185 gNewExpectedWindow = framesetWindow.frames[0];
michael@0 1186 expectFocusShift(function () synthesizeKey("VK_TAB", { }, framesetWindow),
michael@0 1187 gNewExpectedWindow, getById("f1"), true, "frameset tab key wrap to start");
michael@0 1188 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1189 gNewExpectedWindow = framesetWindow.frames[3];
michael@0 1190 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }, framesetWindow),
michael@0 1191 gNewExpectedWindow, getById("f8"), true, "frameset shift tab key wrap to end");
michael@0 1192
michael@0 1193 for (idx = 7; idx >= 1; idx--) {
michael@0 1194 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1195 gNewExpectedWindow = framesetWindow.frames[(idx - 1) >> 1];
michael@0 1196 expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }, framesetWindow),
michael@0 1197 gNewExpectedWindow, getById("f" + idx), true, "frameset shift tab key f" + idx);
michael@0 1198 }
michael@0 1199
michael@0 1200 // document shifting
michael@0 1201 // XXXndeakin P3 ctrl+tab doesn't seem to be testable currently for some reason
michael@0 1202 gNewExpectedWindow = framesetWindow.frames[1];
michael@0 1203 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true }, framesetWindow),
michael@0 1204 gNewExpectedWindow, getById("f3"), true, "switch document forward with f6");
michael@0 1205 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1206 gNewExpectedWindow = framesetWindow.frames[2];
michael@0 1207 expectFocusShift(function () synthesizeKey("VK_F6", { }, framesetWindow),
michael@0 1208 gNewExpectedWindow, getById("f5"), true, "switch document forward with ctrl+tab");
michael@0 1209 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1210 gNewExpectedWindow = framesetWindow.frames[3];
michael@0 1211 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true }, framesetWindow),
michael@0 1212 gNewExpectedWindow, getById("f7"), true, "switch document forward with ctrl+f6");
michael@0 1213 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1214 gNewExpectedWindow = framesetWindow.frames[0];
michael@0 1215 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true }, framesetWindow),
michael@0 1216 gNewExpectedWindow, getById("f1"), true, "switch document forward and wrap");
michael@0 1217
michael@0 1218 // going backwards by document and wrapping doesn't currently work, but didn't work
michael@0 1219 // before the focus reworking either
michael@0 1220
michael@0 1221 /*
michael@0 1222 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1223 gNewExpectedWindow = framesetWindow.frames[3];
michael@0 1224 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
michael@0 1225 gNewExpectedWindow, getById("f7"), true, "switch document backward and wrap");
michael@0 1226 */
michael@0 1227
michael@0 1228 fm.moveFocus(framesetWindow.frames[3], null, fm.MOVEFOCUS_ROOT, 0);
michael@0 1229 gEvents = "";
michael@0 1230
michael@0 1231 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1232 gNewExpectedWindow = framesetWindow.frames[2];
michael@0 1233 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
michael@0 1234 gNewExpectedWindow, getById("f5"), true, "switch document backward with f6");
michael@0 1235 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1236 gNewExpectedWindow = framesetWindow.frames[1];
michael@0 1237 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
michael@0 1238 gNewExpectedWindow, getById("f3"), true, "switch document backward with ctrl+tab");
michael@0 1239 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1240 gNewExpectedWindow = framesetWindow.frames[0];
michael@0 1241 expectFocusShift(function () synthesizeKey("VK_F6", { ctrlKey: true, shiftKey: true }, framesetWindow),
michael@0 1242 gNewExpectedWindow, getById("f1"), true, "switch document backward with ctrl+f6");
michael@0 1243
michael@0 1244 // skip the window switching tests for now on Linux, as raising and lowering
michael@0 1245 // a window is asynchronous there
michael@0 1246 if (navigator.platform.indexOf("Linux") == -1) {
michael@0 1247 window.openDialog("focus_window2.xul", "_blank", "chrome", switchWindowTest, framesetWindow);
michael@0 1248 }
michael@0 1249 else {
michael@0 1250 gOldExpectedWindow = null;
michael@0 1251 gNewExpectedWindow = null;
michael@0 1252 framesetWindow.close();
michael@0 1253 SimpleTest.waitForFocus(doWindowNoRootTest);
michael@0 1254 }
michael@0 1255 }
michael@0 1256
michael@0 1257 // test switching between two windows
michael@0 1258 function switchWindowTest(otherWindow, framesetWindow)
michael@0 1259 {
michael@0 1260 initEvents(otherWindow);
michael@0 1261 var otherElement = otherWindow.document.getElementById("other");
michael@0 1262 otherElement.focus();
michael@0 1263
michael@0 1264 framesetWindow.frames[1].document.getElementById("f4").focus();
michael@0 1265
michael@0 1266 is(fm.focusedElement, otherElement, "focus after inactive window focus");
michael@0 1267
michael@0 1268 gLastFocus = otherElement;
michael@0 1269 gLastFocusWindow = otherWindow;
michael@0 1270 gEvents = "";
michael@0 1271 gOldExpectedWindow = otherWindow;
michael@0 1272 gNewExpectedWindow = framesetWindow.frames[1];
michael@0 1273
michael@0 1274 expectFocusShift(function () gNewExpectedWindow.focus(),
michael@0 1275 gNewExpectedWindow, getById("f4"), true, "switch to frame in another window");
michael@0 1276 is(fm.getFocusedElementForWindow(otherWindow, false, {}).id, "other", "inactive window has focused element");
michael@0 1277
michael@0 1278 gOldExpectedWindow = framesetWindow.frames[1];
michael@0 1279 gNewExpectedWindow = otherWindow;
michael@0 1280 expectFocusShift(function () otherWindow.focus(),
michael@0 1281 gNewExpectedWindow, getById("other"), true, "switch to another window");
michael@0 1282
michael@0 1283 var exh = false;
michael@0 1284 try {
michael@0 1285 fm.activeWindow = framesetWindow.frames[0];
michael@0 1286 }
michael@0 1287 catch (ex) { exh = true; }
michael@0 1288 is(exh, true, "activeWindow set to non top-level window");
michael@0 1289
michael@0 1290 exh = false;
michael@0 1291 try {
michael@0 1292 fm.activeWindow = null;
michael@0 1293 }
michael@0 1294 catch (ex) { exh = true; }
michael@0 1295 is(exh, true, "activeWindow set to null");
michael@0 1296 is(fm.activeWindow, otherWindow, "window not changed when activeWindow set to null");
michael@0 1297
michael@0 1298 var topWindow = getTopWindow(framesetWindow);
michael@0 1299
michael@0 1300 ok(topWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
michael@0 1301 "getControllerForCommand for focused window set");
michael@0 1302 ok(otherWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
michael@0 1303 "getControllerForCommand for non-focused window set");
michael@0 1304 ok(topWindow.document.commandDispatcher.getControllerForCommand("cmd_copy") !=
michael@0 1305 otherWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
michael@0 1306 "getControllerForCommand for two windows different");
michael@0 1307 ok(topWindow.document.commandDispatcher.getControllers() !=
michael@0 1308 otherWindow.document.commandDispatcher.getControllers(),
michael@0 1309 "getControllers for two windows different");
michael@0 1310
michael@0 1311 gOldExpectedWindow = otherWindow;
michael@0 1312 gNewExpectedWindow = framesetWindow.frames[1];
michael@0 1313 expectFocusShift(function () fm.activeWindow = topWindow,
michael@0 1314 gNewExpectedWindow, getById("f4"), true, "switch to frame activeWindow");
michael@0 1315
michael@0 1316 fm.clearFocus(otherWindow);
michael@0 1317 gOldExpectedWindow = gNewExpectedWindow;
michael@0 1318 gNewExpectedWindow = otherWindow;
michael@0 1319 expectFocusShift(function () fm.setFocus(otherElement, fm.FLAG_RAISE),
michael@0 1320 gNewExpectedWindow, getById("other"), true, "switch to window with raise");
michael@0 1321
michael@0 1322 getTopWindow(framesetWindow).document.commandDispatcher.focusedWindow = gOldExpectedWindow;
michael@0 1323 is(fm.activeWindow, gNewExpectedWindow, "setting commandDispatcher focusedWindow doesn't raise window");
michael@0 1324
michael@0 1325 fm.moveFocus(otherWindow, null, fm.MOVEFOCUS_FORWARD, 0);
michael@0 1326 var otherTextbox = otherWindow.document.getElementById("other-textbox");
michael@0 1327 otherTextbox.setSelectionRange(2, 3);
michael@0 1328 fm.activeWindow = topWindow;
michael@0 1329 fm.activeWindow = otherWindow;
michael@0 1330 is(otherTextbox.selectionStart, 2, "selectionStart after textbox focus and window raise");
michael@0 1331 is(otherTextbox.selectionEnd, 3, "selectionEnd after textbox focus and window raise");
michael@0 1332 is(fm.getLastFocusMethod(null), fm.FLAG_BYMOVEFOCUS, "last focus method after textbox focus and window raise");
michael@0 1333
michael@0 1334 fm.clearFocus(otherWindow);
michael@0 1335
michael@0 1336 // test to ensure that a synthetic event works
michael@0 1337 var synevent = document.createEvent("Event");
michael@0 1338 synevent.initEvent("focus", false, false);
michael@0 1339 otherTextbox.inputField.dispatchEvent(synevent);
michael@0 1340 is(synevent.type, "focus", "event.type after synthetic focus event");
michael@0 1341 is(synevent.target, otherTextbox, "event.target after synthetic focus event");
michael@0 1342 is(fm.focusedElement, null, "focusedElement after synthetic focus event");
michael@0 1343 is(otherWindow.document.activeElement, otherWindow.document.documentElement,
michael@0 1344 "document.activeElement after synthetic focus event");
michael@0 1345
michael@0 1346 // check accessing a focus event after the event has finishing firing
michael@0 1347 function continueTest(event) {
michael@0 1348 is(event.type, "focus", "event.type after accessing focus event in timeout");
michael@0 1349 is(event.target, otherTextbox, "event.target after accessing focus event in timeout");
michael@0 1350
michael@0 1351 gOldExpectedWindow = null;
michael@0 1352 gNewExpectedWindow = null;
michael@0 1353 otherWindow.close();
michael@0 1354 framesetWindow.close();
michael@0 1355
michael@0 1356 SimpleTest.waitForFocus(doWindowNoRootTest);
michael@0 1357 }
michael@0 1358
michael@0 1359 function textboxFocused(event) {
michael@0 1360 otherTextbox.removeEventListener("focus", textboxFocused, true);
michael@0 1361 setTimeout(continueTest, 0, event);
michael@0 1362 }
michael@0 1363
michael@0 1364 otherTextbox.addEventListener("focus", textboxFocused, true);
michael@0 1365 otherTextbox.focus();
michael@0 1366 }
michael@0 1367
michael@0 1368 // open a window with no root element
michael@0 1369 var noRootWindow = null;
michael@0 1370 function doWindowNoRootTest()
michael@0 1371 {
michael@0 1372 var data = "data:application/vnd.mozilla.xul+xml," + unescape(
michael@0 1373 "<window onfocus='dostuff()' xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
michael@0 1374 " style='-moz-user-focus: normal;'>" +
michael@0 1375 "<script>function dostuff() { setTimeout(function() { " +
michael@0 1376 "document.documentElement.focus(); document.removeChild(document.documentElement);" +
michael@0 1377 "window.opener.focus(); }, 100); }</script></window>");
michael@0 1378
michael@0 1379 addEventListener("focus", doFrameSwitchingTests, true);
michael@0 1380 noRootWindow = window.open(data, "_blank", "chrome,width=100,height=100");
michael@0 1381 }
michael@0 1382
michael@0 1383 // these tests check when focus is moved between a tree of frames to ensure
michael@0 1384 // that the focus is in the right place at each event step.
michael@0 1385 function doFrameSwitchingTests()
michael@0 1386 {
michael@0 1387 removeEventListener("focus", doFrameSwitchingTests, true);
michael@0 1388 noRootWindow.close();
michael@0 1389
michael@0 1390 var framea = document.getElementById("ifa");
michael@0 1391 var frameb = document.getElementById("ifb");
michael@0 1392 framea.style.MozUserFocus = "";
michael@0 1393 frameb.style.MozUserFocus = "";
michael@0 1394
michael@0 1395 window.removeEventListener("focus", eventOccured, true);
michael@0 1396 window.removeEventListener("blur", eventOccured, true);
michael@0 1397
michael@0 1398 var inputa = framea.contentDocument.body.firstChild;
michael@0 1399 inputa.focus();
michael@0 1400
michael@0 1401 addFrameSwitchingListeners(framea);
michael@0 1402 addFrameSwitchingListeners(frameb);
michael@0 1403 var framec = framea.contentDocument.body.lastChild;
michael@0 1404 addFrameSwitchingListeners(framec);
michael@0 1405
michael@0 1406 var framed = framec.contentDocument.body.lastChild;
michael@0 1407 addFrameSwitchingListeners(framed);
michael@0 1408
michael@0 1409 var inputc = framec.contentDocument.body.firstChild;
michael@0 1410
michael@0 1411 var expectedMainWindowFocus = framea;
michael@0 1412
michael@0 1413 // An element in the immediate parent frame is focused. Focus an element in
michael@0 1414 // the child. The child should be focused and the parent's current focus should
michael@0 1415 // be the child iframe.
michael@0 1416 gEventMatched = true;
michael@0 1417 is(fm.getFocusedElementForWindow(window, false, {}), expectedMainWindowFocus,
michael@0 1418 "parent of framea has iframe focused");
michael@0 1419 gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea],
michael@0 1420 [framea.contentDocument, "blur", null, null, window, framea],
michael@0 1421 [framea.contentWindow, "blur", null, null, window, framea],
michael@0 1422 [framec.contentDocument, "focus", null, framec.contentWindow, window, framea],
michael@0 1423 [framec.contentWindow, "focus", null, framec.contentWindow, window, framea],
michael@0 1424 [inputc, "focus", inputc, framec.contentWindow, window, framea]];
michael@0 1425 inputc.focus();
michael@0 1426 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from parent input to child input" + gExpectedEvents);
michael@0 1427
michael@0 1428 // An element in a child is focused. Focus an element in the immediate
michael@0 1429 // parent.
michael@0 1430 gEventMatched = true;
michael@0 1431 gExpectedEvents = [[inputc, "blur", null, framec.contentWindow, window, framea],
michael@0 1432 [framec.contentDocument, "blur", null, null, window, framea],
michael@0 1433 [framec.contentWindow, "blur", null, null, window, framea],
michael@0 1434 [framea.contentDocument, "focus", null, framea.contentWindow, window, framea],
michael@0 1435 [framea.contentWindow, "focus", null, framea.contentWindow, window, framea],
michael@0 1436 [inputa, "focus", inputa, framea.contentWindow, window, framea]];
michael@0 1437 inputa.focus();
michael@0 1438 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to parent input");
michael@0 1439
michael@0 1440 // An element in a frame is focused. Focus an element in a sibling frame.
michael@0 1441 // The common ancestor of the two frames should have its focused node
michael@0 1442 // cleared after the element is blurred.
michael@0 1443 var inputb = frameb.contentDocument.body.firstChild;
michael@0 1444
michael@0 1445 gEventMatched = true;
michael@0 1446 gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea],
michael@0 1447 [framea.contentDocument, "blur", null, null, window, null],
michael@0 1448 [framea.contentWindow, "blur", null, null, window, null],
michael@0 1449 [frameb.contentDocument, "focus", null, frameb.contentWindow, window, frameb],
michael@0 1450 [frameb.contentWindow, "focus", null, frameb.contentWindow, window, frameb],
michael@0 1451 [inputb, "focus", inputb, frameb.contentWindow, window, frameb]];
michael@0 1452 inputb.focus();
michael@0 1453 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from input to sibling frame");
michael@0 1454 is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), inputa,
michael@0 1455 "blurred frame still has input as focus");
michael@0 1456
michael@0 1457 // focus a descendant in a sibling
michael@0 1458 var inputd = framed.contentDocument.body.firstChild;
michael@0 1459 gEventMatched = true;
michael@0 1460 gExpectedEvents = [[inputb, "blur", null, frameb.contentWindow, window, frameb],
michael@0 1461 [frameb.contentDocument, "blur", null, null, window, null],
michael@0 1462 [frameb.contentWindow, "blur", null, null, window, null],
michael@0 1463 [framed.contentDocument, "focus", null, framed.contentWindow, window, framea],
michael@0 1464 [framed.contentWindow, "focus", null, framed.contentWindow, window, framea],
michael@0 1465 [inputd, "focus", inputd, framed.contentWindow, window, framea]];
michael@0 1466 inputd.focus();
michael@0 1467 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from input to sibling descendant");
michael@0 1468 is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec,
michael@0 1469 "sibling parent focus has shifted to frame");
michael@0 1470
michael@0 1471 // focus an ancestor
michael@0 1472 gEventMatched = true;
michael@0 1473 gExpectedEvents = [[inputd, "blur", null, framed.contentWindow, window, framea],
michael@0 1474 [framed.contentDocument, "blur", null, null, window, framea],
michael@0 1475 [framed.contentWindow, "blur", null, null, window, framea],
michael@0 1476 [framea.contentDocument, "focus", null, framea.contentWindow, window, framea],
michael@0 1477 [framea.contentWindow, "focus", null, framea.contentWindow, window, framea],
michael@0 1478 [inputa, "focus", inputa, framea.contentWindow, window, framea]];
michael@0 1479 inputa.focus();
michael@0 1480 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to ancestor");
michael@0 1481
michael@0 1482 // focus a descendant
michael@0 1483 gEventMatched = true;
michael@0 1484 gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea],
michael@0 1485 [framea.contentDocument, "blur", null, null, window, framea],
michael@0 1486 [framea.contentWindow, "blur", null, null, window, framea],
michael@0 1487 [framed.contentDocument, "focus", null, framed.contentWindow, window, framea],
michael@0 1488 [framed.contentWindow, "focus", null, framed.contentWindow, window, framea],
michael@0 1489 [inputd, "focus", inputd, framed.contentWindow, window, framea]];
michael@0 1490 inputd.focus();
michael@0 1491 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to ancestor");
michael@0 1492 is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec,
michael@0 1493 "parent focus has shifted to frame");
michael@0 1494
michael@0 1495 // focus a sibling frame by setting focusedWindow
michael@0 1496 gEventMatched = true;
michael@0 1497 gExpectedEvents = [[inputd, "blur", null, framed.contentWindow, window, framea],
michael@0 1498 [framed.contentDocument, "blur", null, null, window, null],
michael@0 1499 [framed.contentWindow, "blur", null, null, window, null],
michael@0 1500 [frameb.contentDocument, "focus", null, frameb.contentWindow, window, frameb],
michael@0 1501 [frameb.contentWindow, "focus", null, frameb.contentWindow, window, frameb],
michael@0 1502 [inputb, "focus", inputb, frameb.contentWindow, window, frameb]];
michael@0 1503 fm.focusedWindow = frameb.contentWindow;
michael@0 1504 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch using focusedWindow");
michael@0 1505
michael@0 1506 // clear the focus in an unfocused frame
michael@0 1507 gEventMatched = true;
michael@0 1508 gExpectedEvents = [];
michael@0 1509 fm.clearFocus(framec.contentWindow);
michael@0 1510 ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in unfocused frame");
michael@0 1511
michael@0 1512 // focus a sibling frame by setting focusedWindow when no element is focused in that frame
michael@0 1513 gEventMatched = true;
michael@0 1514 gExpectedEvents = [[inputb, "blur", null, frameb.contentWindow, window, frameb],
michael@0 1515 [frameb.contentDocument, "blur", null, null, window, null],
michael@0 1516 [frameb.contentWindow, "blur", null, null, window, null],
michael@0 1517 [framec.contentDocument, "focus", null, framec.contentWindow, window, framea],
michael@0 1518 [framec.contentWindow, "focus", null, framec.contentWindow, window, framea]];
michael@0 1519 fm.focusedWindow = framec.contentWindow;
michael@0 1520 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch using focusedWindow with no element focused");
michael@0 1521 is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec,
michael@0 1522 "parent focus has shifted to frame using focusedWindow");
michael@0 1523
michael@0 1524 // focus the parent frame by setting focusedWindow. This should have no effect.
michael@0 1525 gEventMatched = true;
michael@0 1526 gExpectedEvents = [];
michael@0 1527 fm.focusedWindow = framea.contentWindow;
michael@0 1528 ok(gEventMatched && gExpectedEvents.length == 0, "frame switch to parent using focusedWindow");
michael@0 1529
michael@0 1530 // clear the focus in the parent frame
michael@0 1531 gEventMatched = true;
michael@0 1532 gExpectedEvents = [[framec.contentDocument, "blur", null, null, window, framea],
michael@0 1533 [framec.contentWindow, "blur", null, null, window, framea],
michael@0 1534 [framea.contentDocument, "focus", null, framea.contentWindow, window, framea],
michael@0 1535 [framea.contentWindow, "focus", null, framea.contentWindow, window, framea]];
michael@0 1536 fm.clearFocus(framea.contentWindow);
michael@0 1537 ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in parent frame");
michael@0 1538
michael@0 1539 // clear the focus in an unfocused child frame
michael@0 1540 gEventMatched = true;
michael@0 1541 gExpectedEvents = [];
michael@0 1542 fm.clearFocus(framed.contentWindow);
michael@0 1543 ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in unfocused child frame");
michael@0 1544
michael@0 1545 var exh = false;
michael@0 1546 try {
michael@0 1547 fm.focusedWindow = null;
michael@0 1548 }
michael@0 1549 catch (ex) { exh = true; }
michael@0 1550 is(exh, true, "focusedWindow set to null");
michael@0 1551 is(fm.focusedWindow, framea.contentWindow, "window not changed when focusedWindow set to null");
michael@0 1552
michael@0 1553 doFrameHistoryTests()
michael@0 1554 }
michael@0 1555
michael@0 1556 function doFrameHistoryTests()
michael@0 1557 {
michael@0 1558 var t20 = getById("t20");
michael@0 1559 t20.focus();
michael@0 1560
michael@0 1561 gChildWindow.addEventListener("focus",
michael@0 1562 function(event) {
michael@0 1563 if (event.target == t20) {
michael@0 1564 is(fm.focusedElement, t20, "focus restored after history back"); done();
michael@0 1565 }
michael@0 1566 }, true);
michael@0 1567
michael@0 1568 // make sure that loading a new page and then going back maintains the focus
michael@0 1569 gChildWindow.location = "data:text/html,<script>window.onload=function() {setTimeout(function () {window.back();}, 0);}</script>";
michael@0 1570 }
michael@0 1571
michael@0 1572 function addFrameSwitchingListeners(frame)
michael@0 1573 {
michael@0 1574 frame.contentWindow.addEventListener("focus", frameSwitchingEventOccured, false);
michael@0 1575 frame.contentWindow.addEventListener("blur", frameSwitchingEventOccured, false);
michael@0 1576 frame.contentDocument.addEventListener("focus", frameSwitchingEventOccured, false);
michael@0 1577 frame.contentDocument.addEventListener("blur", frameSwitchingEventOccured, false);
michael@0 1578
michael@0 1579 var node = frame.contentDocument.body.firstChild;
michael@0 1580 node.addEventListener("focus", frameSwitchingEventOccured, false);
michael@0 1581 node.addEventListener("blur", frameSwitchingEventOccured, false);
michael@0 1582 }
michael@0 1583
michael@0 1584 function frameSwitchingEventOccured(event)
michael@0 1585 {
michael@0 1586 if (!gExpectedEvents.length) {
michael@0 1587 gEventMatched = false;
michael@0 1588 return;
michael@0 1589 }
michael@0 1590
michael@0 1591 try {
michael@0 1592 var events = gExpectedEvents.shift();
michael@0 1593 is(event.target, events[0], "event target");
michael@0 1594 is(event.type, events[1], "event type");
michael@0 1595 is(fm.focusedElement, events[2], "focused element");
michael@0 1596 is(fm.focusedWindow, events[3], "focused frame");
michael@0 1597 if (events[4])
michael@0 1598 is(fm.getFocusedElementForWindow(events[4], false, {}), events[5], "focused element in frame");
michael@0 1599
michael@0 1600 if (gEventMatched && event.target == events[0] && event.type == events[1] &&
michael@0 1601 fm.focusedElement == events[2] && fm.focusedWindow == events[3]) {
michael@0 1602 if (!events[4] || fm.getFocusedElementForWindow(events[4], false, {}) == events[5])
michael@0 1603 return;
michael@0 1604 }
michael@0 1605 } catch (ex) { ok(ex, "exception"); }
michael@0 1606
michael@0 1607 gEventMatched = false;
michael@0 1608 }
michael@0 1609
michael@0 1610 SimpleTest.waitForExplicitFinish();
michael@0 1611 SimpleTest.waitForFocus(startTest);
michael@0 1612
michael@0 1613 ]]>
michael@0 1614 </script>
michael@0 1615
michael@0 1616 <commandset id="cu"
michael@0 1617 commandupdater="true"
michael@0 1618 events="focus"
michael@0 1619 oncommandupdate="eventOccured(event)"/>
michael@0 1620
michael@0 1621 <!--
michael@0 1622 The elements with ids starting with t are focusable and in the taborder.
michael@0 1623 The elements with ids starting with o are:
michael@0 1624 odd numbered ids - focusable but not part of the tab order
michael@0 1625 even numbered ids - not focusable with -moz-user-focus: ignore or disabled
michael@0 1626 The elements with ids starting with n are:
michael@0 1627 odd numbered ids - not focusable with -moz-user-focus: none
michael@0 1628 even numbered ids - focusable but not part of the tab order
michael@0 1629 -->
michael@0 1630 <vbox id="buttonbox">
michael@0 1631 <hbox id="innerbox">
michael@0 1632 <button id="t4" accesskey="h" label="no tabindex"/>
michael@0 1633 <button id="o1" accesskey="i" label="tabindex = -1" tabindex="-1"/>
michael@0 1634 <listbox id="t5" label="tabindex = 0" tabindex="0" rows="1">
michael@0 1635 <listitem/>
michael@0 1636 </listbox>
michael@0 1637 <button id="t1" label="tabindex = 2" tabindex="2"/>
michael@0 1638 </hbox>
michael@0 1639 <hbox>
michael@0 1640 <button id="o2" accesskey="o" style="-moz-user-focus: ignore;" label="no tabindex"/>
michael@0 1641 <button id="o4" style="-moz-user-focus: ignore;" label="tabindex = -1" tabindex="-1"/>
michael@0 1642 <button id="t6" style="-moz-user-focus: ignore;" label="tabindex = 0" tabindex="0"/>
michael@0 1643 <button id="t2" style="-moz-user-focus: ignore;" label="tabindex = 2" tabindex="2"/>
michael@0 1644 </hbox>
michael@0 1645 <hbox id="specialroot">
michael@0 1646 <button id="t7" style="-moz-user-focus: normal;" label="no tabindex"/>
michael@0 1647 <button id="o3" style="-moz-user-focus: normal;" label="tabindex = -1" tabindex="-1"/>
michael@0 1648 <button id="t8" style="-moz-user-focus: normal;" label="tabindex = 0" tabindex="0"/>
michael@0 1649 <listbox id="t3" style="-moz-user-focus: normal;" label="tabindex = 2" tabindex="2" rows="1">
michael@0 1650 <listitem/>
michael@0 1651 </listbox>
michael@0 1652 </hbox>
michael@0 1653 <hbox>
michael@0 1654 <button accesskey="p" style="display: none;"/> <button accesskey="q" style="visibility: collapse;"/>
michael@0 1655 <button style="display: none;" tabindex="2"/> <button style="visibility: collapse;" tabindex="2"/>
michael@0 1656 </hbox>
michael@0 1657 <hbox>
michael@0 1658 <button id="o20" accesskey="s" label="no tabindex" disabled="true"/>
michael@0 1659 <button id="o22" label="tabindex = -1" tabindex="-1" disabled="true"/>
michael@0 1660 <button id="o24" label="tabindex = 0" tabindex="0" disabled="true"/>
michael@0 1661 <button id="o26" label="tabindex = 2" tabindex="2" disabled="true"/>
michael@0 1662 </hbox>
michael@0 1663 </vbox>
michael@0 1664 <vbox>
michael@0 1665 <hbox>
michael@0 1666 <dropmarker id="o6" value="no tabindex"/>
michael@0 1667 <dropmarker id="o8" value="tabindex = -1" tabindex="-1"/>
michael@0 1668 <dropmarker id="o10" value="tabindex = 0" tabindex="0"/>
michael@0 1669 <dropmarker id="o12" value="tabindex = 2" tabindex="2"/>
michael@0 1670 <dropmarker id="t9" accesskey="r" style="-moz-user-focus: normal;" value="no tabindex" />
michael@0 1671 <dropmarker id="t10" style="-moz-user-focus: normal;" value="tabindex = -1" tabindex="-1" />
michael@0 1672 <dropmarker id="t11" style="-moz-user-focus: normal;" value="tabindex = 0" tabindex="0" />
michael@0 1673 <dropmarker id="t12" style="-moz-user-focus: normal;" value="tabindex = 2" tabindex="2" />
michael@0 1674 <dropmarker id="o14" style="-moz-user-focus: ignore;" value="no tabindex"/>
michael@0 1675 <dropmarker id="o16" style="-moz-user-focus: ignore;" value="tabindex = -1" tabindex="-1"/>
michael@0 1676 <dropmarker id="n1" style="-moz-user-focus: none;" value="tabindex = 0" tabindex="0"/>
michael@0 1677 <dropmarker id="n3" style="-moz-user-focus: none;" value="tabindex = 2" tabindex="2"/>
michael@0 1678 </hbox>
michael@0 1679 </vbox>
michael@0 1680 <browser id="childframe" type="content" src="child_focus_frame.html" width="300" height="195"/>
michael@0 1681 <button id="t34"/>
michael@0 1682 <tabbox id="tabbox">
michael@0 1683 <tabs><tab id="t35" label="One"/><tab id="tab2" label="Two"/></tabs>
michael@0 1684 <tabpanels>
michael@0 1685 <tabpanel>
michael@0 1686 <checkbox id="t36"/>
michael@0 1687 <button id="t37"/>
michael@0 1688 </tabpanel>
michael@0 1689 <tabpanel>
michael@0 1690 <checkbox id="htab1"/>
michael@0 1691 <button id="nohtab2" tabindex="7"/>
michael@0 1692 <checkbox id="htab2" tabindex="0"/>
michael@0 1693 </tabpanel>
michael@0 1694 </tabpanels>
michael@0 1695 </tabbox>
michael@0 1696 <hbox>
michael@0 1697 <panel>
michael@0 1698 <button id="inpopup1" label="One"/>
michael@0 1699 <textbox label="Two"/>
michael@0 1700 </panel>
michael@0 1701 <description label="o" accesskey="v"/>
michael@0 1702 <button id="t38"/>
michael@0 1703 <!-- The 't' element tests end here so it doesn't matter that these elements are tabbable -->
michael@0 1704 <label id="aj" value="j" accesskey="j" control="o9"/>
michael@0 1705 <label id="ak" accesskey="k" control="n4">k</label>
michael@0 1706 <checkbox id="o5"/><checkbox id="o7"/><hbox><checkbox id="o9"/></hbox>
michael@0 1707 <checkbox id="o13"/><checkbox id="o15"/><checkbox id="o17"/><checkbox id="o19"/><checkbox id="o21"/><checkbox id="o23"/><checkbox id="o25"/>
michael@0 1708 <checkbox id="n2"/><checkbox id="n4"/>
michael@0 1709 <listbox id="last" width="20" rows="1"/>
michael@0 1710
michael@0 1711 <iframe id="ifa" width="40" height="60" style="-moz-user-focus: ignore;" type="content"
michael@0 1712 src="data:text/html,&lt;input id=fra size='2'&gt;&lt;input id='fra-b' size='2'&gt;
michael@0 1713 &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;"/>
michael@0 1714 <iframe id="ifb" width="20" height="20" style="-moz-user-focus: ignore;"
michael@0 1715 src="data:text/html,&lt;input id=frd&gt;&lt;/iframe&gt;"/>
michael@0 1716
michael@0 1717 </hbox>
michael@0 1718 </window>

mercurial