Skip to content

Commit

Permalink
♻️ Use TabManager in ext-tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
trickypr committed Apr 26, 2024
1 parent d6b9949 commit b05f000
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 107 deletions.
8 changes: 8 additions & 0 deletions apps/extensions/lib/parent/ext-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ class TabManager extends TabManagerBase {
wrapTab(nativeTab) {
return new Tab(this.extension, nativeTab, nativeTab.view.browserId || -1)
}

/**
* @param {NativeTab} nativeTab
* @public
*/
publicWrapTab(nativeTab) {
return this.wrapTab(nativeTab)
}
}

extensions.on('startup', (type, extension) => {
Expand Down
155 changes: 54 additions & 101 deletions apps/extensions/lib/parent/ext-tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ this.tabs = class extends ExtensionAPIPersistent {
PERSISTENT_EVENTS = {}

/**
* @param {BaseContext} context
* @returns {tabs__tabs.ApiGetterReturn}
*/
getAPI(context) {
Expand All @@ -76,140 +77,90 @@ this.tabs = class extends ExtensionAPIPersistent {
* @param {number} tabId
*/
async function get(tabId) {
const window = [...lazy.WindowTracker.registeredWindows.values()].find(
(window) =>
window.windowTabs().some((tab) => tab.view.browserId === tabId),
)
const tab = extension.tabManager.get(tabId)

if (!window) {
if (!tab) {
return Promise.reject({
message: `Cannot find tab matching the id ${tabId}`,
})
}

const tab = window
.windowTabs()
.find((tab) => tab.view.browserId === tabId)
return tab
}

if (!tab) {
return Promise.reject({
message: `Cannot find tab matching the id ${tabId}`,
})
/**
* @param {number} [tabId]
*/
async function getTabOrActive(tabId) {
/** @type {TabBase} */
let tab

if (tabId) {
tab = extension.tabManager.get(tabId)
} else {
const nativeTab = lazy.WindowTracker.getActiveWindow()?.activeTab()
if (!nativeTab) {
return Promise.reject({
message: 'Could not find active tab',
})
}
tab = extension.tabManager.publicWrapTab(nativeTab)
}

return { tab, window }
return tab
}

return {
tabs: {
async get(tabId) {
const { tab, window } = await get(tabId)
return serialize(extension)([tab, window])
const tab = await get(tabId)
return tab.convert()
},

async goBack(tabId) {
let tab

if (tabId) {
tab = await get(tabId).then((all) => all.tab)
} else {
tab = lazy.WindowTracker.getActiveWindow()?.activeTab()
if (!tab) {
return
}
}
const complete = new Promise((res) => {
/** @param {boolean} isLoading */
function complete(isLoading) {
if (isLoading) {
return
}
tab.view.events.off('loadingChange', complete)
res(undefined)
}

tab.view.events.on('loadingChange', complete)
})
tab.view.browser.goBack()
return complete
const tab = await getTabOrActive(tabId)
tab.browser.goBack()
},

async goForward(tabId) {
let tab

if (tabId) {
tab = await get(tabId).then((all) => all.tab)
} else {
tab = lazy.WindowTracker.getActiveWindow()?.activeTab()
if (!tab) {
return
}
}

const complete = new Promise((res) => {
/** @param {boolean} isLoading */
function complete(isLoading) {
if (isLoading) {
return
}
tab.view.events.off('loadingChange', complete)
res(undefined)
}

tab.view.events.on('loadingChange', complete)
})
tab.view.browser.goForward()
return complete
const tab = await getTabOrActive(tabId)
tab.browser.goForward()
},

async query(queryInfo) {
return query(queryInfo).map(serialize(extension))
return Array.from(extension.tabManager.query(queryInfo, context)).map(
(tab) => tab.convert(),
)
},

async remove(tabIds) {
const windows = [...lazy.WindowTracker.registeredWindows.entries()]

if (typeof tabIds === 'number') {
for (const window of windows.map((w) => w[1])) {
const tabs = window.windowTabs()
for (const tab of tabs) {
if (tab.view.browserId === tabIds) {
return window.windowTabs.update((tabs) =>
tabs.filter((tab) => tab.view.browserId !== tabIds),
)
}
}
}
async remove(tabSelector) {
const tabIds =
typeof tabSelector == 'number' ? [tabSelector] : tabSelector

return
}
const windows = [...lazy.WindowTracker.registeredWindows.entries()]

for (const window of windows.map((w) => w[1])) {
const tabs = window.windowTabs()
for (const tab of tabs) {
if (tabIds.includes(tab.view.browserId || -1)) {
window.windowTabs.update((tabs) =>
tabs.filter(
(tab) => !tabIds.includes(tab.view.browserId || -1),
),
)
break
}

if (tabs.some((tab) => tabIds.includes(tab.view.browserId || -1))) {
window.windowTabs.update((tabs) =>
tabs.filter(
(tab) => !tabIds.includes(tab.view.browserId || -1),
),
)
}
}
},

async reload(tabIds) {
if (typeof tabIds === 'number') {
const { tab } = await get(tabIds)
tab.view.browser.reload()
return
}
async reload(tabSelector) {
const tabIds =
typeof tabSelector == 'number' ? [tabSelector] : tabSelector

for (const id of tabIds) {
const { tab } = await get(id)
tab.view.browser.reload()
}
await Promise.all(
tabIds
.map((id) => get(id))
.map((tab) => tab.then((tab) => tab.browser.reload())),
)
},

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

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

window.windowTabs.update((tabs) =>
Expand Down Expand Up @@ -267,7 +219,8 @@ this.tabs = class extends ExtensionAPIPersistent {
}

if (retTab) {
return serialize(extension)([retTab, window])
const tab = extension.tabManager.getWrapper(retTab)
return tab?.convert()
}

return
Expand Down
11 changes: 5 additions & 6 deletions apps/extensions/lib/types/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ declare global {
type XULElement = Element

interface Extension extends ToolkitExtension {
tabManager: TabManagerBase
tabManager: TabManagerBase & { publicWrapTab(nativeTab: NativeTab): Tab }
manifest: Omit<browser._manifest.WebExtensionManifest, 'browser_action'> &
browser_action__manifest.WebExtensionManifest__extended
}
Expand Down Expand Up @@ -174,7 +174,7 @@ declare global {
extension: Extension
destroy(): void
onManifestEntry(entry: any): void
getAPI(context: any): void
getAPI(context: BaseContext): unknown
}
/**
* Subclass to add APIs commonly used with persistent events.
Expand Down Expand Up @@ -250,7 +250,7 @@ declare global {
_lastError: any
contextId: any
unloaded: boolean
extension: any
extension: Extension
manifestVersion: any
jsonSandbox: any
active: boolean
Expand Down Expand Up @@ -1214,12 +1214,11 @@ declare global {
*
* @param queryInfo An object containing properties on which to filter.
* @param context The extension context for which the matching is being performed.
* @returns Iterator<TabBase>
*/
query(
queryInfo?: object | null,
context?: BaseContext | null,
): Iterator<TabBase>
): Iterable<TabBase>

/**
* Returns a TabBase wrapper for the tab with the given ID.
Expand Down Expand Up @@ -1390,7 +1389,7 @@ declare global {
* @readonly
* @abstract
*/
abstract readonly browser: XULElement
abstract readonly browser: XULBrowserElement

/**
* @property browsingContext
Expand Down

0 comments on commit b05f000

Please sign in to comment.