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