Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
ContextualIdentityService:
"resource://gre/modules/ContextualIdentityService.sys.mjs",
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
});
export class OpenTabsController {
/**
* Checks if a given tab is within a container (contextual identity)
*
* @param {MozTabbrowserTab[]} tab
* Tab to fetch container info on.
* @returns {object[]}
* Container object.
*/
#getContainerObj(tab) {
let userContextId = tab.getAttribute("usercontextid");
let containerObj = null;
if (userContextId) {
containerObj =
lazy.ContextualIdentityService.getPublicIdentityFromId(userContextId);
}
return containerObj;
}
/**
* Gets an array of tab indicators (if any) when normalizing for fxview-tab-list
*
* @param {MozTabbrowserTab[]} tab
* Tab to fetch container info on.
* @returns {Array[]}
* Array of named tab indicators
*/
#getIndicatorsForTab(tab) {
const url = tab.linkedBrowser?.currentURI?.spec || "";
let tabIndicators = [];
let hasAttention =
(tab.pinned &&
(tab.hasAttribute("attention") || tab.hasAttribute("titlechanged"))) ||
(!tab.pinned && tab.hasAttribute("attention"));
if (tab.pinned) {
tabIndicators.push("pinned");
}
if (this.#getContainerObj(tab)) {
tabIndicators.push("container");
}
if (hasAttention) {
tabIndicators.push("attention");
}
if (tab.hasAttribute("soundplaying") && !tab.hasAttribute("muted")) {
tabIndicators.push("soundplaying");
}
if (tab.hasAttribute("muted")) {
tabIndicators.push("muted");
}
if (this.#checkIfPinnedNewTab(url)) {
tabIndicators.push("pinnedOnNewTab");
}
return tabIndicators;
}
/**
* Check if a given url is pinned on the new tab page
*
* @param {string} url
* url to check
* @returns {boolean}
* is tabbed pinned on new tab page
*/
#checkIfPinnedNewTab(url) {
return url && lazy.NewTabUtils.pinnedLinks.isPinned({ url });
}
/**
* Gets the primary l10n id for a tab when normalizing for fxview-tab-list
*
* @param {boolean} isRecentBrowsing
* Whether the tabs are going to be displayed on the Recent Browsing page or not
* @param {Array[]} tabIndicators
* Array of tab indicators for the given tab
* @returns {string}
* L10n ID string
*/
getPrimaryL10nId(isRecentBrowsing, tabIndicators) {
let indicatorL10nId = null;
if (isRecentBrowsing) {
return indicatorL10nId;
}
if (
tabIndicators?.includes("pinned") &&
tabIndicators?.includes("bookmark")
) {
indicatorL10nId = "firefoxview-opentabs-bookmarked-pinned-tab";
} else if (tabIndicators?.includes("pinned")) {
indicatorL10nId = "firefoxview-opentabs-pinned-tab";
} else if (tabIndicators?.includes("bookmark")) {
indicatorL10nId = "firefoxview-opentabs-bookmarked-tab";
}
return indicatorL10nId;
}
/**
* Gets the primary l10n args for a tab when normalizing for fxview-tab-list
*
* @param {MozTabbrowserTab[]} tab
* Tab to fetch container info on.
* @param {boolean} isRecentBrowsing
* Whether the tabs are going to be displayed on the Recent Browsing page or not
* @param {string} url
* URL for the given tab
* @returns {string}
* L10n ID args
*/
#getPrimaryL10nArgs(tab, isRecentBrowsing, url) {
return JSON.stringify({ tabTitle: tab.label, url });
}
/**
* Convert a list of tabs into the format expected by the fxview-tab-list
* component.
*
* @param {MozTabbrowserTab[]} tabs
* Tabs to format.
* @param {boolean} isRecentBrowsing
* Whether the tabs are going to be displayed on the Recent Browsing page or not
* @returns {object[]}
* Formatted objects.
*/
getTabListItems(tabs, isRecentBrowsing) {
let filtered = tabs?.filter(tab => !tab.closing && !tab.hidden);
return filtered.map(tab => {
let tabIndicators = this.#getIndicatorsForTab(tab);
let containerObj = this.#getContainerObj(tab);
const url = tab?.linkedBrowser?.currentURI?.spec || "";
return {
containerObj,
indicators: tabIndicators,
icon: tab.getAttribute("image"),
primaryL10nId: this.getPrimaryL10nId(isRecentBrowsing, tabIndicators),
primaryL10nArgs: this.#getPrimaryL10nArgs(tab, isRecentBrowsing, url),
secondaryL10nId:
isRecentBrowsing || (!isRecentBrowsing && !tab.pinned)
? "fxviewtabrow-options-menu-button"
: null,
secondaryL10nArgs:
isRecentBrowsing || (!isRecentBrowsing && !tab.pinned)
? JSON.stringify({ tabTitle: tab.label })
: null,
tertiaryL10nId:
isRecentBrowsing || (!isRecentBrowsing && !tab.pinned)
? "fxviewtabrow-close-tab-button"
: null,
tertiaryL10nArgs:
isRecentBrowsing || (!isRecentBrowsing && !tab.pinned)
? JSON.stringify({ tabTitle: tab.label })
: null,
tabElement: tab,
time: tab.lastSeenActive,
title: tab.label,
url,
};
});
}
}