# HG changeset patch # User Frank-Rainer Grahl # Date 1729077928 -7200 # Parent e39a9a79b3b463b098bc3fd717b48782f276835c Bug 1925037 - Pass optional parameters to switchToTabHavingURI as an array. r=IanN a=IanN Aligns the call syntax with Firefox and toolkit usage. Drive by fixes: Undefined e.button warning in strict mode and a trailing blank removal. diff --git a/suite/base/content/tasksOverlay.js b/suite/base/content/tasksOverlay.js --- a/suite/base/content/tasksOverlay.js +++ b/suite/base/content/tasksOverlay.js @@ -39,39 +39,47 @@ function toDataManager(aView) if (useDlg) { var url = "chrome://communicator/content/dataman/dataman.xul"; var win = toOpenWindowByType("data:manager", url, "", aView); if (win && aView) win.gDataman.loadView(aView); return; } - switchToTabHavingURI("about:data", true, function(browser) { - if (aView) - browser.contentWindow.wrappedJSObject.gDataman.loadView(aView); + switchToTabHavingURI("about:data", true, { + browserCallback: function(browser) { + if (aView) { + browser.contentWindow.wrappedJSObject.gDataman.loadView(aView); + } + } }); } function toEM(aView) { var useDlg = Services.prefs.getBoolPref("suite.manager.addons.openAsDialog"); if (useDlg) { var view = aView ? { view: aView } : null; var url = "chrome://mozapps/content/extensions/extensions.xul"; var win = toOpenWindowByType("Addons:Manager", url, "", view); if (win && aView) win.loadView(aView); return; } - switchToTabHavingURI("about:addons", true, function(browser) { - if (aView) - browser.contentWindow.wrappedJSObject.loadView(aView); + switchToTabHavingURI("about:addons", true, { + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + browserCallback: function(browser) { + if (aView) { + browser.contentWindow.wrappedJSObject.loadView(aView); + } + } }); + } function toBookmarksManager() { toOpenWindowByType("Places:Organizer", "chrome://communicator/content/places/places.xul"); } diff --git a/suite/base/content/utilityOverlay.js b/suite/base/content/utilityOverlay.js --- a/suite/base/content/utilityOverlay.js +++ b/suite/base/content/utilityOverlay.js @@ -1406,17 +1406,17 @@ function whereToOpenLink(e, ignoreButton return "current"; var shift = e.shiftKey; var ctrl = e.ctrlKey; var meta = e.metaKey; var alt = e.altKey && !ignoreSave; // ignoreButton allows "middle-click paste" to use function without always opening in a new window. - var middle = !ignoreButton && e.button == 1; + var middle = !ignoreButton && e.button && e.button == 1; // Don't do anything special with right-mouse clicks. They're probably clicks on context menu items. // On macOS ctrl is not evaluated. var metaKey = AppConstants.platform == "macosx" ? meta : ctrl; if (metaKey || middle) { if (Services.prefs.getBoolPref("browser.tabs.opentabfor.middleclick", true)) @@ -1701,17 +1701,17 @@ function openUILinkArrayIn(urlArray, whe var w = getTopWin(); if (!w || where == "window") { return window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", urlArray.join("\n"), // Pretend that we're a home page group null, null, null, allowThirdPartyFixup); } - var loadInBackground = + var loadInBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground"); var browser = w.getBrowser(); switch (where) { case "current": w.loadURI(urlArray[0], null, null, allowThirdPartyFixup); w.content.focus(); break; @@ -1728,76 +1728,125 @@ function openUILinkArrayIn(urlArray, whe var relatedToCurrent = where == "current"; for (var i = 1; i < urlArray.length; i++) browser.addTab(urlArray[i], {allowThirdPartyFixup: allowThirdPartyFixup, relatedToCurrent: relatedToCurrent}); return w; } /** - * Switch to a tab that has a given URI, and focusses its browser window. - * If a matching tab is in this window, it will be switched to. Otherwise, other - * windows will be searched. + * Switch to a tab that has a given URI, and focuses its browser window. + * If a matching tab is in this window, it will be switched to. Otherwise, + * other windows will be searched. * * @param aURI * URI to search for * @param aOpenNew - * True to open a new tab and switch to it, if no existing tab is found - * @param A callback to call when the tab is open, the tab's browser will be - * passed as an argument - * @return True if a tab was switched to (or opened), false otherwise + * True to open a new tab and switch to it, if no existing tab is found. + * If no suitable window is found, a new one will be opened. + * @param aOpenParams + * If switching to this URI results in us opening a tab, aOpenParams + * will be the parameter object that gets passed to openUILinkIn. Please + * see the documentation for openUILinkIn to see what parameters can be + * passed via this object. + * This object also allows: + * - 'browserCallback' a callback to call when the tab is open, the + * tab's browser will be passed as an argument + + * @return True if an existing tab was found, false otherwise */ -function switchToTabHavingURI(aURI, aOpenNew, aCallback) { +function switchToTabHavingURI(aURI, aOpenNew, aOpenParams = {}) { + // Certain URLs can be switched to irrespective of the source or destination + // window being in private browsing mode: + const kPrivateBrowsingWhitelist = new Set([ + "about:addons", + ]); + + let browserCallback = aOpenParams.browserCallback; + + // These properties are only used by switchToTabHavingURI and should + // not be used as a parameter for the new load. + delete aOpenParams.browserCallback; + + // This will switch to the tab in aWindow having aURI, if present. function switchIfURIInWindow(aWindow) { - if (!aWindow.gBrowser) + if (!aWindow.gBrowser) { return false; + } + + // Only switch to the tab if neither the source nor the destination window + // are private and they are not in permanent private browsing mode + if (!kPrivateBrowsingWhitelist.has(aURI.spec) && + (PrivateBrowsingUtils.isWindowPrivate(window) || + PrivateBrowsingUtils.isWindowPrivate(aWindow)) && + !PrivateBrowsingUtils.permanentPrivateBrowsing) { + return false; + } + let browsers = aWindow.gBrowser.browsers; for (let i = 0; i < browsers.length; i++) { let browser = browsers[i]; if (browser.currentURI.equals(aURI)) { // Focus the matching window & tab aWindow.focus(); aWindow.gBrowser.tabContainer.selectedIndex = i; - if (aCallback) - aCallback(browser); + if (browserCallback) { + browserCallback(browser); + } + return true; } } return false; } // This can be passed either nsIURI or a string. - if (!(aURI instanceof Ci.nsIURI)) + if (!(aURI instanceof Ci.nsIURI)) { aURI = Services.io.newURI(aURI); + } + + let isBrowserWindow = !!window.gBrowser; // Prioritise this window. - if (switchIfURIInWindow(window)) + if (isBrowserWindow && switchIfURIInWindow(window)) { return true; + } let winEnum = Services.wm.getEnumerator("navigator:browser"); while (winEnum.hasMoreElements()) { let browserWin = winEnum.getNext(); // Skip closed (but not yet destroyed) windows, // and the current window (which was checked earlier). - if (browserWin.closed || browserWin == window) + if (browserWin.closed || browserWin == window) { continue; - if (switchIfURIInWindow(browserWin)) + } + if (switchIfURIInWindow(browserWin)) { return true; + } } // No opened tab has that url. if (aOpenNew) { - let browserWin = openUILinkIn(aURI.spec, "tabfocused"); - if (aCallback) { - browserWin.addEventListener("pageshow", function browserWinPageShow(event) { - if (event.target.location.href != aURI.spec) - return; - browserWin.removeEventListener("pageshow", browserWinPageShow, true); - aCallback(browserWin.getBrowser().selectedBrowser); - }, true); + let browserWinNew; + if (isBrowserWindow && isTabEmpty(gBrowser.selectedTab)) { + browserWinNew = openUILinkIn(aURI.spec, "current", aOpenParams); + } else { + browserWinNew = openUILinkIn(aURI.spec, "tab", aOpenParams); + } + if (browserCallback) { + browserWinNew.addEventListener("pageshow", + function browserWinPageShow(event) { + if (event.target.location.href != aURI.spec) { + return; + } + browserWinNew.removeEventListener("pageshow", browserWinPageShow, + true); + browserCallback(browserWinNew.getBrowser().selectedBrowser); + }, + true); } return true; } return false; } // Determines if a browser is "empty" diff --git a/suite/browser/navigator.js b/suite/browser/navigator.js --- a/suite/browser/navigator.js +++ b/suite/browser/navigator.js @@ -1733,17 +1733,17 @@ function BrowserOpenTab() setTimeout(WindowFocusTimerCallback, 0, gURLBar); else setTimeout(WindowFocusTimerCallback, 0, content); } } function BrowserOpenSyncTabs() { - switchToTabHavingURI("about:sync-tabs", true); + switchToTabHavingURI("about:sync-tabs", true, aOpenParams = {}); } // Class for saving the last directory and filter Index in the prefs. // Used for open file and upload file. class RememberLastDir { // The pref names are constructed from the prefix parameter in the constructor. // The pref names should not be changed later. diff --git a/suite/components/tests/browser/browser_isempty.js b/suite/components/tests/browser/browser_isempty.js --- a/suite/components/tests/browser/browser_isempty.js +++ b/suite/components/tests/browser/browser_isempty.js @@ -10,19 +10,21 @@ var gWindowObject; var gTabCount; function test() { waitForExplicitFinish(); gTabCount = gBrowser.tabs.length; gBrowser.selectedTab = gBrowser.addTab(); is(isTabEmpty(gBrowser.selectedTab), true, "Added tab is empty"); - switchToTabHavingURI("about:", true, function(aBrowser) { - gWindowObject = aBrowser.contentWindow.wrappedJSObject; - end_test(); + switchToTabHavingURI("about:", true, { + browserCallback: function(aBrowser) { + gWindowObject = aBrowser.contentWindow.wrappedJSObject; + end_test(); + } }); } function end_test() { gWindowObject.close(); is(gBrowser.tabs.length, gTabCount, "We're still at the same number of tabs"); finish(); }