<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?> <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script> <html:style xmlns:html="http://www.w3.org/1999/xhtml" type="text/css"> * { outline: none; } #l1:-moz-focusring, #l3:-moz-focusring, #b1:-moz-focusring { outline: 2px solid red; } #l2:focus, #b2:focus { outline: 2px solid red; } </html:style> <script> <![CDATA[ SimpleTest.waitForExplicitFinish(); function snapShot(element) { var rect = element.getBoundingClientRect(); adjustedRect = { left: rect.left - 6, top: rect.top - 6, width: rect.width + 12, height: rect.height + 12 } return SpecialPowers.snapshotRect(window, adjustedRect, "transparent"); } function initTest() { SpecialPowers.pushPrefEnv({"set": [['accessibility.tabfocus', 7]]}, runTest); } function runTest() { var isMac = (navigator.platform.indexOf("Mac") >= 0); var isWin = (navigator.platform.indexOf("Win") >= 0); function checkFocus(element, visible, testid) { var outline = getComputedStyle(element, "").outlineWidth; is(outline, visible ? "2px" : "0px", testid); } // make sure that a focus ring appears on the focused button if (navigator.platform.indexOf("Mac") >= 0) { var focusedButton = $("b3"); ok(compareSnapshots(snapShot(focusedButton), snapShot($("b2")), true)[0], "unfocused shows no ring"); focusedButton.focus(); ok(compareSnapshots(snapShot(focusedButton), snapShot($("b2")), false)[0], "focus shows ring"); } checkFocus($("l1"), false, "initial appearance"); // we can't really test the situation on Windows where a dialog doesn't show // focus rings until a key is pressed, as the default state depends on what // kind of real user input, mouse or key, was last entered. But we can handle // the test regardless of which user input last occurred. $("l1").focus(); var expectedVisible = (!isWin || getComputedStyle($("l1"), "").outlineWidth == "2px"); testHTMLElements(htmlElements, isMac, isWin && !expectedVisible); $("l1").focus(); checkFocus($("l1"), expectedVisible, "appearance on list after focus() with :moz-focusring"); $("l2").focus(); checkFocus($("l2"), true, "appearance on list after focus() with :focus"); is(getComputedStyle($("l1"), "").outlineWidth, "0px", "appearance on previous list after focus() with :focus"); synthesizeMouse($("l1"), 4, 4, { }); checkFocus($("l1"), expectedVisible, "appearance on list after mouse focus with :moz-focusring"); synthesizeMouse($("l2"), 4, 4, { }); checkFocus($("l2"), true, "appearance on list after mouse focus with :focus"); synthesizeMouse($("b1"), 4, 4, { }); checkFocus($("b1"), !isMac && expectedVisible, "appearance on button after mouse focus with :moz-focusring"); if (navigator.platform.indexOf("Mac") >= 0) { ok(compareSnapshots(snapShot($("b1")), snapShot($("b2")), false)[0], "focus after mouse shows no ring"); } synthesizeMouse($("b2"), 4, 4, { }); checkFocus($("b2"), !isMac, "appearance on button after mouse focus with :focus"); // after a key is pressed, the focus ring will always be visible $("l2").focus(); synthesizeKey("VK_TAB", { }); checkFocus($("l3"), true, "appearance on list after tab focus"); if (isMac) { SpecialPowers.pushPrefEnv({"set": [['accessibility.mouse_focuses_formcontrol', true]]}, testMacFocusesFormControl); } else { SimpleTest.finish(); } } function testMacFocusesFormControl() { testHTMLElements(htmlElementsMacPrefSet, true, false); SimpleTest.finish(); } var htmlElements = [ "<button id='elem'>Button</button>", "<input id='elem' class='canfocus'>", "<input id='elem' type='password' class='canfocus'>", "<input id='elem' type='button'>", "<input id='elem' type='checkbox'>", "<textarea id='elem' class='canfocus'></textarea>", "<select id='elem' class='canfocus'><option>One</select>", "<select id='elem' rows='5' class='canfocus'><option>One</select>", "<div id='elem' tabindex='0' class='canfocus' style='width: 10px; height: 10px;'></div>", "<a href='about:blank' class='canfocus' onclick='return false;'>about:blank</a>", ]; var htmlElementsMacPrefSet = [ "<button id='elem' class='canfocus'>Button</button>", "<input id='elem' class='canfocus'>", "<input id='elem' type='button' class='canfocus'>", "<input id='elem' type='checkbox' class='canfocus'>", ]; function testHTMLElements(list, isMac, expectedNoRingsOnWin) { var childwin = frames[0]; var childdoc = childwin.document; var container = childdoc.getElementById("container"); for (var e = 0; e < list.length; e++) { container.innerHTML = list[e]; var elem = container.firstChild; var shouldFocus = !isMac || (elem.className == "canfocus"); var ringSize = (shouldFocus ? (expectedNoRingsOnWin ? 2 : 1) : 0) + "px"; if (elem.localName == "a") ringSize = "0px"; synthesizeMouse(elem, 8, 8, { }, childwin); is(childdoc.activeElement, shouldFocus ? elem : childdoc.body, "mouse click on " + list[e]); is(childwin.getComputedStyle(elem, "").outlineWidth, ringSize, "mouse click on " + list[e] + " ring"); if (childdoc.activeElement) childdoc.activeElement.blur(); ringSize = (elem.localName == "a" ? "0" : (expectedNoRingsOnWin ? 2 : 1)) + "px"; elem.focus(); is(childdoc.activeElement, elem, "focus() on " + list[e]); is(childwin.getComputedStyle(elem, "").outlineWidth, ringSize, "focus() on " + list[e] + " ring"); childdoc.activeElement.blur(); } } SimpleTest.waitForFocus(runTest); ]]> </script> <listbox id="l1" class="plain" height="20"/> <listbox id="l2" class="plain" height="20"/> <listbox id="l3" class="plain" height="20"/> <button id="b1" label="Button"/> <button id="b2" label="Button"/> <button id="b3" label="Button"/> <iframe id="child" src="data:text/html,<html><style>* { outline: none; -moz-appearance: none; } %23elem:focus { outline: 2px solid red; } %23elem:-moz-focusring { outline: 1px solid blue; }</style><div id='container'></html>"/> <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/> </window>