|
@@ -0,0 +1,361 @@
|
|
|
|
+# HG changeset patch
|
|
|
|
+# User Frank-Rainer Grahl <frgrahl@gmx.net>
|
|
|
|
+# Date 1729077928 -7200
|
|
|
|
+# Parent f7d4d44c38a4243fe43c572c2203446239bc637a
|
|
|
|
+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,177 @@ 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:
|
|
|
|
++ * - 'ignoreFragment' property to be set to true to exclude
|
|
|
|
++ * fragment-portion matching when comparing URIs.
|
|
|
|
++ * If set to "whenComparing", the fragment will be unmodified.
|
|
|
|
++ * If set to "whenComparingAndReplace", the fragment will be replaced.
|
|
|
|
++ * - 'ignoreQueryString' boolean property to be set to true to exclude
|
|
|
|
++ * query string matching when comparing URIs.
|
|
|
|
++ * - 'replaceQueryString' boolean property to be set to true to exclude
|
|
|
|
++ * query string matching when comparing URIs and overwrite the initial
|
|
|
|
++ * query string with the one from the new URI.
|
|
|
|
++ * - '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 ignoreFragment = aOpenParams.ignoreFragment;
|
|
|
|
++ let ignoreQueryString = aOpenParams.ignoreQueryString;
|
|
|
|
++ let replaceQueryString = aOpenParams.replaceQueryString;
|
|
|
|
++ 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.ignoreFragment;
|
|
|
|
++ delete aOpenParams.ignoreQueryString;
|
|
|
|
++ delete aOpenParams.replaceQueryString;
|
|
|
|
++ delete aOpenParams.browserCallback;
|
|
|
|
++
|
|
|
|
++ // This will switch to the tab in aWindow having aURI, if present.
|
|
|
|
+ function switchIfURIInWindow(aWindow) {
|
|
|
|
+- if (!aWindow.gBrowser)
|
|
|
|
++ // 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;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ // Remove the query string, fragment, both, or neither from a given url.
|
|
|
|
++ function cleanURL(url, removeQuery, removeFragment) {
|
|
|
|
++ let ret = url;
|
|
|
|
++ if (removeFragment) {
|
|
|
|
++ ret = ret.split("#")[0];
|
|
|
|
++ if (removeQuery) {
|
|
|
|
++ // This removes a query, if present before the fragment.
|
|
|
|
++ ret = ret.split("?")[0];
|
|
|
|
++ }
|
|
|
|
++ } else if (removeQuery) {
|
|
|
|
++ // This is needed in case there is a fragment after the query.
|
|
|
|
++ let fragment = ret.split("#")[1];
|
|
|
|
++ ret = ret.split("?")[0].concat(
|
|
|
|
++ (fragment != undefined) ? "#".concat(fragment) : "");
|
|
|
|
++ }
|
|
|
|
++ return ret;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ // Need to handle nsSimpleURIs here too (e.g. about:...), which don't
|
|
|
|
++ // work correctly with URL objects - so treat them as strings
|
|
|
|
++ let ignoreFragmentWhenComparing =
|
|
|
|
++ typeof ignoreFragment == "string" &&
|
|
|
|
++ ignoreFragment.startsWith("whenComparing");
|
|
|
|
++ let requestedCompare = cleanURL(
|
|
|
|
++ aURI.displaySpec, ignoreQueryString || replaceQueryString,
|
|
|
|
++ ignoreFragmentWhenComparing);
|
|
|
|
+ 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
|
|
|
|
++ let browserCompare = cleanURL(
|
|
|
|
++ browser.currentURI.displaySpec,
|
|
|
|
++ ignoreQueryString || replaceQueryString,
|
|
|
|
++ ignoreFragmentWhenComparing);
|
|
|
|
++ if (requestedCompare == browserCompare) {
|
|
|
|
+ aWindow.focus();
|
|
|
|
++ if (ignoreFragment == "whenComparingAndReplace" ||
|
|
|
|
++ replaceQueryString) {
|
|
|
|
++ browser.loadURI(aURI.spec);
|
|
|
|
++ }
|
|
|
|
+ aWindow.gBrowser.tabContainer.selectedIndex = i;
|
|
|
|
+- if (aCallback)
|
|
|
|
+- aCallback(browser);
|
|
|
|
++ if (browserCallback) {
|
|
|
|
++ // Services.console
|
|
|
|
++ // .logStringMessage("switchToTabHavingURI browsercallb 1");
|
|
|
|
++ 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);
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ // Services.console.logStringMessage("switchToTabHavingURI " + aURI.spec);
|
|
|
|
++
|
|
|
|
++ 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) {
|
|
|
|
++ // Services.console
|
|
|
|
++ // .logStringMessage("switchToTabHavingURI browsercallb pre");
|
|
|
|
++ browserWinNew.addEventListener("pageshow",
|
|
|
|
++ function browserWinPageShow(event) {
|
|
|
|
++ if (event.target.location.href != aURI.spec) {
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++ browserWinNew.removeEventListener("pageshow", browserWinPageShow,
|
|
|
|
++ true);
|
|
|
|
++ // Services.console
|
|
|
|
++ // .logStringMessage("switchToTabHavingURI browsercallb 2");
|
|
|
|
++ 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();
|
|
|
|
+ }
|