Bug 1933112: Tab groups only appear in TOM menus for windows with same privateness r=dao,tabbrowser-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D237604
This commit is contained in:
Jeremy Swinarton
2025-02-13 14:25:36 +00:00
parent 3e39e2e2b1
commit eea0d1bd7f
3 changed files with 97 additions and 11 deletions

View File

@@ -3018,14 +3018,18 @@
} }
getAllTabGroups() { getAllTabGroups() {
return BrowserWindowTracker.orderedWindows.reduce( return BrowserWindowTracker.getOrderedWindows({
(acc, window) => acc.concat(window.gBrowser.tabGroups), private: PrivateBrowsingUtils.isWindowPrivate(window),
}).reduce(
(acc, thisWindow) => acc.concat(thisWindow.gBrowser.tabGroups),
[] []
); );
} }
getTabGroupById(id) { getTabGroupById(id) {
for (const win of BrowserWindowTracker.orderedWindows) { for (const win of BrowserWindowTracker.getOrderedWindows({
private: PrivateBrowsingUtils.isWindowPrivate(window),
})) {
for (const group of win.gBrowser.tabGroups) { for (const group of win.gBrowser.tabGroups) {
if (group.id === id) { if (group.id === id) {
return group; return group;

View File

@@ -265,10 +265,11 @@ add_task(async function test_groupsViewShowMore() {
} }
let allTabsMenu = await openTabsMenu(); let allTabsMenu = await openTabsMenu();
Assert.equal( await BrowserTestUtils.waitForCondition(
allTabsMenu.querySelectorAll("#allTabsMenu-groupsView .all-tabs-group-item") () =>
.length, allTabsMenu.querySelectorAll(
5, "#allTabsMenu-groupsView .all-tabs-group-item"
).length === 5,
"5 groups should be shown in groups list" "5 groups should be shown in groups list"
); );
Assert.ok( Assert.ok(
@@ -550,3 +551,65 @@ add_task(async function test_tabGroupsViewContextMenu_openGroups() {
await BrowserTestUtils.closeWindow(newWindow); await BrowserTestUtils.closeWindow(newWindow);
forgetSavedTabGroups(); forgetSavedTabGroups();
}); });
/**
* Tests that groups opened in non-private windows do not appear in menus in
* private windows, and vice-versa.
*/
add_task(async function test_tabGroupsIsolatedByPrivateness() {
forgetSavedTabGroups();
const groupsViewId = "#allTabsMenu-groupsView toolbaritem";
info("Test that non-private windows don't appear in private menus");
let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
privateWindow.gTabsPanel.init();
let allTabsMenuPrivate = await openTabsMenu(privateWindow);
Assert.equal(
allTabsMenuPrivate.querySelectorAll(groupsViewId).length,
0,
"Tab groups section is initially empty in private window"
);
await closeTabsMenu(privateWindow);
let nonPrivateGroup = await createTestGroup({
label: "non-private-group",
});
allTabsMenuPrivate = await openTabsMenu(privateWindow);
Assert.equal(
allTabsMenuPrivate.querySelectorAll(groupsViewId).length,
0,
"Tab groups section is still empty even when tab group open in non-private window"
);
await closeTabsMenu(privateWindow);
await removeTabGroup(nonPrivateGroup);
info("Test that private windows don't appear in non-private menus");
let allTabsMenuNonPrivate = await openTabsMenu();
Assert.equal(
allTabsMenuNonPrivate.querySelectorAll(groupsViewId).length,
0,
"Tab groups section is initially empty in non-private window"
);
await closeTabsMenu();
let privateGroup = await createTestGroup({
label: "private-group",
targetWin: privateWindow,
});
allTabsMenuNonPrivate = await openTabsMenu();
Assert.equal(
allTabsMenuNonPrivate.querySelectorAll(groupsViewId).length,
0,
"Tab groups section is still empty even when tab group open in private window"
);
await closeTabsMenu();
await removeTabGroup(privateGroup);
await BrowserTestUtils.closeWindow(privateWindow, { animate: false });
forgetSavedTabGroups();
});

View File

@@ -388,14 +388,33 @@ export const BrowserWindowTracker = {
return _trackedWindows.length; return _trackedWindows.length;
}, },
get orderedWindows() {
return this.getOrderedWindows();
},
/** /**
* Array of browser windows ordered by z-index, in reverse order. * Array of browser windows ordered by z-index, in reverse order.
* This means that the top-most browser window will be the first item. * This means that the top-most browser window will be the first item.
* @param {object} options
* @param {boolean} [options.private]
* If set, returns only windows with the specified privateness. i.e. `true`
* will return only private windows. The default value, `null`, will return
* all windows.
*/ */
get orderedWindows() { getOrderedWindows({ private: isPrivate = undefined } = {}) {
// Clone the windows array immediately as it may change during iteration, // Clone the windows array immediately as it may change during iteration.
// we'd rather have an outdated order than skip/revisit windows. // We'd rather have an outdated order than skip/revisit windows.
return [..._trackedWindows]; const windows = [..._trackedWindows];
if (
typeof isPrivate !== "boolean" ||
(isPrivate && lazy.PrivateBrowsingUtils.permanentPrivateBrowsing)
) {
return windows;
}
return windows.filter(
w => lazy.PrivateBrowsingUtils.isWindowPrivate(w) === isPrivate
);
}, },
getAllVisibleTabs() { getAllVisibleTabs() {