Fix #2747: open/reopen container tabs in tab groups when appropriate
Firefox 137 introduced tab groups. Tab group web extension support is rolling out in Firefox 138 and later. Creating a new tab after the last tab in a tab group can inadvertently create the new tab outside of the tab group. When a user opens a new tab that should be in a container, this patch will make sure that the new tab resides in the same tab group as the original tab.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* Firefox does not yet have the `tabGroups` API, which exposes this constant
|
||||
* to indicate that a tab is not in a tab group. But the Firefox `tabs` API
|
||||
* currently returns this constant value for `Tab.groupId`.
|
||||
* @see https://searchfox.org/mozilla-central/rev/3b95c8dbe724b10390c96c1b9dd0f12c873e2f2e/browser/components/extensions/schemas/tabs.json#235
|
||||
*/
|
||||
const TAB_GROUP_ID_NONE = -1;
|
||||
|
||||
window.assignManager = {
|
||||
MENU_ASSIGN_ID: "open-in-this-container",
|
||||
MENU_REMOVE_ID: "remove-open-in-this-container",
|
||||
@@ -326,7 +334,8 @@ window.assignManager = {
|
||||
options.url,
|
||||
tab.index + 1,
|
||||
tab.active,
|
||||
openTabId
|
||||
openTabId,
|
||||
tab.groupId
|
||||
);
|
||||
} else {
|
||||
this.reloadPageInContainer(
|
||||
@@ -336,7 +345,8 @@ window.assignManager = {
|
||||
tab.index + 1,
|
||||
tab.active,
|
||||
siteSettings.neverAsk,
|
||||
openTabId
|
||||
openTabId,
|
||||
tab.groupId
|
||||
);
|
||||
}
|
||||
this.calculateContextMenu(tab);
|
||||
@@ -727,7 +737,15 @@ window.assignManager = {
|
||||
});
|
||||
},
|
||||
|
||||
reloadPageInDefaultContainer(url, index, active, openerTabId) {
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {number} index
|
||||
* @param {boolean} active
|
||||
* @param {number} [openerTabId]
|
||||
* @param {number} [groupId]
|
||||
* @returns {void}
|
||||
*/
|
||||
reloadPageInDefaultContainer(url, index, active, openerTabId, groupId) {
|
||||
// To create a new tab in the default container, it is easiest just to omit the
|
||||
// cookieStoreId entirely.
|
||||
//
|
||||
@@ -746,16 +764,58 @@ window.assignManager = {
|
||||
// does not automatically return to the original opener tab. To get this desired behaviour,
|
||||
// we MUST specify the openerTabId when creating the new tab.
|
||||
const cookieStoreId = "firefox-default";
|
||||
browser.tabs.create({url, cookieStoreId, index, active, openerTabId});
|
||||
this.createTabWrapper(url, cookieStoreId, index, active, openerTabId, groupId);
|
||||
},
|
||||
|
||||
reloadPageInContainer(url, currentUserContextId, userContextId, index, active, neverAsk = false, openerTabId = null) {
|
||||
|
||||
/**
|
||||
* Wraps around `browser.tabs.create` and `browser.tabs.group` to create a
|
||||
* tab and ensure that it ends up in the requested tab group, if applicable.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {string} cookieStoreId
|
||||
* @param {number} index
|
||||
* @param {boolean} active
|
||||
* @param {number} openerTabId
|
||||
* @param {number} [groupId]
|
||||
* @returns {Promise<Tab>}
|
||||
*/
|
||||
async createTabWrapper(url, cookieStoreId, index, active, openerTabId, groupId) {
|
||||
const newTab = await browser.tabs.create({
|
||||
url,
|
||||
cookieStoreId,
|
||||
index,
|
||||
active,
|
||||
openerTabId,
|
||||
});
|
||||
|
||||
if (groupId && groupId !== TAB_GROUP_ID_NONE && browser.tabs.group) {
|
||||
// If the original tab was in a tab group, make sure that the reopened tab
|
||||
// stays in the same tab group.
|
||||
await browser.tabs.group({ groupId, tabIds: newTab.id });
|
||||
}
|
||||
|
||||
return newTab;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {string} currentUserContextId
|
||||
* @param {string} userContextId
|
||||
* @param {number} index
|
||||
* @param {boolean} active
|
||||
* @param {boolean} [neverAsk=false]
|
||||
* @param {number} [openerTabId=null]
|
||||
* @param {number} [groupId]
|
||||
* @returns {Promise<Tab>}
|
||||
*/
|
||||
reloadPageInContainer(url, currentUserContextId, userContextId, index, active, neverAsk = false, openerTabId = null, groupId = undefined) {
|
||||
const cookieStoreId = backgroundLogic.cookieStoreId(userContextId);
|
||||
const loadPage = browser.runtime.getURL("confirm-page.html");
|
||||
// False represents assignment is not permitted
|
||||
// If the user has explicitly checked "Never Ask Again" on the warning page we will send them straight there
|
||||
if (neverAsk) {
|
||||
return browser.tabs.create({url, cookieStoreId, index, active, openerTabId});
|
||||
return this.createTabWrapper(url, cookieStoreId, index, active, openerTabId, groupId);
|
||||
} else {
|
||||
let confirmUrl = `${loadPage}?url=${this.encodeURLProperty(url)}&cookieStoreId=${cookieStoreId}`;
|
||||
let currentCookieStoreId;
|
||||
@@ -763,13 +823,14 @@ window.assignManager = {
|
||||
currentCookieStoreId = backgroundLogic.cookieStoreId(currentUserContextId);
|
||||
confirmUrl += `¤tCookieStoreId=${currentCookieStoreId}`;
|
||||
}
|
||||
return browser.tabs.create({
|
||||
url: confirmUrl,
|
||||
cookieStoreId: currentCookieStoreId,
|
||||
openerTabId,
|
||||
return this.createTabWrapper(
|
||||
confirmUrl,
|
||||
currentCookieStoreId,
|
||||
index,
|
||||
active
|
||||
}).then(() => {
|
||||
active,
|
||||
openerTabId,
|
||||
groupId
|
||||
).then(() => {
|
||||
// We don't want to sync this URL ever nor clutter the users history
|
||||
browser.history.deleteUrl({url: confirmUrl});
|
||||
}).catch((e) => {
|
||||
|
||||
Reference in New Issue
Block a user