Skip to content

Commit 60c8a41

Browse files
committed
♻️ Use TabManager in ext-tabs
1 parent c79fc64 commit 60c8a41

File tree

3 files changed

+67
-107
lines changed

3 files changed

+67
-107
lines changed

apps/extensions/lib/parent/ext-browser.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ class TabManager extends TabManagerBase {
192192
wrapTab(nativeTab) {
193193
return new Tab(this.extension, nativeTab, nativeTab.view.browserId || -1)
194194
}
195+
196+
/**
197+
* @param {NativeTab} nativeTab
198+
* @public
199+
*/
200+
publicWrapTab(nativeTab) {
201+
return this.wrapTab(nativeTab)
202+
}
195203
}
196204

197205
extensions.on('startup', (type, extension) => {

apps/extensions/lib/parent/ext-tabs.js

Lines changed: 54 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ this.tabs = class extends ExtensionAPIPersistent {
6767
PERSISTENT_EVENTS = {}
6868

6969
/**
70+
* @param {BaseContext} context
7071
* @returns {tabs__tabs.ApiGetterReturn}
7172
*/
7273
getAPI(context) {
@@ -76,140 +77,90 @@ this.tabs = class extends ExtensionAPIPersistent {
7677
* @param {number} tabId
7778
*/
7879
async function get(tabId) {
79-
const window = [...lazy.WindowTracker.registeredWindows.values()].find(
80-
(window) =>
81-
window.windowTabs().some((tab) => tab.view.browserId === tabId),
82-
)
80+
const tab = extension.tabManager.get(tabId)
8381

84-
if (!window) {
82+
if (!tab) {
8583
return Promise.reject({
8684
message: `Cannot find tab matching the id ${tabId}`,
8785
})
8886
}
8987

90-
const tab = window
91-
.windowTabs()
92-
.find((tab) => tab.view.browserId === tabId)
88+
return tab
89+
}
9390

94-
if (!tab) {
95-
return Promise.reject({
96-
message: `Cannot find tab matching the id ${tabId}`,
97-
})
91+
/**
92+
* @param {number} [tabId]
93+
*/
94+
async function getTabOrActive(tabId) {
95+
/** @type {TabBase} */
96+
let tab
97+
98+
if (tabId) {
99+
tab = extension.tabManager.get(tabId)
100+
} else {
101+
const nativeTab = lazy.WindowTracker.getActiveWindow()?.activeTab()
102+
if (!nativeTab) {
103+
return Promise.reject({
104+
message: 'Could not find active tab',
105+
})
106+
}
107+
tab = extension.tabManager.publicWrapTab(nativeTab)
98108
}
99109

100-
return { tab, window }
110+
return tab
101111
}
102112

103113
return {
104114
tabs: {
105115
async get(tabId) {
106-
const { tab, window } = await get(tabId)
107-
return serialize(extension)([tab, window])
116+
const tab = await get(tabId)
117+
return tab.convert()
108118
},
109119

110120
async goBack(tabId) {
111-
let tab
112-
113-
if (tabId) {
114-
tab = await get(tabId).then((all) => all.tab)
115-
} else {
116-
tab = lazy.WindowTracker.getActiveWindow()?.activeTab()
117-
if (!tab) {
118-
return
119-
}
120-
}
121-
const complete = new Promise((res) => {
122-
/** @param {boolean} isLoading */
123-
function complete(isLoading) {
124-
if (isLoading) {
125-
return
126-
}
127-
tab.view.events.off('loadingChange', complete)
128-
res(undefined)
129-
}
130-
131-
tab.view.events.on('loadingChange', complete)
132-
})
133-
tab.view.browser.goBack()
134-
return complete
121+
const tab = await getTabOrActive(tabId)
122+
tab.browser.goBack()
135123
},
136124

137125
async goForward(tabId) {
138-
let tab
139-
140-
if (tabId) {
141-
tab = await get(tabId).then((all) => all.tab)
142-
} else {
143-
tab = lazy.WindowTracker.getActiveWindow()?.activeTab()
144-
if (!tab) {
145-
return
146-
}
147-
}
148-
149-
const complete = new Promise((res) => {
150-
/** @param {boolean} isLoading */
151-
function complete(isLoading) {
152-
if (isLoading) {
153-
return
154-
}
155-
tab.view.events.off('loadingChange', complete)
156-
res(undefined)
157-
}
158-
159-
tab.view.events.on('loadingChange', complete)
160-
})
161-
tab.view.browser.goForward()
162-
return complete
126+
const tab = await getTabOrActive(tabId)
127+
tab.browser.goForward()
163128
},
164129

165130
async query(queryInfo) {
166-
return query(queryInfo).map(serialize(extension))
131+
return Array.from(extension.tabManager.query(queryInfo, context)).map(
132+
(tab) => tab.convert(),
133+
)
167134
},
168135

169-
async remove(tabIds) {
170-
const windows = [...lazy.WindowTracker.registeredWindows.entries()]
171-
172-
if (typeof tabIds === 'number') {
173-
for (const window of windows.map((w) => w[1])) {
174-
const tabs = window.windowTabs()
175-
for (const tab of tabs) {
176-
if (tab.view.browserId === tabIds) {
177-
return window.windowTabs.update((tabs) =>
178-
tabs.filter((tab) => tab.view.browserId !== tabIds),
179-
)
180-
}
181-
}
182-
}
136+
async remove(tabSelector) {
137+
const tabIds =
138+
typeof tabSelector == 'number' ? [tabSelector] : tabSelector
183139

184-
return
185-
}
140+
const windows = [...lazy.WindowTracker.registeredWindows.entries()]
186141

187142
for (const window of windows.map((w) => w[1])) {
188143
const tabs = window.windowTabs()
189-
for (const tab of tabs) {
190-
if (tabIds.includes(tab.view.browserId || -1)) {
191-
window.windowTabs.update((tabs) =>
192-
tabs.filter(
193-
(tab) => !tabIds.includes(tab.view.browserId || -1),
194-
),
195-
)
196-
break
197-
}
144+
145+
if (tabs.some((tab) => tabIds.includes(tab.view.browserId || -1))) {
146+
window.windowTabs.update((tabs) =>
147+
tabs.filter(
148+
(tab) => !tabIds.includes(tab.view.browserId || -1),
149+
),
150+
)
198151
}
199152
}
200153
},
201154

202-
async reload(tabIds) {
203-
if (typeof tabIds === 'number') {
204-
const { tab } = await get(tabIds)
205-
tab.view.browser.reload()
206-
return
207-
}
155+
async reload(tabSelector) {
156+
const tabIds =
157+
typeof tabSelector == 'number' ? [tabSelector] : tabSelector
208158

209-
for (const id of tabIds) {
210-
const { tab } = await get(id)
211-
tab.view.browser.reload()
212-
}
159+
await Promise.all(
160+
tabIds
161+
.map((id) => get(id))
162+
.map((tab) => tab.then((tab) => tab.browser.reload())),
163+
)
213164
},
214165

215166
async update(tabId, updateProperties) {
@@ -223,6 +174,7 @@ this.tabs = class extends ExtensionAPIPersistent {
223174
}
224175

225176
let errors = null
177+
/** @type {import("@browser/tabs").WindowTab | undefined} */
226178
let retTab
227179

228180
window.windowTabs.update((tabs) =>
@@ -267,7 +219,8 @@ this.tabs = class extends ExtensionAPIPersistent {
267219
}
268220

269221
if (retTab) {
270-
return serialize(extension)([retTab, window])
222+
const tab = extension.tabManager.getWrapper(retTab)
223+
return tab?.convert()
271224
}
272225

273226
return

apps/extensions/lib/types/utils.d.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ declare global {
1616
type XULElement = Element
1717

1818
interface Extension extends ToolkitExtension {
19-
tabManager: TabManagerBase
19+
tabManager: TabManagerBase & { publicWrapTab(nativeTab: NativeTab): Tab }
2020
manifest: Omit<browser._manifest.WebExtensionManifest, 'browser_action'> &
2121
browser_action__manifest.WebExtensionManifest__extended
2222
}
@@ -174,7 +174,7 @@ declare global {
174174
extension: Extension
175175
destroy(): void
176176
onManifestEntry(entry: any): void
177-
getAPI(context: any): void
177+
getAPI(context: BaseContext): unknown
178178
}
179179
/**
180180
* Subclass to add APIs commonly used with persistent events.
@@ -250,7 +250,7 @@ declare global {
250250
_lastError: any
251251
contextId: any
252252
unloaded: boolean
253-
extension: any
253+
extension: Extension
254254
manifestVersion: any
255255
jsonSandbox: any
256256
active: boolean
@@ -1214,12 +1214,11 @@ declare global {
12141214
*
12151215
* @param queryInfo An object containing properties on which to filter.
12161216
* @param context The extension context for which the matching is being performed.
1217-
* @returns Iterator<TabBase>
12181217
*/
12191218
query(
12201219
queryInfo?: object | null,
12211220
context?: BaseContext | null,
1222-
): Iterator<TabBase>
1221+
): Iterable<TabBase>
12231222

12241223
/**
12251224
* Returns a TabBase wrapper for the tab with the given ID.
@@ -1390,7 +1389,7 @@ declare global {
13901389
* @readonly
13911390
* @abstract
13921391
*/
1393-
abstract readonly browser: XULElement
1392+
abstract readonly browser: XULBrowserElement
13941393

13951394
/**
13961395
* @property browsingContext

0 commit comments

Comments
 (0)