commit 2c4830e80d05b5f5f43a17431b8d3f12ce9886cd
parent 097fef61129031a6873c30cbcb57a95b9e1bd624
Author: Atila Butkovits <abutkovits@mozilla.com>
Date: Wed, 29 Oct 2025 20:03:49 +0200
Revert "Bug 1990551 - Send tabs to other profiles from context menu. r=profiles-reviewers,fluent-reviewers,bolsson,jhirsch" for causing failures at test_delete_last_profile.js.
This reverts commit f5ade40d4fc4a0b43da6204531a5f1d7ea4f4fc1.
Diffstat:
12 files changed, 11 insertions(+), 311 deletions(-)
diff --git a/browser/base/content/browser-profiles.js b/browser/base/content/browser-profiles.js
@@ -194,16 +194,6 @@ var gProfiles = {
});
},
- async openTabsInProfile(aEvent, tabsToOpen) {
- let profile = await SelectableProfileService.getProfile(
- aEvent.target.getAttribute("profileid")
- );
- SelectableProfileService.launchInstance(
- profile,
- tabsToOpen.map(tab => tab.linkedBrowser.currentURI.spec)
- );
- },
-
async handleCommand(aEvent) {
switch (aEvent.target.id) {
/* App menu button events */
@@ -257,16 +247,6 @@ var gProfiles = {
this.launchProfile(aEvent.sourceEvent);
break;
}
- case "Profiles:MoveTabsToProfile": {
- let tabs;
- if (TabContextMenu.contextTab.multiselected) {
- tabs = gBrowser.selectedTabs;
- } else {
- tabs = [TabContextMenu.contextTab];
- }
- this.openTabsInProfile(aEvent.sourceEvent, tabs);
- break;
- }
}
/* Subpanel profile events that may be triggered in FxA menu or app menu */
if (aEvent.target.classList.contains("profile-item")) {
@@ -447,50 +427,4 @@ var gProfiles = {
profilesList.appendChild(button);
}
},
-
- async populateMoveTabMenu(menuPopup) {
- if (!SelectableProfileService.initialized) {
- return;
- }
-
- const profiles = await SelectableProfileService.getAllProfiles();
- const currentProfile = SelectableProfileService.currentProfile;
-
- const separator = document.getElementById("moveTabSeparator");
- separator.hidden = profiles.length < 2;
-
- let existingItems = [
- ...menuPopup.querySelectorAll(":scope > menuitem[profileid]"),
- ];
-
- for (let profile of profiles) {
- if (profile.id === currentProfile.id) {
- continue;
- }
-
- let menuitem = existingItems.shift();
- let isNewItem = !menuitem;
- if (isNewItem) {
- menuitem = document.createXULElement("menuitem");
- menuitem.setAttribute("tbattr", "tabbrowser-multiple-visible");
- menuitem.setAttribute("data-l10n-id", "move-to-new-profile");
- menuitem.setAttribute("command", "Profiles:MoveTabsToProfile");
- }
-
- menuitem.disabled = false;
- menuitem.setAttribute("profileid", profile.id);
- menuitem.setAttribute(
- "data-l10n-args",
- JSON.stringify({ profileName: profile.name })
- );
-
- if (isNewItem) {
- menuPopup.appendChild(menuitem);
- }
- }
- // If there's any old item to remove, do so now.
- for (let remaining of existingItems) {
- remaining.remove();
- }
- },
};
diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc
@@ -78,7 +78,6 @@
<command id="Profiles:CreateProfile" />
<command id="Profiles:ManageProfiles" />
<command id="Profiles:LaunchProfile" />
- <command id="Profiles:MoveTabsToProfile" />
<command id="Browser:NextTab" />
<command id="Browser:PrevTab" />
<command id="Browser:ShowAllTabs" />
diff --git a/browser/base/content/browser-sets.js b/browser/base/content/browser-sets.js
@@ -203,7 +203,6 @@ document.addEventListener(
case "Profiles:CreateProfile":
case "Profiles:ManageProfiles":
case "Profiles:LaunchProfile":
- case "Profiles:MoveTabsToProfile":
gProfiles.handleCommand(event);
break;
case "Tools:Search":
diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content/main-popupset.inc.xhtml
@@ -75,7 +75,6 @@
tbattr="tabbrowser-multiple-visible"/>
<menuitem id="context_openTabInWindow" data-lazy-l10n-id="move-to-new-window"
tbattr="tabbrowser-multiple-visible"/>
- <menuseparator id="moveTabSeparator" hidden="true"/>
</menupopup>
</menu>
<menu id="context_sendTabToDevice"
diff --git a/browser/base/content/main-popupset.js b/browser/base/content/main-popupset.js
@@ -532,9 +532,6 @@ document.addEventListener(
case "tabContextMenu":
TabContextMenu.addNewBadge();
break;
- case "moveTabOptionsMenu":
- gProfiles.populateMoveTabMenu(event.target);
- break;
}
});
diff --git a/browser/components/profiles/SelectableProfileService.sys.mjs b/browser/components/profiles/SelectableProfileService.sys.mjs
@@ -619,17 +619,13 @@ class SelectableProfileServiceClass extends EventEmitter {
* Launch a new Firefox instance using the given selectable profile.
*
* @param {SelectableProfile} aProfile The profile to launch
- * @param {Array<string>} aUrls An array of urls to open in launched profile
+ * @param {string} aUrl A url to open in launched profile
*/
- launchInstance(aProfile, aUrls) {
+ launchInstance(aProfile, aUrl) {
let args = [];
- if (aUrls?.length) {
- // See https://wiki.mozilla.org/Firefox/CommandLineOptions#-url_URL
- // Use '-new-tab' instead of '-url' because when opening multiple URLs,
- // Firefox always opens them as tabs in a new window and we want to
- // attempt opening these tabs in an existing window.
- args.push(...aUrls.flatMap(url => ["-new-tab", url]));
+ if (aUrl) {
+ args.push("-url", aUrl);
} else {
args.push(`--${COMMAND_LINE_ACTIVATE}`);
}
@@ -1444,7 +1440,7 @@ class SelectableProfileServiceClass extends EventEmitter {
let profile = await this.#createProfile();
if (launchProfile) {
- this.launchInstance(profile, ["about:newprofile"]);
+ this.launchInstance(profile, "about:newprofile");
}
return profile;
}
diff --git a/browser/components/profiles/content/profile-selector.mjs b/browser/components/profiles/content/profile-selector.mjs
@@ -126,7 +126,7 @@ export class ProfileSelector extends MozLitElement {
await this.setLaunchArguments(profile, url ? ["-url", url] : []);
await this.selectableProfileService.uninit();
} else {
- this.selectableProfileService.launchInstance(profile, [url]);
+ this.selectableProfileService.launchInstance(profile, url);
}
window.close();
diff --git a/browser/components/profiles/tests/browser/browser.toml b/browser/components/profiles/tests/browser/browser.toml
@@ -50,8 +50,6 @@ skip-if = [
["browser_menubar_profiles.js"]
head = "../unit/head.js head.js"
-["browser_moveTabToProfile.js"]
-
["browser_notify_changes.js"]
run-if = ["os != 'linux'"] # Linux clients cannot remote themselves.
skip-if = ["os == 'mac' && os_version == '15.30' && arch == 'aarch64' && opt && !socketprocess_networking"] # Bug 1929273
diff --git a/browser/components/profiles/tests/browser/browser_moveTabToProfile.js b/browser/components/profiles/tests/browser/browser_moveTabToProfile.js
@@ -1,220 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- https://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { sinon } = ChromeUtils.importESModule(
- "resource://testing-common/Sinon.sys.mjs"
-);
-const { ObjectUtils } = ChromeUtils.importESModule(
- "resource://gre/modules/ObjectUtils.sys.mjs"
-);
-
-const EXAMPLE_URL = "https://example.com/";
-
-async function addTab(url = EXAMPLE_URL) {
- const tab = BrowserTestUtils.addTab(gBrowser, url, {
- skipAnimation: true,
- });
- const browser = gBrowser.getBrowserForTab(tab);
- await BrowserTestUtils.browserLoaded(browser);
- return tab;
-}
-
-async function openContextMenu(tab) {
- let contextMenu = document.getElementById("tabContextMenu");
- let openTabContextMenuPromise = BrowserTestUtils.waitForPopupEvent(
- contextMenu,
- "shown"
- );
-
- await sendAndWaitForMouseEvent(tab, { type: "contextmenu" });
- await openTabContextMenuPromise;
- return contextMenu;
-}
-
-async function openMoveTabOptionsMenuPopup(contextMenu) {
- let moveTabMenuItem = contextMenu.querySelector("#context_moveTabOptions");
- let subMenu = contextMenu.querySelector("#moveTabOptionsMenu");
- let popupShown = BrowserTestUtils.waitForEvent(subMenu, "popupshown");
-
- if (AppConstants.platform === "macosx") {
- moveTabMenuItem.openMenu(true);
- } else {
- await sendAndWaitForMouseEvent(moveTabMenuItem);
- }
-
- await popupShown;
-
- const separator = subMenu.querySelector("#moveTabSeparator");
- await TestUtils.waitForCondition(
- () =>
- BrowserTestUtils.isVisible(separator) &&
- BrowserTestUtils.isVisible(separator.nextElementSibling)
- );
-
- return subMenu;
-}
-
-async function clickMoveToProfileMenuItem(subMenu) {
- let profileMenuItem = subMenu.querySelector(":scope > menuitem[profileid]");
- if (AppConstants.platform === "macosx") {
- subMenu.activateItem(profileMenuItem);
- } else {
- await sendAndWaitForMouseEvent(profileMenuItem);
- }
-}
-
-async function sendAndWaitForMouseEvent(target, options = {}) {
- let promise = BrowserTestUtils.waitForEvent(target, options.type ?? "click");
- EventUtils.synthesizeMouseAtCenter(target, options);
- return promise;
-}
-
-const execProcess = sinon.fake();
-const sendCommandLine = sinon.fake.throws(Cr.NS_ERROR_NOT_AVAILABLE);
-sinon.replace(
- SelectableProfileService,
- "sendCommandLine",
- (path, args, raise) => sendCommandLine(path, [...args], raise)
-);
-sinon.replace(SelectableProfileService, "execProcess", execProcess);
-
-registerCleanupFunction(() => {
- sinon.restore();
-});
-
-let lastCommandLineCallCount = 1;
-async function assertCommandLineExists(expected) {
- await TestUtils.waitForCondition(
- () => sendCommandLine.callCount > lastCommandLineCallCount,
- "Waiting for notify task to complete"
- );
-
- let allCommandLineCalls = sendCommandLine.getCalls();
-
- lastCommandLineCallCount++;
-
- let expectedCount = allCommandLineCalls.reduce((count, call) => {
- if (ObjectUtils.deepEqual(call.args, expected)) {
- return count + 1;
- }
-
- return count;
- }, 0);
-
- Assert.equal(expectedCount, 1, "Found expected args");
- Assert.deepEqual(
- allCommandLineCalls.find(call => ObjectUtils.deepEqual(call.args, expected))
- .args,
- expected,
- "Expected sendCommandLine arguments to open tab in profile"
- );
-}
-
-add_task(async function test_moveSelectedTab() {
- await initGroupDatabase();
-
- const allProfiles = await SelectableProfileService.getAllProfiles();
- let otherProfile;
- if (allProfiles.length < 2) {
- otherProfile = await SelectableProfileService.createNewProfile(false);
- } else {
- otherProfile = allProfiles.find(
- p => p.id !== SelectableProfileService.currentProfile.id
- );
- }
-
- let tab2 = await addTab(EXAMPLE_URL + "2");
-
- gBrowser.selectedTab = tab2;
-
- let contextMenu = await openContextMenu(tab2);
- let subMenu = await openMoveTabOptionsMenuPopup(contextMenu);
- await clickMoveToProfileMenuItem(subMenu);
-
- let expectedArgs = ["-new-tab", EXAMPLE_URL + "2"];
-
- await assertCommandLineExists([otherProfile.path, expectedArgs, true]);
-
- gBrowser.removeTab(tab2);
-});
-
-add_task(async function test_moveNonSelectedTab() {
- await initGroupDatabase();
-
- const allProfiles = await SelectableProfileService.getAllProfiles();
- let otherProfile;
- if (allProfiles.length < 2) {
- otherProfile = await SelectableProfileService.createNewProfile(false);
- } else {
- otherProfile = allProfiles.find(
- p => p.id !== SelectableProfileService.currentProfile.id
- );
- }
-
- let tab2 = await addTab(EXAMPLE_URL + "2");
- let tab3 = await addTab(EXAMPLE_URL + "3");
-
- gBrowser.selectedTab = tab2;
-
- let contextMenu = await openContextMenu(tab3);
- let subMenu = await openMoveTabOptionsMenuPopup(contextMenu);
- await clickMoveToProfileMenuItem(subMenu);
-
- let expectedArgs = ["-new-tab", EXAMPLE_URL + "3"];
-
- await assertCommandLineExists([otherProfile.path, expectedArgs, true]);
-
- gBrowser.removeTabs([tab2, tab3]);
-});
-
-add_task(async function test_moveMultipleSelectedTabs() {
- await initGroupDatabase();
-
- const allProfiles = await SelectableProfileService.getAllProfiles();
- let otherProfile;
- if (allProfiles.length < 2) {
- otherProfile = await SelectableProfileService.createNewProfile(false);
- } else {
- otherProfile = allProfiles.find(
- p => p.id !== SelectableProfileService.currentProfile.id
- );
- }
-
- let tab2 = await addTab(EXAMPLE_URL + "2");
- let tab3 = await addTab(EXAMPLE_URL + "3");
- let tab4 = await addTab(EXAMPLE_URL + "4");
-
- gBrowser.selectedTab = tab2;
-
- await sendAndWaitForMouseEvent(tab2);
- if (AppConstants.platform === "macosx") {
- await sendAndWaitForMouseEvent(tab3, { metaKey: true });
- await sendAndWaitForMouseEvent(tab4, { metaKey: true });
- } else {
- await sendAndWaitForMouseEvent(tab3, { ctrlKey: true });
- await sendAndWaitForMouseEvent(tab4, { ctrlKey: true });
- }
-
- Assert.ok(tab2.multiselected, "Tab2 is multiselected");
- Assert.ok(tab3.multiselected, "Tab3 is multiselected");
- Assert.ok(tab4.multiselected, "Tab4 is multiselected");
-
- let contextMenu = await openContextMenu(tab4);
- let subMenu = await openMoveTabOptionsMenuPopup(contextMenu);
- await clickMoveToProfileMenuItem(subMenu);
-
- let expectedArgs = [
- "-new-tab",
- EXAMPLE_URL + "2",
- "-new-tab",
- EXAMPLE_URL + "3",
- "-new-tab",
- EXAMPLE_URL + "4",
- ];
-
- await assertCommandLineExists([otherProfile.path, expectedArgs, true]);
-
- gBrowser.removeTabs([tab2, tab3, tab4]);
-});
diff --git a/browser/components/profiles/tests/unit/test_delete_last_profile.js b/browser/components/profiles/tests/unit/test_delete_last_profile.js
@@ -15,6 +15,8 @@ const execProcess = sinon.fake();
const sendCommandLine = sinon.fake.throws(Cr.NS_ERROR_NOT_AVAILABLE);
add_setup(async () => {
+ await initSelectableProfileService();
+
sinon.replace(
getSelectableProfileService(),
"sendCommandLine",
@@ -51,7 +53,7 @@ add_task(async function test_delete_last_profile() {
profile = profiles[0];
- let expected = ["-new-tab", "about:newprofile"];
+ let expected = ["-url", "about:newprofile"];
await TestUtils.waitForCondition(
() => sendCommandLine.callCount > 1,
diff --git a/browser/components/profiles/tests/unit/test_selectable_profile_launch.js b/browser/components/profiles/tests/unit/test_selectable_profile_launch.js
@@ -59,9 +59,9 @@ add_task(async function test_launcher() {
sendCommandLine.resetHistory();
execProcess.resetHistory();
- SelectableProfileService.launchInstance(profile, ["about:profilemanager"]);
+ SelectableProfileService.launchInstance(profile, "about:profilemanager");
- expected = ["-new-tab", "about:profilemanager"];
+ expected = ["-url", "about:profilemanager"];
Assert.equal(
sendCommandLine.callCount,
diff --git a/browser/locales/en-US/browser/tabContextMenu.ftl b/browser/locales/en-US/browser/tabContextMenu.ftl
@@ -93,10 +93,6 @@ move-to-end =
move-to-new-window =
.label = Move to New Window
.accesskey = W
-# Variables
-# $profileName (string): The name of the profile to move tab to
-move-to-new-profile =
- .label = Move to { $profileName }
tab-context-close-multiple-tabs =
.label = Close Multiple Tabs
.accesskey = M