lib/tabs.ts: enable accessing all tabs through tri.tabs

This commit is contained in:
glacambre 2024-01-26 18:56:17 +01:00
parent a0e4060a94
commit 1522b0e2dc
2 changed files with 19 additions and 12 deletions

View file

@ -5890,9 +5890,19 @@ export async function js(...str: string[]) {
* - Get the URL of the tab whose id 3:
* `:jsb tri.tabs[3].location.href.then(console.log)`
* - Set the title of the tab whose id is 6:
* `:jsb tri.tabs[3].document.title = "New title!"`
* - Run `alert()` in all tabs:
* `:jsb browser.tabs.query({}).then(tabs => tabs.forEach(tab => tri.tabs[tab.id].tri.excmds.js('alert()')))`
* `:jsb tri.tabs[6].document.title = "New title!"`
* - Run `alert()` in a tab whose id is 9:
* `:jsb tri.tabs[9].alert()`
*
* You can also directly access the corresonding property in all tabs by using
* the "tabs" object itself, e.g.
*
* - Build a string containing the id of the active element of each tab:
* `:jsb tri.tabs.document.activeElement.id.then(ids => ids.reduce(s, id => s + " " + id))`
* - Scroll all tabs to the tenth pixel:
* `:jsb tri.tabs.document.documentElement.scrollTop = 10`
* - Use tridactyl's JS ex command to perform a complex computation:
* `:jsb tri.tabs.tri.excmds.js("let x = 1; let y = 2; x + y").then(console.log)`
*
* When fetching a value or running a function in a tab through the `tabs` property, the returned value is a Promise and must be awaited.
* Setting values through the `tab` property is asynchronous too and there is no way to await this operation.

View file

@ -2,9 +2,6 @@ import * as Messaging from "@src/lib/messaging"
const allTabs = -1
// Small wrapper meant to enable sending a message either to a single tab or
// multiple ones. Note that for now, sending messages to all tabs does not
// work, for reasons unknown.
const msg = (tabId, ...args) => {
if (tabId === allTabs) {
return Messaging.messageAllTabs("omniscient_content", ...args)
@ -80,11 +77,11 @@ export const tabsProxy = new Proxy(Object.create(null), {
// for a single tab
return tabProxy(id, [])
}
throw Error("Foreground tabs proxy needs to be indexed by tab ID.")
// Ideally, if p is a string, we should construct a proxy for all
// existing tabs. This unfortunately does not seem to work:
// Messaging.messageAllTab seems to return an array of undefined when
// running e.g. `tabs.document.title`.
// return tabProxy(allTabs, []);
if (typeof p === "string") {
// If `p` is a string, then we return a proxy with a sentinel value
// indicating that the request should be sent to all tabs instead.
return tabProxy(allTabs, [])[p]
}
throw new Error(`'tabs' object can only be accessed by a number (e.g. tabs[3]) or a string (e.g. tabs.document or tabs['document']). Type of accessor: "${typeof p}"`)
},
})