···11-# Note: deno.json config and import_map.json are used by Deno.emit.
22-# They are intentionally NOT used by this file
33-44-build:
55- deno run --allow-env --allow-net --allow-read --allow-write --allow-run bundler.ts
66-77-chrome:
88- deno run --allow-env --allow-net --allow-read --allow-write --allow-run bundler.ts chrome
99-1010-firefox:
1111- deno run --allow-env --allow-net --allow-read --allow-write --allow-run bundler.ts firefox
1212-1313-test:
1414- deno fmt
1515- deno lint
1616- deno test
1717- deno check source/background.ts source/content_script.ts source/options.tsx source/popup.tsx
+11-17
README.md
···18181919You need to download [Deno](https://deno.land/) in order to build this app.
20202121-> 1. Need to use Deno version PRE v1.22.0
2222->
2323-> - Deno.emit is not supported in v1.22.0
2424-> - We will transition to v1.22.0 when we can make a stable configuration for the userland [deno_emit](https://github.com/denoland/deno_emit) module
2525-> - To use unstable Deno v1.21.3: `deno upgrade --version 1.21.3`
2626->
2727-> 2. This application uses the unstable Deno api [`Deno.emit`](https://doc.deno.land/deno/unstable@v1.21.3/~/Deno.emit)
2828-> 3. `chrome` and `browser` globals are currently `any` type
2121+After, we want to install [bext](https://github.com/bpevs/bext):
29223030-| Commands | What they Do |
3131-| -------------------- | ------------------------------------------ |
3232-| `make` | bundles extension |
3333-| `make chrome` | bundles extension only for chrome |
3434-| `make firefox` | bundles extension only for firefox |
3535-| `make watch` | watch for js changes, and bundle on change |
3636-| `make watch-chrome` | watch only for chrome |
3737-| `make watch-firefox` | watch only for firefox |
3838-| `make test` | run code formatter, then unit tests |
2323+```sh
2424+deno install --name=bext --allow-read --allow-write --allow-run --allow-env -f https://deno.land/x/bext/main.ts
2525+```
2626+2727+| Commands | What they Do |
2828+| ---------------- | ----------------------------------- |
2929+| `bext` | bundles extension and watch code |
3030+| `bext chrome` | bundles extension only for chrome |
3131+| `bext firefox` | bundles extension only for firefox |
3232+| `deno task test` | run code formatter, then unit tests |
39334034If you have bundled using make commands, you should be able to load your
4135unpacked extension using a browser.
···11-// deno-lint-ignore-file
22-33-/**
44- * API for more platform-agnostic access to browser extension apis.
55- * Since browers ext API is kind of shifting sands, let's not do too much
66- * work to try and make 100% stable. But we can use this for the more stable
77- * APIs to avoid putting (chrome || browser) everywhere
88- *
99- * @reference https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions
1010- * @reference https://developer.chrome.com/docs/extensions/reference
1111- * @reference https://docs.microsoft.com/en-us/microsoft-edge/extensions-chromium/developer-guide/api-support
1212- *
1313- * @todo Borrows heavily from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/chrome
1414- */
1515-import { isChrome } from '../utilities/predicates.ts';
1616-1717-import type { PermissionsModule } from './modules/permissions.ts';
1818-import type { RuntimeModule } from './modules/runtime.ts';
1919-import type { StorageModule } from './modules/storage.ts';
2020-import type { TabsModule } from './modules/tabs.ts';
2121-export * from './modules/tabs.ts';
2222-2323-export interface BrowserAPI {
2424- permissions: PermissionsModule;
2525- runtime: RuntimeModule;
2626- storage: StorageModule;
2727- tabs: TabsModule;
2828-}
2929-3030-const browserAPI: BrowserAPI = isChrome()
3131- // deno-lint-ignore no-explicit-any
3232- ? (globalThis as any).chrome
3333- : // deno-lint-ignore no-explicit-any
3434- (globalThis as any).browser;
3535-3636-export default browserAPI;
···11-// deno-lint-ignore-file no-empty-interface
22-33-import { EventWithRequiredFilterInAddListener, Function } from './event.ts';
44-55-export type ResourceType =
66- | 'main_frame'
77- | 'sub_frame'
88- | 'stylesheet'
99- | 'script'
1010- | 'image'
1111- | 'font'
1212- | 'object'
1313- | 'xmlhttprequest'
1414- | 'ping'
1515- | 'csp_report'
1616- | 'media'
1717- | 'websocket'
1818- | 'other';
1919-2020-export interface AuthCredentials {
2121- username: string;
2222- password: string;
2323-}
2424-2525-export interface HttpHeader {
2626- name: string;
2727- value?: string | undefined;
2828- binaryValue?: ArrayBuffer | undefined;
2929-}
3030-3131-/** Returns value for event handlers that have the 'blocking' extraInfoSpec applied. Allows the event handler to modify network requests. */
3232-export interface BlockingResponse {
3333- /** Optional. If true, the request is cancelled. Used in onBeforeRequest, this prevents the request from being sent. */
3434- cancel?: boolean | undefined;
3535- /**
3636- * Optional.
3737- * Only used as a response to the onBeforeRequest and onHeadersReceived events. If set, the original request is prevented from being sent/completed and is instead redirected to the given URL. Redirections to non-HTTP schemes such as data: are allowed. Redirects initiated by a redirect action use the original request method for the redirect, with one exception: If the redirect is initiated at the onHeadersReceived stage, then the redirect will be issued using the GET method.
3838- */
3939- redirectUrl?: string | undefined;
4040- /**
4141- * Optional.
4242- * Only used as a response to the onHeadersReceived event. If set, the server is assumed to have responded with these response headers instead. Only return responseHeaders if you really want to modify the headers in order to limit the number of conflicts (only one extension may modify responseHeaders for each request).
4343- */
4444- responseHeaders?: HttpHeader[] | undefined;
4545- /** Optional. Only used as a response to the onAuthRequired event. If set, the request is made using the supplied credentials. */
4646- authCredentials?: AuthCredentials | undefined;
4747- /**
4848- * Optional.
4949- * Only used as a response to the onBeforeSendHeaders event. If set, the request is made with these request headers instead.
5050- */
5151- requestHeaders?: HttpHeader[] | undefined;
5252-}
5353-5454-/** An object describing filters to apply to webRequest events. */
5555-export interface RequestFilter {
5656- /** Optional. */
5757- tabId?: number | undefined;
5858- /**
5959- * A list of request types. Requests that cannot match any of the types will be filtered out.
6060- */
6161- types?: ResourceType[] | undefined;
6262- /** A list of URLs or URL patterns. Requests that cannot match any of the URLs will be filtered out. */
6363- urls: string[];
6464-6565- /** Optional. */
6666- windowId?: number | undefined;
6767-}
6868-6969-/**
7070- * Contains data uploaded in a URL request.
7171- * @since Chrome 23.
7272- */
7373-export interface UploadData {
7474- /** Optional. An ArrayBuffer with a copy of the data. */
7575- bytes?: ArrayBuffer | undefined;
7676- /** Optional. A string with the file's path and name. */
7777- file?: string | undefined;
7878-}
7979-8080-export interface WebRequestBody {
8181- /** Optional. Errors when obtaining request body data. */
8282- error?: string | undefined;
8383- /**
8484- * Optional.
8585- * If the request method is POST and the body is a sequence of key-value pairs encoded in UTF8, encoded as either multipart/form-data, or application/x-www-form-urlencoded, this dictionary is present and for each key contains the list of all values for that key. If the data is of another media type, or if it is malformed, the dictionary is not present. An example value of this dictionary is {'key': ['value1', 'value2']}.
8686- */
8787- formData?: { [key: string]: string[] } | undefined;
8888- /**
8989- * Optional.
9090- * If the request method is PUT or POST, and the body is not already parsed in formData, then the unparsed request body elements are contained in this array.
9191- */
9292- raw?: UploadData[] | undefined;
9393-}
9494-9595-export interface WebAuthChallenger {
9696- host: string;
9797- port: number;
9898-}
9999-100100-export interface ResourceRequest {
101101- url: string;
102102- /** The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request. */
103103- requestId: string;
104104- /** The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab. */
105105- frameId: number;
106106- /** ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists. */
107107- parentFrameId: number;
108108- /** The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab. */
109109- tabId: number;
110110- /**
111111- * How the requested resource will be used.
112112- */
113113- type: ResourceType;
114114- /** The time when this signal is triggered, in milliseconds since the epoch. */
115115- timeStamp: number;
116116- /** The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used.
117117- * @since Since Chrome 63.
118118- */
119119- initiator?: string | undefined;
120120-}
121121-122122-export interface WebRequestDetails extends ResourceRequest {
123123- /** Standard HTTP method. */
124124- method: string;
125125-}
126126-127127-export interface WebRequestHeadersDetails extends WebRequestDetails {
128128- /** Optional. The HTTP request headers that are going to be sent out with this request. */
129129- requestHeaders?: HttpHeader[] | undefined;
130130-}
131131-132132-export interface WebRequestBodyDetails extends WebRequestDetails {
133133- /**
134134- * Contains the HTTP request body data. Only provided if extraInfoSpec contains 'requestBody'.
135135- * @since Chrome 23.
136136- */
137137- requestBody: WebRequestBody | null;
138138-}
139139-140140-export interface WebRequestFullDetails
141141- extends WebRequestHeadersDetails, WebRequestBodyDetails {}
142142-143143-export interface WebResponseDetails extends ResourceRequest {
144144- /** HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line). */
145145- statusLine: string;
146146- /**
147147- * Standard HTTP status code returned by the server.
148148- * @since Chrome 43.
149149- */
150150- statusCode: number;
151151-}
152152-153153-export interface WebResponseHeadersDetails extends WebResponseDetails {
154154- /** Optional. The HTTP response headers that have been received with this response. */
155155- responseHeaders?: HttpHeader[] | undefined;
156156- method: string /** standard HTTP method i.e. GET, POST, PUT, etc. */;
157157-}
158158-159159-export interface WebResponseCacheDetails extends WebResponseHeadersDetails {
160160- /**
161161- * Optional.
162162- * The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address.
163163- */
164164- ip?: string | undefined;
165165- /** Indicates if this response was fetched from disk cache. */
166166- fromCache: boolean;
167167-}
168168-169169-export interface WebRedirectionResponseDetails extends WebResponseCacheDetails {
170170- /** The new URL. */
171171- redirectUrl: string;
172172-}
173173-174174-export interface WebAuthenticationChallengeDetails
175175- extends WebResponseHeadersDetails {
176176- /** The authentication scheme, e.g. Basic or Digest. */
177177- scheme: string;
178178- /** The authentication realm provided by the server, if there is one. */
179179- realm?: string | undefined;
180180- /** The server requesting authentication. */
181181- challenger: WebAuthChallenger;
182182- /** True for Proxy-Authenticate, false for WWW-Authenticate. */
183183- isProxy: boolean;
184184-}
185185-186186-export interface WebResponseErrorDetails extends WebResponseCacheDetails {
187187- /** The error description. This string is not guaranteed to remain backwards compatible between releases. You must not parse and act based upon its content. */
188188- error: string;
189189-}
190190-191191-export interface WebRequestBodyEvent
192192- extends
193193- EventWithRequiredFilterInAddListener<
194194- (details: WebRequestBodyDetails) => BlockingResponse | void
195195- > {
196196- addListener(
197197- callback: (details: WebRequestBodyDetails) => BlockingResponse | void,
198198- filter: RequestFilter,
199199- opt_extraInfoSpec?: string[],
200200- ): void;
201201-}
202202-203203-export interface WebRequestHeadersSynchronousEvent
204204- extends
205205- EventWithRequiredFilterInAddListener<
206206- (details: WebRequestHeadersDetails) => BlockingResponse | void
207207- > {
208208- addListener(
209209- callback: (details: WebRequestHeadersDetails) => BlockingResponse | void,
210210- filter: RequestFilter,
211211- opt_extraInfoSpec?: string[],
212212- ): void;
213213-}
214214-215215-export interface WebRequestHeadersEvent
216216- extends
217217- EventWithRequiredFilterInAddListener<
218218- (details: WebRequestHeadersDetails) => void
219219- > {
220220- addListener(
221221- callback: (details: WebRequestHeadersDetails) => void,
222222- filter: RequestFilter,
223223- opt_extraInfoSpec?: string[],
224224- ): void;
225225-}
226226-227227-export interface _WebResponseHeadersEvent<T extends WebResponseHeadersDetails>
228228- extends EventWithRequiredFilterInAddListener<(details: T) => void> {
229229- addListener(
230230- callback: (details: T) => void,
231231- filter: RequestFilter,
232232- opt_extraInfoSpec?: string[],
233233- ): void;
234234-}
235235-236236-export interface WebResponseHeadersEvent
237237- extends
238238- EventWithRequiredFilterInAddListener<
239239- (details: WebResponseHeadersDetails) => BlockingResponse | void
240240- > {
241241- addListener(
242242- callback: (details: WebResponseHeadersDetails) => BlockingResponse | void,
243243- filter: RequestFilter,
244244- opt_extraInfoSpec?: string[],
245245- ): void;
246246-}
247247-248248-export interface WebResponseCacheEvent
249249- extends _WebResponseHeadersEvent<WebResponseCacheDetails> {}
250250-251251-export interface WebRedirectionResponseEvent
252252- extends _WebResponseHeadersEvent<WebRedirectionResponseDetails> {}
253253-254254-export interface WebAuthenticationChallengeEvent
255255- extends
256256- EventWithRequiredFilterInAddListener<
257257- (
258258- details: WebAuthenticationChallengeDetails,
259259- callback?: (response: BlockingResponse) => void,
260260- ) => void
261261- > {
262262- addListener(
263263- callback: (
264264- details: WebAuthenticationChallengeDetails,
265265- callback?: (response: BlockingResponse) => void,
266266- ) => void,
267267- filter: RequestFilter,
268268- opt_extraInfoSpec?: string[],
269269- ): void;
270270-}
271271-272272-export interface WebResponseErrorEvent
273273- extends _WebResponseHeadersEvent<WebResponseErrorDetails> {}
274274-275275-export interface WebRequest {
276276- MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES: number;
277277- handlerBehaviorChanged: (callback?: Function) => void;
278278- onBeforeRequest: WebRequestBodyEvent;
279279- onBeforeSendHeaders: WebRequestHeadersSynchronousEvent;
280280- onSendHeaders: WebRequestHeadersEvent;
281281- onHeadersReceived: WebResponseHeadersEvent;
282282- onAuthRequired: WebAuthenticationChallengeEvent;
283283- onResponseStarted: WebResponseCacheEvent;
284284- onBeforeRedirect: WebRedirectionResponseEvent;
285285- onCompleted: WebResponseCacheEvent;
286286- onErrorOccurred: WebResponseErrorEvent;
287287-}