From b05f000e3bd7930ff7cf50f309b808b9271c016c Mon Sep 17 00:00:00 2001 From: TrickyPR <23250792+trickypr@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:38:23 +1000 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Use=20TabManager=20in=20ex?= =?UTF-8?q?t-tabs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/extensions/lib/parent/ext-browser.js | 8 ++ apps/extensions/lib/parent/ext-tabs.js | 155 ++++++++-------------- apps/extensions/lib/types/utils.d.ts | 11 +- 3 files changed, 67 insertions(+), 107 deletions(-) diff --git a/apps/extensions/lib/parent/ext-browser.js b/apps/extensions/lib/parent/ext-browser.js index afc79e7..5058fed 100644 --- a/apps/extensions/lib/parent/ext-browser.js +++ b/apps/extensions/lib/parent/ext-browser.js @@ -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) => { diff --git a/apps/extensions/lib/parent/ext-tabs.js b/apps/extensions/lib/parent/ext-tabs.js index ab00470..d9f869f 100644 --- a/apps/extensions/lib/parent/ext-tabs.js +++ b/apps/extensions/lib/parent/ext-tabs.js @@ -67,6 +67,7 @@ this.tabs = class extends ExtensionAPIPersistent { PERSISTENT_EVENTS = {} /** + * @param {BaseContext} context * @returns {tabs__tabs.ApiGetterReturn} */ getAPI(context) { @@ -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) { @@ -223,6 +174,7 @@ this.tabs = class extends ExtensionAPIPersistent { } let errors = null + /** @type {import("@browser/tabs").WindowTab | undefined} */ let retTab window.windowTabs.update((tabs) => @@ -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 diff --git a/apps/extensions/lib/types/utils.d.ts b/apps/extensions/lib/types/utils.d.ts index 476b1b4..97b7b17 100644 --- a/apps/extensions/lib/types/utils.d.ts +++ b/apps/extensions/lib/types/utils.d.ts @@ -16,7 +16,7 @@ declare global { type XULElement = Element interface Extension extends ToolkitExtension { - tabManager: TabManagerBase + tabManager: TabManagerBase & { publicWrapTab(nativeTab: NativeTab): Tab } manifest: Omit & browser_action__manifest.WebExtensionManifest__extended } @@ -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. @@ -250,7 +250,7 @@ declare global { _lastError: any contextId: any unloaded: boolean - extension: any + extension: Extension manifestVersion: any jsonSandbox: any active: boolean @@ -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 */ query( queryInfo?: object | null, context?: BaseContext | null, - ): Iterator + ): Iterable /** * Returns a TabBase wrapper for the tab with the given ID. @@ -1390,7 +1389,7 @@ declare global { * @readonly * @abstract */ - abstract readonly browser: XULElement + abstract readonly browser: XULBrowserElement /** * @property browsingContext