wxt 0.18.15 → 0.19.0
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/bin/wxt.mjs +1 -1
- package/dist/browser/chrome.d.ts +17 -0
- package/dist/browser/chrome.mjs +7 -0
- package/dist/browser/index.d.ts +18 -0
- package/dist/browser/index.mjs +2 -0
- package/dist/builtin-modules/index.d.ts +2 -0
- package/dist/builtin-modules/index.mjs +2 -0
- package/dist/builtin-modules/unimport.d.ts +8 -0
- package/dist/builtin-modules/unimport.mjs +99 -0
- package/dist/cli/cli-utils.d.ts +25 -0
- package/dist/cli/cli-utils.mjs +58 -0
- package/dist/cli/commands.d.ts +2 -0
- package/dist/cli/commands.mjs +104 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.mjs +11 -0
- package/dist/client/app-config.d.ts +2 -0
- package/dist/client/app-config.mjs +4 -0
- package/dist/client/content-scripts/content-script-context.d.ts +114 -0
- package/dist/client/content-scripts/content-script-context.mjs +169 -0
- package/dist/client/content-scripts/custom-events.d.ts +10 -0
- package/dist/client/content-scripts/custom-events.mjs +13 -0
- package/dist/client/content-scripts/index.d.ts +2 -0
- package/dist/client/content-scripts/index.mjs +2 -0
- package/dist/client/content-scripts/location-watcher.d.ts +12 -0
- package/dist/client/content-scripts/location-watcher.mjs +22 -0
- package/dist/client/content-scripts/ui/index.d.ts +23 -0
- package/dist/client/content-scripts/ui/index.mjs +188 -0
- package/dist/{client.d.ts → client/content-scripts/ui/types.d.ts} +17 -45
- package/dist/client/content-scripts/ui/types.mjs +0 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.mjs +2 -0
- package/dist/core/build.d.ts +15 -0
- package/dist/core/build.mjs +6 -0
- package/dist/core/builders/vite/index.d.ts +3 -0
- package/dist/core/builders/vite/index.mjs +285 -0
- package/dist/core/builders/vite/plugins/bundleAnalysis.d.ts +7 -0
- package/dist/core/builders/vite/plugins/bundleAnalysis.mjs +15 -0
- package/dist/core/builders/vite/plugins/cssEntrypoints.d.ts +13 -0
- package/dist/core/builders/vite/plugins/cssEntrypoints.mjs +22 -0
- package/dist/core/builders/vite/plugins/defineImportMeta.d.ts +14 -0
- package/dist/core/builders/vite/plugins/defineImportMeta.mjs +13 -0
- package/dist/core/builders/vite/plugins/devHtmlPrerender.d.ts +7 -0
- package/dist/core/builders/vite/plugins/devHtmlPrerender.mjs +140 -0
- package/dist/core/builders/vite/plugins/devServerGlobals.d.ts +6 -0
- package/dist/core/builders/vite/plugins/devServerGlobals.mjs +15 -0
- package/dist/core/builders/vite/plugins/download.d.ts +10 -0
- package/dist/core/builders/vite/plugins/download.mjs +14 -0
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.d.ts +6 -0
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +16 -0
- package/dist/core/builders/vite/plugins/extensionApiMock.d.ts +11 -0
- package/dist/core/builders/vite/plugins/extensionApiMock.mjs +26 -0
- package/dist/core/builders/vite/plugins/globals.d.ts +3 -0
- package/dist/core/builders/vite/plugins/globals.mjs +15 -0
- package/dist/core/builders/vite/plugins/index.d.ts +17 -0
- package/dist/core/builders/vite/plugins/index.mjs +17 -0
- package/dist/core/builders/vite/plugins/multipageMove.d.ts +20 -0
- package/dist/core/builders/vite/plugins/multipageMove.mjs +59 -0
- package/dist/core/builders/vite/plugins/noopBackground.d.ts +6 -0
- package/dist/core/builders/vite/plugins/noopBackground.mjs +17 -0
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.d.ts +6 -0
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.mjs +12 -0
- package/dist/core/builders/vite/plugins/resolveAppConfig.d.ts +6 -0
- package/dist/core/builders/vite/plugins/resolveAppConfig.mjs +26 -0
- package/dist/core/builders/vite/plugins/resolveExtensionApi.d.ts +10 -0
- package/dist/core/builders/vite/plugins/resolveExtensionApi.mjs +15 -0
- package/dist/core/builders/vite/plugins/resolveVirtualModules.d.ts +6 -0
- package/dist/core/builders/vite/plugins/resolveVirtualModules.mjs +30 -0
- package/dist/core/builders/vite/plugins/tsconfigPaths.d.ts +3 -0
- package/dist/core/builders/vite/plugins/tsconfigPaths.mjs +12 -0
- package/dist/core/builders/vite/plugins/wxtPluginLoader.d.ts +6 -0
- package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +56 -0
- package/dist/core/clean.d.ts +21 -0
- package/dist/core/clean.mjs +38 -0
- package/dist/core/create-server.d.ts +11 -0
- package/dist/core/create-server.mjs +206 -0
- package/dist/core/define-config.d.ts +2 -0
- package/dist/core/define-config.mjs +3 -0
- package/dist/core/define-runner-config.d.ts +2 -0
- package/dist/core/define-runner-config.mjs +3 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.mjs +8 -0
- package/dist/core/initialize.d.ts +5 -0
- package/dist/core/initialize.mjs +128 -0
- package/dist/core/package-managers/bun.d.ts +2 -0
- package/dist/core/package-managers/bun.mjs +19 -0
- package/dist/core/package-managers/index.d.ts +2 -0
- package/dist/core/package-managers/index.mjs +65 -0
- package/dist/core/package-managers/npm.d.ts +17 -0
- package/dist/core/package-managers/npm.mjs +58 -0
- package/dist/core/package-managers/pnpm.d.ts +2 -0
- package/dist/core/package-managers/pnpm.mjs +21 -0
- package/dist/core/package-managers/types.d.ts +2 -0
- package/dist/core/package-managers/types.mjs +0 -0
- package/dist/core/package-managers/yarn.d.ts +2 -0
- package/dist/core/package-managers/yarn.mjs +31 -0
- package/dist/core/prepare.d.ts +2 -0
- package/dist/core/prepare.mjs +8 -0
- package/dist/core/runners/index.d.ts +2 -0
- package/dist/core/runners/index.mjs +12 -0
- package/dist/core/runners/manual.d.ts +5 -0
- package/dist/core/runners/manual.mjs +16 -0
- package/dist/core/runners/safari.d.ts +5 -0
- package/dist/core/runners/safari.mjs +16 -0
- package/dist/core/runners/web-ext.d.ts +5 -0
- package/dist/core/runners/web-ext.mjs +78 -0
- package/dist/core/runners/wsl.d.ts +5 -0
- package/dist/core/runners/wsl.mjs +16 -0
- package/dist/core/utils/arrays.d.ts +13 -0
- package/dist/{chunk-BERPNPEZ.js → core/utils/arrays.mjs} +6 -10
- package/dist/core/utils/building/build-entrypoints.d.ts +3 -0
- package/dist/core/utils/building/build-entrypoints.mjs +47 -0
- package/dist/core/utils/building/detect-dev-changes.d.ts +57 -0
- package/dist/core/utils/building/detect-dev-changes.mjs +93 -0
- package/dist/core/utils/building/find-entrypoints.d.ts +5 -0
- package/dist/core/utils/building/find-entrypoints.mjs +385 -0
- package/dist/core/utils/building/generate-wxt-dir.d.ts +5 -0
- package/dist/core/utils/building/generate-wxt-dir.mjs +192 -0
- package/dist/core/utils/building/group-entrypoints.d.ts +8 -0
- package/dist/core/utils/building/group-entrypoints.mjs +37 -0
- package/dist/core/utils/building/import-entrypoint.d.ts +16 -0
- package/dist/core/utils/building/import-entrypoint.mjs +97 -0
- package/dist/core/utils/building/index.d.ts +9 -0
- package/dist/core/utils/building/index.mjs +9 -0
- package/dist/core/utils/building/internal-build.d.ts +12 -0
- package/dist/core/utils/building/internal-build.mjs +112 -0
- package/dist/core/utils/building/rebuild.d.ts +23 -0
- package/dist/core/utils/building/rebuild.mjs +39 -0
- package/dist/core/utils/building/resolve-config.d.ts +11 -0
- package/dist/core/utils/building/resolve-config.mjs +364 -0
- package/dist/core/utils/cache.d.ts +8 -0
- package/dist/core/utils/cache.mjs +21 -0
- package/dist/core/utils/cli.d.ts +3 -0
- package/dist/core/utils/cli.mjs +26 -0
- package/dist/core/utils/constants.d.ts +5 -0
- package/dist/core/utils/constants.mjs +1 -0
- package/dist/core/utils/content-scripts.d.ts +11 -0
- package/dist/core/utils/content-scripts.mjs +60 -0
- package/dist/core/utils/content-security-policy.d.ts +14 -0
- package/dist/core/utils/content-security-policy.mjs +39 -0
- package/dist/core/utils/entrypoints.d.ts +25 -0
- package/dist/core/utils/entrypoints.mjs +31 -0
- package/dist/core/utils/eslint.d.ts +1 -0
- package/dist/core/utils/eslint.mjs +11 -0
- package/dist/core/utils/fs.d.ts +13 -0
- package/dist/core/utils/fs.mjs +15 -0
- package/dist/core/utils/globals.d.ts +11 -0
- package/dist/core/utils/globals.mjs +53 -0
- package/dist/core/utils/i18n.d.ts +11 -0
- package/dist/core/utils/i18n.mjs +35 -0
- package/dist/core/utils/log/index.d.ts +4 -0
- package/dist/core/utils/log/index.mjs +4 -0
- package/dist/core/utils/log/printBuildSummary.d.ts +2 -0
- package/dist/core/utils/log/printBuildSummary.mjs +32 -0
- package/dist/core/utils/log/printFileList.d.ts +1 -0
- package/dist/core/utils/log/printFileList.mjs +42 -0
- package/dist/core/utils/log/printHeader.d.ts +1 -0
- package/dist/core/utils/log/printHeader.mjs +7 -0
- package/dist/core/utils/log/printTable.d.ts +1 -0
- package/dist/core/utils/log/printTable.mjs +22 -0
- package/dist/core/utils/manifest.d.ts +44 -0
- package/dist/core/utils/manifest.mjs +512 -0
- package/dist/core/utils/network.d.ts +7 -0
- package/dist/core/utils/network.mjs +38 -0
- package/dist/core/utils/package.d.ts +6 -0
- package/dist/core/utils/package.mjs +14 -0
- package/dist/core/utils/paths.d.ts +11 -0
- package/dist/core/utils/paths.mjs +10 -0
- package/dist/core/utils/strings.d.ts +14 -0
- package/dist/core/utils/strings.mjs +18 -0
- package/dist/core/utils/testing/fake-objects.d.ts +4556 -0
- package/dist/core/utils/testing/fake-objects.mjs +322 -0
- package/dist/core/utils/time.d.ts +9 -0
- package/dist/core/utils/time.mjs +17 -0
- package/dist/core/utils/transform.d.ts +9 -0
- package/dist/core/utils/transform.mjs +17 -0
- package/dist/core/utils/types.d.ts +10 -0
- package/dist/core/utils/types.mjs +0 -0
- package/dist/core/utils/validation.d.ts +15 -0
- package/dist/core/utils/validation.mjs +55 -0
- package/dist/core/utils/virtual-modules.d.ts +22 -0
- package/dist/core/utils/virtual-modules.mjs +14 -0
- package/dist/core/utils/wsl.d.ts +4 -0
- package/dist/core/utils/wsl.mjs +4 -0
- package/dist/core/wxt.d.ts +19 -0
- package/dist/core/wxt.mjs +41 -0
- package/dist/core/zip.d.ts +7 -0
- package/dist/core/zip.mjs +137 -0
- package/dist/index.d.ts +4 -79
- package/dist/index.mjs +3 -0
- package/dist/modules.d.ts +10 -20
- package/dist/{chunk-6XSIWUWF.js → modules.mjs} +7 -16
- package/dist/sandbox/define-app-config.d.ts +19 -0
- package/dist/sandbox/define-app-config.mjs +3 -0
- package/dist/sandbox/define-background.d.ts +3 -0
- package/dist/sandbox/define-background.mjs +4 -0
- package/dist/sandbox/define-content-script.d.ts +2 -0
- package/dist/sandbox/define-content-script.mjs +3 -0
- package/dist/sandbox/define-unlisted-script.d.ts +3 -0
- package/dist/sandbox/define-unlisted-script.mjs +4 -0
- package/dist/sandbox/define-wxt-plugin.d.ts +2 -0
- package/dist/sandbox/define-wxt-plugin.mjs +3 -0
- package/dist/sandbox/dev-server-websocket.d.ts +21 -0
- package/dist/sandbox/dev-server-websocket.mjs +37 -0
- package/dist/sandbox/index.d.ts +11 -0
- package/dist/sandbox/index.mjs +6 -0
- package/dist/sandbox/utils/logger.d.ts +9 -0
- package/dist/sandbox/utils/logger.mjs +15 -0
- package/dist/storage.d.ts +39 -16
- package/dist/{storage.js → storage.mjs} +30 -41
- package/dist/testing/fake-browser.d.ts +1 -0
- package/dist/testing/fake-browser.mjs +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.mjs +2 -0
- package/dist/{testing.d.ts → testing/wxt-vitest-plugin.d.ts} +3 -15
- package/dist/testing/wxt-vitest-plugin.mjs +26 -0
- package/dist/{index-nWRfwAJi.d.cts → types.d.ts} +150 -264
- package/dist/types.mjs +0 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.mjs +1 -0
- package/dist/virtual/{background-entrypoint.js → background-entrypoint.mjs} +31 -40
- package/dist/virtual/{content-script-isolated-world-entrypoint.js → content-script-isolated-world-entrypoint.mjs} +9 -13
- package/dist/virtual/{content-script-main-world-entrypoint.js → content-script-main-world-entrypoint.mjs} +9 -14
- package/dist/virtual/mock-browser.mjs +6 -0
- package/dist/virtual/{reload-html.js → reload-html.mjs} +8 -9
- package/dist/virtual/{unlisted-script-entrypoint.js → unlisted-script-entrypoint.mjs} +8 -12
- package/package.json +47 -57
- package/dist/browser.d.ts +0 -18
- package/dist/browser.js +0 -6
- package/dist/chunk-BM6QYGAW.js +0 -1063
- package/dist/chunk-FNTE2L27.js +0 -7
- package/dist/chunk-FP7RYLVL.js +0 -3617
- package/dist/chunk-KPD5J7PZ.js +0 -1065
- package/dist/chunk-QGM4M3NI.js +0 -37
- package/dist/chunk-SGKCDMVR.js +0 -38
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -4438
- package/dist/client.js +0 -424
- package/dist/define-app-config-bg54F_lV.d.ts +0 -294
- package/dist/execa-4UBDUBJZ.js +0 -7244
- package/dist/execa-QLUM2B3W.js +0 -7245
- package/dist/index-nWRfwAJi.d.ts +0 -1401
- package/dist/index.cjs +0 -14473
- package/dist/index.d.cts +0 -81
- package/dist/index.js +0 -696
- package/dist/modules.cjs +0 -96
- package/dist/modules.d.cts +0 -119
- package/dist/modules.js +0 -17
- package/dist/prompt-25QIVJDC.js +0 -755
- package/dist/prompt-7BMKNSWS.js +0 -754
- package/dist/sandbox.d.ts +0 -16
- package/dist/sandbox.js +0 -36
- package/dist/storage.cjs +0 -439
- package/dist/storage.d.cts +0 -200
- package/dist/testing.cjs +0 -2815
- package/dist/testing.d.cts +0 -30
- package/dist/testing.js +0 -40
- package/dist/virtual/mock-browser.js +0 -6
package/bin/wxt.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import '../dist/cli.
|
|
2
|
+
import '../dist/cli/index.mjs';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EXPERIMENTAL
|
|
3
|
+
*
|
|
4
|
+
* Includes the `chrome` API and types when using `extensionApi: 'chrome'`.
|
|
5
|
+
*
|
|
6
|
+
* @module wxt/browser/chrome
|
|
7
|
+
*/
|
|
8
|
+
export interface WxtRuntime {
|
|
9
|
+
}
|
|
10
|
+
export interface WxtI18n {
|
|
11
|
+
}
|
|
12
|
+
export type Chrome = typeof chrome;
|
|
13
|
+
export type WxtBrowser = Omit<Chrome, 'runtime' | 'i18n'> & {
|
|
14
|
+
runtime: WxtRuntime & Omit<Chrome['runtime'], 'getURL'>;
|
|
15
|
+
i18n: WxtI18n & Omit<Chrome['i18n'], 'getMessage'>;
|
|
16
|
+
};
|
|
17
|
+
export declare const browser: WxtBrowser;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Includes the `browser` API and types when using `extensionApi: 'webextension-polyfill'` (the default).
|
|
3
|
+
*
|
|
4
|
+
* @module wxt/browser
|
|
5
|
+
*/
|
|
6
|
+
import { Browser, Runtime, I18n } from 'webextension-polyfill';
|
|
7
|
+
export interface AugmentedBrowser extends Browser {
|
|
8
|
+
runtime: WxtRuntime;
|
|
9
|
+
i18n: WxtI18n;
|
|
10
|
+
}
|
|
11
|
+
export interface WxtRuntime extends Runtime.Static {
|
|
12
|
+
}
|
|
13
|
+
export interface WxtI18n extends I18n.Static {
|
|
14
|
+
}
|
|
15
|
+
export declare const browser: AugmentedBrowser;
|
|
16
|
+
/** @ignore */
|
|
17
|
+
export type { ActivityLog, Alarms, Bookmarks, Action, BrowserAction, BrowserSettings, BrowsingData, CaptivePortal, Clipboard, Commands, ContentScripts, ContextualIdentities, Cookies, DeclarativeNetRequest, Devtools, Dns, Downloads, Events, Experiments, Extension, ExtensionTypes, Find, GeckoProfiler, History, I18n, Identity, Idle, Management, Manifest, // TODO: Export custom manifest types that are valid for both Chrome and Firefox.
|
|
18
|
+
ContextMenus, Menus, NetworkStatus, NormandyAddonStudy, Notifications, Omnibox, PageAction, Permissions, Pkcs11, Privacy, Proxy, Runtime, Scripting, Search, Sessions, SidebarAction, Storage, Tabs, Theme, TopSites, Types, Urlbar, UserScripts, WebNavigation, WebRequest, Windows, } from 'webextension-polyfill';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { EslintGlobalsPropValue, WxtDirFileEntry, WxtModule, WxtResolvedUnimportOptions } from '../types';
|
|
2
|
+
import { type Unimport } from 'unimport';
|
|
3
|
+
import { Plugin } from 'vite';
|
|
4
|
+
declare const _default: WxtModule<import("../types").WxtModuleOptions>;
|
|
5
|
+
export default _default;
|
|
6
|
+
export declare function vitePlugin(unimport: Unimport): Plugin;
|
|
7
|
+
export declare function getEslint8ConfigEntry(options: WxtResolvedUnimportOptions, globals: Record<string, EslintGlobalsPropValue>): WxtDirFileEntry;
|
|
8
|
+
export declare function getEslint9ConfigEntry(options: WxtResolvedUnimportOptions, globals: Record<string, EslintGlobalsPropValue>): WxtDirFileEntry;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { addViteConfig, defineWxtModule } from "../modules.mjs";
|
|
2
|
+
import { createUnimport } from "unimport";
|
|
3
|
+
import { extname } from "node:path";
|
|
4
|
+
export default defineWxtModule({
|
|
5
|
+
name: "wxt:built-in:unimport",
|
|
6
|
+
setup(wxt) {
|
|
7
|
+
const options = wxt.config.imports;
|
|
8
|
+
if (options === false) return;
|
|
9
|
+
let unimport;
|
|
10
|
+
wxt.hooks.hook("ready", () => {
|
|
11
|
+
const addModuleImports = (module) => {
|
|
12
|
+
if (!module.imports) return;
|
|
13
|
+
options.imports ??= [];
|
|
14
|
+
options.imports.push(...module.imports);
|
|
15
|
+
};
|
|
16
|
+
wxt.config.builtinModules.forEach(addModuleImports);
|
|
17
|
+
wxt.config.userModules.forEach(addModuleImports);
|
|
18
|
+
});
|
|
19
|
+
wxt.hooks.afterEach((event) => {
|
|
20
|
+
if (event.name === "ready") {
|
|
21
|
+
unimport = createUnimport(options);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
wxt.hooks.hook("prepare:types", async (_, entries) => {
|
|
25
|
+
await unimport.init();
|
|
26
|
+
entries.push(await getImportsDeclarationEntry(unimport));
|
|
27
|
+
if (options.eslintrc.enabled === false) return;
|
|
28
|
+
entries.push(
|
|
29
|
+
await getEslintConfigEntry(unimport, options.eslintrc.enabled, options)
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
addViteConfig(wxt, () => ({
|
|
33
|
+
plugins: [vitePlugin(unimport)]
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
export function vitePlugin(unimport) {
|
|
38
|
+
const ENABLED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
39
|
+
".js",
|
|
40
|
+
".jsx",
|
|
41
|
+
".ts",
|
|
42
|
+
".tsx",
|
|
43
|
+
".vue",
|
|
44
|
+
".svelte"
|
|
45
|
+
]);
|
|
46
|
+
return {
|
|
47
|
+
name: "wxt:unimport",
|
|
48
|
+
async transform(code, id) {
|
|
49
|
+
if (id.includes("node_modules")) return;
|
|
50
|
+
if (!ENABLED_EXTENSIONS.has(extname(id))) return;
|
|
51
|
+
const injected = await unimport.injectImports(code, id);
|
|
52
|
+
return {
|
|
53
|
+
code: injected.code,
|
|
54
|
+
map: injected.s.generateMap({ hires: "boundary", source: id })
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function getImportsDeclarationEntry(unimport) {
|
|
60
|
+
await unimport.init();
|
|
61
|
+
return {
|
|
62
|
+
path: "types/imports.d.ts",
|
|
63
|
+
text: [
|
|
64
|
+
"// Generated by wxt",
|
|
65
|
+
await unimport.generateTypeDeclarations(),
|
|
66
|
+
""
|
|
67
|
+
].join("\n"),
|
|
68
|
+
tsReference: true
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async function getEslintConfigEntry(unimport, version, options) {
|
|
72
|
+
const globals = (await unimport.getImports()).map((i) => i.as ?? i.name).filter(Boolean).sort().reduce((globals2, name) => {
|
|
73
|
+
globals2[name] = options.eslintrc.globalsPropValue;
|
|
74
|
+
return globals2;
|
|
75
|
+
}, {});
|
|
76
|
+
if (version <= 8) return getEslint8ConfigEntry(options, globals);
|
|
77
|
+
else return getEslint9ConfigEntry(options, globals);
|
|
78
|
+
}
|
|
79
|
+
export function getEslint8ConfigEntry(options, globals) {
|
|
80
|
+
return {
|
|
81
|
+
path: options.eslintrc.filePath,
|
|
82
|
+
text: JSON.stringify({ globals }, null, 2) + "\n"
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function getEslint9ConfigEntry(options, globals) {
|
|
86
|
+
return {
|
|
87
|
+
path: options.eslintrc.filePath,
|
|
88
|
+
text: `const globals = ${JSON.stringify(globals, null, 2)}
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
name: "wxt/auto-imports",
|
|
92
|
+
languageOptions: {
|
|
93
|
+
globals,
|
|
94
|
+
sourceType: "module",
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
`
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CAC, Command } from 'cac';
|
|
2
|
+
/**
|
|
3
|
+
* Wrap an action handler to add a timer, error handling, and maybe enable debug mode.
|
|
4
|
+
*/
|
|
5
|
+
export declare function wrapAction(cb: (...args: any[]) => void | {
|
|
6
|
+
isOngoing?: boolean;
|
|
7
|
+
} | Promise<void | {
|
|
8
|
+
isOngoing?: boolean;
|
|
9
|
+
}>, options?: {
|
|
10
|
+
disableFinishedLog?: boolean;
|
|
11
|
+
}): (...args: any[]) => Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Array flags, when not passed, are either `undefined` or `[undefined]`. This function filters out
|
|
14
|
+
* the
|
|
15
|
+
*/
|
|
16
|
+
export declare function getArrayFromFlags<T>(flags: any, name: string): T[] | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* @param base Command to add this one to
|
|
19
|
+
* @param name The command name to add
|
|
20
|
+
* @param alias The CLI tool being aliased
|
|
21
|
+
* @param bin The CLI tool binary name. Usually the same as the alias
|
|
22
|
+
* @param docsUrl URL to the docs for the aliased CLI tool
|
|
23
|
+
*/
|
|
24
|
+
export declare function createAliasedCommand(base: CAC, name: string, alias: string, bin: string, docsUrl: string): void;
|
|
25
|
+
export declare function isAliasedCommand(command: Command | undefined): boolean;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import consola, { LogLevels } from "consola";
|
|
2
|
+
import { filterTruthy, toArray } from "../core/utils/arrays.mjs";
|
|
3
|
+
import { printHeader } from "../core/utils/log/index.mjs";
|
|
4
|
+
import { formatDuration } from "../core/utils/time.mjs";
|
|
5
|
+
import { ValidationError } from "../core/utils/validation.mjs";
|
|
6
|
+
import { registerWxt } from "../core/wxt.mjs";
|
|
7
|
+
export function wrapAction(cb, options) {
|
|
8
|
+
return async (...args) => {
|
|
9
|
+
const isDebug = !!args.find((arg) => arg?.debug);
|
|
10
|
+
if (isDebug) {
|
|
11
|
+
consola.level = LogLevels.debug;
|
|
12
|
+
}
|
|
13
|
+
const startTime = Date.now();
|
|
14
|
+
try {
|
|
15
|
+
printHeader();
|
|
16
|
+
const status = await cb(...args);
|
|
17
|
+
if (!status?.isOngoing && !options?.disableFinishedLog)
|
|
18
|
+
consola.success(
|
|
19
|
+
`Finished in ${formatDuration(Date.now() - startTime)}`
|
|
20
|
+
);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
consola.fail(
|
|
23
|
+
`Command failed after ${formatDuration(Date.now() - startTime)}`
|
|
24
|
+
);
|
|
25
|
+
if (err instanceof ValidationError) {
|
|
26
|
+
} else {
|
|
27
|
+
consola.error(err);
|
|
28
|
+
}
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function getArrayFromFlags(flags, name) {
|
|
34
|
+
const array = toArray(flags[name]);
|
|
35
|
+
const result = filterTruthy(array);
|
|
36
|
+
return result.length ? result : void 0;
|
|
37
|
+
}
|
|
38
|
+
const aliasCommandNames = /* @__PURE__ */ new Set();
|
|
39
|
+
export function createAliasedCommand(base, name, alias, bin, docsUrl) {
|
|
40
|
+
const aliasedCommand = base.command(name, `Alias for ${alias} (${docsUrl})`).allowUnknownOptions().action(async () => {
|
|
41
|
+
try {
|
|
42
|
+
await registerWxt("build");
|
|
43
|
+
const args = process.argv.slice(
|
|
44
|
+
process.argv.indexOf(aliasedCommand.name) + 1
|
|
45
|
+
);
|
|
46
|
+
const { execa } = await import("execa");
|
|
47
|
+
await execa(bin, args, {
|
|
48
|
+
stdio: "inherit"
|
|
49
|
+
});
|
|
50
|
+
} catch {
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
aliasCommandNames.add(aliasedCommand.name);
|
|
55
|
+
}
|
|
56
|
+
export function isAliasedCommand(command) {
|
|
57
|
+
return !!command && aliasCommandNames.has(command.name);
|
|
58
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import cac from "cac";
|
|
2
|
+
import { build, clean, createServer, initialize, prepare, zip } from "../core/index.mjs";
|
|
3
|
+
import {
|
|
4
|
+
createAliasedCommand,
|
|
5
|
+
getArrayFromFlags,
|
|
6
|
+
wrapAction
|
|
7
|
+
} from "./cli-utils.mjs";
|
|
8
|
+
const cli = cac("wxt");
|
|
9
|
+
cli.option("--debug", "enable debug mode");
|
|
10
|
+
cli.command("[root]", "start dev server").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option("-p, --port <port>", "specify a port for the dev server").option(
|
|
11
|
+
"-e, --filter-entrypoint <entrypoint>",
|
|
12
|
+
"only build specific entrypoints",
|
|
13
|
+
{
|
|
14
|
+
type: []
|
|
15
|
+
}
|
|
16
|
+
).option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").action(
|
|
17
|
+
wrapAction(async (root, flags) => {
|
|
18
|
+
const server = await createServer({
|
|
19
|
+
root,
|
|
20
|
+
mode: flags.mode,
|
|
21
|
+
browser: flags.browser,
|
|
22
|
+
manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : void 0,
|
|
23
|
+
configFile: flags.config,
|
|
24
|
+
debug: flags.debug,
|
|
25
|
+
filterEntrypoints: getArrayFromFlags(flags, "filterEntrypoint"),
|
|
26
|
+
dev: flags.port == null ? void 0 : {
|
|
27
|
+
server: {
|
|
28
|
+
port: parseInt(flags.port)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
await server.start();
|
|
33
|
+
return { isOngoing: true };
|
|
34
|
+
})
|
|
35
|
+
);
|
|
36
|
+
cli.command("build [root]", "build for production").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option(
|
|
37
|
+
"-e, --filter-entrypoint <entrypoint>",
|
|
38
|
+
"only build specific entrypoints",
|
|
39
|
+
{
|
|
40
|
+
type: []
|
|
41
|
+
}
|
|
42
|
+
).option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").option("--analyze", "visualize extension bundle").option("--analyze-open", "automatically open stats.html in browser").action(
|
|
43
|
+
wrapAction(async (root, flags) => {
|
|
44
|
+
await build({
|
|
45
|
+
root,
|
|
46
|
+
mode: flags.mode,
|
|
47
|
+
browser: flags.browser,
|
|
48
|
+
manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : void 0,
|
|
49
|
+
configFile: flags.config,
|
|
50
|
+
debug: flags.debug,
|
|
51
|
+
analysis: flags.analyze ? {
|
|
52
|
+
enabled: true,
|
|
53
|
+
open: flags.analyzeOpen
|
|
54
|
+
} : void 0,
|
|
55
|
+
filterEntrypoints: getArrayFromFlags(flags, "filterEntrypoint")
|
|
56
|
+
});
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
cli.command("zip [root]", "build for production and zip output").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").action(
|
|
60
|
+
wrapAction(async (root, flags) => {
|
|
61
|
+
await zip({
|
|
62
|
+
root,
|
|
63
|
+
mode: flags.mode,
|
|
64
|
+
browser: flags.browser,
|
|
65
|
+
manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : void 0,
|
|
66
|
+
configFile: flags.config,
|
|
67
|
+
debug: flags.debug
|
|
68
|
+
});
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
cli.command("prepare [root]", "prepare typescript project").option("-c, --config <file>", "use specified config file").action(
|
|
72
|
+
wrapAction(async (root, flags) => {
|
|
73
|
+
await prepare({
|
|
74
|
+
root,
|
|
75
|
+
configFile: flags.config,
|
|
76
|
+
debug: flags.debug
|
|
77
|
+
});
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
cli.command("clean [root]", "clean generated files and caches").alias("cleanup").option("-c, --config <file>", "use specified config file").action(
|
|
81
|
+
wrapAction(async (root, flags) => {
|
|
82
|
+
await clean({ root, configFile: flags.config, debug: flags.debug });
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
cli.command("init [directory]", "initialize a new project").option("-t, --template <template>", "template to use").option("--pm <packageManager>", "which package manager to use").action(
|
|
86
|
+
wrapAction(
|
|
87
|
+
async (directory, flags) => {
|
|
88
|
+
await initialize({
|
|
89
|
+
directory,
|
|
90
|
+
template: flags.template,
|
|
91
|
+
packageManager: flags.pm
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
{ disableFinishedLog: true }
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
createAliasedCommand(
|
|
98
|
+
cli,
|
|
99
|
+
"submit",
|
|
100
|
+
"publish-extension",
|
|
101
|
+
"wxt-publish-extension",
|
|
102
|
+
"https://www.npmjs.com/publish-browser-extension"
|
|
103
|
+
);
|
|
104
|
+
export default cli;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import cli from "./commands.mjs";
|
|
2
|
+
import { version } from "../version.mjs";
|
|
3
|
+
import { isAliasedCommand } from "./cli-utils.mjs";
|
|
4
|
+
process.env.VITE_CJS_IGNORE_WARNING = "true";
|
|
5
|
+
cli.parse(process.argv, { run: false });
|
|
6
|
+
if (!isAliasedCommand(cli.matchedCommand)) {
|
|
7
|
+
cli.help();
|
|
8
|
+
cli.version(version);
|
|
9
|
+
cli.parse(process.argv, { run: false });
|
|
10
|
+
}
|
|
11
|
+
await cli.runMatchedCommand();
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ContentScriptDefinition } from '../../types';
|
|
2
|
+
import { WxtLocationChangeEvent } from './custom-events';
|
|
3
|
+
/**
|
|
4
|
+
* Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
|
|
5
|
+
* Used to detect and stop content script code when the script is invalidated.
|
|
6
|
+
*
|
|
7
|
+
* It also provides several utilities like `ctx.setTimeout` and `ctx.setInterval` that should be used in
|
|
8
|
+
* content scripts instead of `window.setTimeout` or `window.setInterval`.
|
|
9
|
+
*
|
|
10
|
+
* To create context for testing, you can use the class's constructor:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { ContentScriptContext } from 'wxt/client';
|
|
14
|
+
*
|
|
15
|
+
* test("storage listener should be removed when context is invalidated", () => {
|
|
16
|
+
* const ctx = new ContentScriptContext('test');
|
|
17
|
+
* const item = storage.defineItem("local:count", { defaultValue: 0 });
|
|
18
|
+
* const watcher = vi.fn();
|
|
19
|
+
*
|
|
20
|
+
* const unwatch = item.watch(watcher);
|
|
21
|
+
* ctx.onInvalidated(unwatch); // Listen for invalidate here
|
|
22
|
+
*
|
|
23
|
+
* await item.setValue(1);
|
|
24
|
+
* expect(watcher).toBeCalledTimes(1);
|
|
25
|
+
* expect(watcher).toBeCalledWith(1, 0);
|
|
26
|
+
*
|
|
27
|
+
* ctx.notifyInvalidated(); // Use this function to invalidate the context
|
|
28
|
+
* await item.setValue(2);
|
|
29
|
+
* expect(watcher).toBeCalledTimes(1);
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class ContentScriptContext implements AbortController {
|
|
34
|
+
#private;
|
|
35
|
+
private readonly contentScriptName;
|
|
36
|
+
readonly options?: Omit<ContentScriptDefinition, "main"> | undefined;
|
|
37
|
+
private static SCRIPT_STARTED_MESSAGE_TYPE;
|
|
38
|
+
constructor(contentScriptName: string, options?: Omit<ContentScriptDefinition, "main"> | undefined);
|
|
39
|
+
get signal(): AbortSignal;
|
|
40
|
+
abort(reason?: any): void;
|
|
41
|
+
get isInvalid(): boolean;
|
|
42
|
+
get isValid(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Add a listener that is called when the content script's context is invalidated.
|
|
45
|
+
*
|
|
46
|
+
* @returns A function to remove the listener.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* browser.runtime.onMessage.addListener(cb);
|
|
50
|
+
* const removeInvalidatedListener = ctx.onInvalidated(() => {
|
|
51
|
+
* browser.runtime.onMessage.removeListener(cb);
|
|
52
|
+
* })
|
|
53
|
+
* // ...
|
|
54
|
+
* removeInvalidatedListener();
|
|
55
|
+
*/
|
|
56
|
+
onInvalidated(cb: () => void): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Return a promise that never resolves. Useful if you have an async function that shouldn't run
|
|
59
|
+
* after the context is expired.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const getValueFromStorage = async () => {
|
|
63
|
+
* if (ctx.isInvalid) return ctx.block();
|
|
64
|
+
*
|
|
65
|
+
* // ...
|
|
66
|
+
* }
|
|
67
|
+
*/
|
|
68
|
+
block<T>(): Promise<T>;
|
|
69
|
+
/**
|
|
70
|
+
* Wrapper around `window.setInterval` that automatically clears the interval when invalidated.
|
|
71
|
+
*/
|
|
72
|
+
setInterval(handler: () => void, timeout?: number): number;
|
|
73
|
+
/**
|
|
74
|
+
* Wrapper around `window.setTimeout` that automatically clears the interval when invalidated.
|
|
75
|
+
*/
|
|
76
|
+
setTimeout(handler: () => void, timeout?: number): number;
|
|
77
|
+
/**
|
|
78
|
+
* Wrapper around `window.requestAnimationFrame` that automatically cancels the request when
|
|
79
|
+
* invalidated.
|
|
80
|
+
*/
|
|
81
|
+
requestAnimationFrame(callback: FrameRequestCallback): number;
|
|
82
|
+
/**
|
|
83
|
+
* Wrapper around `window.requestIdleCallback` that automatically cancels the request when
|
|
84
|
+
* invalidated.
|
|
85
|
+
*/
|
|
86
|
+
requestIdleCallback(callback: IdleRequestCallback, options?: IdleRequestOptions): number;
|
|
87
|
+
/**
|
|
88
|
+
* Call `target.addEventListener` and remove the event listener when the context is invalidated.
|
|
89
|
+
*
|
|
90
|
+
* Includes additional events useful for content scripts:
|
|
91
|
+
*
|
|
92
|
+
* - `"wxt:locationchange"` - Triggered when HTML5 history mode is used to change URL. Content
|
|
93
|
+
* scripts are not reloaded when navigating this way, so this can be used to reset the content
|
|
94
|
+
* script state on URL change, or run custom code.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ctx.addEventListener(document, "visibilitychange", () => {
|
|
98
|
+
* // ...
|
|
99
|
+
* });
|
|
100
|
+
* ctx.addEventListener(document, "wxt:locationchange", () => {
|
|
101
|
+
* // ...
|
|
102
|
+
* });
|
|
103
|
+
*/
|
|
104
|
+
addEventListener<TTarget extends EventTarget, TType extends keyof WxtContentScriptEventMap>(target: TTarget, type: TType, handler: (event: WxtContentScriptEventMap[TType]) => void, options?: AddEventListenerOptions): void;
|
|
105
|
+
/**
|
|
106
|
+
* @internal
|
|
107
|
+
* Abort the abort controller and execute all `onInvalidated` listeners.
|
|
108
|
+
*/
|
|
109
|
+
notifyInvalidated(): void;
|
|
110
|
+
}
|
|
111
|
+
interface WxtContentScriptEventMap extends WindowEventMap {
|
|
112
|
+
'wxt:locationchange': WxtLocationChangeEvent;
|
|
113
|
+
}
|
|
114
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { browser } from "wxt/browser";
|
|
2
|
+
import { logger } from "../../sandbox/utils/logger.mjs";
|
|
3
|
+
import { getUniqueEventName } from "./custom-events.mjs";
|
|
4
|
+
import { createLocationWatcher } from "./location-watcher.mjs";
|
|
5
|
+
export class ContentScriptContext {
|
|
6
|
+
constructor(contentScriptName, options) {
|
|
7
|
+
this.contentScriptName = contentScriptName;
|
|
8
|
+
this.options = options;
|
|
9
|
+
this.#abortController = new AbortController();
|
|
10
|
+
if (this.#isTopFrame) {
|
|
11
|
+
this.#stopOldScripts();
|
|
12
|
+
}
|
|
13
|
+
this.setTimeout(() => {
|
|
14
|
+
this.#listenForNewerScripts();
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
static SCRIPT_STARTED_MESSAGE_TYPE = "wxt:content-script-started";
|
|
18
|
+
#isTopFrame = window.self === window.top;
|
|
19
|
+
#abortController;
|
|
20
|
+
#locationWatcher = createLocationWatcher(this);
|
|
21
|
+
get signal() {
|
|
22
|
+
return this.#abortController.signal;
|
|
23
|
+
}
|
|
24
|
+
abort(reason) {
|
|
25
|
+
return this.#abortController.abort(reason);
|
|
26
|
+
}
|
|
27
|
+
get isInvalid() {
|
|
28
|
+
if (browser.runtime.id == null) {
|
|
29
|
+
this.notifyInvalidated();
|
|
30
|
+
}
|
|
31
|
+
return this.signal.aborted;
|
|
32
|
+
}
|
|
33
|
+
get isValid() {
|
|
34
|
+
return !this.isInvalid;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Add a listener that is called when the content script's context is invalidated.
|
|
38
|
+
*
|
|
39
|
+
* @returns A function to remove the listener.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* browser.runtime.onMessage.addListener(cb);
|
|
43
|
+
* const removeInvalidatedListener = ctx.onInvalidated(() => {
|
|
44
|
+
* browser.runtime.onMessage.removeListener(cb);
|
|
45
|
+
* })
|
|
46
|
+
* // ...
|
|
47
|
+
* removeInvalidatedListener();
|
|
48
|
+
*/
|
|
49
|
+
onInvalidated(cb) {
|
|
50
|
+
this.signal.addEventListener("abort", cb);
|
|
51
|
+
return () => this.signal.removeEventListener("abort", cb);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Return a promise that never resolves. Useful if you have an async function that shouldn't run
|
|
55
|
+
* after the context is expired.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const getValueFromStorage = async () => {
|
|
59
|
+
* if (ctx.isInvalid) return ctx.block();
|
|
60
|
+
*
|
|
61
|
+
* // ...
|
|
62
|
+
* }
|
|
63
|
+
*/
|
|
64
|
+
block() {
|
|
65
|
+
return new Promise(() => {
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Wrapper around `window.setInterval` that automatically clears the interval when invalidated.
|
|
70
|
+
*/
|
|
71
|
+
setInterval(handler, timeout) {
|
|
72
|
+
const id = setInterval(() => {
|
|
73
|
+
if (this.isValid) handler();
|
|
74
|
+
}, timeout);
|
|
75
|
+
this.onInvalidated(() => clearInterval(id));
|
|
76
|
+
return id;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Wrapper around `window.setTimeout` that automatically clears the interval when invalidated.
|
|
80
|
+
*/
|
|
81
|
+
setTimeout(handler, timeout) {
|
|
82
|
+
const id = setTimeout(() => {
|
|
83
|
+
if (this.isValid) handler();
|
|
84
|
+
}, timeout);
|
|
85
|
+
this.onInvalidated(() => clearTimeout(id));
|
|
86
|
+
return id;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Wrapper around `window.requestAnimationFrame` that automatically cancels the request when
|
|
90
|
+
* invalidated.
|
|
91
|
+
*/
|
|
92
|
+
requestAnimationFrame(callback) {
|
|
93
|
+
const id = requestAnimationFrame((...args) => {
|
|
94
|
+
if (this.isValid) callback(...args);
|
|
95
|
+
});
|
|
96
|
+
this.onInvalidated(() => cancelAnimationFrame(id));
|
|
97
|
+
return id;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Wrapper around `window.requestIdleCallback` that automatically cancels the request when
|
|
101
|
+
* invalidated.
|
|
102
|
+
*/
|
|
103
|
+
requestIdleCallback(callback, options) {
|
|
104
|
+
const id = requestIdleCallback((...args) => {
|
|
105
|
+
if (!this.signal.aborted) callback(...args);
|
|
106
|
+
}, options);
|
|
107
|
+
this.onInvalidated(() => cancelIdleCallback(id));
|
|
108
|
+
return id;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Call `target.addEventListener` and remove the event listener when the context is invalidated.
|
|
112
|
+
*
|
|
113
|
+
* Includes additional events useful for content scripts:
|
|
114
|
+
*
|
|
115
|
+
* - `"wxt:locationchange"` - Triggered when HTML5 history mode is used to change URL. Content
|
|
116
|
+
* scripts are not reloaded when navigating this way, so this can be used to reset the content
|
|
117
|
+
* script state on URL change, or run custom code.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ctx.addEventListener(document, "visibilitychange", () => {
|
|
121
|
+
* // ...
|
|
122
|
+
* });
|
|
123
|
+
* ctx.addEventListener(document, "wxt:locationchange", () => {
|
|
124
|
+
* // ...
|
|
125
|
+
* });
|
|
126
|
+
*/
|
|
127
|
+
addEventListener(target, type, handler, options) {
|
|
128
|
+
if (type === "wxt:locationchange") {
|
|
129
|
+
if (this.isValid) this.#locationWatcher.run();
|
|
130
|
+
}
|
|
131
|
+
target.addEventListener?.(
|
|
132
|
+
type.startsWith("wxt:") ? getUniqueEventName(type) : type,
|
|
133
|
+
// @ts-expect-error: Event don't match, but that's OK, EventTarget doesn't allow custom types in the callback
|
|
134
|
+
handler,
|
|
135
|
+
{
|
|
136
|
+
...options,
|
|
137
|
+
signal: this.signal
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* @internal
|
|
143
|
+
* Abort the abort controller and execute all `onInvalidated` listeners.
|
|
144
|
+
*/
|
|
145
|
+
notifyInvalidated() {
|
|
146
|
+
this.abort("Content script context invalidated");
|
|
147
|
+
logger.debug(
|
|
148
|
+
`Content script "${this.contentScriptName}" context invalidated`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
#stopOldScripts() {
|
|
152
|
+
window.postMessage(
|
|
153
|
+
{
|
|
154
|
+
type: ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE,
|
|
155
|
+
contentScriptName: this.contentScriptName
|
|
156
|
+
},
|
|
157
|
+
"*"
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
#listenForNewerScripts() {
|
|
161
|
+
const cb = (event) => {
|
|
162
|
+
if (event.data?.type === ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE && event.data?.contentScriptName === this.contentScriptName) {
|
|
163
|
+
this.notifyInvalidated();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
addEventListener("message", cb);
|
|
167
|
+
this.onInvalidated(() => removeEventListener("message", cb));
|
|
168
|
+
}
|
|
169
|
+
}
|