mirror of
https://github.com/tridactyl/tridactyl.git
synced 2026-09-10 07:16:33 -04:00
Merge pull request #5235 from tridactyl/better-webrequest-autocmds
Better webrequest autocmds
This commit is contained in:
commit
dc18d58edc
|
|
@ -195,27 +195,6 @@ for (const requestEvent of webrequests.requestEvents) {
|
|||
})
|
||||
}
|
||||
|
||||
config.addChangeListener("autocmds", (previous, current) =>
|
||||
webrequests.requestEvents.forEach(
|
||||
requestEvent =>
|
||||
// If there are autocmd(s) for this requestEvent
|
||||
current[requestEvent] !== undefined &&
|
||||
Object.entries(
|
||||
current[requestEvent] as Record<string, string>,
|
||||
).forEach(([pattern, func]) => {
|
||||
// R.path returns undefined if any part of the path is missing rather than saying "computer says no"
|
||||
const path = R.path([requestEvent, pattern])
|
||||
|
||||
// If this is a new autocmd, register it
|
||||
path(current) !== path(previous) &&
|
||||
webrequests.registerWebRequestAutocmd(
|
||||
requestEvent,
|
||||
pattern,
|
||||
func,
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
// }}}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const requestEvents = Object.keys(requestEventExpraInfoSpecMap)
|
|||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export const LISTENERS: Record<string, Record<string, Function>> = {}
|
||||
|
||||
export const registerWebRequestAutocmd = (
|
||||
export const registerWebRequestAutocmd = async (
|
||||
requestEvent: string,
|
||||
pattern: string,
|
||||
func: string,
|
||||
|
|
@ -23,16 +23,30 @@ export const registerWebRequestAutocmd = (
|
|||
// I'm being lazy - strictly the functions map strings to void | blocking responses
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const listener = eval(func) as Function
|
||||
|
||||
if (!LISTENERS[requestEvent]) LISTENERS[requestEvent] = {}
|
||||
LISTENERS[requestEvent][pattern] = listener
|
||||
return browser.webRequest["on" + requestEvent].addListener(
|
||||
|
||||
await browser.webRequest["on" + requestEvent].addListener(
|
||||
listener,
|
||||
{ urls: [pattern] },
|
||||
requestEventExpraInfoSpecMap[requestEvent],
|
||||
)
|
||||
const oldListener = LISTENERS[requestEvent][pattern];
|
||||
// Add the new listener to our list if everything was successful
|
||||
LISTENERS[requestEvent][pattern] = listener
|
||||
|
||||
// Remove any previously registered autocmd for the same pattern
|
||||
if (oldListener) {
|
||||
await browser.webRequest["on" + requestEvent].removeListener(
|
||||
oldListener
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const unregisterWebRequestAutocmd = (requestEvent, pattern) =>
|
||||
browser.webRequest["on" + requestEvent].removeListener(
|
||||
LISTENERS[requestEvent][pattern],
|
||||
)
|
||||
export const unregisterWebRequestAutocmd = async (requestEvent, pattern) => {
|
||||
if (LISTENERS[requestEvent] && LISTENERS[requestEvent][pattern]) {
|
||||
await browser.webRequest["on" + requestEvent].removeListener(
|
||||
LISTENERS[requestEvent][pattern],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4725,29 +4725,36 @@ export function getAutocmdEvents() {
|
|||
- DocEnd: When a webpage unloaded/closed or backward/forward in history. Exactly, the [pagehide event](https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event).
|
||||
- TabEnter: When a tab get focus.
|
||||
- TabLeft: When a tab lost focus or closed.
|
||||
|
||||
- A supported webRequest event (AuthRequired, BeforeRedirect, BeforeRequest, BeforeSendHeaders, Completed, ErrorOccured, HeadersReceived, ResponseStarted and SendHeaders): the corresponding [WebExtension webRequest event](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest#Events)
|
||||
|
||||
- The 'HistoryState' event is triggered when a page uses the web history API to change the page location / URI. It should be used in preference to 'UriChange' below since it will use almost no resources. The 'UriChange' event may work on websites where 'HistoryState' does not.
|
||||
- The 'HistoryPushState' is triggered only when a page calls 'history.pushState' to change URI, and 'HistoryReplace' is for 'history.replace'. By the way, the HistoryPopState is not implemented.
|
||||
- The 'UriChange' event is for "single page applications" which change their URIs without triggering DocStart or DocLoad events. It uses a timer to check whether the URI has changed, which has a small impact on battery life on pages matching the `url` parameter. We suggest using it sparingly.
|
||||
*
|
||||
* The 'HistoryState' event is triggered when a page uses the web history API to change the page location / URI. It should be used in preference to 'UriChange' below since it will use almost no resources. The 'UriChange' event may work on websites where 'HistoryState' does not.
|
||||
* @param url type depends on the event
|
||||
*
|
||||
* The 'HistoryPushState' is triggered only when a page call 'history.pushState' to change URI, and 'HistoryReplace' is for 'history.replace'. By the way, the HistoryPopState is not implemented.
|
||||
- For most events (DocStart, DocEnd, TabEnter, TabLeft, ...): a JavaScript regex (e.g. `www\.amazon\.co.*`)
|
||||
- We just use [URL.search](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search)
|
||||
- For TriStart: regular expression that matches the hostname of the computer the autocmd should be run on. This requires the native messenger to be installed, except for the ".*" regular expression which will always be triggered, even without the native messenger.
|
||||
- For webRequest events (AuthRequired, BeforeRedirect, BeforeRequest, BeforeSendHeaders, Completed, ErrorOccured, HeadersReceived, ResponseStarted and SendHeaders): a [URL match pattern](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns)
|
||||
*
|
||||
* The 'UriChange' event is for "single page applications" which change their URIs without triggering DocStart or DocLoad events. It uses a timer to check whether the URI has changed, which has a small impact on battery life on pages matching the `url` parameter. We suggest using it sparingly.
|
||||
*
|
||||
* @param url For DocStart, DocEnd, TabEnter, and TabLeft: a JavaScript regex (e.g. `www\.amazon\.co.*`)
|
||||
*
|
||||
* We just use [URL.search](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search).
|
||||
*
|
||||
* For TriStart: A regular expression that matches the hostname of the computer
|
||||
* the autocmd should be run on. This requires the native messenger to be
|
||||
* installed, except for the ".*" regular expression which will always be
|
||||
* triggered, even without the native messenger.
|
||||
*
|
||||
* For AuthRequired, BeforeRedirect, BeforeRequest, BeforeSendHeaders, Completed, ErrorOccured, HeadersReceived, ResponseStarted and SendHeaders, a [URL match pattern](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns)
|
||||
*
|
||||
* @param excmd The excmd to run (use [[composite]] to run multiple commands), __except__ for AuthRequired, BeforeRedirect, BeforeRequest, BeforeSendHeaders, Completed, ErrorOccured, HeadersReceived, ResponseStarted and SendHeaders, events where it must be an inline JavaScript function which maps [details objects specific to the event](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest#Events) to [blocking responses](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/BlockingResponse). This JavaScript function will run in the background context.
|
||||
*
|
||||
* For example: `autocmd BeforeRequest https://www.bbc.co.uk/* () => ({redirectUrl: "https://old.reddit.com"})`. Note the brackets which ensure JavaScript returns a blocking response object rather than interpreting it as a block statement.
|
||||
*
|
||||
* For DocStart, DocLoad, DocEnd, TabEnter, TabLeft, FullscreenEnter, FullscreenLeft, FullscreenChange and UriChange: magic variables are available which are replaced with the relevant string at runtime:
|
||||
* @param command type depends on the event
|
||||
|
||||
- For most events (DocStart, DocEnd, TabEnter, TabLeft, ...): the excmd to run (use [[composite]] to run multiple commands).
|
||||
- Example for zooming in more on a website:
|
||||
```
|
||||
autocmd DocStart .*example\.com.* zoom 150 false TRI_FIRED_MOZ_TABID
|
||||
```
|
||||
|
||||
- For webRequest events (AuthRequired, BeforeRedirect, BeforeRequest, BeforeSendHeaders, Completed, ErrorOccured, HeadersReceived, ResponseStarted and SendHeaders): the text of a javascript function that should accept a [details objects specific to the event](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest#Events) and return a [blocking response](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/BlockingResponse). This JavaScript function will run in the background context.
|
||||
- Example for redirecting from new to old reddit:
|
||||
```
|
||||
autocmd BeforeRequest https://www.reddit.com/r/* (details) => ({redirectUrl: details.url.replace(/^https:\/\/www\./, "https://old.")})
|
||||
```
|
||||
|
||||
* For non-webRequest events, magic variables are available which are replaced with the relevant string at runtime:
|
||||
|
||||
- `TRI_FIRED_MOZ_TABID`: Provides Mozilla's `tabID` associated with the fired event.
|
||||
- `TRI_FIRED_TRI_TABINDEX`: Provides tridactyls internal tab index associated with the fired event.
|
||||
- `TRI_FIRED_MOZ_WINID`: Provides Mozilla's `windowId` associated with the fired event.
|
||||
|
|
@ -4765,18 +4772,20 @@ export function getAutocmdEvents() {
|
|||
- `TRI_FIRED_PINNED`: Whether the tab is pinned.
|
||||
- `TRI_FIRED_TITLE`: The title of the tab.
|
||||
- `TRI_FIRED_URL`: The URL of the document that the tab is displaying.
|
||||
*
|
||||
* For example: `autocmd DocStart .*example\.com.* zoom 150 false TRI_FIRED_MOZ_TABID`.
|
||||
*
|
||||
|
||||
* For debugging, use `:set logging.autocmds debug` and check the Firefox web console. `WebRequest` events have no logging.
|
||||
*
|
||||
*/
|
||||
//#background
|
||||
export function autocmd(event: string, url: string, ...excmd: string[]) {
|
||||
export async function autocmd(event: string, url: string, ...excmd: string[]) {
|
||||
// rudimentary run time type checking
|
||||
// TODO: Decide on autocmd event names
|
||||
if (!getAutocmdEvents().includes(event)) throw new Error(event + " is not a supported event.")
|
||||
return config.set("autocmds", event, url, excmd.join(" "))
|
||||
if (!getAutocmdEvents().includes(event)) {
|
||||
throw new Error(event + " is not a supported event.");
|
||||
}
|
||||
if (webrequests.requestEvents.includes(event)) {
|
||||
await webrequests.registerWebRequestAutocmd(event, url, excmd.join(" "));
|
||||
}
|
||||
return config.set("autocmds", event, url, excmd.join(" "));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue