|
1 <?xml version="1.0"?> |
|
2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> |
|
3 <?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?> |
|
4 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
|
5 |
|
6 <script type="application/javascript" |
|
7 src="/tests/SimpleTest/SimpleTest.js"></script> |
|
8 <script type="application/javascript" |
|
9 src="/tests/SimpleTest/EventUtils.js"></script> |
|
10 <script type="application/javascript" |
|
11 src="/tests/SimpleTest/WindowSnapshot.js"></script> |
|
12 |
|
13 <html:style xmlns:html="http://www.w3.org/1999/xhtml" type="text/css"> |
|
14 * { outline: none; } |
|
15 #l1:-moz-focusring, #l3:-moz-focusring, #b1:-moz-focusring { outline: 2px solid red; } |
|
16 #l2:focus, #b2:focus { outline: 2px solid red; } |
|
17 </html:style> |
|
18 |
|
19 <script> |
|
20 <![CDATA[ |
|
21 |
|
22 SimpleTest.waitForExplicitFinish(); |
|
23 |
|
24 function setOrRestoreTabFocus(newValue) { |
|
25 const prefSvcContractID = "@mozilla.org/preferences-service;1"; |
|
26 const prefSvcIID = SpecialPowers.Ci.nsIPrefService; |
|
27 var prefs = SpecialPowers.Cc[prefSvcContractID].getService(prefSvcIID) |
|
28 .getBranch("accessibility."); |
|
29 if (!newValue) { |
|
30 if (prefs.prefHasUserValue("tabfocus")) { |
|
31 prefs.clearUserPref("tabfocus"); |
|
32 } |
|
33 } else { |
|
34 prefs.setIntPref("tabfocus", newValue); |
|
35 } |
|
36 } |
|
37 |
|
38 function snapShot(element) { |
|
39 var rect = element.getBoundingClientRect(); |
|
40 adjustedRect = { left: rect.left - 6, top: rect.top - 6, |
|
41 width: rect.width + 12, height: rect.height + 12 } |
|
42 return SpecialPowers.snapshotRect(window, adjustedRect, "transparent"); |
|
43 } |
|
44 |
|
45 function runTest() |
|
46 { |
|
47 setOrRestoreTabFocus(7); |
|
48 |
|
49 var isMac = (navigator.platform.indexOf("Mac") >= 0); |
|
50 var isWin = (navigator.platform.indexOf("Win") >= 0); |
|
51 |
|
52 function checkFocus(element, visible, testid) |
|
53 { |
|
54 var outline = getComputedStyle(element, "").outlineWidth; |
|
55 is(outline, visible ? "2px" : "0px", testid); |
|
56 } |
|
57 |
|
58 // make sure that a focus ring appears on the focused button |
|
59 if (navigator.platform.indexOf("Mac") >= 0) { |
|
60 var focusedButton = $("b3"); |
|
61 ok(compareSnapshots(snapShot(focusedButton), snapShot($("b2")), true)[0], "unfocused shows no ring"); |
|
62 focusedButton.focus(); |
|
63 ok(compareSnapshots(snapShot(focusedButton), snapShot($("b2")), false)[0], "focus shows ring"); |
|
64 } |
|
65 |
|
66 checkFocus($("l1"), false, "initial appearance"); |
|
67 |
|
68 // we can't really test the situation on Windows where a dialog doesn't show |
|
69 // focus rings until a key is pressed, as the default state depends on what |
|
70 // kind of real user input, mouse or key, was last entered. But we can handle |
|
71 // the test regardless of which user input last occurred. |
|
72 $("l1").focus(); |
|
73 var expectedVisible = (!isWin || getComputedStyle($("l1"), "").outlineWidth == "2px"); |
|
74 testHTMLElements(htmlElements, isMac, isWin && !expectedVisible); |
|
75 |
|
76 if (isMac) { |
|
77 var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]. |
|
78 getService(SpecialPowers.Ci.nsIPrefBranch); |
|
79 prefs.setBoolPref("accessibility.mouse_focuses_formcontrol", true); |
|
80 |
|
81 testHTMLElements(htmlElementsMacPrefSet, true, false); |
|
82 |
|
83 prefs.setBoolPref("accessibility.mouse_focuses_formcontrol", false); |
|
84 } |
|
85 |
|
86 $("l1").focus(); |
|
87 checkFocus($("l1"), expectedVisible, "appearance on list after focus() with :moz-focusring"); |
|
88 $("l2").focus(); |
|
89 |
|
90 checkFocus($("l2"), true, "appearance on list after focus() with :focus"); |
|
91 |
|
92 is(getComputedStyle($("l1"), "").outlineWidth, "0px", "appearance on previous list after focus() with :focus"); |
|
93 |
|
94 synthesizeMouse($("l1"), 4, 4, { }); |
|
95 checkFocus($("l1"), expectedVisible, "appearance on list after mouse focus with :moz-focusring"); |
|
96 synthesizeMouse($("l2"), 4, 4, { }); |
|
97 checkFocus($("l2"), true, "appearance on list after mouse focus with :focus"); |
|
98 |
|
99 synthesizeMouse($("b1"), 4, 4, { }); |
|
100 checkFocus($("b1"), !isMac && expectedVisible, "appearance on button after mouse focus with :moz-focusring"); |
|
101 if (navigator.platform.indexOf("Mac") >= 0) { |
|
102 ok(compareSnapshots(snapShot($("b1")), snapShot($("b2")), false)[0], "focus after mouse shows no ring"); |
|
103 } |
|
104 |
|
105 synthesizeMouse($("b2"), 4, 4, { }); |
|
106 checkFocus($("b2"), !isMac, "appearance on button after mouse focus with :focus"); |
|
107 |
|
108 // after a key is pressed, the focus ring will always be visible |
|
109 $("l2").focus(); |
|
110 synthesizeKey("VK_TAB", { }); |
|
111 checkFocus($("l3"), true, "appearance on list after tab focus"); |
|
112 |
|
113 setOrRestoreTabFocus(0); |
|
114 SimpleTest.finish(); |
|
115 } |
|
116 |
|
117 var htmlElements = [ |
|
118 "<button id='elem'>Button</button>", |
|
119 "<input id='elem' class='canfocus'>", |
|
120 "<input id='elem' type='password' class='canfocus'>", |
|
121 "<input id='elem' type='button'>", |
|
122 "<input id='elem' type='checkbox'>", |
|
123 "<textarea id='elem' class='canfocus'></textarea>", |
|
124 "<select id='elem' class='canfocus'><option>One</select>", |
|
125 "<select id='elem' rows='5' class='canfocus'><option>One</select>", |
|
126 "<div id='elem' tabindex='0' class='canfocus' style='width: 10px; height: 10px;'></div>", |
|
127 "<a href='about:blank' class='canfocus' onclick='return false;'>about:blank</a>", |
|
128 ]; |
|
129 |
|
130 var htmlElementsMacPrefSet = [ |
|
131 "<button id='elem' class='canfocus'>Button</button>", |
|
132 "<input id='elem' class='canfocus'>", |
|
133 "<input id='elem' type='button' class='canfocus'>", |
|
134 "<input id='elem' type='checkbox' class='canfocus'>", |
|
135 ]; |
|
136 |
|
137 function testHTMLElements(list, isMac, expectedNoRingsOnWin) |
|
138 { |
|
139 var childwin = frames[0]; |
|
140 var childdoc = childwin.document; |
|
141 var container = childdoc.getElementById("container"); |
|
142 for (var e = 0; e < list.length; e++) { |
|
143 container.innerHTML = list[e]; |
|
144 |
|
145 var elem = container.firstChild; |
|
146 |
|
147 var shouldFocus = !isMac || (elem.className == "canfocus"); |
|
148 var ringSize = (shouldFocus ? (expectedNoRingsOnWin ? 2 : 1) : 0) + "px"; |
|
149 if (elem.localName == "a") |
|
150 ringSize = "0px"; |
|
151 |
|
152 synthesizeMouse(elem, 8, 8, { }, childwin); |
|
153 is(childdoc.activeElement, shouldFocus ? elem : childdoc.body, "mouse click on " + list[e]); |
|
154 is(childwin.getComputedStyle(elem, "").outlineWidth, ringSize, "mouse click on " + list[e] + " ring"); |
|
155 |
|
156 if (childdoc.activeElement) |
|
157 childdoc.activeElement.blur(); |
|
158 |
|
159 ringSize = (elem.localName == "a" ? "0" : (expectedNoRingsOnWin ? 2 : 1)) + "px"; |
|
160 |
|
161 elem.focus(); |
|
162 is(childdoc.activeElement, elem, "focus() on " + list[e]); |
|
163 is(childwin.getComputedStyle(elem, "").outlineWidth, ringSize, |
|
164 "focus() on " + list[e] + " ring"); |
|
165 |
|
166 childdoc.activeElement.blur(); |
|
167 } |
|
168 } |
|
169 |
|
170 SimpleTest.waitForFocus(runTest); |
|
171 |
|
172 ]]> |
|
173 </script> |
|
174 |
|
175 <listbox id="l1" class="plain" height="20"/> |
|
176 <listbox id="l2" class="plain" height="20"/> |
|
177 <listbox id="l3" class="plain" height="20"/> |
|
178 <button id="b1" label="Button"/> |
|
179 <button id="b2" label="Button"/> |
|
180 <button id="b3" label="Button"/> |
|
181 |
|
182 <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>"/> |
|
183 |
|
184 <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/> |
|
185 |
|
186 </window> |