OpenTabsController.sys.mjs (5447B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const lazy = {}; 6 7 ChromeUtils.defineESModuleGetters(lazy, { 8 ContextualIdentityService: 9 "resource://gre/modules/ContextualIdentityService.sys.mjs", 10 NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs", 11 }); 12 13 export class OpenTabsController { 14 /** 15 * Checks if a given tab is within a container (contextual identity) 16 * 17 * @param {MozTabbrowserTab[]} tab 18 * Tab to fetch container info on. 19 * @returns {object[]} 20 * Container object. 21 */ 22 #getContainerObj(tab) { 23 let userContextId = tab.getAttribute("usercontextid"); 24 let containerObj = null; 25 if (userContextId) { 26 containerObj = 27 lazy.ContextualIdentityService.getPublicIdentityFromId(userContextId); 28 } 29 return containerObj; 30 } 31 32 /** 33 * Gets an array of tab indicators (if any) when normalizing for fxview-tab-list 34 * 35 * @param {MozTabbrowserTab[]} tab 36 * Tab to fetch container info on. 37 * @returns {Array[]} 38 * Array of named tab indicators 39 */ 40 #getIndicatorsForTab(tab) { 41 const url = tab.linkedBrowser?.currentURI?.spec || ""; 42 let tabIndicators = []; 43 let hasAttention = 44 (tab.pinned && 45 (tab.hasAttribute("attention") || tab.hasAttribute("titlechanged"))) || 46 (!tab.pinned && tab.hasAttribute("attention")); 47 48 if (tab.pinned) { 49 tabIndicators.push("pinned"); 50 } 51 if (this.#getContainerObj(tab)) { 52 tabIndicators.push("container"); 53 } 54 if (hasAttention) { 55 tabIndicators.push("attention"); 56 } 57 if (tab.hasAttribute("soundplaying") && !tab.hasAttribute("muted")) { 58 tabIndicators.push("soundplaying"); 59 } 60 if (tab.hasAttribute("muted")) { 61 tabIndicators.push("muted"); 62 } 63 if (this.#checkIfPinnedNewTab(url)) { 64 tabIndicators.push("pinnedOnNewTab"); 65 } 66 67 return tabIndicators; 68 } 69 70 /** 71 * Check if a given url is pinned on the new tab page 72 * 73 * @param {string} url 74 * url to check 75 * @returns {boolean} 76 * is tabbed pinned on new tab page 77 */ 78 #checkIfPinnedNewTab(url) { 79 return url && lazy.NewTabUtils.pinnedLinks.isPinned({ url }); 80 } 81 82 /** 83 * Gets the primary l10n id for a tab when normalizing for fxview-tab-list 84 * 85 * @param {boolean} isRecentBrowsing 86 * Whether the tabs are going to be displayed on the Recent Browsing page or not 87 * @param {Array[]} tabIndicators 88 * Array of tab indicators for the given tab 89 * @returns {string} 90 * L10n ID string 91 */ 92 getPrimaryL10nId(isRecentBrowsing, tabIndicators) { 93 let indicatorL10nId = null; 94 if (isRecentBrowsing) { 95 return indicatorL10nId; 96 } 97 if ( 98 tabIndicators?.includes("pinned") && 99 tabIndicators?.includes("bookmark") 100 ) { 101 indicatorL10nId = "firefoxview-opentabs-bookmarked-pinned-tab"; 102 } else if (tabIndicators?.includes("pinned")) { 103 indicatorL10nId = "firefoxview-opentabs-pinned-tab"; 104 } else if (tabIndicators?.includes("bookmark")) { 105 indicatorL10nId = "firefoxview-opentabs-bookmarked-tab"; 106 } 107 return indicatorL10nId; 108 } 109 110 /** 111 * Gets the primary l10n args for a tab when normalizing for fxview-tab-list 112 * 113 * @param {MozTabbrowserTab[]} tab 114 * Tab to fetch container info on. 115 * @param {boolean} isRecentBrowsing 116 * Whether the tabs are going to be displayed on the Recent Browsing page or not 117 * @param {string} url 118 * URL for the given tab 119 * @returns {string} 120 * L10n ID args 121 */ 122 #getPrimaryL10nArgs(tab, isRecentBrowsing, url) { 123 return JSON.stringify({ tabTitle: tab.label, url }); 124 } 125 126 /** 127 * Convert a list of tabs into the format expected by the fxview-tab-list 128 * component. 129 * 130 * @param {MozTabbrowserTab[]} tabs 131 * Tabs to format. 132 * @param {boolean} isRecentBrowsing 133 * Whether the tabs are going to be displayed on the Recent Browsing page or not 134 * @returns {object[]} 135 * Formatted objects. 136 */ 137 getTabListItems(tabs, isRecentBrowsing) { 138 let filtered = tabs?.filter(tab => !tab.closing && !tab.hidden); 139 140 return filtered.map(tab => { 141 let tabIndicators = this.#getIndicatorsForTab(tab); 142 let containerObj = this.#getContainerObj(tab); 143 const url = tab?.linkedBrowser?.currentURI?.spec || ""; 144 return { 145 containerObj, 146 indicators: tabIndicators, 147 icon: tab.getAttribute("image"), 148 primaryL10nId: this.getPrimaryL10nId(isRecentBrowsing, tabIndicators), 149 primaryL10nArgs: this.#getPrimaryL10nArgs(tab, isRecentBrowsing, url), 150 secondaryL10nId: 151 isRecentBrowsing || (!isRecentBrowsing && !tab.pinned) 152 ? "fxviewtabrow-options-menu-button" 153 : null, 154 secondaryL10nArgs: 155 isRecentBrowsing || (!isRecentBrowsing && !tab.pinned) 156 ? JSON.stringify({ tabTitle: tab.label }) 157 : null, 158 tertiaryL10nId: 159 isRecentBrowsing || (!isRecentBrowsing && !tab.pinned) 160 ? "fxviewtabrow-close-tab-button" 161 : null, 162 tertiaryL10nArgs: 163 isRecentBrowsing || (!isRecentBrowsing && !tab.pinned) 164 ? JSON.stringify({ tabTitle: tab.label }) 165 : null, 166 tabElement: tab, 167 time: tab.lastSeenActive, 168 title: tab.label, 169 url, 170 }; 171 }); 172 } 173 }