diff --git a/apps/extensions/lib/parent/ext-tabs.js b/apps/extensions/lib/parent/ext-tabs.js index fe92a94..7f8b24a 100644 --- a/apps/extensions/lib/parent/ext-tabs.js +++ b/apps/extensions/lib/parent/ext-tabs.js @@ -13,7 +13,6 @@ */ function query(queryInfo) { const windows = [...lazy.WindowTracker.registeredWindows.entries()] - console.log(queryInfo) const urlMatchSet = (queryInfo.url && @@ -90,6 +89,39 @@ this.tabs = class extends ExtensionAPIPersistent { async query(queryInfo) { return query(queryInfo).map(serialize(extension)) }, + + 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), + ) + } + } + } + + return + } + + 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 + } + } + } + }, }, } } diff --git a/apps/extensions/lib/schemaTypes/tabs.d.ts b/apps/extensions/lib/schemaTypes/tabs.d.ts index 902d978..21ee398 100644 --- a/apps/extensions/lib/schemaTypes/tabs.d.ts +++ b/apps/extensions/lib/schemaTypes/tabs.d.ts @@ -29,6 +29,7 @@ declare module tabs__tabs { type ApiGetterReturn = { tabs: { query: (queryInfo: QueryInfo) => Promise + remove: (tabIds: number | number[]) => unknown } } } diff --git a/apps/extensions/lib/schemas/tabs.json b/apps/extensions/lib/schemas/tabs.json index 284735a..a51e763 100644 --- a/apps/extensions/lib/schemas/tabs.json +++ b/apps/extensions/lib/schemas/tabs.json @@ -104,6 +104,20 @@ "$ref": "Tab" } } + }, + { + "name": "remove", + "type": "function", + "async": true, + "parameters": [ + { + "name": "tabIds", + "choices": [ + { "type": "integer" }, + { "type": "array", "items": { "type": "integer" } } + ] + } + ] } ] } diff --git a/apps/tests/integrations/extensions/tabs.mjs b/apps/tests/integrations/extensions/tabs.mjs index 20838a1..0f39daa 100644 --- a/apps/tests/integrations/extensions/tabs.mjs +++ b/apps/tests/integrations/extensions/tabs.mjs @@ -1,3 +1,6 @@ +/* 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 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // @ts-check /// /// @@ -57,7 +60,6 @@ await TestManager.withBrowser( const windowResults = await b.tabs.query({ windowId, }) - console.log(JSON.stringify(windowResults)) b.test.assertEq( 2, windowResults.length, @@ -93,5 +95,54 @@ await TestManager.withBrowser( .then((e) => e.awaitMsg('done')) .then((e) => e.unload()) }) + + await TestManager.test('tabs - Remove', async (test) => { + const extension = ExtensionTestUtils.loadExtension( + { + manifest: { + permissions: ['tabs'], + }, + async background() { + /** @type {import('resource://app/modules/ExtensionTestUtils.sys.mjs').TestBrowser} */ + const b = this.browser + + b.test.onMessage.addListener(async (msg) => { + const windowId = Number(msg) + + const windowResults = await b.tabs.query({ + windowId, + }) + b.test.assertEq( + ['https://example.com/', 'https://www.google.com/'].join(','), + [windowResults[0].url, windowResults[1].url].join(','), + 'Window is correctly setup', + ) + + await b.tabs.remove(windowResults[1].id) + + const resultsAfterRemove = await b.tabs.query({ + windowId, + }) + b.test.assertEq(1, resultsAfterRemove.length, 'Only one tab left') + b.test.assertEq( + ['https://example.com/'].join(','), + resultsAfterRemove.map((r) => r.url).join(','), + 'Window is correctly setup', + ) + + b.test.sendMessage('done') + }) + }, + }, + test, + ) + + await extension + .testCount(3) + .startup() + .then((e) => e.sendMsg(window.windowId.toString())) + .then((e) => e.awaitMsg('done')) + .then((e) => e.unload()) + }) }, )