extension-develop 3.0.0-next.62 → 3.0.0-next.68
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/README.md +56 -16
- package/dist/content-script-wrapper.js +34 -11
- package/dist/extension-js-theme/chrome/manifest.json +65 -0
- package/dist/extension-js-theme/chromium/manifest.json +65 -0
- package/dist/extension-js-theme/edge/manifest.json +65 -0
- package/dist/extension-js-theme/firefox/manifest.json +6 -0
- package/dist/main-world-bridge.js +97 -0
- package/dist/minimum-script-file.js +24 -0
- package/dist/module.js +2305 -1137
- package/dist/warn-no-default-export.js +5 -1
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
[npm-version-image]: https://img.shields.io/npm/v/extension-develop.svg?color=0971fe
|
|
2
2
|
[npm-version-url]: https://www.npmjs.com/package/extension-develop
|
|
3
|
-
[downloads-image]: https://img.shields.io/npm/dm/extension-develop.svg?color=
|
|
4
|
-
[downloads-url]: https://npmjs.
|
|
5
|
-
[
|
|
6
|
-
[
|
|
3
|
+
[npm-downloads-image]: https://img.shields.io/npm/dm/extension-develop.svg?color=0971fe
|
|
4
|
+
[npm-downloads-url]: https://www.npmjs.com/package/extension-develop
|
|
5
|
+
[powered-image]: https://img.shields.io/badge/Powered%20by-Extension.js-0971fe
|
|
6
|
+
[powered-url]: https://extension.js.org
|
|
7
|
+
[action-image]: https://github.com/extension-js/extension.js/actions/workflows/ci.yml/badge.svg?branch=main&color=0971fe
|
|
8
|
+
[action-url]: https://github.com/extension-js/extension.js/actions
|
|
7
9
|
|
|
8
|
-
[![
|
|
10
|
+
[![Powered by Extension.js][powered-image]][powered-url]
|
|
9
11
|
|
|
10
|
-
# extension-develop
|
|
12
|
+
# extension-develop [![Version][npm-version-image]][npm-version-url] [![Downloads][npm-downloads-image]][npm-downloads-url] [![workflow][action-image]][action-url]
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
Develop, build, preview, and package [Extension.js](https://extension.js.org) projects.
|
|
13
15
|
|
|
14
16
|
This package powers Extension.js during local development and production builds. It provides the commands and build plugins that compile your extension, run it in browsers, and produce distributable artifacts.
|
|
15
17
|
|
|
@@ -68,18 +70,18 @@ run()
|
|
|
68
70
|
- Zipping: distribution and/or source packages (respects `.gitignore`)
|
|
69
71
|
- Auto-install of missing dependencies and package manager detection
|
|
70
72
|
- Type generation for TS projects via `extension-env.d.ts`
|
|
71
|
-
- User config via `extension.config.(js|mjs)` for commands, browser
|
|
73
|
+
- User config via `extension.config.(js|mjs)` for commands, browser start, unified logger defaults, and webpack config hooks
|
|
72
74
|
- Managed dependency guard to avoid conflicts
|
|
73
75
|
|
|
74
76
|
## Commands
|
|
75
77
|
|
|
76
|
-
| Name | Summary
|
|
77
|
-
| ------- |
|
|
78
|
-
| dev | - Starts a local development server with live reload/HMR<br/>- Auto-installs dependencies if missing<br/>- Generates TypeScript shim types (`extension-env.d.ts`) when applicable<br/>-
|
|
79
|
-
| build | - Production build using the webpack/Rspack plugin stack<br/>- Cleans `dist/<browser>` before emitting<br/>- Optional packaging: distribution zip and/or source zip<br/>- Merges user config; excludes browser runners during compilation
|
|
80
|
-
| start | - Runs a silent production build, then
|
|
81
|
-
| preview | -
|
|
82
|
-
| cleanup | - Removes orphaned browser instances and temporary profiles created during development
|
|
78
|
+
| Name | Summary |
|
|
79
|
+
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| dev | - Starts a local development server with live reload/HMR<br/>- Auto-installs dependencies if missing<br/>- Generates TypeScript shim types (`extension-env.d.ts`) when applicable<br/>- Runs a target browser with an isolated/stable profile |
|
|
81
|
+
| build | - Production build using the webpack/Rspack plugin stack<br/>- Cleans `dist/<browser>` before emitting<br/>- Optional packaging: distribution zip and/or source zip<br/>- Merges user config; excludes browser runners during compilation |
|
|
82
|
+
| start | - Runs a silent production build, then runs preview from `dist/<browser>`<br/>- Mirrors the runtime environment of shipped output |
|
|
83
|
+
| preview | - Runs the extension for manual testing without dev server<br/>- Uses `dist/<browser>` when present, otherwise uses the project directory<br/>- Preserves production settings; only browser runners are applied |
|
|
84
|
+
| cleanup | - Removes orphaned browser instances and temporary profiles created during development |
|
|
83
85
|
|
|
84
86
|
## Command options
|
|
85
87
|
|
|
@@ -158,10 +160,48 @@ Options accepted by each command. Values shown are typical types or enumerations
|
|
|
158
160
|
- Supported sections:
|
|
159
161
|
- config(config: Configuration): mutate the assembled Rspack config. Supports a function or a plain object. When an object is provided, it is deep‑merged on top of the assembled config.
|
|
160
162
|
- commands.dev | .build | .start | .preview: per‑command options (browser, profile, binaries, flags, preferences, unified logger defaults, packaging). These defaults are applied for all respective commands.
|
|
161
|
-
- browser.chrome | .firefox | .edge | .chromium-based | .gecko-based:
|
|
163
|
+
- browser.chrome | .firefox | .edge | .chromium-based | .gecko-based: start flags, excluded flags, preferences, binaries, and profile reuse (persistProfile).
|
|
164
|
+
- extensions: load-only companion extensions (unpacked dirs) loaded alongside your extension in dev/preview/start.
|
|
165
|
+
- Example: { dir: "./extensions" } loads every "./extensions/\*" folder that contains a manifest.json.
|
|
162
166
|
- Precedence when composing options: browser._ → commands._ → CLI flags. CLI flags always win over config defaults.
|
|
167
|
+
- Browser key aliases when resolving `browser.*` from `extension.config.*`:
|
|
168
|
+
- When the runtime asks for `chromium`, `loadBrowserConfig` prefers `browser.chromium` and then falls back to `browser['chromium-based']`.
|
|
169
|
+
- When the runtime asks for `chromium-based`, it prefers `browser['chromium-based']` and then `browser.chromium`.
|
|
170
|
+
- When the runtime asks for `firefox`, it prefers `browser.firefox` and then `browser['gecko-based']`.
|
|
171
|
+
- When the runtime asks for `gecko-based`, it prefers `browser['gecko-based']` and then `browser.firefox`.
|
|
163
172
|
- When detected, a one‑time notice is printed to indicate config is active.
|
|
164
173
|
|
|
174
|
+
### Companion extensions (load-only)
|
|
175
|
+
|
|
176
|
+
Use this when you have other unpacked extensions you want loaded alongside your main extension during `dev`, `start`, and `preview`.
|
|
177
|
+
|
|
178
|
+
- **What it loads**: directories that contain a `manifest.json` at their root (unpacked extension roots).
|
|
179
|
+
- **How they’re loaded**: they’re appended into the browser runner’s `--load-extension` list (Chromium) / addon install list (Firefox) **before** your extension. Your extension is always loaded last for precedence.
|
|
180
|
+
- **Discovery**:
|
|
181
|
+
- `extensions.dir`: scans one level deep (e.g. `./extensions/*/manifest.json`)
|
|
182
|
+
- `extensions.paths`: explicit directories (absolute or relative to the project root)
|
|
183
|
+
- **Overrides**: top-level `extensions` applies to all commands, but `commands.<cmd>.extensions` overrides it for that command.
|
|
184
|
+
- **Invalid entries**: ignored. In author mode (`EXTENSION_AUTHOR_MODE=true`) we print a warning if `extensions` is configured but nothing resolves.
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
// extension.config.mjs
|
|
190
|
+
export default {
|
|
191
|
+
// Applies to dev/start/preview unless overridden per-command
|
|
192
|
+
extensions: {
|
|
193
|
+
dir: './extensions',
|
|
194
|
+
paths: ['./vendor/some-unpacked-extension']
|
|
195
|
+
},
|
|
196
|
+
commands: {
|
|
197
|
+
dev: {
|
|
198
|
+
// Override only for dev
|
|
199
|
+
extensions: ['./extensions/debug-helper']
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
165
205
|
### Environment variables in `extension.config.*`
|
|
166
206
|
|
|
167
207
|
- `extension.config.*` runs in a Node context during command startup.
|
|
@@ -72,12 +72,16 @@ function content_script_wrapper(source) {
|
|
|
72
72
|
}
|
|
73
73
|
const resourceAbsPath = external_path_default().normalize(this.resourcePath);
|
|
74
74
|
const isDeclaredContentScript = declaredContentJsAbsPaths.some((abs)=>resourceAbsPath === external_path_default().normalize(abs));
|
|
75
|
-
|
|
75
|
+
const scriptsDir = external_path_default().resolve(projectPath, "scripts");
|
|
76
|
+
const relToScripts = external_path_default().relative(scriptsDir, resourceAbsPath);
|
|
77
|
+
const isScriptsFolderScript = relToScripts && !relToScripts.startsWith('..') && !external_path_default().isAbsolute(relToScripts);
|
|
78
|
+
const isContentScriptLike = isDeclaredContentScript || isScriptsFolderScript;
|
|
79
|
+
if (!isContentScriptLike) return source;
|
|
76
80
|
const resourceQuery = String(this.resourceQuery || '');
|
|
77
81
|
const isInnerWrapperRequest = /\b__extjs_inner=1\b/.test(resourceQuery);
|
|
78
82
|
if (!isInnerWrapperRequest) {
|
|
79
83
|
if (isProd) {
|
|
80
|
-
if (!
|
|
84
|
+
if (!isContentScriptLike) return source;
|
|
81
85
|
if (!/\bexport\s+default\b/.test(source)) return source;
|
|
82
86
|
if (source.includes('__EXTENSIONJS_MOUNT_WRAPPED__')) return source;
|
|
83
87
|
const replaced = source.replace(/\bexport\s+default\b/, 'const __EXTENSIONJS_default__ =');
|
|
@@ -101,22 +105,41 @@ function content_script_wrapper(source) {
|
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
const runtimeProdInline = "function __EXTENSIONJS_mount(mount){\n var cleanup;\n function apply(){ cleanup = mount() }\n function unmount(){ if (typeof cleanup === 'function') cleanup() }\n if (typeof document !== 'undefined') {\n if (document.readyState === 'complete') { apply(); }\n else {\n var onReady = function(){ if (document.readyState === 'complete') { document.removeEventListener('readystatechange', onReady); apply(); } };\n document.addEventListener('readystatechange', onReady);\n }\n } else { apply() }\n return unmount;\n}\n";
|
|
104
|
-
const injected = `${runtimeProdInline}${cleaned}\n;/* __EXTENSIONJS_MOUNT_WRAPPED__ */\ntry { __EXTENSIONJS_mount(__EXTENSIONJS_default__) } catch {}\nexport default __EXTENSIONJS_default__\n`;
|
|
108
|
+
const injected = `${runtimeProdInline}${cleaned}\n;/* __EXTENSIONJS_MOUNT_WRAPPED__ */\ntry { __EXTENSIONJS_mount(__EXTENSIONJS_default__) } catch (error) {}\nexport default __EXTENSIONJS_default__\n`;
|
|
105
109
|
return injected;
|
|
106
110
|
}
|
|
107
111
|
const innerSpecifier = JSON.stringify(this.resourcePath.replace(/\\/g, '/') + '?__extjs_inner=1');
|
|
108
112
|
const proxyCode = [
|
|
109
113
|
"/* extension.js content script proxy */",
|
|
114
|
+
'try {',
|
|
115
|
+
" if (typeof location === 'object' && location && !String(location.protocol || '').includes('-extension:')) {",
|
|
116
|
+
" var __extjsProto = (typeof Object === 'function' && Object.getPrototypeOf) ? Object.getPrototypeOf(location) : null;",
|
|
117
|
+
" if (__extjsProto && typeof __extjsProto.reload === 'function' && !__extjsProto.__extjsReloadPatched) {",
|
|
118
|
+
' __extjsProto.__extjsReloadPatched = true;',
|
|
119
|
+
' __extjsProto.__extjsOrigReload = __extjsProto.reload;',
|
|
120
|
+
' __extjsProto.reload = function(){',
|
|
121
|
+
" try { console.warn('[extension.js] blocked HMR-triggered location.reload() in content script context to prevent infinite reload loop. Fix the syntax error and HMR will recover on next successful compile.'); } catch (error) {}",
|
|
122
|
+
' };',
|
|
123
|
+
' }',
|
|
124
|
+
' }',
|
|
125
|
+
'} catch (error) {',
|
|
126
|
+
' // Do nothing',
|
|
127
|
+
'}',
|
|
110
128
|
'function loadInnerWrappedModule(){',
|
|
111
129
|
` try { import(/* webpackMode: "eager" */ ${innerSpecifier}).catch(function(e){ console.warn('[extension.js] content script failed to load. waiting for next successful compile', e) }) } catch (e) { console.warn('[extension.js] content script failed to load. waiting for next successful compile', e) }`,
|
|
112
130
|
'}',
|
|
113
131
|
'loadInnerWrappedModule()',
|
|
114
|
-
'
|
|
115
|
-
'
|
|
116
|
-
' if (
|
|
117
|
-
'
|
|
118
|
-
'}',
|
|
119
|
-
'
|
|
132
|
+
'try {',
|
|
133
|
+
' var hotModuleReplacement = (typeof module !== "undefined" && module && module.hot) ? module.hot : null;',
|
|
134
|
+
' if (hotModuleReplacement) {',
|
|
135
|
+
' var isExtensionJsDisposed = false;',
|
|
136
|
+
' if (typeof hotModuleReplacement.dispose === "function") hotModuleReplacement.dispose(function(){ isExtensionJsDisposed = true });',
|
|
137
|
+
' // Accept updates, but avoid triggering reload from inside accept callback',
|
|
138
|
+
' // (it can run during disposal and cause "[HMR] unexpected require(...) from disposed module" warnings).',
|
|
139
|
+
' if (typeof hotModuleReplacement.accept === "function") hotModuleReplacement.accept();',
|
|
140
|
+
' if (typeof hotModuleReplacement.addStatusHandler === "function") hotModuleReplacement.addStatusHandler(function(status){ if (isExtensionJsDisposed) return; if (status === "idle") loadInnerWrappedModule(); });',
|
|
141
|
+
' }',
|
|
142
|
+
'} catch (error) {}'
|
|
120
143
|
].join('\n');
|
|
121
144
|
return proxyCode;
|
|
122
145
|
}
|
|
@@ -153,8 +176,8 @@ function content_script_wrapper(source) {
|
|
|
153
176
|
null == (_this_emitWarning2 = (_this2 = this).emitWarning) || _this_emitWarning2.call(_this2, new Error(`Removed direct call to ${defaultName}() to prevent double mount; wrapper handles mounting.`));
|
|
154
177
|
}
|
|
155
178
|
}
|
|
156
|
-
const cssAccepts = cssSpecifiers.length ? `\ntry {\n if (import.meta.webpackHot) {\n ${cssSpecifiers.map((s)=>`import.meta.webpackHot.accept(${JSON.stringify(s)}, () => { try { window.dispatchEvent(new CustomEvent('__EXTENSIONJS_CSS_UPDATE__')) } catch {} })`).join('\n ')}\n }\n} catch {}\n` : '';
|
|
157
|
-
const injected = `${runtimeInline}${cleaned}\n;/* __EXTENSIONJS_MOUNT_WRAPPED__ */\ntry { __EXTENSIONJS_mountWithHMR(__EXTENSIONJS_default__) } catch {}\n${cssAccepts}export default __EXTENSIONJS_default__\n`;
|
|
179
|
+
const cssAccepts = cssSpecifiers.length ? `\ntry {\n if (import.meta.webpackHot) {\n ${cssSpecifiers.map((s)=>`import.meta.webpackHot.accept(${JSON.stringify(s)}, () => { try { window.dispatchEvent(new CustomEvent('__EXTENSIONJS_CSS_UPDATE__')) } catch (error) {} })`).join('\n ')}\n }\n} catch (error) {}\n` : '';
|
|
180
|
+
const injected = `${runtimeInline}${cleaned}\n;/* __EXTENSIONJS_MOUNT_WRAPPED__ */\ntry { __EXTENSIONJS_mountWithHMR(__EXTENSIONJS_default__) } catch (error) {}\n${cssAccepts}export default __EXTENSIONJS_default__\n`;
|
|
158
181
|
return injected;
|
|
159
182
|
}
|
|
160
183
|
exports["default"] = __webpack_exports__["default"];
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Extension.js Theme",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Browser theme for Extension.js",
|
|
5
|
+
"manifest_version": 3,
|
|
6
|
+
"theme": {
|
|
7
|
+
"colors": {
|
|
8
|
+
"frame": [
|
|
9
|
+
37,
|
|
10
|
+
37,
|
|
11
|
+
39
|
|
12
|
+
],
|
|
13
|
+
"frame_inactive": [
|
|
14
|
+
49,
|
|
15
|
+
49,
|
|
16
|
+
53
|
|
17
|
+
],
|
|
18
|
+
"toolbar": [
|
|
19
|
+
25,
|
|
20
|
+
25,
|
|
21
|
+
26
|
|
22
|
+
],
|
|
23
|
+
"tab_background_text": [
|
|
24
|
+
255,
|
|
25
|
+
255,
|
|
26
|
+
255
|
|
27
|
+
],
|
|
28
|
+
"tab_text": [
|
|
29
|
+
255,
|
|
30
|
+
255,
|
|
31
|
+
255
|
|
32
|
+
],
|
|
33
|
+
"tab_background_text_inactive": [
|
|
34
|
+
62,
|
|
35
|
+
62,
|
|
36
|
+
66
|
|
37
|
+
],
|
|
38
|
+
"tab_text_inactive": [
|
|
39
|
+
255,
|
|
40
|
+
255,
|
|
41
|
+
255
|
|
42
|
+
],
|
|
43
|
+
"bookmark_text": [
|
|
44
|
+
153,
|
|
45
|
+
153,
|
|
46
|
+
159
|
|
47
|
+
],
|
|
48
|
+
"ntp_background": [
|
|
49
|
+
179,
|
|
50
|
+
179,
|
|
51
|
+
183
|
|
52
|
+
],
|
|
53
|
+
"ntp_text": [
|
|
54
|
+
37,
|
|
55
|
+
37,
|
|
56
|
+
39
|
|
57
|
+
],
|
|
58
|
+
"button_background": [
|
|
59
|
+
28,
|
|
60
|
+
28,
|
|
61
|
+
30
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Extension.js Theme",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Browser theme for Extension.js",
|
|
5
|
+
"manifest_version": 3,
|
|
6
|
+
"theme": {
|
|
7
|
+
"colors": {
|
|
8
|
+
"frame": [
|
|
9
|
+
37,
|
|
10
|
+
37,
|
|
11
|
+
39
|
|
12
|
+
],
|
|
13
|
+
"frame_inactive": [
|
|
14
|
+
49,
|
|
15
|
+
49,
|
|
16
|
+
53
|
|
17
|
+
],
|
|
18
|
+
"toolbar": [
|
|
19
|
+
25,
|
|
20
|
+
25,
|
|
21
|
+
26
|
|
22
|
+
],
|
|
23
|
+
"tab_background_text": [
|
|
24
|
+
255,
|
|
25
|
+
255,
|
|
26
|
+
255
|
|
27
|
+
],
|
|
28
|
+
"tab_text": [
|
|
29
|
+
255,
|
|
30
|
+
255,
|
|
31
|
+
255
|
|
32
|
+
],
|
|
33
|
+
"tab_background_text_inactive": [
|
|
34
|
+
62,
|
|
35
|
+
62,
|
|
36
|
+
66
|
|
37
|
+
],
|
|
38
|
+
"tab_text_inactive": [
|
|
39
|
+
255,
|
|
40
|
+
255,
|
|
41
|
+
255
|
|
42
|
+
],
|
|
43
|
+
"bookmark_text": [
|
|
44
|
+
153,
|
|
45
|
+
153,
|
|
46
|
+
159
|
|
47
|
+
],
|
|
48
|
+
"ntp_background": [
|
|
49
|
+
179,
|
|
50
|
+
179,
|
|
51
|
+
183
|
|
52
|
+
],
|
|
53
|
+
"ntp_text": [
|
|
54
|
+
37,
|
|
55
|
+
37,
|
|
56
|
+
39
|
|
57
|
+
],
|
|
58
|
+
"button_background": [
|
|
59
|
+
28,
|
|
60
|
+
28,
|
|
61
|
+
30
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Extension.js Theme",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Browser theme for Extension.js",
|
|
5
|
+
"manifest_version": 3,
|
|
6
|
+
"theme": {
|
|
7
|
+
"colors": {
|
|
8
|
+
"frame": [
|
|
9
|
+
37,
|
|
10
|
+
37,
|
|
11
|
+
39
|
|
12
|
+
],
|
|
13
|
+
"frame_inactive": [
|
|
14
|
+
49,
|
|
15
|
+
49,
|
|
16
|
+
53
|
|
17
|
+
],
|
|
18
|
+
"toolbar": [
|
|
19
|
+
25,
|
|
20
|
+
25,
|
|
21
|
+
26
|
|
22
|
+
],
|
|
23
|
+
"tab_background_text": [
|
|
24
|
+
255,
|
|
25
|
+
255,
|
|
26
|
+
255
|
|
27
|
+
],
|
|
28
|
+
"tab_text": [
|
|
29
|
+
255,
|
|
30
|
+
255,
|
|
31
|
+
255
|
|
32
|
+
],
|
|
33
|
+
"tab_background_text_inactive": [
|
|
34
|
+
62,
|
|
35
|
+
62,
|
|
36
|
+
66
|
|
37
|
+
],
|
|
38
|
+
"tab_text_inactive": [
|
|
39
|
+
255,
|
|
40
|
+
255,
|
|
41
|
+
255
|
|
42
|
+
],
|
|
43
|
+
"bookmark_text": [
|
|
44
|
+
153,
|
|
45
|
+
153,
|
|
46
|
+
159
|
|
47
|
+
],
|
|
48
|
+
"ntp_background": [
|
|
49
|
+
179,
|
|
50
|
+
179,
|
|
51
|
+
183
|
|
52
|
+
],
|
|
53
|
+
"ntp_text": [
|
|
54
|
+
37,
|
|
55
|
+
37,
|
|
56
|
+
39
|
|
57
|
+
],
|
|
58
|
+
"button_background": [
|
|
59
|
+
28,
|
|
60
|
+
28,
|
|
61
|
+
30
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
var __webpack_exports__ = {};
|
|
2
|
+
const EXTJS_MARK = '__extjs__';
|
|
3
|
+
const REQ_TYPE = 'EXTJS_WTW_LOAD';
|
|
4
|
+
const RES_TYPE = 'EXTJS_WTW_LOADED';
|
|
5
|
+
function safeString(x) {
|
|
6
|
+
return 'string' == typeof x && x.length > 0;
|
|
7
|
+
}
|
|
8
|
+
function hasForbiddenProtocol(url) {
|
|
9
|
+
return /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(url) && !/^((chrome|moz)-extension):\/\//.test(url);
|
|
10
|
+
}
|
|
11
|
+
function getRuntime() {
|
|
12
|
+
try {
|
|
13
|
+
if ('object' == typeof globalThis.browser) return globalThis.browser;
|
|
14
|
+
} catch {}
|
|
15
|
+
try {
|
|
16
|
+
if ('object' == typeof globalThis.chrome) return globalThis.chrome;
|
|
17
|
+
} catch {}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function resolveExtensionUrl(inputUrl) {
|
|
21
|
+
var _rt_runtime;
|
|
22
|
+
if (!safeString(inputUrl)) return null;
|
|
23
|
+
if (hasForbiddenProtocol(inputUrl)) return null;
|
|
24
|
+
if (/^((chrome|moz)-extension):\/\//.test(inputUrl)) return inputUrl;
|
|
25
|
+
const rt = getRuntime();
|
|
26
|
+
const getURL = null == rt ? void 0 : null == (_rt_runtime = rt.runtime) ? void 0 : _rt_runtime.getURL;
|
|
27
|
+
if ('function' != typeof getURL) return null;
|
|
28
|
+
let p = inputUrl;
|
|
29
|
+
try {
|
|
30
|
+
if (p.startsWith('/')) p = new URL('https://example.invalid' + p).pathname;
|
|
31
|
+
else if (p.includes('?') || p.includes('#')) p = p.split('?')[0].split('#')[0];
|
|
32
|
+
} catch {}
|
|
33
|
+
if (!p) return null;
|
|
34
|
+
if (!p.startsWith('/')) p = '/' + p;
|
|
35
|
+
return String(getURL(p));
|
|
36
|
+
}
|
|
37
|
+
function injectScript(src) {
|
|
38
|
+
return new Promise((resolve, reject)=>{
|
|
39
|
+
const el = document.createElement("script");
|
|
40
|
+
el.src = src;
|
|
41
|
+
el.async = false;
|
|
42
|
+
el.onload = ()=>{
|
|
43
|
+
try {
|
|
44
|
+
el.remove();
|
|
45
|
+
} catch {}
|
|
46
|
+
resolve();
|
|
47
|
+
};
|
|
48
|
+
el.onerror = ()=>{
|
|
49
|
+
try {
|
|
50
|
+
el.remove();
|
|
51
|
+
} catch {}
|
|
52
|
+
reject(new Error("Failed to load script: " + src));
|
|
53
|
+
};
|
|
54
|
+
(document.head || document.documentElement).appendChild(el);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function postResponse(res) {
|
|
58
|
+
try {
|
|
59
|
+
window.postMessage(res, '*');
|
|
60
|
+
} catch {}
|
|
61
|
+
}
|
|
62
|
+
window.addEventListener('message', (event)=>{
|
|
63
|
+
if (event.source !== window) return;
|
|
64
|
+
const data = event.data;
|
|
65
|
+
if (!data || true !== data[EXTJS_MARK]) return;
|
|
66
|
+
if (data.type !== REQ_TYPE) return;
|
|
67
|
+
if (!safeString(data.requestId) || !safeString(data.url)) return;
|
|
68
|
+
const requestId = data.requestId;
|
|
69
|
+
const resolved = resolveExtensionUrl(data.url);
|
|
70
|
+
if (!resolved) return void postResponse({
|
|
71
|
+
[EXTJS_MARK]: true,
|
|
72
|
+
type: RES_TYPE,
|
|
73
|
+
requestId,
|
|
74
|
+
ok: false,
|
|
75
|
+
error: 'No extension runtime available to resolve URL'
|
|
76
|
+
});
|
|
77
|
+
injectScript(resolved).then(()=>{
|
|
78
|
+
postResponse({
|
|
79
|
+
[EXTJS_MARK]: true,
|
|
80
|
+
type: RES_TYPE,
|
|
81
|
+
requestId,
|
|
82
|
+
ok: true
|
|
83
|
+
});
|
|
84
|
+
}).catch((e)=>{
|
|
85
|
+
postResponse({
|
|
86
|
+
[EXTJS_MARK]: true,
|
|
87
|
+
type: RES_TYPE,
|
|
88
|
+
requestId,
|
|
89
|
+
ok: false,
|
|
90
|
+
error: e instanceof Error ? e.message : String(e)
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
95
|
+
Object.defineProperty(exports, '__esModule', {
|
|
96
|
+
value: true
|
|
97
|
+
});
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
1
13
|
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
try {
|
|
16
|
+
if ('object' == typeof location && location && String(location.protocol || '').includes('-extension:')) {
|
|
17
|
+
const q = String(location.search || '');
|
|
18
|
+
if (q.toLowerCase().includes('webpack-dev-server-hot=false')) ;
|
|
19
|
+
else if ('function' == typeof URL && 'object' == typeof history && history && 'function' == typeof history.replaceState) {
|
|
20
|
+
const u = new URL(String(location.href));
|
|
21
|
+
u.searchParams.set('webpack-dev-server-hot', 'false');
|
|
22
|
+
history.replaceState(null, '', u.toString());
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
} catch {}
|
|
2
26
|
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
3
27
|
Object.defineProperty(exports, '__esModule', {
|
|
4
28
|
value: true
|