wxt 0.20.13 → 0.20.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.mts +20 -0
- package/dist/browser.mjs +18 -3
- package/dist/builtin-modules/index.mjs +7 -2
- package/dist/builtin-modules/unimport.mjs +69 -75
- package/dist/cli/cli-utils.mjs +54 -50
- package/dist/cli/commands.mjs +78 -103
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +9 -4
- package/dist/core/{build.d.ts → build.d.mts} +6 -2
- package/dist/core/build.mjs +23 -4
- package/dist/core/builders/vite/index.mjs +293 -343
- package/dist/core/builders/vite/plugins/bundleAnalysis.mjs +11 -12
- package/dist/core/builders/vite/plugins/cssEntrypoints.mjs +27 -20
- package/dist/core/builders/vite/plugins/defineImportMeta.mjs +17 -12
- package/dist/core/builders/vite/plugins/devHtmlPrerender.mjs +105 -136
- package/dist/core/builders/vite/plugins/devServerGlobals.mjs +15 -14
- package/dist/core/builders/vite/plugins/download.mjs +23 -12
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +18 -14
- package/dist/core/builders/vite/plugins/extensionApiMock.mjs +31 -33
- package/dist/core/builders/vite/plugins/globals.mjs +14 -13
- package/dist/core/builders/vite/plugins/iifeFooter.mjs +17 -11
- package/dist/core/builders/vite/plugins/index.mjs +18 -16
- package/dist/core/builders/vite/plugins/noopBackground.mjs +21 -15
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.mjs +26 -23
- package/dist/core/builders/vite/plugins/resolveAppConfig.mjs +26 -24
- package/dist/core/builders/vite/plugins/resolveVirtualModules.mjs +28 -26
- package/dist/core/builders/vite/plugins/tsconfigPaths.mjs +11 -11
- package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +42 -47
- package/dist/core/{clean.d.ts → clean.d.mts} +7 -3
- package/dist/core/clean.mjs +38 -35
- package/dist/core/{create-server.d.ts → create-server.d.mts} +6 -2
- package/dist/core/create-server.mjs +236 -247
- package/dist/core/define-config.d.mts +6 -0
- package/dist/core/define-config.mjs +6 -2
- package/dist/core/define-web-ext-config.d.mts +13 -0
- package/dist/core/define-web-ext-config.mjs +16 -7
- package/dist/core/generate-wxt-dir.mjs +110 -148
- package/dist/core/index.d.mts +9 -0
- package/dist/core/index.mjs +12 -8
- package/dist/core/initialize.d.mts +8 -0
- package/dist/core/initialize.mjs +110 -124
- package/dist/core/keyboard-shortcuts.mjs +30 -28
- package/dist/core/package-managers/bun.mjs +18 -16
- package/dist/core/package-managers/deno.mjs +12 -8
- package/dist/core/package-managers/index.mjs +52 -60
- package/dist/core/package-managers/npm.mjs +51 -52
- package/dist/core/package-managers/pnpm.mjs +21 -18
- package/dist/core/package-managers/yarn.mjs +31 -28
- package/dist/core/prepare.d.mts +6 -0
- package/dist/core/prepare.mjs +12 -7
- package/dist/core/resolve-config.mjs +393 -462
- package/dist/core/runners/index.mjs +15 -10
- package/dist/core/runners/manual.mjs +13 -14
- package/dist/core/runners/safari.mjs +13 -14
- package/dist/core/runners/web-ext.mjs +62 -83
- package/dist/core/runners/wsl.mjs +13 -14
- package/dist/core/utils/arrays.mjs +23 -12
- package/dist/core/utils/building/build-entrypoints.mjs +44 -40
- package/dist/core/utils/building/detect-dev-changes.mjs +84 -105
- package/dist/core/utils/building/find-entrypoints.mjs +278 -359
- package/dist/core/utils/building/group-entrypoints.mjs +42 -35
- package/dist/core/utils/building/index.mjs +8 -6
- package/dist/core/utils/building/internal-build.mjs +86 -102
- package/dist/core/utils/building/rebuild.mjs +50 -30
- package/dist/core/utils/cache.mjs +29 -18
- package/dist/core/utils/constants.mjs +9 -1
- package/dist/core/utils/content-scripts.mjs +56 -54
- package/dist/core/utils/content-security-policy.mjs +36 -39
- package/dist/core/utils/entrypoints.mjs +51 -28
- package/dist/core/utils/env.mjs +22 -17
- package/dist/core/utils/environments/browser-environment.mjs +13 -12
- package/dist/core/utils/environments/environment.mjs +36 -33
- package/dist/core/utils/environments/extension-environment.mjs +15 -10
- package/dist/core/utils/environments/index.mjs +4 -2
- package/dist/core/utils/eslint.mjs +11 -10
- package/dist/core/utils/fs.mjs +23 -11
- package/dist/core/utils/globals.mjs +53 -51
- package/dist/core/utils/i18n.mjs +41 -32
- package/dist/core/utils/index.mjs +3 -0
- package/dist/core/utils/log/index.mjs +6 -4
- package/dist/core/utils/log/printBuildSummary.mjs +20 -25
- package/dist/core/utils/log/printFileList.mjs +30 -33
- package/dist/core/utils/log/printHeader.mjs +9 -5
- package/dist/core/utils/log/printTable.mjs +19 -21
- package/dist/core/utils/manifest.mjs +366 -479
- package/dist/core/utils/minimatch-multiple.mjs +26 -15
- package/dist/core/utils/network.mjs +27 -33
- package/dist/core/utils/number.mjs +7 -3
- package/dist/core/utils/package.mjs +20 -13
- package/dist/core/utils/paths.d.mts +8 -0
- package/dist/core/utils/paths.mjs +26 -7
- package/dist/core/utils/strings.mjs +19 -14
- package/dist/core/utils/syntax-errors.mjs +14 -16
- package/dist/core/utils/time.mjs +19 -15
- package/dist/core/utils/transform.mjs +129 -160
- package/dist/core/utils/types.d.mts +6 -0
- package/dist/core/utils/validation.mjs +43 -50
- package/dist/core/utils/virtual-modules.mjs +20 -12
- package/dist/core/utils/wsl.mjs +11 -3
- package/dist/core/wxt.mjs +65 -60
- package/dist/core/{zip.d.ts → zip.d.mts} +6 -2
- package/dist/core/zip.mjs +118 -140
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +13 -3
- package/dist/{modules.d.ts → modules.d.mts} +14 -16
- package/dist/modules.mjs +179 -51
- package/dist/testing/fake-browser.d.mts +2 -0
- package/dist/testing/fake-browser.mjs +3 -1
- package/dist/testing/index.d.mts +3 -0
- package/dist/testing/index.mjs +4 -2
- package/dist/testing/{wxt-vitest-plugin.d.ts → wxt-vitest-plugin.d.mts} +7 -9
- package/dist/testing/wxt-vitest-plugin.mjs +38 -19
- package/dist/types.d.mts +1475 -0
- package/dist/utils/app-config.d.mts +6 -0
- package/dist/utils/app-config.mjs +8 -2
- package/dist/utils/content-script-context.d.mts +134 -0
- package/dist/utils/content-script-context.mjs +187 -175
- package/dist/utils/content-script-ui/iframe.d.mts +42 -0
- package/dist/utils/content-script-ui/iframe.mjs +42 -27
- package/dist/utils/content-script-ui/integrated.d.mts +37 -0
- package/dist/utils/content-script-ui/integrated.mjs +36 -29
- package/dist/utils/content-script-ui/shadow-root.d.mts +80 -0
- package/dist/utils/content-script-ui/shadow-root.mjs +75 -82
- package/dist/utils/content-script-ui/shared.mjs +115 -150
- package/dist/utils/content-script-ui/types.d.mts +107 -0
- package/dist/utils/content-script-ui/types.mjs +1 -0
- package/dist/utils/{define-app-config.d.ts → define-app-config.d.mts} +5 -3
- package/dist/utils/define-app-config.mjs +22 -2
- package/dist/utils/define-background.d.mts +7 -0
- package/dist/utils/define-background.mjs +7 -3
- package/dist/utils/define-content-script.d.mts +6 -0
- package/dist/utils/define-content-script.mjs +6 -2
- package/dist/utils/define-unlisted-script.d.mts +7 -0
- package/dist/utils/define-unlisted-script.mjs +7 -3
- package/dist/utils/define-wxt-plugin.d.mts +6 -0
- package/dist/utils/define-wxt-plugin.mjs +6 -2
- package/dist/utils/inject-script.d.mts +41 -0
- package/dist/utils/inject-script.mjs +44 -34
- package/dist/utils/internal/custom-events.d.mts +9 -0
- package/dist/utils/internal/custom-events.mjs +18 -10
- package/dist/utils/internal/location-watcher.mjs +23 -20
- package/dist/utils/internal/logger.mjs +15 -12
- package/dist/utils/match-patterns.d.mts +1 -0
- package/dist/utils/match-patterns.mjs +3 -1
- package/dist/utils/{split-shadow-root-css.d.ts → split-shadow-root-css.d.mts} +6 -3
- package/dist/utils/split-shadow-root-css.mjs +16 -7
- package/dist/utils/storage.d.mts +1 -0
- package/dist/utils/storage.mjs +3 -1
- package/dist/version.d.mts +4 -0
- package/dist/version.mjs +5 -1
- package/dist/virtual/background-entrypoint.d.mts +4 -0
- package/dist/virtual/background-entrypoint.mjs +143 -161
- package/dist/virtual/content-script-isolated-world-entrypoint.d.mts +4 -0
- package/dist/virtual/content-script-isolated-world-entrypoint.mjs +26 -27
- package/dist/virtual/content-script-main-world-entrypoint.d.mts +4 -0
- package/dist/virtual/content-script-main-world-entrypoint.mjs +24 -24
- package/dist/virtual/mock-browser.d.mts +6 -0
- package/dist/virtual/mock-browser.mjs +5 -3
- package/dist/virtual/reload-html.d.mts +1 -0
- package/dist/virtual/reload-html.mjs +57 -53
- package/dist/virtual/unlisted-script-entrypoint.d.mts +4 -0
- package/dist/virtual/unlisted-script-entrypoint.mjs +35 -43
- package/package.json +56 -50
- package/dist/browser.d.ts +0 -30
- package/dist/builtin-modules/index.d.ts +0 -2
- package/dist/builtin-modules/unimport.d.ts +0 -5
- package/dist/cli/cli-utils.d.ts +0 -25
- package/dist/cli/commands.d.ts +0 -2
- package/dist/cli/index.d.ts +0 -1
- package/dist/core/builders/vite/index.d.ts +0 -7
- package/dist/core/builders/vite/plugins/bundleAnalysis.d.ts +0 -7
- package/dist/core/builders/vite/plugins/cssEntrypoints.d.ts +0 -13
- package/dist/core/builders/vite/plugins/defineImportMeta.d.ts +0 -14
- package/dist/core/builders/vite/plugins/devHtmlPrerender.d.ts +0 -7
- package/dist/core/builders/vite/plugins/devServerGlobals.d.ts +0 -6
- package/dist/core/builders/vite/plugins/download.d.ts +0 -10
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.d.ts +0 -6
- package/dist/core/builders/vite/plugins/extensionApiMock.d.ts +0 -6
- package/dist/core/builders/vite/plugins/globals.d.ts +0 -3
- package/dist/core/builders/vite/plugins/iifeFooter.d.ts +0 -8
- package/dist/core/builders/vite/plugins/index.d.ts +0 -16
- package/dist/core/builders/vite/plugins/noopBackground.d.ts +0 -6
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.d.ts +0 -6
- package/dist/core/builders/vite/plugins/resolveAppConfig.d.ts +0 -6
- package/dist/core/builders/vite/plugins/resolveVirtualModules.d.ts +0 -6
- package/dist/core/builders/vite/plugins/tsconfigPaths.d.ts +0 -3
- package/dist/core/builders/vite/plugins/wxtPluginLoader.d.ts +0 -6
- package/dist/core/define-config.d.ts +0 -2
- package/dist/core/define-web-ext-config.d.ts +0 -9
- package/dist/core/generate-wxt-dir.d.ts +0 -5
- package/dist/core/index.d.ts +0 -8
- package/dist/core/initialize.d.ts +0 -5
- package/dist/core/keyboard-shortcuts.d.ts +0 -12
- package/dist/core/package-managers/bun.d.ts +0 -2
- package/dist/core/package-managers/deno.d.ts +0 -2
- package/dist/core/package-managers/index.d.ts +0 -2
- package/dist/core/package-managers/npm.d.ts +0 -17
- package/dist/core/package-managers/pnpm.d.ts +0 -2
- package/dist/core/package-managers/types.d.ts +0 -2
- package/dist/core/package-managers/types.mjs +0 -0
- package/dist/core/package-managers/yarn.d.ts +0 -2
- package/dist/core/prepare.d.ts +0 -2
- package/dist/core/resolve-config.d.ts +0 -11
- package/dist/core/runners/index.d.ts +0 -2
- package/dist/core/runners/manual.d.ts +0 -5
- package/dist/core/runners/safari.d.ts +0 -5
- package/dist/core/runners/web-ext.d.ts +0 -5
- package/dist/core/runners/wsl.d.ts +0 -5
- package/dist/core/utils/arrays.d.ts +0 -13
- package/dist/core/utils/building/build-entrypoints.d.ts +0 -3
- package/dist/core/utils/building/detect-dev-changes.d.ts +0 -61
- package/dist/core/utils/building/find-entrypoints.d.ts +0 -5
- package/dist/core/utils/building/group-entrypoints.d.ts +0 -8
- package/dist/core/utils/building/index.d.ts +0 -6
- package/dist/core/utils/building/internal-build.d.ts +0 -12
- package/dist/core/utils/building/rebuild.d.ts +0 -23
- package/dist/core/utils/cache.d.ts +0 -8
- package/dist/core/utils/cli.d.ts +0 -3
- package/dist/core/utils/cli.mjs +0 -26
- package/dist/core/utils/constants.d.ts +0 -5
- package/dist/core/utils/content-scripts.d.ts +0 -12
- package/dist/core/utils/content-security-policy.d.ts +0 -14
- package/dist/core/utils/entrypoints.d.ts +0 -31
- package/dist/core/utils/env.d.ts +0 -5
- package/dist/core/utils/environments/browser-environment.d.ts +0 -3
- package/dist/core/utils/environments/environment.d.ts +0 -8
- package/dist/core/utils/environments/extension-environment.d.ts +0 -6
- package/dist/core/utils/environments/index.d.ts +0 -2
- package/dist/core/utils/eslint.d.ts +0 -1
- package/dist/core/utils/fs.d.ts +0 -13
- package/dist/core/utils/globals.d.ts +0 -11
- package/dist/core/utils/i18n.d.ts +0 -11
- package/dist/core/utils/log/index.d.ts +0 -4
- package/dist/core/utils/log/printBuildSummary.d.ts +0 -2
- package/dist/core/utils/log/printFileList.d.ts +0 -1
- package/dist/core/utils/log/printHeader.d.ts +0 -1
- package/dist/core/utils/log/printTable.d.ts +0 -1
- package/dist/core/utils/manifest.d.ts +0 -40
- package/dist/core/utils/minimatch-multiple.d.ts +0 -15
- package/dist/core/utils/network.d.ts +0 -7
- package/dist/core/utils/number.d.ts +0 -1
- package/dist/core/utils/package.d.ts +0 -6
- package/dist/core/utils/paths.d.ts +0 -11
- package/dist/core/utils/strings.d.ts +0 -14
- package/dist/core/utils/syntax-errors.d.ts +0 -11
- package/dist/core/utils/testing/fake-objects.d.ts +0 -11665
- package/dist/core/utils/testing/fake-objects.mjs +0 -326
- package/dist/core/utils/time.d.ts +0 -9
- package/dist/core/utils/transform.d.ts +0 -11
- package/dist/core/utils/types.d.ts +0 -13
- package/dist/core/utils/types.mjs +0 -0
- package/dist/core/utils/validation.d.ts +0 -15
- package/dist/core/utils/virtual-modules.d.ts +0 -22
- package/dist/core/utils/wsl.d.ts +0 -4
- package/dist/core/wxt.d.ts +0 -24
- package/dist/index.d.ts +0 -11
- package/dist/testing/fake-browser.d.ts +0 -10
- package/dist/testing/index.d.ts +0 -10
- package/dist/types.d.ts +0 -1459
- package/dist/types.mjs +0 -0
- package/dist/utils/app-config.d.ts +0 -2
- package/dist/utils/content-script-context.d.ts +0 -134
- package/dist/utils/content-script-ui/iframe.d.ts +0 -32
- package/dist/utils/content-script-ui/integrated.d.ts +0 -34
- package/dist/utils/content-script-ui/shadow-root.d.ts +0 -76
- package/dist/utils/content-script-ui/shared.d.ts +0 -5
- package/dist/utils/content-script-ui/types.d.ts +0 -104
- package/dist/utils/define-background.d.ts +0 -4
- package/dist/utils/define-content-script.d.ts +0 -3
- package/dist/utils/define-unlisted-script.d.ts +0 -4
- package/dist/utils/define-wxt-plugin.d.ts +0 -3
- package/dist/utils/inject-script.d.ts +0 -36
- package/dist/utils/internal/custom-events.d.ts +0 -10
- package/dist/utils/internal/dev-server-websocket.d.ts +0 -21
- package/dist/utils/internal/dev-server-websocket.mjs +0 -37
- package/dist/utils/internal/location-watcher.d.ts +0 -12
- package/dist/utils/internal/logger.d.ts +0 -9
- package/dist/utils/match-patterns.d.ts +0 -5
- package/dist/utils/storage.d.ts +0 -5
- package/dist/version.d.ts +0 -1
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import appConfig from "virtual:app-config";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
//#region src/utils/app-config.ts
|
|
4
|
+
/** @module wxt/utils/app-config */
|
|
5
|
+
function useAppConfig() {
|
|
6
|
+
return appConfig;
|
|
4
7
|
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { useAppConfig };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { WxtLocationChangeEvent } from "./internal/custom-events.mjs";
|
|
2
|
+
import { ContentScriptDefinition } from "../types.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/content-script-context.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
|
|
7
|
+
* Used to detect and stop content script code when the script is invalidated.
|
|
8
|
+
*
|
|
9
|
+
* It also provides several utilities like `ctx.setTimeout` and `ctx.setInterval` that should be used in
|
|
10
|
+
* content scripts instead of `window.setTimeout` or `window.setInterval`.
|
|
11
|
+
*
|
|
12
|
+
* To create context for testing, you can use the class's constructor:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { ContentScriptContext } from 'wxt/utils/content-scripts-context';
|
|
16
|
+
*
|
|
17
|
+
* test("storage listener should be removed when context is invalidated", () => {
|
|
18
|
+
* const ctx = new ContentScriptContext('test');
|
|
19
|
+
* const item = storage.defineItem("local:count", { defaultValue: 0 });
|
|
20
|
+
* const watcher = vi.fn();
|
|
21
|
+
*
|
|
22
|
+
* const unwatch = item.watch(watcher);
|
|
23
|
+
* ctx.onInvalidated(unwatch); // Listen for invalidate here
|
|
24
|
+
*
|
|
25
|
+
* await item.setValue(1);
|
|
26
|
+
* expect(watcher).toBeCalledTimes(1);
|
|
27
|
+
* expect(watcher).toBeCalledWith(1, 0);
|
|
28
|
+
*
|
|
29
|
+
* ctx.notifyInvalidated(); // Use this function to invalidate the context
|
|
30
|
+
* await item.setValue(2);
|
|
31
|
+
* expect(watcher).toBeCalledTimes(1);
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare class ContentScriptContext implements AbortController {
|
|
36
|
+
private readonly contentScriptName;
|
|
37
|
+
readonly options?: Omit<ContentScriptDefinition, "main"> | undefined;
|
|
38
|
+
private static SCRIPT_STARTED_MESSAGE_TYPE;
|
|
39
|
+
private id;
|
|
40
|
+
private abortController;
|
|
41
|
+
private locationWatcher;
|
|
42
|
+
constructor(contentScriptName: string, options?: Omit<ContentScriptDefinition, "main"> | undefined);
|
|
43
|
+
get signal(): AbortSignal;
|
|
44
|
+
abort(reason?: any): void;
|
|
45
|
+
get isInvalid(): boolean;
|
|
46
|
+
get isValid(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Add a listener that is called when the content script's context is invalidated.
|
|
49
|
+
*
|
|
50
|
+
* @returns A function to remove the listener.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* browser.runtime.onMessage.addListener(cb);
|
|
54
|
+
* const removeInvalidatedListener = ctx.onInvalidated(() => {
|
|
55
|
+
* browser.runtime.onMessage.removeListener(cb);
|
|
56
|
+
* })
|
|
57
|
+
* // ...
|
|
58
|
+
* removeInvalidatedListener();
|
|
59
|
+
*/
|
|
60
|
+
onInvalidated(cb: () => void): () => void;
|
|
61
|
+
/**
|
|
62
|
+
* Return a promise that never resolves. Useful if you have an async function that shouldn't run
|
|
63
|
+
* after the context is expired.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* const getValueFromStorage = async () => {
|
|
67
|
+
* if (ctx.isInvalid) return ctx.block();
|
|
68
|
+
*
|
|
69
|
+
* // ...
|
|
70
|
+
* }
|
|
71
|
+
*/
|
|
72
|
+
block<T>(): Promise<T>;
|
|
73
|
+
/**
|
|
74
|
+
* Wrapper around `window.setInterval` that automatically clears the interval when invalidated.
|
|
75
|
+
*
|
|
76
|
+
* Intervals can be cleared by calling the normal `clearInterval` function.
|
|
77
|
+
*/
|
|
78
|
+
setInterval(handler: () => void, timeout?: number): number;
|
|
79
|
+
/**
|
|
80
|
+
* Wrapper around `window.setTimeout` that automatically clears the interval when invalidated.
|
|
81
|
+
*
|
|
82
|
+
* Timeouts can be cleared by calling the normal `setTimeout` function.
|
|
83
|
+
*/
|
|
84
|
+
setTimeout(handler: () => void, timeout?: number): number;
|
|
85
|
+
/**
|
|
86
|
+
* Wrapper around `window.requestAnimationFrame` that automatically cancels the request when
|
|
87
|
+
* invalidated.
|
|
88
|
+
*
|
|
89
|
+
* Callbacks can be canceled by calling the normal `cancelAnimationFrame` function.
|
|
90
|
+
*/
|
|
91
|
+
requestAnimationFrame(callback: FrameRequestCallback): number;
|
|
92
|
+
/**
|
|
93
|
+
* Wrapper around `window.requestIdleCallback` that automatically cancels the request when
|
|
94
|
+
* invalidated.
|
|
95
|
+
*
|
|
96
|
+
* Callbacks can be canceled by calling the normal `cancelIdleCallback` function.
|
|
97
|
+
*/
|
|
98
|
+
requestIdleCallback(callback: IdleRequestCallback, options?: IdleRequestOptions): number;
|
|
99
|
+
/**
|
|
100
|
+
* Call `target.addEventListener` and remove the event listener when the context is invalidated.
|
|
101
|
+
*
|
|
102
|
+
* Listeners can be canceled by calling the normal `removeEventListener` function.
|
|
103
|
+
*
|
|
104
|
+
* Includes additional events useful for content scripts:
|
|
105
|
+
*
|
|
106
|
+
* - `"wxt:locationchange"` - Triggered when HTML5 history mode is used to change URL. Content
|
|
107
|
+
* scripts are not reloaded when navigating this way, so this can be used to reset the content
|
|
108
|
+
* script state on URL change, or run custom code.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ctx.addEventListener(document, "visibilitychange", () => {
|
|
112
|
+
* // ...
|
|
113
|
+
* });
|
|
114
|
+
* ctx.addEventListener(window, "wxt:locationchange", () => {
|
|
115
|
+
* // ...
|
|
116
|
+
* });
|
|
117
|
+
*/
|
|
118
|
+
addEventListener<TType extends keyof WxtWindowEventMap>(target: Window, type: TType, handler: (event: WxtWindowEventMap[TType]) => void, options?: AddEventListenerOptions): void;
|
|
119
|
+
addEventListener<TType extends keyof DocumentEventMap>(target: Document, type: TType, handler: (event: DocumentEventMap[TType]) => void, options?: AddEventListenerOptions): void;
|
|
120
|
+
addEventListener<TTarget extends EventTarget>(target: TTarget, ...params: Parameters<TTarget['addEventListener']>): void;
|
|
121
|
+
/**
|
|
122
|
+
* @internal
|
|
123
|
+
* Abort the abort controller and execute all `onInvalidated` listeners.
|
|
124
|
+
*/
|
|
125
|
+
notifyInvalidated(): void;
|
|
126
|
+
stopOldScripts(): void;
|
|
127
|
+
verifyScriptStartedEvent(event: CustomEvent): boolean;
|
|
128
|
+
listenForNewerScripts(): void;
|
|
129
|
+
}
|
|
130
|
+
interface WxtWindowEventMap extends WindowEventMap {
|
|
131
|
+
'wxt:locationchange': WxtLocationChangeEvent;
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
134
|
+
export { ContentScriptContext, WxtWindowEventMap };
|
|
@@ -1,176 +1,188 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
getUniqueEventName
|
|
5
|
-
} from "./internal/custom-events.mjs";
|
|
1
|
+
import { logger } from "./internal/logger.mjs";
|
|
2
|
+
import { getUniqueEventName } from "./internal/custom-events.mjs";
|
|
6
3
|
import { createLocationWatcher } from "./internal/location-watcher.mjs";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
4
|
+
import { browser } from "wxt/browser";
|
|
5
|
+
|
|
6
|
+
//#region src/utils/content-script-context.ts
|
|
7
|
+
/**
|
|
8
|
+
* Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
|
|
9
|
+
* Used to detect and stop content script code when the script is invalidated.
|
|
10
|
+
*
|
|
11
|
+
* It also provides several utilities like `ctx.setTimeout` and `ctx.setInterval` that should be used in
|
|
12
|
+
* content scripts instead of `window.setTimeout` or `window.setInterval`.
|
|
13
|
+
*
|
|
14
|
+
* To create context for testing, you can use the class's constructor:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { ContentScriptContext } from 'wxt/utils/content-scripts-context';
|
|
18
|
+
*
|
|
19
|
+
* test("storage listener should be removed when context is invalidated", () => {
|
|
20
|
+
* const ctx = new ContentScriptContext('test');
|
|
21
|
+
* const item = storage.defineItem("local:count", { defaultValue: 0 });
|
|
22
|
+
* const watcher = vi.fn();
|
|
23
|
+
*
|
|
24
|
+
* const unwatch = item.watch(watcher);
|
|
25
|
+
* ctx.onInvalidated(unwatch); // Listen for invalidate here
|
|
26
|
+
*
|
|
27
|
+
* await item.setValue(1);
|
|
28
|
+
* expect(watcher).toBeCalledTimes(1);
|
|
29
|
+
* expect(watcher).toBeCalledWith(1, 0);
|
|
30
|
+
*
|
|
31
|
+
* ctx.notifyInvalidated(); // Use this function to invalidate the context
|
|
32
|
+
* await item.setValue(2);
|
|
33
|
+
* expect(watcher).toBeCalledTimes(1);
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
var ContentScriptContext = class ContentScriptContext {
|
|
38
|
+
static SCRIPT_STARTED_MESSAGE_TYPE = getUniqueEventName("wxt:content-script-started");
|
|
39
|
+
id;
|
|
40
|
+
abortController;
|
|
41
|
+
locationWatcher = createLocationWatcher(this);
|
|
42
|
+
constructor(contentScriptName, options) {
|
|
43
|
+
this.contentScriptName = contentScriptName;
|
|
44
|
+
this.options = options;
|
|
45
|
+
this.id = Math.random().toString(36).slice(2);
|
|
46
|
+
this.abortController = new AbortController();
|
|
47
|
+
this.stopOldScripts();
|
|
48
|
+
this.listenForNewerScripts();
|
|
49
|
+
}
|
|
50
|
+
get signal() {
|
|
51
|
+
return this.abortController.signal;
|
|
52
|
+
}
|
|
53
|
+
abort(reason) {
|
|
54
|
+
return this.abortController.abort(reason);
|
|
55
|
+
}
|
|
56
|
+
get isInvalid() {
|
|
57
|
+
if (browser.runtime?.id == null) this.notifyInvalidated();
|
|
58
|
+
return this.signal.aborted;
|
|
59
|
+
}
|
|
60
|
+
get isValid() {
|
|
61
|
+
return !this.isInvalid;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Add a listener that is called when the content script's context is invalidated.
|
|
65
|
+
*
|
|
66
|
+
* @returns A function to remove the listener.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* browser.runtime.onMessage.addListener(cb);
|
|
70
|
+
* const removeInvalidatedListener = ctx.onInvalidated(() => {
|
|
71
|
+
* browser.runtime.onMessage.removeListener(cb);
|
|
72
|
+
* })
|
|
73
|
+
* // ...
|
|
74
|
+
* removeInvalidatedListener();
|
|
75
|
+
*/
|
|
76
|
+
onInvalidated(cb) {
|
|
77
|
+
this.signal.addEventListener("abort", cb);
|
|
78
|
+
return () => this.signal.removeEventListener("abort", cb);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Return a promise that never resolves. Useful if you have an async function that shouldn't run
|
|
82
|
+
* after the context is expired.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const getValueFromStorage = async () => {
|
|
86
|
+
* if (ctx.isInvalid) return ctx.block();
|
|
87
|
+
*
|
|
88
|
+
* // ...
|
|
89
|
+
* }
|
|
90
|
+
*/
|
|
91
|
+
block() {
|
|
92
|
+
return new Promise(() => {});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Wrapper around `window.setInterval` that automatically clears the interval when invalidated.
|
|
96
|
+
*
|
|
97
|
+
* Intervals can be cleared by calling the normal `clearInterval` function.
|
|
98
|
+
*/
|
|
99
|
+
setInterval(handler, timeout) {
|
|
100
|
+
const id = setInterval(() => {
|
|
101
|
+
if (this.isValid) handler();
|
|
102
|
+
}, timeout);
|
|
103
|
+
this.onInvalidated(() => clearInterval(id));
|
|
104
|
+
return id;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Wrapper around `window.setTimeout` that automatically clears the interval when invalidated.
|
|
108
|
+
*
|
|
109
|
+
* Timeouts can be cleared by calling the normal `setTimeout` function.
|
|
110
|
+
*/
|
|
111
|
+
setTimeout(handler, timeout) {
|
|
112
|
+
const id = setTimeout(() => {
|
|
113
|
+
if (this.isValid) handler();
|
|
114
|
+
}, timeout);
|
|
115
|
+
this.onInvalidated(() => clearTimeout(id));
|
|
116
|
+
return id;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Wrapper around `window.requestAnimationFrame` that automatically cancels the request when
|
|
120
|
+
* invalidated.
|
|
121
|
+
*
|
|
122
|
+
* Callbacks can be canceled by calling the normal `cancelAnimationFrame` function.
|
|
123
|
+
*/
|
|
124
|
+
requestAnimationFrame(callback) {
|
|
125
|
+
const id = requestAnimationFrame((...args) => {
|
|
126
|
+
if (this.isValid) callback(...args);
|
|
127
|
+
});
|
|
128
|
+
this.onInvalidated(() => cancelAnimationFrame(id));
|
|
129
|
+
return id;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Wrapper around `window.requestIdleCallback` that automatically cancels the request when
|
|
133
|
+
* invalidated.
|
|
134
|
+
*
|
|
135
|
+
* Callbacks can be canceled by calling the normal `cancelIdleCallback` function.
|
|
136
|
+
*/
|
|
137
|
+
requestIdleCallback(callback, options) {
|
|
138
|
+
const id = requestIdleCallback((...args) => {
|
|
139
|
+
if (!this.signal.aborted) callback(...args);
|
|
140
|
+
}, options);
|
|
141
|
+
this.onInvalidated(() => cancelIdleCallback(id));
|
|
142
|
+
return id;
|
|
143
|
+
}
|
|
144
|
+
addEventListener(target, type, handler, options) {
|
|
145
|
+
if (type === "wxt:locationchange") {
|
|
146
|
+
if (this.isValid) this.locationWatcher.run();
|
|
147
|
+
}
|
|
148
|
+
target.addEventListener?.(type.startsWith("wxt:") ? getUniqueEventName(type) : type, handler, {
|
|
149
|
+
...options,
|
|
150
|
+
signal: this.signal
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* @internal
|
|
155
|
+
* Abort the abort controller and execute all `onInvalidated` listeners.
|
|
156
|
+
*/
|
|
157
|
+
notifyInvalidated() {
|
|
158
|
+
this.abort("Content script context invalidated");
|
|
159
|
+
logger.debug(`Content script "${this.contentScriptName}" context invalidated`);
|
|
160
|
+
}
|
|
161
|
+
stopOldScripts() {
|
|
162
|
+
document.dispatchEvent(new CustomEvent(ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE, { detail: {
|
|
163
|
+
contentScriptName: this.contentScriptName,
|
|
164
|
+
messageId: this.id
|
|
165
|
+
} }));
|
|
166
|
+
window.postMessage({
|
|
167
|
+
type: ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE,
|
|
168
|
+
contentScriptName: this.contentScriptName,
|
|
169
|
+
messageId: this.id
|
|
170
|
+
}, "*");
|
|
171
|
+
}
|
|
172
|
+
verifyScriptStartedEvent(event) {
|
|
173
|
+
const isSameContentScript = event.detail?.contentScriptName === this.contentScriptName;
|
|
174
|
+
const isFromSelf = event.detail?.messageId === this.id;
|
|
175
|
+
return isSameContentScript && !isFromSelf;
|
|
176
|
+
}
|
|
177
|
+
listenForNewerScripts() {
|
|
178
|
+
const cb = (event) => {
|
|
179
|
+
if (!(event instanceof CustomEvent) || !this.verifyScriptStartedEvent(event)) return;
|
|
180
|
+
this.notifyInvalidated();
|
|
181
|
+
};
|
|
182
|
+
document.addEventListener(ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE, cb);
|
|
183
|
+
this.onInvalidated(() => document.removeEventListener(ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE, cb));
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
//#endregion
|
|
188
|
+
export { ContentScriptContext };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ContentScriptContext } from "../content-script-context.mjs";
|
|
2
|
+
import { ContentScriptUi, ContentScriptUiOptions } from "./types.mjs";
|
|
3
|
+
import * as wxt_browser0 from "wxt/browser";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/content-script-ui/iframe.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Create a content script UI using an iframe.
|
|
8
|
+
*
|
|
9
|
+
* @see https://wxt.dev/guide/essentials/content-scripts.html#iframe
|
|
10
|
+
*/
|
|
11
|
+
declare function createIframeUi<TMounted>(ctx: ContentScriptContext, options: IframeContentScriptUiOptions<TMounted>): IframeContentScriptUi<TMounted>;
|
|
12
|
+
interface IframeContentScriptUi<TMounted> extends ContentScriptUi<TMounted> {
|
|
13
|
+
/**
|
|
14
|
+
* The iframe added to the DOM.
|
|
15
|
+
*/
|
|
16
|
+
iframe: HTMLIFrameElement;
|
|
17
|
+
/**
|
|
18
|
+
* A wrapper div that assists in positioning.
|
|
19
|
+
*/
|
|
20
|
+
wrapper: HTMLDivElement;
|
|
21
|
+
}
|
|
22
|
+
type IframeContentScriptUiOptions<TMounted> = ContentScriptUiOptions<TMounted> & {
|
|
23
|
+
/**
|
|
24
|
+
* The path to the HTML page that will be shown in the iframe. This string is passed into
|
|
25
|
+
* `browser.runtime.getURL`.
|
|
26
|
+
*/
|
|
27
|
+
page: wxt_browser0.HtmlPublicPath;
|
|
28
|
+
/**
|
|
29
|
+
* Callback executed when mounting the UI. Use this function to customize the iframe or wrapper
|
|
30
|
+
* element's appearance. It is called every time `ui.mount()` is called.
|
|
31
|
+
*
|
|
32
|
+
* Optionally return a value that can be accessed at `ui.mounted` or in the `onRemove` callback.
|
|
33
|
+
*/
|
|
34
|
+
onMount?: (wrapper: HTMLElement, iframe: HTMLIFrameElement) => TMounted;
|
|
35
|
+
/**
|
|
36
|
+
* Callback executed before mounting the UI. Use this function to customize the iframe or wrapper
|
|
37
|
+
* elements before they are injected into the DOM. It is called every time `ui.mount()` is called.
|
|
38
|
+
*/
|
|
39
|
+
onBeforeMount?: (wrapper: HTMLElement, iframe: HTMLIFrameElement) => void;
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
export { IframeContentScriptUi, IframeContentScriptUiOptions, createIframeUi };
|
|
@@ -1,29 +1,44 @@
|
|
|
1
|
-
import { browser } from "wxt/browser";
|
|
2
1
|
import { applyPosition, createMountFunctions, mountUi } from "./shared.mjs";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
import { browser } from "wxt/browser";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/content-script-ui/iframe.ts
|
|
5
|
+
/** @module wxt/utils/content-script-ui/iframe */
|
|
6
|
+
/**
|
|
7
|
+
* Create a content script UI using an iframe.
|
|
8
|
+
*
|
|
9
|
+
* @see https://wxt.dev/guide/essentials/content-scripts.html#iframe
|
|
10
|
+
*/
|
|
11
|
+
function createIframeUi(ctx, options) {
|
|
12
|
+
const wrapper = document.createElement("div");
|
|
13
|
+
const iframe = document.createElement("iframe");
|
|
14
|
+
iframe.src = browser.runtime.getURL(options.page);
|
|
15
|
+
wrapper.appendChild(iframe);
|
|
16
|
+
let mounted;
|
|
17
|
+
const mount = () => {
|
|
18
|
+
applyPosition(wrapper, iframe, options);
|
|
19
|
+
options.onBeforeMount?.(wrapper, iframe);
|
|
20
|
+
mountUi(wrapper, options);
|
|
21
|
+
mounted = options.onMount?.(wrapper, iframe);
|
|
22
|
+
};
|
|
23
|
+
const remove = () => {
|
|
24
|
+
options.onRemove?.(mounted);
|
|
25
|
+
wrapper.remove();
|
|
26
|
+
mounted = void 0;
|
|
27
|
+
};
|
|
28
|
+
const mountFunctions = createMountFunctions({
|
|
29
|
+
mount,
|
|
30
|
+
remove
|
|
31
|
+
}, options);
|
|
32
|
+
ctx.onInvalidated(remove);
|
|
33
|
+
return {
|
|
34
|
+
get mounted() {
|
|
35
|
+
return mounted;
|
|
36
|
+
},
|
|
37
|
+
iframe,
|
|
38
|
+
wrapper,
|
|
39
|
+
...mountFunctions
|
|
40
|
+
};
|
|
29
41
|
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { createIframeUi };
|