michael@0: /* michael@0: * This test checks that focus is adjusted properly when switching tabs. michael@0: */ michael@0: michael@0: let testPage1 = "data:text/html,"; michael@0: let testPage2 = "data:text/html,"; michael@0: let testPage3 = "data:text/html,"; michael@0: michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: michael@0: var tab1 = gBrowser.addTab(); michael@0: var browser1 = gBrowser.getBrowserForTab(tab1); michael@0: michael@0: var tab2 = gBrowser.addTab(); michael@0: var browser2 = gBrowser.getBrowserForTab(tab2); michael@0: michael@0: gURLBar.focus(); michael@0: michael@0: var loadCount = 0; michael@0: function check() michael@0: { michael@0: // wait for both tabs to load michael@0: if (++loadCount != 2) michael@0: return; michael@0: michael@0: browser1.removeEventListener("load", check, true); michael@0: browser2.removeEventListener("load", check, true); michael@0: executeSoon(_run_focus_tests); michael@0: } michael@0: michael@0: function _run_focus_tests() { michael@0: window.focus(); michael@0: michael@0: _browser_tabfocus_test_lastfocus = gURLBar; michael@0: _browser_tabfocus_test_lastfocuswindow = window; michael@0: michael@0: window.addEventListener("focus", _browser_tabfocus_test_eventOccured, true); michael@0: window.addEventListener("blur", _browser_tabfocus_test_eventOccured, true); michael@0: michael@0: // make sure that the focus initially starts out blank michael@0: var fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); michael@0: var focusedWindow = {}; michael@0: is(fm.getFocusedElementForWindow(browser1.contentWindow, false, focusedWindow), null, "initial focus in tab 1"); michael@0: is(focusedWindow.value, browser1.contentWindow, "initial frame focus in tab 1"); michael@0: is(fm.getFocusedElementForWindow(browser2.contentWindow, false, focusedWindow), null, "initial focus in tab 2"); michael@0: is(focusedWindow.value, browser2.contentWindow, "initial frame focus in tab 2"); michael@0: michael@0: expectFocusShift(function () gBrowser.selectedTab = tab2, michael@0: browser2.contentWindow, null, true, michael@0: "focusedElement after tab change, focus in new tab"); michael@0: michael@0: // switching tabs when nothing in the new tab is focused michael@0: // should focus the browser michael@0: expectFocusShift(function () gBrowser.selectedTab = tab1, michael@0: browser1.contentWindow, null, true, michael@0: "focusedElement after tab change, focus in new tab"); michael@0: michael@0: // focusing a button in the current tab should focus it michael@0: var button1 = browser1.contentDocument.getElementById("button1"); michael@0: expectFocusShift(function () button1.focus(), michael@0: browser1.contentWindow, button1, true, michael@0: "focusedWindow after focus in focused tab"); michael@0: michael@0: // focusing a button in a background tab should not change the actual michael@0: // focus, but should set the focus that would be in that background tab to michael@0: // that button. michael@0: var button2 = browser2.contentDocument.getElementById("button2"); michael@0: button2.focus(); michael@0: michael@0: expectFocusShift(function () button2.focus(), michael@0: browser1.contentWindow, button1, false, michael@0: "focusedWindow after focus in unfocused tab"); michael@0: is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "focus in unfocused tab"); michael@0: michael@0: // switching tabs should now make the button in the other tab focused michael@0: expectFocusShift(function () gBrowser.selectedTab = tab2, michael@0: browser2.contentWindow, button2, true, michael@0: "focusedWindow after tab change"); michael@0: michael@0: // blurring an element in a background tab should not change the active michael@0: // focus, but should clear the focus in that tab. michael@0: expectFocusShift(function () button1.blur(), michael@0: browser2.contentWindow, button2, false, michael@0: "focusedWindow after blur in unfocused tab"); michael@0: is(fm.getFocusedElementForWindow(browser1.contentWindow, false, {}), null, "blur in unfocused tab"); michael@0: michael@0: // When focus is in the tab bar, it should be retained there michael@0: expectFocusShift(function () gBrowser.selectedTab.focus(), michael@0: window, gBrowser.selectedTab, true, michael@0: "focusing tab element"); michael@0: expectFocusShift(function () gBrowser.selectedTab = tab1, michael@0: window, tab1, true, michael@0: "tab change when selected tab element was focused"); michael@0: expectFocusShift(function () gBrowser.selectedTab = tab2, michael@0: window, tab2, true, michael@0: "tab change when selected tab element was focused"); michael@0: expectFocusShift(function () gBrowser.selectedTab.blur(), michael@0: window, null, true, michael@0: "blurring tab element"); michael@0: michael@0: // focusing the url field should switch active focus away from the browser but michael@0: // not clear what would be the focus in the browser michael@0: button1.focus(); michael@0: expectFocusShift(function () gURLBar.focus(), michael@0: window, gURLBar.inputField, true, michael@0: "focusedWindow after url field focused"); michael@0: is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "url field focused, button in browser"); michael@0: expectFocusShift(function () gURLBar.blur(), michael@0: window, null, true, michael@0: "blurring url field"); michael@0: michael@0: // when a chrome element is focused, switching tabs to a tab with a button michael@0: // with the current focus should focus the button michael@0: expectFocusShift(function () gBrowser.selectedTab = tab1, michael@0: browser1.contentWindow, button1, true, michael@0: "focusedWindow after tab change, focus in url field, button focused in new tab"); michael@0: is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "after switch tab, focus in unfocused tab"); michael@0: michael@0: // blurring an element in the current tab should clear the active focus michael@0: expectFocusShift(function () button1.blur(), michael@0: browser1.contentWindow, null, true, michael@0: "focusedWindow after blur in focused tab"); michael@0: michael@0: // blurring an non-focused url field should have no effect michael@0: expectFocusShift(function () gURLBar.blur(), michael@0: browser1.contentWindow, null, false, michael@0: "focusedWindow after blur in unfocused url field"); michael@0: michael@0: // switch focus to a tab with a currently focused element michael@0: expectFocusShift(function () gBrowser.selectedTab = tab2, michael@0: browser2.contentWindow, button2, true, michael@0: "focusedWindow after switch from unfocused to focused tab"); michael@0: michael@0: // clearing focus on the chrome window should switch the focus to the michael@0: // chrome window michael@0: expectFocusShift(function () fm.clearFocus(window), michael@0: window, null, true, michael@0: "focusedWindow after switch to chrome with no focused element"); michael@0: michael@0: // switch focus to another tab when neither have an active focus michael@0: expectFocusShift(function () gBrowser.selectedTab = tab1, michael@0: browser1.contentWindow, null, true, michael@0: "focusedWindow after tab switch from no focus to no focus"); michael@0: michael@0: gURLBar.focus(); michael@0: _browser_tabfocus_test_events = ""; michael@0: _browser_tabfocus_test_lastfocus = gURLBar; michael@0: _browser_tabfocus_test_lastfocuswindow = window; michael@0: michael@0: expectFocusShift(function () EventUtils.synthesizeKey("VK_F6", { }), michael@0: browser1.contentWindow, browser1.contentDocument.documentElement, michael@0: true, "switch document forward with f6"); michael@0: EventUtils.synthesizeKey("VK_F6", { }); michael@0: is(fm.focusedWindow, window, "switch document forward again with f6"); michael@0: michael@0: browser1.style.MozUserFocus = "ignore"; michael@0: browser1.clientWidth; michael@0: EventUtils.synthesizeKey("VK_F6", { }); michael@0: is(fm.focusedWindow, window, "switch document forward again with f6 when browser non-focusable"); michael@0: michael@0: window.removeEventListener("focus", _browser_tabfocus_test_eventOccured, true); michael@0: window.removeEventListener("blur", _browser_tabfocus_test_eventOccured, true); michael@0: michael@0: // next, check whether navigating forward, focusing the urlbar and then michael@0: // navigating back maintains the focus in the urlbar. michael@0: browser1.addEventListener("pageshow", _browser_tabfocus_navigation_test_eventOccured, true); michael@0: button1.focus(); michael@0: browser1.contentWindow.location = testPage3; michael@0: } michael@0: michael@0: browser1.addEventListener("load", check, true); michael@0: browser2.addEventListener("load", check, true); michael@0: browser1.contentWindow.location = testPage1; michael@0: browser2.contentWindow.location = testPage2; michael@0: } michael@0: michael@0: var _browser_tabfocus_test_lastfocus; michael@0: var _browser_tabfocus_test_lastfocuswindow = null; michael@0: var _browser_tabfocus_test_events = ""; michael@0: michael@0: function _browser_tabfocus_test_eventOccured(event) michael@0: { michael@0: var id; michael@0: if (event.target instanceof Window) michael@0: id = event.originalTarget.document.documentElement.id + "-window"; michael@0: else if (event.target instanceof Document) michael@0: id = event.originalTarget.documentElement.id + "-document"; michael@0: else if (event.target.id == "urlbar" && event.originalTarget.localName == "input") michael@0: id = "urlbar"; michael@0: else michael@0: id = event.originalTarget.id; michael@0: michael@0: if (_browser_tabfocus_test_events) michael@0: _browser_tabfocus_test_events += " "; michael@0: _browser_tabfocus_test_events += event.type + ": " + id; michael@0: } michael@0: michael@0: function _browser_tabfocus_navigation_test_eventOccured(event) michael@0: { michael@0: if (event.target instanceof Document) { michael@0: var contentwin = event.target.defaultView; michael@0: if (contentwin.location.toString().indexOf("3") > 0) { michael@0: // just moved forward, so focus the urlbar and go back michael@0: gURLBar.focus(); michael@0: setTimeout(function () contentwin.history.back(), 0); michael@0: } michael@0: else if (contentwin.location.toString().indexOf("2") > 0) { michael@0: event.currentTarget.removeEventListener("pageshow", _browser_tabfocus_navigation_test_eventOccured, true); michael@0: is(window.document.activeElement, gURLBar.inputField, "urlbar still focused after navigating back"); michael@0: gBrowser.removeCurrentTab(); michael@0: gBrowser.removeCurrentTab(); michael@0: finish(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: function getId(element) michael@0: { michael@0: return (element.localName == "input") ? "urlbar" : element.id; michael@0: } michael@0: michael@0: function expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid) michael@0: { michael@0: var expectedEvents = ""; michael@0: if (focusChanged) { michael@0: if (_browser_tabfocus_test_lastfocus) michael@0: expectedEvents += "blur: " + getId(_browser_tabfocus_test_lastfocus); michael@0: michael@0: if (_browser_tabfocus_test_lastfocuswindow && michael@0: _browser_tabfocus_test_lastfocuswindow != expectedWindow) { michael@0: if (expectedEvents) michael@0: expectedEvents += " "; michael@0: var windowid = _browser_tabfocus_test_lastfocuswindow.document.documentElement.id; michael@0: expectedEvents += "blur: " + windowid + "-document " + michael@0: "blur: " + windowid + "-window"; michael@0: } michael@0: michael@0: if (expectedWindow && _browser_tabfocus_test_lastfocuswindow != expectedWindow) { michael@0: if (expectedEvents) michael@0: expectedEvents += " "; michael@0: var windowid = expectedWindow.document.documentElement.id; michael@0: expectedEvents += "focus: " + windowid + "-document " + michael@0: "focus: " + windowid + "-window"; michael@0: } michael@0: michael@0: if (expectedElement && expectedElement != expectedElement.ownerDocument.documentElement) { michael@0: if (expectedEvents) michael@0: expectedEvents += " "; michael@0: expectedEvents += "focus: " + getId(expectedElement); michael@0: } michael@0: michael@0: _browser_tabfocus_test_lastfocus = expectedElement; michael@0: _browser_tabfocus_test_lastfocuswindow = expectedWindow; michael@0: } michael@0: michael@0: callback(); michael@0: michael@0: is(_browser_tabfocus_test_events, expectedEvents, testid + " events"); michael@0: _browser_tabfocus_test_events = ""; michael@0: michael@0: var fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); michael@0: michael@0: var focusedElement = fm.focusedElement; michael@0: is(focusedElement ? getId(focusedElement) : "none", michael@0: expectedElement ? getId(expectedElement) : "none", testid + " focusedElement"); michael@0: is(fm.focusedWindow, expectedWindow, testid + " focusedWindow"); michael@0: var focusedWindow = {}; michael@0: is(fm.getFocusedElementForWindow(expectedWindow, false, focusedWindow), michael@0: expectedElement, testid + " getFocusedElementForWindow"); michael@0: is(focusedWindow.value, expectedWindow, testid + " getFocusedElementForWindow frame"); michael@0: is(expectedWindow.document.hasFocus(), true, testid + " hasFocus"); michael@0: var expectedActive = expectedElement; michael@0: if (!expectedActive) michael@0: expectedActive = expectedWindow.document instanceof XULDocument ? michael@0: expectedWindow.document.documentElement : expectedWindow.document.body; michael@0: is(expectedWindow.document.activeElement, expectedActive, testid + " activeElement"); michael@0: }