|
1 /* |
|
2 * This test checks that focus is adjusted properly when switching tabs. |
|
3 */ |
|
4 |
|
5 let testPage1 = "data:text/html,<html id='tab1'><body><button id='button1'>Tab 1</button></body></html>"; |
|
6 let testPage2 = "data:text/html,<html id='tab2'><body><button id='button2'>Tab 2</button></body></html>"; |
|
7 let testPage3 = "data:text/html,<html id='tab3'><body><button id='button3'>Tab 3</button></body></html>"; |
|
8 |
|
9 function test() { |
|
10 waitForExplicitFinish(); |
|
11 |
|
12 var tab1 = gBrowser.addTab(); |
|
13 var browser1 = gBrowser.getBrowserForTab(tab1); |
|
14 |
|
15 var tab2 = gBrowser.addTab(); |
|
16 var browser2 = gBrowser.getBrowserForTab(tab2); |
|
17 |
|
18 gURLBar.focus(); |
|
19 |
|
20 var loadCount = 0; |
|
21 function check() |
|
22 { |
|
23 // wait for both tabs to load |
|
24 if (++loadCount != 2) |
|
25 return; |
|
26 |
|
27 browser1.removeEventListener("load", check, true); |
|
28 browser2.removeEventListener("load", check, true); |
|
29 executeSoon(_run_focus_tests); |
|
30 } |
|
31 |
|
32 function _run_focus_tests() { |
|
33 window.focus(); |
|
34 |
|
35 _browser_tabfocus_test_lastfocus = gURLBar; |
|
36 _browser_tabfocus_test_lastfocuswindow = window; |
|
37 |
|
38 window.addEventListener("focus", _browser_tabfocus_test_eventOccured, true); |
|
39 window.addEventListener("blur", _browser_tabfocus_test_eventOccured, true); |
|
40 |
|
41 // make sure that the focus initially starts out blank |
|
42 var fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); |
|
43 var focusedWindow = {}; |
|
44 is(fm.getFocusedElementForWindow(browser1.contentWindow, false, focusedWindow), null, "initial focus in tab 1"); |
|
45 is(focusedWindow.value, browser1.contentWindow, "initial frame focus in tab 1"); |
|
46 is(fm.getFocusedElementForWindow(browser2.contentWindow, false, focusedWindow), null, "initial focus in tab 2"); |
|
47 is(focusedWindow.value, browser2.contentWindow, "initial frame focus in tab 2"); |
|
48 |
|
49 expectFocusShift(function () gBrowser.selectedTab = tab2, |
|
50 browser2.contentWindow, null, true, |
|
51 "focusedElement after tab change, focus in new tab"); |
|
52 |
|
53 // switching tabs when nothing in the new tab is focused |
|
54 // should focus the browser |
|
55 expectFocusShift(function () gBrowser.selectedTab = tab1, |
|
56 browser1.contentWindow, null, true, |
|
57 "focusedElement after tab change, focus in new tab"); |
|
58 |
|
59 // focusing a button in the current tab should focus it |
|
60 var button1 = browser1.contentDocument.getElementById("button1"); |
|
61 expectFocusShift(function () button1.focus(), |
|
62 browser1.contentWindow, button1, true, |
|
63 "focusedWindow after focus in focused tab"); |
|
64 |
|
65 // focusing a button in a background tab should not change the actual |
|
66 // focus, but should set the focus that would be in that background tab to |
|
67 // that button. |
|
68 var button2 = browser2.contentDocument.getElementById("button2"); |
|
69 button2.focus(); |
|
70 |
|
71 expectFocusShift(function () button2.focus(), |
|
72 browser1.contentWindow, button1, false, |
|
73 "focusedWindow after focus in unfocused tab"); |
|
74 is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "focus in unfocused tab"); |
|
75 |
|
76 // switching tabs should now make the button in the other tab focused |
|
77 expectFocusShift(function () gBrowser.selectedTab = tab2, |
|
78 browser2.contentWindow, button2, true, |
|
79 "focusedWindow after tab change"); |
|
80 |
|
81 // blurring an element in a background tab should not change the active |
|
82 // focus, but should clear the focus in that tab. |
|
83 expectFocusShift(function () button1.blur(), |
|
84 browser2.contentWindow, button2, false, |
|
85 "focusedWindow after blur in unfocused tab"); |
|
86 is(fm.getFocusedElementForWindow(browser1.contentWindow, false, {}), null, "blur in unfocused tab"); |
|
87 |
|
88 // When focus is in the tab bar, it should be retained there |
|
89 expectFocusShift(function () gBrowser.selectedTab.focus(), |
|
90 window, gBrowser.selectedTab, true, |
|
91 "focusing tab element"); |
|
92 expectFocusShift(function () gBrowser.selectedTab = tab1, |
|
93 window, tab1, true, |
|
94 "tab change when selected tab element was focused"); |
|
95 expectFocusShift(function () gBrowser.selectedTab = tab2, |
|
96 window, tab2, true, |
|
97 "tab change when selected tab element was focused"); |
|
98 expectFocusShift(function () gBrowser.selectedTab.blur(), |
|
99 window, null, true, |
|
100 "blurring tab element"); |
|
101 |
|
102 // focusing the url field should switch active focus away from the browser but |
|
103 // not clear what would be the focus in the browser |
|
104 button1.focus(); |
|
105 expectFocusShift(function () gURLBar.focus(), |
|
106 window, gURLBar.inputField, true, |
|
107 "focusedWindow after url field focused"); |
|
108 is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "url field focused, button in browser"); |
|
109 expectFocusShift(function () gURLBar.blur(), |
|
110 window, null, true, |
|
111 "blurring url field"); |
|
112 |
|
113 // when a chrome element is focused, switching tabs to a tab with a button |
|
114 // with the current focus should focus the button |
|
115 expectFocusShift(function () gBrowser.selectedTab = tab1, |
|
116 browser1.contentWindow, button1, true, |
|
117 "focusedWindow after tab change, focus in url field, button focused in new tab"); |
|
118 is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "after switch tab, focus in unfocused tab"); |
|
119 |
|
120 // blurring an element in the current tab should clear the active focus |
|
121 expectFocusShift(function () button1.blur(), |
|
122 browser1.contentWindow, null, true, |
|
123 "focusedWindow after blur in focused tab"); |
|
124 |
|
125 // blurring an non-focused url field should have no effect |
|
126 expectFocusShift(function () gURLBar.blur(), |
|
127 browser1.contentWindow, null, false, |
|
128 "focusedWindow after blur in unfocused url field"); |
|
129 |
|
130 // switch focus to a tab with a currently focused element |
|
131 expectFocusShift(function () gBrowser.selectedTab = tab2, |
|
132 browser2.contentWindow, button2, true, |
|
133 "focusedWindow after switch from unfocused to focused tab"); |
|
134 |
|
135 // clearing focus on the chrome window should switch the focus to the |
|
136 // chrome window |
|
137 expectFocusShift(function () fm.clearFocus(window), |
|
138 window, null, true, |
|
139 "focusedWindow after switch to chrome with no focused element"); |
|
140 |
|
141 // switch focus to another tab when neither have an active focus |
|
142 expectFocusShift(function () gBrowser.selectedTab = tab1, |
|
143 browser1.contentWindow, null, true, |
|
144 "focusedWindow after tab switch from no focus to no focus"); |
|
145 |
|
146 gURLBar.focus(); |
|
147 _browser_tabfocus_test_events = ""; |
|
148 _browser_tabfocus_test_lastfocus = gURLBar; |
|
149 _browser_tabfocus_test_lastfocuswindow = window; |
|
150 |
|
151 expectFocusShift(function () EventUtils.synthesizeKey("VK_F6", { }), |
|
152 browser1.contentWindow, browser1.contentDocument.documentElement, |
|
153 true, "switch document forward with f6"); |
|
154 EventUtils.synthesizeKey("VK_F6", { }); |
|
155 is(fm.focusedWindow, window, "switch document forward again with f6"); |
|
156 |
|
157 browser1.style.MozUserFocus = "ignore"; |
|
158 browser1.clientWidth; |
|
159 EventUtils.synthesizeKey("VK_F6", { }); |
|
160 is(fm.focusedWindow, window, "switch document forward again with f6 when browser non-focusable"); |
|
161 |
|
162 window.removeEventListener("focus", _browser_tabfocus_test_eventOccured, true); |
|
163 window.removeEventListener("blur", _browser_tabfocus_test_eventOccured, true); |
|
164 |
|
165 // next, check whether navigating forward, focusing the urlbar and then |
|
166 // navigating back maintains the focus in the urlbar. |
|
167 browser1.addEventListener("pageshow", _browser_tabfocus_navigation_test_eventOccured, true); |
|
168 button1.focus(); |
|
169 browser1.contentWindow.location = testPage3; |
|
170 } |
|
171 |
|
172 browser1.addEventListener("load", check, true); |
|
173 browser2.addEventListener("load", check, true); |
|
174 browser1.contentWindow.location = testPage1; |
|
175 browser2.contentWindow.location = testPage2; |
|
176 } |
|
177 |
|
178 var _browser_tabfocus_test_lastfocus; |
|
179 var _browser_tabfocus_test_lastfocuswindow = null; |
|
180 var _browser_tabfocus_test_events = ""; |
|
181 |
|
182 function _browser_tabfocus_test_eventOccured(event) |
|
183 { |
|
184 var id; |
|
185 if (event.target instanceof Window) |
|
186 id = event.originalTarget.document.documentElement.id + "-window"; |
|
187 else if (event.target instanceof Document) |
|
188 id = event.originalTarget.documentElement.id + "-document"; |
|
189 else if (event.target.id == "urlbar" && event.originalTarget.localName == "input") |
|
190 id = "urlbar"; |
|
191 else |
|
192 id = event.originalTarget.id; |
|
193 |
|
194 if (_browser_tabfocus_test_events) |
|
195 _browser_tabfocus_test_events += " "; |
|
196 _browser_tabfocus_test_events += event.type + ": " + id; |
|
197 } |
|
198 |
|
199 function _browser_tabfocus_navigation_test_eventOccured(event) |
|
200 { |
|
201 if (event.target instanceof Document) { |
|
202 var contentwin = event.target.defaultView; |
|
203 if (contentwin.location.toString().indexOf("3") > 0) { |
|
204 // just moved forward, so focus the urlbar and go back |
|
205 gURLBar.focus(); |
|
206 setTimeout(function () contentwin.history.back(), 0); |
|
207 } |
|
208 else if (contentwin.location.toString().indexOf("2") > 0) { |
|
209 event.currentTarget.removeEventListener("pageshow", _browser_tabfocus_navigation_test_eventOccured, true); |
|
210 is(window.document.activeElement, gURLBar.inputField, "urlbar still focused after navigating back"); |
|
211 gBrowser.removeCurrentTab(); |
|
212 gBrowser.removeCurrentTab(); |
|
213 finish(); |
|
214 } |
|
215 } |
|
216 } |
|
217 |
|
218 function getId(element) |
|
219 { |
|
220 return (element.localName == "input") ? "urlbar" : element.id; |
|
221 } |
|
222 |
|
223 function expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid) |
|
224 { |
|
225 var expectedEvents = ""; |
|
226 if (focusChanged) { |
|
227 if (_browser_tabfocus_test_lastfocus) |
|
228 expectedEvents += "blur: " + getId(_browser_tabfocus_test_lastfocus); |
|
229 |
|
230 if (_browser_tabfocus_test_lastfocuswindow && |
|
231 _browser_tabfocus_test_lastfocuswindow != expectedWindow) { |
|
232 if (expectedEvents) |
|
233 expectedEvents += " "; |
|
234 var windowid = _browser_tabfocus_test_lastfocuswindow.document.documentElement.id; |
|
235 expectedEvents += "blur: " + windowid + "-document " + |
|
236 "blur: " + windowid + "-window"; |
|
237 } |
|
238 |
|
239 if (expectedWindow && _browser_tabfocus_test_lastfocuswindow != expectedWindow) { |
|
240 if (expectedEvents) |
|
241 expectedEvents += " "; |
|
242 var windowid = expectedWindow.document.documentElement.id; |
|
243 expectedEvents += "focus: " + windowid + "-document " + |
|
244 "focus: " + windowid + "-window"; |
|
245 } |
|
246 |
|
247 if (expectedElement && expectedElement != expectedElement.ownerDocument.documentElement) { |
|
248 if (expectedEvents) |
|
249 expectedEvents += " "; |
|
250 expectedEvents += "focus: " + getId(expectedElement); |
|
251 } |
|
252 |
|
253 _browser_tabfocus_test_lastfocus = expectedElement; |
|
254 _browser_tabfocus_test_lastfocuswindow = expectedWindow; |
|
255 } |
|
256 |
|
257 callback(); |
|
258 |
|
259 is(_browser_tabfocus_test_events, expectedEvents, testid + " events"); |
|
260 _browser_tabfocus_test_events = ""; |
|
261 |
|
262 var fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); |
|
263 |
|
264 var focusedElement = fm.focusedElement; |
|
265 is(focusedElement ? getId(focusedElement) : "none", |
|
266 expectedElement ? getId(expectedElement) : "none", testid + " focusedElement"); |
|
267 is(fm.focusedWindow, expectedWindow, testid + " focusedWindow"); |
|
268 var focusedWindow = {}; |
|
269 is(fm.getFocusedElementForWindow(expectedWindow, false, focusedWindow), |
|
270 expectedElement, testid + " getFocusedElementForWindow"); |
|
271 is(focusedWindow.value, expectedWindow, testid + " getFocusedElementForWindow frame"); |
|
272 is(expectedWindow.document.hasFocus(), true, testid + " hasFocus"); |
|
273 var expectedActive = expectedElement; |
|
274 if (!expectedActive) |
|
275 expectedActive = expectedWindow.document instanceof XULDocument ? |
|
276 expectedWindow.document.documentElement : expectedWindow.document.body; |
|
277 is(expectedWindow.document.activeElement, expectedActive, testid + " activeElement"); |
|
278 } |