diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 1de89a858924..a39abe49cea1 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6559,10 +6559,7 @@ function undoCloseTab(aIndex) { var blankTabToRemove = null; if (gBrowser.tabs.length == 1 && !gPrefService.getBoolPref("browser.tabs.autoHide") && - gBrowser.sessionHistory.count < 2 && - gBrowser.currentURI.spec == "about:blank" && - !gBrowser.contentDocument.body.hasChildNodes() && - !gBrowser.selectedTab.hasAttribute("busy")) + isTabEmpty(gBrowser.selectedTab)) blankTabToRemove = gBrowser.selectedTab; var tab = null; @@ -6594,6 +6591,18 @@ function undoCloseWindow(aIndex) { return window; } +/* + * Determines if a tab is "empty", usually used in the context of determining + * if it's ok to close the tab. + */ +function isTabEmpty(aTab) { + let browser = aTab.linkedBrowser; + return browser.sessionHistory.count < 2 && + browser.currentURI.spec == "about:blank" && + !browser.contentDocument.body.hasChildNodes() && + !aTab.hasAttribute("busy"); +} + /** * Format a URL * eg: @@ -7585,10 +7594,16 @@ function switchToTabHavingURI(aURI, aOpenNew, aCallback) { let browser = browsers[i]; if (browser.currentURI.equals(aURI)) { gURLBar.handleRevert(); + // We need the current tab so we can check if we should close it + let prevTab = gBrowser.selectedTab; + // Focus the matching window & tab aWindow.focus(); aWindow.gBrowser.tabContainer.selectedIndex = i; if (aCallback) aCallback(browser); + // Close the previously selected tab if it was empty + if (isTabEmpty(prevTab)) + gBrowser.removeTab(prevTab); return true; } } diff --git a/browser/base/content/test/Makefile.in b/browser/base/content/test/Makefile.in index d3aaa1b9604f..01cd008d780e 100644 --- a/browser/base/content/test/Makefile.in +++ b/browser/base/content/test/Makefile.in @@ -129,6 +129,7 @@ _BROWSER_FILES = \ browser_bug537474.js \ browser_bug550565.js \ browser_bug555224.js \ + browser_bug555767.js \ browser_bug556061.js \ browser_bug562649.js \ browser_bug563588.js \ diff --git a/browser/base/content/test/browser_bug555767.js b/browser/base/content/test/browser_bug555767.js new file mode 100644 index 000000000000..4e09adcd87c6 --- /dev/null +++ b/browser/base/content/test/browser_bug555767.js @@ -0,0 +1,101 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is bug 555767 test. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Paul O’Shannessy + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function test() { + waitForExplicitFinish(); + + let testURL = "http://example.org/browser/browser/base/content/test/dummy_page.html"; + let tabSelected = false; + + // Open the base tab + let baseTab = gBrowser.addTab(testURL); + baseTab.linkedBrowser.addEventListener("load", function() { + // Wait for the tab to be fully loaded so matching happens correctly + if (baseTab.linkedBrowser.currentURI.spec == "about:blank") + return; + baseTab.linkedBrowser.removeEventListener("load", arguments.callee, true); + + let testTab = gBrowser.addTab(); + + // Select the testTab + gBrowser.selectedTab = testTab; + + // Ensure that this tab has no history entries + ok(testTab.linkedBrowser.sessionHistory.count < 2, + "The test tab has 1 or less history entries"); + // Ensure that this tab is on about:blank + is(testTab.linkedBrowser.currentURI.spec, "about:blank", + "The test tab is on about:blank"); + // Ensure that this tab's document has no child nodes + ok(!testTab.linkedBrowser.contentDocument.body.hasChildNodes(), + "The test tab has no child nodes"); + ok(!testTab.hasAttribute("busy"), + "The test tab doesn't have the busy attribute"); + + // Set the urlbar to include the moz-action + gURLBar.value = "moz-action:switchtab," + testURL; + // Focus the urlbar so we can press enter + gURLBar.focus(); + + // Functions for TabClose and TabSelect + function onTabClose(aEvent) { + gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, false); + // Make sure we get the TabClose event for testTab + is(aEvent.originalTarget, testTab, "Got the TabClose event for the right tab"); + // Confirm that we did select the tab + ok(tabSelected, "Confirming that the tab was selected"); + gBrowser.removeTab(baseTab); + finish(); + } + function onTabSelect(aEvent) { + gBrowser.tabContainer.removeEventListener("TabSelect", onTabSelect, false); + // Make sure we got the TabSelect event for baseTab + is(aEvent.originalTarget, baseTab, "Got the TabSelect event for the right tab"); + // Confirm that the selected tab is in fact base tab + is(gBrowser.selectedTab, baseTab, "We've switched to the correct tab"); + tabSelected = true; + } + + // Add the TabClose, TabSelect event listeners before we press enter + gBrowser.tabContainer.addEventListener("TabClose", onTabClose, false); + gBrowser.tabContainer.addEventListener("TabSelect", onTabSelect, false); + + // Press enter! + EventUtils.synthesizeKey("VK_RETURN", {}); + }, true); +} +