extension-develop 3.10.3 → 3.10.4-canary.1
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/215.cjs +350 -69
- package/dist/323.cjs +456 -26
- package/dist/324.cjs +15 -9
- package/dist/{270.cjs → 677.cjs} +3118 -504
- package/dist/ensure-hmr-for-scripts.cjs +50 -0
- package/dist/ensure-hmr-for-scripts.js +145 -0
- package/dist/feature-scripts-content-script-wrapper.cjs +237 -0
- package/dist/feature-scripts-content-script-wrapper.js +237 -0
- package/dist/main-world-bridge.js +127 -0
- package/dist/minimum-chromium-file.js +10 -0
- package/dist/minimum-firefox-file.js +10 -0
- package/dist/minimum-script-file.js +31 -0
- package/dist/module.cjs +1999 -1690
- package/dist/package.json +3 -0
- package/dist/resolve-paths-loader.js +1350 -0
- package/package.json +5 -5
- package/dist/add-hmr-accept-code.cjs +0 -91
- package/dist/content-script-wrapper.cjs +0 -319
- package/dist/extension-js-devtools/chrome/assets/developer-mode-off.f9a94937.jpeg +0 -0
- package/dist/extension-js-devtools/chrome/assets/developer-mode-on.ede80e5b.jpeg +0 -0
- package/dist/extension-js-devtools/chrome/assets/local-network-permission.4fae40a7.png +0 -0
- package/dist/extension-js-devtools/chrome/assets/logo.7dc70d61.png +0 -0
- package/dist/extension-js-devtools/chrome/background/service_worker.js +0 -26
- package/dist/extension-js-devtools/chrome/chrome_url_overrides/newtab.html +0 -23
- package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +0 -5
- package/dist/extension-js-devtools/chrome/content_scripts/styles.24e59c3d.css +0 -2
- package/dist/extension-js-devtools/chrome/devtools/index.html +0 -12
- package/dist/extension-js-devtools/chrome/devtools/index.js +0 -1
- package/dist/extension-js-devtools/chrome/icons/logo.png +0 -0
- package/dist/extension-js-devtools/chrome/manifest.json +0 -57
- package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +0 -2
- package/dist/extension-js-devtools/chrome/pages/centralized-logger.html +0 -12
- package/dist/extension-js-devtools/chrome/pages/centralized-logger.js +0 -15
- package/dist/extension-js-devtools/chrome/pages/welcome.css +0 -2
- package/dist/extension-js-devtools/chrome/pages/welcome.html +0 -11
- package/dist/extension-js-devtools/chrome/pages/welcome.js +0 -25
- package/dist/extension-js-devtools/chrome/scripts/logger-client.js +0 -1
- package/dist/extension-js-devtools/chromium/assets/developer-mode-off.f9a94937.jpeg +0 -0
- package/dist/extension-js-devtools/chromium/assets/developer-mode-on.ede80e5b.jpeg +0 -0
- package/dist/extension-js-devtools/chromium/assets/local-network-permission.4fae40a7.png +0 -0
- package/dist/extension-js-devtools/chromium/assets/logo.7dc70d61.png +0 -0
- package/dist/extension-js-devtools/chromium/background/service_worker.js +0 -26
- package/dist/extension-js-devtools/chromium/chrome_url_overrides/newtab.html +0 -23
- package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +0 -5
- package/dist/extension-js-devtools/chromium/content_scripts/styles.24e59c3d.css +0 -2
- package/dist/extension-js-devtools/chromium/devtools/index.html +0 -12
- package/dist/extension-js-devtools/chromium/devtools/index.js +0 -1
- package/dist/extension-js-devtools/chromium/icons/logo.png +0 -0
- package/dist/extension-js-devtools/chromium/manifest.json +0 -57
- package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +0 -2
- package/dist/extension-js-devtools/chromium/pages/centralized-logger.html +0 -12
- package/dist/extension-js-devtools/chromium/pages/centralized-logger.js +0 -15
- package/dist/extension-js-devtools/chromium/pages/welcome.css +0 -2
- package/dist/extension-js-devtools/chromium/pages/welcome.html +0 -11
- package/dist/extension-js-devtools/chromium/pages/welcome.js +0 -25
- package/dist/extension-js-devtools/chromium/scripts/logger-client.js +0 -1
- package/dist/extension-js-devtools/edge/assets/developer-mode-off.f9a94937.jpeg +0 -0
- package/dist/extension-js-devtools/edge/assets/developer-mode-on.ede80e5b.jpeg +0 -0
- package/dist/extension-js-devtools/edge/assets/local-network-permission.4fae40a7.png +0 -0
- package/dist/extension-js-devtools/edge/assets/logo.7dc70d61.png +0 -0
- package/dist/extension-js-devtools/edge/background/service_worker.js +0 -26
- package/dist/extension-js-devtools/edge/chrome_url_overrides/newtab.html +0 -23
- package/dist/extension-js-devtools/edge/content_scripts/content-0.js +0 -5
- package/dist/extension-js-devtools/edge/content_scripts/styles.24e59c3d.css +0 -2
- package/dist/extension-js-devtools/edge/devtools/index.html +0 -12
- package/dist/extension-js-devtools/edge/devtools/index.js +0 -1
- package/dist/extension-js-devtools/edge/icons/logo.png +0 -0
- package/dist/extension-js-devtools/edge/manifest.json +0 -57
- package/dist/extension-js-devtools/edge/pages/centralized-logger.css +0 -2
- package/dist/extension-js-devtools/edge/pages/centralized-logger.html +0 -12
- package/dist/extension-js-devtools/edge/pages/centralized-logger.js +0 -15
- package/dist/extension-js-devtools/edge/pages/welcome.css +0 -2
- package/dist/extension-js-devtools/edge/pages/welcome.html +0 -11
- package/dist/extension-js-devtools/edge/pages/welcome.js +0 -25
- package/dist/extension-js-devtools/edge/scripts/logger-client.js +0 -1
- package/dist/extension-js-devtools/firefox/assets/developer-mode-off.f9a94937.jpeg +0 -0
- package/dist/extension-js-devtools/firefox/assets/developer-mode-on.ede80e5b.jpeg +0 -0
- package/dist/extension-js-devtools/firefox/assets/local-network-permission.4fae40a7.png +0 -0
- package/dist/extension-js-devtools/firefox/assets/logo.7dc70d61.png +0 -0
- package/dist/extension-js-devtools/firefox/background/scripts.js +0 -26
- package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +0 -5
- package/dist/extension-js-devtools/firefox/content_scripts/styles.24e59c3d.css +0 -2
- package/dist/extension-js-devtools/firefox/devtools/index.html +0 -12
- package/dist/extension-js-devtools/firefox/devtools/index.js +0 -1
- package/dist/extension-js-devtools/firefox/icons/logo.png +0 -0
- package/dist/extension-js-devtools/firefox/manifest.json +0 -42
- package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +0 -2
- package/dist/extension-js-devtools/firefox/pages/centralized-logger.html +0 -12
- package/dist/extension-js-devtools/firefox/pages/centralized-logger.js +0 -15
- package/dist/extension-js-devtools/firefox/pages/welcome.css +0 -2
- package/dist/extension-js-devtools/firefox/pages/welcome.html +0 -11
- package/dist/extension-js-devtools/firefox/pages/welcome.js +0 -25
- package/dist/extension-js-devtools/firefox/scripts/logger-client.js +0 -1
- package/dist/extension-js-theme/chrome/manifest.json +0 -66
- package/dist/extension-js-theme/chromium/manifest.json +0 -66
- package/dist/extension-js-theme/edge/manifest.json +0 -66
- package/dist/extension-js-theme/firefox/manifest.json +0 -66
- package/dist/warn-no-default-export.cjs +0 -356
- package/webpack/webpack-lib/optional-dependencies.json +0 -20
package/dist/{270.cjs → 677.cjs}
RENAMED
|
@@ -3,7 +3,7 @@ const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
|
|
|
3
3
|
return "u" < typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
|
|
4
4
|
}();
|
|
5
5
|
exports.ids = [
|
|
6
|
-
"
|
|
6
|
+
"677"
|
|
7
7
|
];
|
|
8
8
|
exports.modules = {
|
|
9
9
|
"./webpack/dev-server/compiler-hooks.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -794,9 +794,11 @@ exports.modules = {
|
|
|
794
794
|
}
|
|
795
795
|
};
|
|
796
796
|
}
|
|
797
|
+
var contracts = __webpack_require__("./webpack/plugin-web-extension/feature-scripts/contracts.ts");
|
|
797
798
|
function isBundledContentPath(filePath, ext) {
|
|
798
799
|
const normalized = String(filePath || '').replace(/\\/g, '/');
|
|
799
|
-
|
|
800
|
+
const bundledAsset = (0, contracts.es)(normalized);
|
|
801
|
+
return bundledAsset?.extension === ext;
|
|
800
802
|
}
|
|
801
803
|
function isAlreadyBundledContentScripts(contentScripts) {
|
|
802
804
|
if (!Array.isArray(contentScripts) || 0 === contentScripts.length) return false;
|
|
@@ -829,7 +831,7 @@ exports.modules = {
|
|
|
829
831
|
result.push({
|
|
830
832
|
...rest,
|
|
831
833
|
js: [
|
|
832
|
-
getFilename(
|
|
834
|
+
getFilename((0, contracts.f6)(bridgeIndex), 'main-world-bridge.js')
|
|
833
835
|
],
|
|
834
836
|
css: []
|
|
835
837
|
});
|
|
@@ -837,10 +839,10 @@ exports.modules = {
|
|
|
837
839
|
result.push({
|
|
838
840
|
...original[index] || {},
|
|
839
841
|
js: [
|
|
840
|
-
...new Set(contentJs.map((js)=>getFilename(
|
|
842
|
+
...new Set(contentJs.map((js)=>getFilename((0, contracts.f6)(index), js)))
|
|
841
843
|
],
|
|
842
844
|
css: [
|
|
843
|
-
...new Set(contentCss.map((css)=>getFilename(
|
|
845
|
+
...new Set(contentCss.map((css)=>getFilename((0, contracts.J4)(index), css)))
|
|
844
846
|
]
|
|
845
847
|
});
|
|
846
848
|
}
|
|
@@ -1455,7 +1457,14 @@ exports.modules = {
|
|
|
1455
1457
|
const manifestName = boring_readJsonFileSafe(this.manifestPath).name;
|
|
1456
1458
|
const line = boring(manifestName, duration, stats);
|
|
1457
1459
|
try {
|
|
1458
|
-
const
|
|
1460
|
+
const fromCompilation = Array.from(stats?.compilation?.modifiedFiles || []);
|
|
1461
|
+
const fromCompiler = Array.from(compiler.modifiedFiles ?? []);
|
|
1462
|
+
const modifiedFiles = [
|
|
1463
|
+
...new Set([
|
|
1464
|
+
...fromCompilation,
|
|
1465
|
+
...fromCompiler
|
|
1466
|
+
])
|
|
1467
|
+
].map((file)=>String(file).replace(/\\/g, '/'));
|
|
1459
1468
|
if (!this.sawUserInvalidation && modifiedFiles.length > 0) {
|
|
1460
1469
|
const context = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
1461
1470
|
const hasUserFileChange = modifiedFiles.some((file)=>{
|
|
@@ -1576,7 +1585,7 @@ exports.modules = {
|
|
|
1576
1585
|
}
|
|
1577
1586
|
plugin_compilation_define_property(CompilationPlugin, "name", 'plugin-compilation');
|
|
1578
1587
|
var css_lib_messages = __webpack_require__("./webpack/plugin-css/css-lib/messages.ts");
|
|
1579
|
-
var
|
|
1588
|
+
var external_optional_deps_lib_ = __webpack_require__("optional-deps-lib");
|
|
1580
1589
|
var sass = __webpack_require__("./webpack/plugin-css/css-tools/sass.ts");
|
|
1581
1590
|
var less = __webpack_require__("./webpack/plugin-css/css-tools/less.ts");
|
|
1582
1591
|
function getStylelintConfigFile(projectPath) {
|
|
@@ -1688,7 +1697,12 @@ exports.modules = {
|
|
|
1688
1697
|
test,
|
|
1689
1698
|
exclude,
|
|
1690
1699
|
type,
|
|
1691
|
-
issuer: isContentScript
|
|
1700
|
+
issuer: isContentScript,
|
|
1701
|
+
resourceQuery: {
|
|
1702
|
+
not: [
|
|
1703
|
+
/url/
|
|
1704
|
+
]
|
|
1705
|
+
}
|
|
1692
1706
|
};
|
|
1693
1707
|
if ('asset' === type) baseConfig.generator = {
|
|
1694
1708
|
filename: "content_scripts/[name].[contenthash:8].css"
|
|
@@ -1763,7 +1777,12 @@ exports.modules = {
|
|
|
1763
1777
|
test,
|
|
1764
1778
|
exclude,
|
|
1765
1779
|
type,
|
|
1766
|
-
issuer: isNotContentScript
|
|
1780
|
+
issuer: isNotContentScript,
|
|
1781
|
+
resourceQuery: {
|
|
1782
|
+
not: [
|
|
1783
|
+
/url/
|
|
1784
|
+
]
|
|
1785
|
+
}
|
|
1767
1786
|
};
|
|
1768
1787
|
if (!loader) return {
|
|
1769
1788
|
...baseConfig,
|
|
@@ -1801,8 +1820,8 @@ exports.modules = {
|
|
|
1801
1820
|
const projectPath = compiler.options.context || process.cwd();
|
|
1802
1821
|
const plugins = [];
|
|
1803
1822
|
const manifestPath = this.manifestPath;
|
|
1804
|
-
const usingSass = (0,
|
|
1805
|
-
const usingLess = (0,
|
|
1823
|
+
const usingSass = (0, external_optional_deps_lib_.hasDependency)(projectPath, 'sass');
|
|
1824
|
+
const usingLess = (0, external_optional_deps_lib_.hasDependency)(projectPath, 'less');
|
|
1806
1825
|
const maybeInstallStylelint = await maybeUseStylelint(projectPath);
|
|
1807
1826
|
plugins.push(...maybeInstallStylelint);
|
|
1808
1827
|
const maybeInstallSass = await (0, sass.IZ)(projectPath);
|
|
@@ -1845,8 +1864,8 @@ exports.modules = {
|
|
|
1845
1864
|
].filter(Boolean);
|
|
1846
1865
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
1847
1866
|
const integrations = [];
|
|
1848
|
-
const usingTailwind = (0,
|
|
1849
|
-
const usingPostcss = (0,
|
|
1867
|
+
const usingTailwind = (0, external_optional_deps_lib_.hasDependency)(projectPath, 'tailwindcss');
|
|
1868
|
+
const usingPostcss = (0, external_optional_deps_lib_.hasDependency)(projectPath, 'postcss') || void 0 !== findPostCssConfig(projectPath) || usingSass || usingLess || usingTailwind;
|
|
1850
1869
|
if (usingPostcss) integrations.push('PostCSS');
|
|
1851
1870
|
if (usingSass) integrations.push('Sass');
|
|
1852
1871
|
if (usingLess) integrations.push('Less');
|
|
@@ -2111,19 +2130,61 @@ exports.modules = {
|
|
|
2111
2130
|
};
|
|
2112
2131
|
return merged;
|
|
2113
2132
|
}
|
|
2133
|
+
patchReactRefreshRules(rules) {
|
|
2134
|
+
for (const rule of rules){
|
|
2135
|
+
if (!rule || 'object' != typeof rule) continue;
|
|
2136
|
+
const uses = Array.isArray(rule.use) ? rule.use : rule.use ? [
|
|
2137
|
+
rule.use
|
|
2138
|
+
] : rule.loader ? [
|
|
2139
|
+
{
|
|
2140
|
+
loader: rule.loader
|
|
2141
|
+
}
|
|
2142
|
+
] : [];
|
|
2143
|
+
const hasReactRefreshLoader = uses.some((useEntry)=>String(useEntry?.loader || '').includes('react-refresh-loader'));
|
|
2144
|
+
if (hasReactRefreshLoader) rule.issuerLayer = {
|
|
2145
|
+
not: contracts.$t
|
|
2146
|
+
};
|
|
2147
|
+
if (Array.isArray(rule.oneOf)) this.patchReactRefreshRules(rule.oneOf);
|
|
2148
|
+
if (Array.isArray(rule.rules)) this.patchReactRefreshRules(rule.rules);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2114
2151
|
async configureOptions(compiler) {
|
|
2115
2152
|
const mode = compiler.options.mode || 'development';
|
|
2116
2153
|
const projectPath = compiler.options.context;
|
|
2154
|
+
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
2155
|
+
const swcIncludeDirs = Array.from(new Set([
|
|
2156
|
+
projectPath,
|
|
2157
|
+
manifestDir,
|
|
2158
|
+
...resolveTranspilePackageDirs(projectPath, this.transpilePackages)
|
|
2159
|
+
]));
|
|
2160
|
+
const contentScriptLikePaths = new Set();
|
|
2161
|
+
const scriptsDir = external_path_.resolve(projectPath, "scripts");
|
|
2162
|
+
const isfeatureScriptsContentLike = (resourcePath)=>{
|
|
2163
|
+
const normalized = external_path_.normalize(resourcePath);
|
|
2164
|
+
if (contentScriptLikePaths.has(normalized)) return true;
|
|
2165
|
+
const relToScripts = external_path_.relative(scriptsDir, normalized);
|
|
2166
|
+
return !!relToScripts && !relToScripts.startsWith('..') && !external_path_.isAbsolute(relToScripts);
|
|
2167
|
+
};
|
|
2117
2168
|
const devtool = compiler.options.devtool;
|
|
2118
2169
|
const wantsSourceMaps = false !== devtool && ('development' === mode || null != devtool);
|
|
2119
|
-
|
|
2170
|
+
try {
|
|
2171
|
+
const manifest = JSON.parse(external_fs_.readFileSync(this.manifestPath, 'utf-8'));
|
|
2172
|
+
const contentScripts = Array.isArray(manifest?.content_scripts) ? manifest.content_scripts : [];
|
|
2173
|
+
for (const contentScript of contentScripts){
|
|
2174
|
+
const jsList = Array.isArray(contentScript?.js) ? contentScript.js : [];
|
|
2175
|
+
for (const jsFile of jsList)contentScriptLikePaths.add(external_path_.resolve(manifestDir, jsFile));
|
|
2176
|
+
}
|
|
2177
|
+
} catch {}
|
|
2178
|
+
const maybeInstallReact = await (0, react.b)(projectPath, {
|
|
2179
|
+
disableRefresh: true,
|
|
2180
|
+
refreshExclude: (resourcePath)=>isfeatureScriptsContentLike(resourcePath)
|
|
2181
|
+
});
|
|
2120
2182
|
const maybeInstallPreact = await (0, preact.b)(projectPath);
|
|
2121
2183
|
const maybeInstallVue = await (0, vue.K)(projectPath, mode);
|
|
2122
2184
|
const maybeInstallSvelte = await (0, svelte.X)(projectPath, mode);
|
|
2123
2185
|
const tsConfigPath = (0, typescript.hB)(projectPath);
|
|
2124
|
-
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
2125
2186
|
const tsRoot = tsConfigPath ? external_path_.dirname(tsConfigPath) : manifestDir;
|
|
2126
|
-
const transpilePackageDirs =
|
|
2187
|
+
const transpilePackageDirs = swcIncludeDirs.filter((dir)=>dir !== projectPath && dir !== manifestDir);
|
|
2127
2188
|
const preferTypeScript = !!tsConfigPath || (0, typescript.eE)(projectPath);
|
|
2128
2189
|
let targets = [
|
|
2129
2190
|
'chrome >= 100'
|
|
@@ -2163,59 +2224,131 @@ exports.modules = {
|
|
|
2163
2224
|
vueLoadersToAdd = [];
|
|
2164
2225
|
}
|
|
2165
2226
|
}
|
|
2166
|
-
|
|
2227
|
+
const swcRuleBase = {
|
|
2228
|
+
test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
|
|
2229
|
+
include: Array.from(new Set([
|
|
2230
|
+
tsRoot,
|
|
2231
|
+
...swcIncludeDirs
|
|
2232
|
+
])),
|
|
2233
|
+
exclude: [
|
|
2234
|
+
(resourcePath)=>{
|
|
2235
|
+
const isInNodeModules = /[\\/]node_modules[\\/]/.test(resourcePath);
|
|
2236
|
+
if (!isInNodeModules) return false;
|
|
2237
|
+
return !transpilePackageDirs.some((dir)=>isSubPath(resourcePath, dir));
|
|
2238
|
+
}
|
|
2239
|
+
]
|
|
2240
|
+
};
|
|
2241
|
+
const swcLoaderBase = {
|
|
2242
|
+
loader: 'builtin:swc-loader',
|
|
2243
|
+
options: {
|
|
2244
|
+
sync: true,
|
|
2245
|
+
module: {
|
|
2246
|
+
type: 'es6'
|
|
2247
|
+
},
|
|
2248
|
+
minify: false,
|
|
2249
|
+
isModule: true,
|
|
2250
|
+
sourceMap: wantsSourceMaps,
|
|
2251
|
+
env: {
|
|
2252
|
+
targets
|
|
2253
|
+
},
|
|
2254
|
+
jsc: {
|
|
2255
|
+
parser: {
|
|
2256
|
+
syntax: preferTypeScript ? "typescript" : "ecmascript",
|
|
2257
|
+
tsx: preferTypeScript ? true : (0, typescript.eE)(projectPath) && ((0, react.S)(projectPath) || (0, preact.K)(projectPath)),
|
|
2258
|
+
jsx: !preferTypeScript && ((0, react.S)(projectPath) || (0, preact.K)(projectPath)),
|
|
2259
|
+
dynamicImport: true
|
|
2260
|
+
},
|
|
2261
|
+
transform: {
|
|
2262
|
+
react: {
|
|
2263
|
+
development: 'development' === mode,
|
|
2264
|
+
runtime: 'automatic',
|
|
2265
|
+
importSource: 'react',
|
|
2266
|
+
...(0, preact.K)(projectPath) ? {
|
|
2267
|
+
pragma: 'h',
|
|
2268
|
+
pragmaFrag: 'Fragment',
|
|
2269
|
+
throwIfNamespace: true,
|
|
2270
|
+
useBuiltins: false
|
|
2271
|
+
} : {}
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
const swcRules = [
|
|
2167
2278
|
{
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2279
|
+
...swcRuleBase,
|
|
2280
|
+
layer: contracts.$t,
|
|
2281
|
+
include: (resourcePath)=>Array.from(new Set([
|
|
2282
|
+
tsRoot,
|
|
2283
|
+
...swcIncludeDirs
|
|
2284
|
+
])).some((dir)=>isSubPath(resourcePath, dir)) && isfeatureScriptsContentLike(resourcePath),
|
|
2285
|
+
use: {
|
|
2286
|
+
...swcLoaderBase,
|
|
2287
|
+
options: {
|
|
2288
|
+
...swcLoaderBase.options,
|
|
2289
|
+
jsc: {
|
|
2290
|
+
...swcLoaderBase.options.jsc,
|
|
2291
|
+
transform: {
|
|
2292
|
+
...swcLoaderBase.options.jsc.transform,
|
|
2293
|
+
react: {
|
|
2294
|
+
...swcLoaderBase.options.jsc.transform.react,
|
|
2295
|
+
refresh: false
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2179
2299
|
}
|
|
2180
|
-
|
|
2300
|
+
}
|
|
2301
|
+
},
|
|
2302
|
+
{
|
|
2303
|
+
...swcRuleBase,
|
|
2304
|
+
issuerLayer: contracts.$t,
|
|
2305
|
+
layer: contracts.$t,
|
|
2181
2306
|
use: {
|
|
2182
|
-
|
|
2307
|
+
...swcLoaderBase,
|
|
2183
2308
|
options: {
|
|
2184
|
-
|
|
2185
|
-
module: {
|
|
2186
|
-
type: 'es6'
|
|
2187
|
-
},
|
|
2188
|
-
minify: false,
|
|
2189
|
-
isModule: true,
|
|
2190
|
-
sourceMap: wantsSourceMaps,
|
|
2191
|
-
env: {
|
|
2192
|
-
targets
|
|
2193
|
-
},
|
|
2309
|
+
...swcLoaderBase.options,
|
|
2194
2310
|
jsc: {
|
|
2195
|
-
|
|
2196
|
-
syntax: preferTypeScript ? "typescript" : "ecmascript",
|
|
2197
|
-
tsx: preferTypeScript ? true : (0, typescript.eE)(projectPath) && ((0, react.S)(projectPath) || (0, preact.K)(projectPath)),
|
|
2198
|
-
jsx: !preferTypeScript && ((0, react.S)(projectPath) || (0, preact.K)(projectPath)),
|
|
2199
|
-
dynamicImport: true
|
|
2200
|
-
},
|
|
2311
|
+
...swcLoaderBase.options.jsc,
|
|
2201
2312
|
transform: {
|
|
2313
|
+
...swcLoaderBase.options.jsc.transform,
|
|
2202
2314
|
react: {
|
|
2203
|
-
|
|
2204
|
-
refresh:
|
|
2205
|
-
runtime: 'automatic',
|
|
2206
|
-
importSource: 'react',
|
|
2207
|
-
...(0, preact.K)(projectPath) ? {
|
|
2208
|
-
pragma: 'h',
|
|
2209
|
-
pragmaFrag: 'Fragment',
|
|
2210
|
-
throwIfNamespace: true,
|
|
2211
|
-
useBuiltins: false
|
|
2212
|
-
} : {}
|
|
2315
|
+
...swcLoaderBase.options.jsc.transform.react,
|
|
2316
|
+
refresh: false
|
|
2213
2317
|
}
|
|
2214
2318
|
}
|
|
2215
2319
|
}
|
|
2216
2320
|
}
|
|
2217
2321
|
}
|
|
2218
2322
|
},
|
|
2323
|
+
{
|
|
2324
|
+
...swcRuleBase,
|
|
2325
|
+
issuerLayer: {
|
|
2326
|
+
not: contracts.$t
|
|
2327
|
+
},
|
|
2328
|
+
exclude: [
|
|
2329
|
+
...swcRuleBase.exclude,
|
|
2330
|
+
(resourcePath)=>isfeatureScriptsContentLike(resourcePath)
|
|
2331
|
+
],
|
|
2332
|
+
use: {
|
|
2333
|
+
...swcLoaderBase,
|
|
2334
|
+
options: {
|
|
2335
|
+
...swcLoaderBase.options,
|
|
2336
|
+
jsc: {
|
|
2337
|
+
...swcLoaderBase.options.jsc,
|
|
2338
|
+
transform: {
|
|
2339
|
+
...swcLoaderBase.options.jsc.transform,
|
|
2340
|
+
react: {
|
|
2341
|
+
...swcLoaderBase.options.jsc.transform.react,
|
|
2342
|
+
refresh: 'development' === mode
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
];
|
|
2350
|
+
compiler.options.module.rules = [
|
|
2351
|
+
...swcRules,
|
|
2219
2352
|
...maybeInstallReact?.loaders || [],
|
|
2220
2353
|
...maybeInstallPreact?.loaders || [],
|
|
2221
2354
|
...vueLoadersToAdd,
|
|
@@ -2226,6 +2359,7 @@ exports.modules = {
|
|
|
2226
2359
|
maybeInstallPreact?.plugins?.forEach((plugin)=>plugin.apply(compiler));
|
|
2227
2360
|
maybeInstallVue?.plugins?.forEach((plugin)=>plugin.apply(compiler));
|
|
2228
2361
|
maybeInstallSvelte?.plugins?.forEach((plugin)=>plugin.apply(compiler));
|
|
2362
|
+
this.patchReactRefreshRules(compiler.options.module.rules);
|
|
2229
2363
|
if ((0, typescript.eE)(projectPath) || !!tsConfigPath) compiler.options.resolve.tsConfig = {
|
|
2230
2364
|
configFile: tsConfigPath
|
|
2231
2365
|
};
|
|
@@ -2347,6 +2481,67 @@ exports.modules = {
|
|
|
2347
2481
|
this.manifestPath = options.manifestPath;
|
|
2348
2482
|
}
|
|
2349
2483
|
}
|
|
2484
|
+
function patchDevContentScriptManifestPaths(compilation, manifest) {
|
|
2485
|
+
if ('development' !== compilation.options.mode) return manifest;
|
|
2486
|
+
const cs = manifest.content_scripts;
|
|
2487
|
+
if (!Array.isArray(cs)) return manifest;
|
|
2488
|
+
const assetNames = new Set((compilation.getAssets?.() || []).map((a)=>a.name || '').filter(Boolean));
|
|
2489
|
+
const currentHashedNames = new Set();
|
|
2490
|
+
const next = cs.map((group, groupIndex)=>{
|
|
2491
|
+
const js = Array.isArray(group.js) ? [
|
|
2492
|
+
...group.js
|
|
2493
|
+
] : [];
|
|
2494
|
+
const css = Array.isArray(group.css) ? [
|
|
2495
|
+
...group.css
|
|
2496
|
+
] : [];
|
|
2497
|
+
const resolvedJs = js.map((p)=>resolveDevContentScriptDeclaredPath(p, groupIndex, 'js', assetNames));
|
|
2498
|
+
const resolvedCss = css.map((p)=>resolveDevContentScriptDeclaredPath(p, groupIndex, 'css', assetNames));
|
|
2499
|
+
for (const n of [
|
|
2500
|
+
...resolvedJs,
|
|
2501
|
+
...resolvedCss
|
|
2502
|
+
])currentHashedNames.add(n);
|
|
2503
|
+
return {
|
|
2504
|
+
...group,
|
|
2505
|
+
js: resolvedJs,
|
|
2506
|
+
css: resolvedCss
|
|
2507
|
+
};
|
|
2508
|
+
});
|
|
2509
|
+
purgeStaleHashedContentScripts(compilation, currentHashedNames);
|
|
2510
|
+
return {
|
|
2511
|
+
...manifest,
|
|
2512
|
+
content_scripts: next
|
|
2513
|
+
};
|
|
2514
|
+
}
|
|
2515
|
+
function resolveDevContentScriptDeclaredPath(declaredPath, groupIndex, ext, assetNames) {
|
|
2516
|
+
const canonical = 'js' === ext ? (0, contracts.f6)(groupIndex) : (0, contracts.J4)(groupIndex);
|
|
2517
|
+
if (declaredPath !== canonical) return declaredPath;
|
|
2518
|
+
const hashed = findHashedContentScriptAsset(assetNames, groupIndex, ext);
|
|
2519
|
+
return hashed || declaredPath;
|
|
2520
|
+
}
|
|
2521
|
+
function findHashedContentScriptAsset(assetNames, groupIndex, ext) {
|
|
2522
|
+
const plain = `content_scripts/content-${groupIndex}.${ext}`;
|
|
2523
|
+
if (assetNames.has(plain)) return plain;
|
|
2524
|
+
const re = new RegExp(`^content_scripts/content-${groupIndex}\\.[a-f0-9]+\\.${ext}$`, 'i');
|
|
2525
|
+
for (const name of assetNames)if (re.test(name)) return name;
|
|
2526
|
+
}
|
|
2527
|
+
function purgeStaleHashedContentScripts(compilation, currentNames) {
|
|
2528
|
+
const outputPath = compilation.options.output?.path;
|
|
2529
|
+
if (!outputPath) return;
|
|
2530
|
+
const csDir = external_path_.join(outputPath, "content_scripts");
|
|
2531
|
+
if (!external_fs_.existsSync(csDir)) return;
|
|
2532
|
+
const hashedRe = /^content-\d+\.[a-f0-9]+\.(js|css)(\.map)?$/i;
|
|
2533
|
+
try {
|
|
2534
|
+
for (const name of external_fs_.readdirSync(csDir)){
|
|
2535
|
+
if (!hashedRe.test(name)) continue;
|
|
2536
|
+
const rel = `content_scripts/${name}`;
|
|
2537
|
+
if (!currentNames.has(rel)) {
|
|
2538
|
+
if (!currentNames.has(rel.replace(/\.map$/, ''))) try {
|
|
2539
|
+
external_fs_.unlinkSync(external_path_.join(csDir, name));
|
|
2540
|
+
} catch {}
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
} catch {}
|
|
2544
|
+
}
|
|
2350
2545
|
function update_manifest_define_property(obj, key, value) {
|
|
2351
2546
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
2352
2547
|
value: value,
|
|
@@ -2375,8 +2570,9 @@ exports.modules = {
|
|
|
2375
2570
|
}, ()=>{
|
|
2376
2571
|
if (compilation.errors.length > 0) return;
|
|
2377
2572
|
const manifest = getManifestContent(compilation, this.manifestPath);
|
|
2378
|
-
|
|
2573
|
+
let patchedManifest = buildCanonicalManifest(this.manifestPath, manifest, this.browser);
|
|
2379
2574
|
const overrides = getManifestOverrides(this.manifestPath, manifest);
|
|
2575
|
+
if ('development' === compiler.options.mode) patchedManifest = patchDevContentScriptManifestPaths(compilation, patchedManifest);
|
|
2380
2576
|
if ('development' === compiler.options.mode) {
|
|
2381
2577
|
if (patchedManifest.content_scripts) patchedManifest.content_scripts = this.applyDevOverrides(patchedManifest);
|
|
2382
2578
|
}
|
|
@@ -2822,17 +3018,17 @@ exports.modules = {
|
|
|
2822
3018
|
for (const r of fontAssets)if (!webAccessibleResourcesV2.includes(r)) webAccessibleResourcesV2.push(r);
|
|
2823
3019
|
}
|
|
2824
3020
|
}
|
|
3021
|
+
const assetKeys = Object.keys(compilation.assets || {});
|
|
3022
|
+
const cssUnderContentScripts = assetKeys.filter((k)=>k.startsWith("content_scripts/")).filter((k)=>k.endsWith('.css')).sort();
|
|
3023
|
+
if (Array.isArray(canonicalManifest.content_scripts)) for (const contentScript of canonicalManifest.content_scripts){
|
|
3024
|
+
const jsFiles = Array.isArray(contentScript.js) ? contentScript.js : [];
|
|
3025
|
+
const canonicalCss = jsFiles.map(toCanonicalContentScriptCss).filter((resource)=>Boolean(resource && cssUnderContentScripts.includes(resource)));
|
|
3026
|
+
if (canonicalCss.length > 0) contentScript.css = Array.from(new Set([
|
|
3027
|
+
...contentScript.css || [],
|
|
3028
|
+
...canonicalCss
|
|
3029
|
+
])).sort();
|
|
3030
|
+
}
|
|
2825
3031
|
if (3 === canonicalManifest.manifest_version) {
|
|
2826
|
-
const assetKeys = Object.keys(compilation.assets || {});
|
|
2827
|
-
const cssUnderContentScripts = assetKeys.filter((k)=>k.startsWith("content_scripts/")).filter((k)=>k.endsWith('.css')).sort();
|
|
2828
|
-
if (Array.isArray(canonicalManifest.content_scripts)) for (const contentScript of canonicalManifest.content_scripts){
|
|
2829
|
-
const jsFiles = Array.isArray(contentScript.js) ? contentScript.js : [];
|
|
2830
|
-
const canonicalCss = jsFiles.map(toCanonicalContentScriptCss).filter((resource)=>Boolean(resource && cssUnderContentScripts.includes(resource)));
|
|
2831
|
-
if (canonicalCss.length > 0) contentScript.css = Array.from(new Set([
|
|
2832
|
-
...contentScript.css || [],
|
|
2833
|
-
...canonicalCss
|
|
2834
|
-
])).sort();
|
|
2835
|
-
}
|
|
2836
3032
|
if (cssUnderContentScripts.length > 0) {
|
|
2837
3033
|
const allMatches = Array.from(new Set((canonicalManifest.content_scripts || []).flatMap((cs)=>cs.matches || [])));
|
|
2838
3034
|
const normalizedMatches = cleanMatches(allMatches);
|
|
@@ -2860,6 +3056,8 @@ exports.modules = {
|
|
|
2860
3056
|
});
|
|
2861
3057
|
}
|
|
2862
3058
|
}
|
|
3059
|
+
} else if (2 === canonicalManifest.manifest_version) {
|
|
3060
|
+
for (const resource of cssUnderContentScripts)if (!webAccessibleResourcesV2.includes(resource)) webAccessibleResourcesV2.push(resource);
|
|
2863
3061
|
}
|
|
2864
3062
|
if (3 === canonicalManifest.manifest_version) {
|
|
2865
3063
|
if (webAccessibleResourcesV3.length > 0) canonicalManifest.web_accessible_resources = webAccessibleResourcesV3.map((entry)=>({
|
|
@@ -3136,6 +3334,7 @@ exports.modules = {
|
|
|
3136
3334
|
permissions: [
|
|
3137
3335
|
...new Set([
|
|
3138
3336
|
"scripting",
|
|
3337
|
+
'tabs',
|
|
3139
3338
|
'management',
|
|
3140
3339
|
...canonicalManifest.permissions || []
|
|
3141
3340
|
])
|
|
@@ -3143,6 +3342,7 @@ exports.modules = {
|
|
|
3143
3342
|
} : {
|
|
3144
3343
|
permissions: [
|
|
3145
3344
|
"scripting",
|
|
3345
|
+
'tabs',
|
|
3146
3346
|
'management'
|
|
3147
3347
|
]
|
|
3148
3348
|
} : {},
|
|
@@ -4240,6 +4440,51 @@ exports.modules = {
|
|
|
4240
4440
|
this.browser = options.browser;
|
|
4241
4441
|
}
|
|
4242
4442
|
}
|
|
4443
|
+
function normalizeBoolean(value, fallback) {
|
|
4444
|
+
return String('boolean' == typeof value ? value : fallback);
|
|
4445
|
+
}
|
|
4446
|
+
function normalizeHotValue(value) {
|
|
4447
|
+
if ('only' === value) return 'only';
|
|
4448
|
+
if ('boolean' == typeof value) return String(value);
|
|
4449
|
+
return 'true';
|
|
4450
|
+
}
|
|
4451
|
+
function getDevServerHmrImports(compiler) {
|
|
4452
|
+
const devServer = compiler.options?.devServer;
|
|
4453
|
+
const envHost = process.env.EXTENSION_DEV_SERVER_HOST;
|
|
4454
|
+
const envPort = process.env.EXTENSION_DEV_SERVER_PORT;
|
|
4455
|
+
const envPath = process.env.EXTENSION_DEV_SERVER_PATH;
|
|
4456
|
+
const envProtocol = process.env.EXTENSION_DEV_SERVER_PROTOCOL;
|
|
4457
|
+
if (!devServer && !envHost && !envPort) return [];
|
|
4458
|
+
const clientConfig = devServer?.client && 'object' == typeof devServer.client ? devServer.client : {};
|
|
4459
|
+
const webSocketURL = clientConfig.webSocketURL && 'object' == typeof clientConfig.webSocketURL ? clientConfig.webSocketURL : {};
|
|
4460
|
+
const protocol = String(webSocketURL.protocol || envProtocol || 'ws');
|
|
4461
|
+
const hostname = String(webSocketURL.hostname || devServer?.host || envHost || '127.0.0.1');
|
|
4462
|
+
const port = webSocketURL.port ?? devServer?.port ?? envPort ?? process.env.EXTENSION_PUBLIC_PORT ?? 8080;
|
|
4463
|
+
const pathname = String(webSocketURL.pathname || envPath || '/ws');
|
|
4464
|
+
const logging = String(clientConfig.logging || 'none');
|
|
4465
|
+
const progress = normalizeBoolean(clientConfig.progress, false);
|
|
4466
|
+
const overlay = normalizeBoolean(clientConfig.overlay, false);
|
|
4467
|
+
const reconnect = String(clientConfig.reconnect ?? 10);
|
|
4468
|
+
const hot = normalizeHotValue(devServer?.hot ?? 'only');
|
|
4469
|
+
const liveReload = normalizeBoolean(devServer?.liveReload, true);
|
|
4470
|
+
const query = new URLSearchParams({
|
|
4471
|
+
protocol,
|
|
4472
|
+
hostname,
|
|
4473
|
+
port: String(port),
|
|
4474
|
+
pathname,
|
|
4475
|
+
logging,
|
|
4476
|
+
progress,
|
|
4477
|
+
overlay,
|
|
4478
|
+
reconnect,
|
|
4479
|
+
hot,
|
|
4480
|
+
'live-reload': liveReload
|
|
4481
|
+
});
|
|
4482
|
+
return [
|
|
4483
|
+
`@rspack/dev-server/client/index.js?${query.toString()}`,
|
|
4484
|
+
'webpack/hot/dev-server'
|
|
4485
|
+
];
|
|
4486
|
+
}
|
|
4487
|
+
var develop_context = __webpack_require__("./webpack/webpack-lib/develop-context.ts");
|
|
4243
4488
|
function add_scripts_and_styles_to_compilation_define_property(obj, key, value) {
|
|
4244
4489
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
4245
4490
|
value: value,
|
|
@@ -4257,6 +4502,7 @@ exports.modules = {
|
|
|
4257
4502
|
const projectRoot = compiler.options.context || manifestDir;
|
|
4258
4503
|
const publicDir = external_path_.join(projectRoot, 'public');
|
|
4259
4504
|
const hasPublicDir = external_fs_.existsSync(publicDir);
|
|
4505
|
+
const devServerHmrImports = 'development' === compiler.options.mode ? getDevServerHmrImports(compiler) : [];
|
|
4260
4506
|
for (const field of Object.entries(htmlEntries)){
|
|
4261
4507
|
const [feature, resource] = field;
|
|
4262
4508
|
if (resource) {
|
|
@@ -4271,7 +4517,8 @@ exports.modules = {
|
|
|
4271
4517
|
...cssAssets
|
|
4272
4518
|
];
|
|
4273
4519
|
if ('development' === compiler.options.mode) {
|
|
4274
|
-
|
|
4520
|
+
if (devServerHmrImports.length > 0) fileAssets.unshift(...devServerHmrImports);
|
|
4521
|
+
const hmrScript = (0, develop_context.G)("minimum-script-file");
|
|
4275
4522
|
fileAssets.push(hmrScript);
|
|
4276
4523
|
}
|
|
4277
4524
|
if (external_fs_.existsSync(resource)) compiler.options.entry = {
|
|
@@ -4688,24 +4935,40 @@ exports.modules = {
|
|
|
4688
4935
|
includeList,
|
|
4689
4936
|
browser: this.browser
|
|
4690
4937
|
}).apply(compiler);
|
|
4691
|
-
if ('production' !== (compiler.options.mode || 'development'))
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
{
|
|
4701
|
-
loader: external_path_.resolve(__dirname, "ensure-hmr-for-scripts"),
|
|
4702
|
-
options: {
|
|
4703
|
-
manifestPath: this.manifestPath,
|
|
4704
|
-
includeList
|
|
4705
|
-
}
|
|
4938
|
+
if ('production' !== (compiler.options.mode || 'development')) {
|
|
4939
|
+
const contentScriptEntryPaths = new Set();
|
|
4940
|
+
try {
|
|
4941
|
+
const manifest = JSON.parse(external_fs_.readFileSync(this.manifestPath, 'utf-8'));
|
|
4942
|
+
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
4943
|
+
const contentScripts = Array.isArray(manifest?.content_scripts) ? manifest.content_scripts : [];
|
|
4944
|
+
for (const contentScript of contentScripts){
|
|
4945
|
+
const jsList = Array.isArray(contentScript?.js) ? contentScript.js : [];
|
|
4946
|
+
for (const jsFile of jsList)contentScriptEntryPaths.add(external_path_.normalize(external_path_.resolve(manifestDir, jsFile)));
|
|
4706
4947
|
}
|
|
4707
|
-
|
|
4708
|
-
|
|
4948
|
+
} catch {}
|
|
4949
|
+
compiler.options.module.rules.push({
|
|
4950
|
+
test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
|
|
4951
|
+
include: [
|
|
4952
|
+
external_path_.dirname(this.manifestPath)
|
|
4953
|
+
],
|
|
4954
|
+
issuerLayer: {
|
|
4955
|
+
not: contracts.$t
|
|
4956
|
+
},
|
|
4957
|
+
exclude: [
|
|
4958
|
+
/([\\/])node_modules\1/,
|
|
4959
|
+
(resourcePath)=>contentScriptEntryPaths.has(external_path_.normalize(resourcePath))
|
|
4960
|
+
],
|
|
4961
|
+
use: [
|
|
4962
|
+
{
|
|
4963
|
+
loader: (0, develop_context.G)("ensure-hmr-for-scripts"),
|
|
4964
|
+
options: {
|
|
4965
|
+
manifestPath: this.manifestPath,
|
|
4966
|
+
includeList
|
|
4967
|
+
}
|
|
4968
|
+
}
|
|
4969
|
+
]
|
|
4970
|
+
});
|
|
4971
|
+
}
|
|
4709
4972
|
new AddToFileDependencies({
|
|
4710
4973
|
manifestPath: this.manifestPath,
|
|
4711
4974
|
includeList,
|
|
@@ -4769,6 +5032,29 @@ exports.modules = {
|
|
|
4769
5032
|
});
|
|
4770
5033
|
return fileAssets;
|
|
4771
5034
|
}
|
|
5035
|
+
function findUpLocalSync(filename, options) {
|
|
5036
|
+
const root = external_path_.parse(options.cwd).root;
|
|
5037
|
+
let currentDir = options.cwd;
|
|
5038
|
+
while(true){
|
|
5039
|
+
const candidate = external_path_.join(currentDir, filename);
|
|
5040
|
+
try {
|
|
5041
|
+
const stat = external_fs_.statSync(candidate);
|
|
5042
|
+
if (stat.isFile()) return candidate;
|
|
5043
|
+
} catch {}
|
|
5044
|
+
if (currentDir === root) return;
|
|
5045
|
+
currentDir = external_path_.dirname(currentDir);
|
|
5046
|
+
}
|
|
5047
|
+
}
|
|
5048
|
+
function findNearestPackageJsonSync(manifestPath) {
|
|
5049
|
+
try {
|
|
5050
|
+
const manifestDir = external_path_.dirname(manifestPath);
|
|
5051
|
+
return findUpLocalSync('package.json', {
|
|
5052
|
+
cwd: manifestDir
|
|
5053
|
+
}) || null;
|
|
5054
|
+
} catch {
|
|
5055
|
+
return null;
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
4772
5058
|
function findPackageRoot(startDir) {
|
|
4773
5059
|
let current = startDir;
|
|
4774
5060
|
for(let i = 0; i < 15; i++){
|
|
@@ -4812,12 +5098,11 @@ exports.modules = {
|
|
|
4812
5098
|
const cs = contentScripts[i];
|
|
4813
5099
|
if (cs?.world !== 'MAIN') continue;
|
|
4814
5100
|
const bridgeIndex = originalCount + bridgeOrdinal++;
|
|
4815
|
-
bridgeScripts[
|
|
5101
|
+
bridgeScripts[(0, contracts.Y0)(bridgeIndex)] = bridgeSource;
|
|
4816
5102
|
}
|
|
4817
5103
|
} catch {}
|
|
4818
5104
|
return bridgeScripts;
|
|
4819
5105
|
}
|
|
4820
|
-
var package_json = __webpack_require__("./webpack/webpack-lib/package-json.ts");
|
|
4821
5106
|
function add_content_script_wrapper_define_property(obj, key, value) {
|
|
4822
5107
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
4823
5108
|
value: value,
|
|
@@ -4832,20 +5117,12 @@ exports.modules = {
|
|
|
4832
5117
|
static getBridgeScripts(manifestPath) {
|
|
4833
5118
|
return getMainWorldBridgeScripts(manifestPath);
|
|
4834
5119
|
}
|
|
4835
|
-
resolveLoader(
|
|
4836
|
-
|
|
4837
|
-
const candidates = [
|
|
4838
|
-
`${base}.cjs`,
|
|
4839
|
-
`${base}.js`,
|
|
4840
|
-
`${base}.mjs`,
|
|
4841
|
-
base
|
|
4842
|
-
];
|
|
4843
|
-
for (const candidate of candidates)if (external_fs_.existsSync(candidate)) return candidate;
|
|
4844
|
-
return base;
|
|
5120
|
+
resolveLoader() {
|
|
5121
|
+
return (0, develop_context.G)("feature-scripts-content-script-wrapper");
|
|
4845
5122
|
}
|
|
4846
5123
|
apply(compiler) {
|
|
4847
5124
|
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
4848
|
-
const packageJsonPath = (
|
|
5125
|
+
const packageJsonPath = findNearestPackageJsonSync(this.manifestPath);
|
|
4849
5126
|
const packageJsonDir = packageJsonPath ? external_path_.dirname(packageJsonPath) : manifestDir;
|
|
4850
5127
|
const includeDirs = packageJsonDir === manifestDir ? [
|
|
4851
5128
|
manifestDir
|
|
@@ -4861,7 +5138,7 @@ exports.modules = {
|
|
|
4861
5138
|
],
|
|
4862
5139
|
use: [
|
|
4863
5140
|
{
|
|
4864
|
-
loader: this.resolveLoader(
|
|
5141
|
+
loader: this.resolveLoader(),
|
|
4865
5142
|
options: {
|
|
4866
5143
|
manifestPath: this.manifestPath,
|
|
4867
5144
|
mode: compiler.options.mode
|
|
@@ -4869,41 +5146,6 @@ exports.modules = {
|
|
|
4869
5146
|
}
|
|
4870
5147
|
]
|
|
4871
5148
|
});
|
|
4872
|
-
if ('production' !== compiler.options.mode) {
|
|
4873
|
-
compiler.options.module.rules.push({
|
|
4874
|
-
test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
|
|
4875
|
-
include: includeDirs,
|
|
4876
|
-
exclude: [
|
|
4877
|
-
/([\\/])node_modules\1/
|
|
4878
|
-
],
|
|
4879
|
-
use: [
|
|
4880
|
-
{
|
|
4881
|
-
loader: this.resolveLoader('warn-no-default-export'),
|
|
4882
|
-
options: {
|
|
4883
|
-
manifestPath: this.manifestPath,
|
|
4884
|
-
mode: compiler.options.mode
|
|
4885
|
-
}
|
|
4886
|
-
}
|
|
4887
|
-
],
|
|
4888
|
-
enforce: 'pre'
|
|
4889
|
-
});
|
|
4890
|
-
compiler.options.module.rules.push({
|
|
4891
|
-
test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
|
|
4892
|
-
include: includeDirs,
|
|
4893
|
-
exclude: [
|
|
4894
|
-
/([\\/])node_modules\1/
|
|
4895
|
-
],
|
|
4896
|
-
use: [
|
|
4897
|
-
{
|
|
4898
|
-
loader: this.resolveLoader('add-hmr-accept-code'),
|
|
4899
|
-
options: {
|
|
4900
|
-
manifestPath: this.manifestPath,
|
|
4901
|
-
mode: compiler.options.mode
|
|
4902
|
-
}
|
|
4903
|
-
}
|
|
4904
|
-
]
|
|
4905
|
-
});
|
|
4906
|
-
}
|
|
4907
5149
|
}
|
|
4908
5150
|
constructor(options){
|
|
4909
5151
|
add_content_script_wrapper_define_property(this, "manifestPath", void 0);
|
|
@@ -4912,17 +5154,6 @@ exports.modules = {
|
|
|
4912
5154
|
this.browser = options.browser || 'chrome';
|
|
4913
5155
|
}
|
|
4914
5156
|
}
|
|
4915
|
-
function scriptsEntriesSummary(entriesAdded, publicTracked) {
|
|
4916
|
-
return `Scripts entries — added=${external_pintor_default().gray(String(entriesAdded))}, publicTracked=${external_pintor_default().gray(String(publicTracked))}`;
|
|
4917
|
-
}
|
|
4918
|
-
function scriptsManifestChangeDetected(before, after) {
|
|
4919
|
-
const parts = [
|
|
4920
|
-
"Manifest scripts change detected",
|
|
4921
|
-
before ? `${external_pintor_default().gray('before')} ${external_pintor_default().underline(before)}` : '',
|
|
4922
|
-
after ? `${external_pintor_default().gray('after')} ${external_pintor_default().underline(after)}` : ''
|
|
4923
|
-
].filter(Boolean);
|
|
4924
|
-
return parts.join(' — ');
|
|
4925
|
-
}
|
|
4926
5157
|
function add_scripts_define_property(obj, key, value) {
|
|
4927
5158
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
4928
5159
|
value: value,
|
|
@@ -4934,14 +5165,22 @@ exports.modules = {
|
|
|
4934
5165
|
return obj;
|
|
4935
5166
|
}
|
|
4936
5167
|
const add_scripts_isRemoteUrl = (entry)=>/^([a-z][a-z0-9+.-]*:)?\/\//i.test(entry);
|
|
5168
|
+
const isContentScriptFeature = (feature)=>feature.startsWith("content_scripts/");
|
|
5169
|
+
const isScriptsFolderFeature = (feature)=>feature.startsWith("scripts/");
|
|
5170
|
+
function createSequentialEntryModule(feature, entryImports) {
|
|
5171
|
+
const source = [
|
|
5172
|
+
`/* extension.js sequential entry: ${feature} */`,
|
|
5173
|
+
...entryImports.map((entryImport)=>`import ${JSON.stringify(String(entryImport))};`)
|
|
5174
|
+
].join('\n');
|
|
5175
|
+
return `data:text/javascript;charset=utf-8,${encodeURIComponent(source)}`;
|
|
5176
|
+
}
|
|
4937
5177
|
class AddScripts {
|
|
4938
5178
|
apply(compiler) {
|
|
4939
5179
|
const bridgeScripts = AddContentScriptWrapper.getBridgeScripts(this.manifestPath);
|
|
4940
|
-
const
|
|
5180
|
+
const scriptFields = {
|
|
4941
5181
|
...this.includeList,
|
|
4942
5182
|
...bridgeScripts
|
|
4943
5183
|
};
|
|
4944
|
-
const scriptFields = mergedIncludeList;
|
|
4945
5184
|
if (compiler?.hooks?.thisCompilation?.tap) compiler.hooks.thisCompilation.tap("scripts:validate-include-list", (compilation)=>{
|
|
4946
5185
|
try {
|
|
4947
5186
|
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
@@ -4952,20 +5191,19 @@ exports.modules = {
|
|
|
4952
5191
|
raw
|
|
4953
5192
|
] : [];
|
|
4954
5193
|
for (const entry of rawEntries){
|
|
4955
|
-
if (!entry || 'string' != typeof entry) continue;
|
|
4956
|
-
if (add_scripts_isRemoteUrl(entry)) continue;
|
|
5194
|
+
if (!entry || 'string' != typeof entry || add_scripts_isRemoteUrl(entry)) continue;
|
|
4957
5195
|
let resolved = entry;
|
|
4958
5196
|
if (!external_fs_.existsSync(resolved)) resolved = external_path_.isAbsolute(entry) ? entry : entry.startsWith('/') ? external_path_.join(manifestDir, entry.slice(1)) : external_path_.join(manifestDir, entry);
|
|
4959
5197
|
if (external_fs_.existsSync(resolved)) continue;
|
|
4960
5198
|
const isPublicRoot = entry.startsWith('/') && !external_path_.isAbsolute(entry);
|
|
4961
5199
|
const displayPath = isPublicRoot ? outputRoot ? external_path_.join(outputRoot, entry.slice(1)) : entry : resolved;
|
|
4962
|
-
const
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
5200
|
+
const err = new ErrorCtor([
|
|
5201
|
+
`Check the ${feature.replace('/', '.')} field in your manifest.json file.`,
|
|
5202
|
+
"The script path must point to an existing file that will be bundled.",
|
|
5203
|
+
isPublicRoot ? "Paths starting with '/' are resolved from the extension output root (served from public/), not your source directory." : '',
|
|
5204
|
+
'',
|
|
5205
|
+
`NOT FOUND ${displayPath}`
|
|
5206
|
+
].filter(Boolean).join('\n'));
|
|
4969
5207
|
err.file = 'manifest.json';
|
|
4970
5208
|
err.name = 'ScriptsMissingFile';
|
|
4971
5209
|
(compilation.errors ||= []).push(err);
|
|
@@ -4976,15 +5214,18 @@ exports.modules = {
|
|
|
4976
5214
|
const newEntries = {};
|
|
4977
5215
|
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
4978
5216
|
const projectPath = compiler.options.context || manifestDir;
|
|
5217
|
+
let manifestJson = {};
|
|
5218
|
+
try {
|
|
5219
|
+
manifestJson = JSON.parse(external_fs_.readFileSync(this.manifestPath, 'utf8'));
|
|
5220
|
+
} catch {
|
|
5221
|
+
manifestJson = {};
|
|
5222
|
+
}
|
|
4979
5223
|
const resolveEntryPath = (entry)=>{
|
|
4980
|
-
if (!entry) return entry;
|
|
4981
|
-
if (add_scripts_isRemoteUrl(entry)) return entry;
|
|
5224
|
+
if (!entry || add_scripts_isRemoteUrl(entry)) return entry;
|
|
4982
5225
|
if (entry.startsWith('/') && !external_path_.isAbsolute(entry)) return external_path_.join(projectPath, entry.slice(1));
|
|
4983
5226
|
if (external_path_.isAbsolute(entry)) return entry;
|
|
4984
5227
|
return external_path_.join(manifestDir, entry);
|
|
4985
5228
|
};
|
|
4986
|
-
let entriesAdded = 0;
|
|
4987
|
-
let publicTracked = 0;
|
|
4988
5229
|
for (const [feature, scriptPath] of Object.entries(scriptFields)){
|
|
4989
5230
|
const rawEntries = Array.isArray(scriptPath) ? scriptPath || [] : scriptPath ? [
|
|
4990
5231
|
scriptPath
|
|
@@ -4992,32 +5233,32 @@ exports.modules = {
|
|
|
4992
5233
|
const resolvedEntries = rawEntries.map(resolveEntryPath);
|
|
4993
5234
|
const scriptImports = getScriptEntries(resolvedEntries);
|
|
4994
5235
|
const cssImports = getCssEntries(resolvedEntries);
|
|
4995
|
-
const
|
|
4996
|
-
...
|
|
4997
|
-
|
|
5236
|
+
const entryImports = [
|
|
5237
|
+
...new Set([
|
|
5238
|
+
...scriptImports,
|
|
5239
|
+
...cssImports
|
|
5240
|
+
])
|
|
4998
5241
|
];
|
|
4999
|
-
const
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
}
|
|
5013
|
-
|
|
5014
|
-
}
|
|
5242
|
+
const shouldUseSequentialEntryModule = isContentScriptFeature(feature) && scriptImports.length > 1;
|
|
5243
|
+
const finalEntryImports = shouldUseSequentialEntryModule ? [
|
|
5244
|
+
createSequentialEntryModule(feature, entryImports)
|
|
5245
|
+
] : entryImports;
|
|
5246
|
+
if (finalEntryImports.length) newEntries[feature] = 'background/service_worker' === feature ? {
|
|
5247
|
+
import: finalEntryImports,
|
|
5248
|
+
...manifestJson.background?.type === 'module' ? {} : {
|
|
5249
|
+
chunkLoading: "import-scripts"
|
|
5250
|
+
}
|
|
5251
|
+
} : {
|
|
5252
|
+
import: finalEntryImports,
|
|
5253
|
+
...isContentScriptFeature(feature) || isScriptsFolderFeature(feature) ? {
|
|
5254
|
+
layer: contracts.$t
|
|
5255
|
+
} : {}
|
|
5256
|
+
};
|
|
5015
5257
|
}
|
|
5016
5258
|
compiler.options.entry = {
|
|
5017
5259
|
...compiler.options.entry,
|
|
5018
5260
|
...newEntries
|
|
5019
5261
|
};
|
|
5020
|
-
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(scriptsEntriesSummary(entriesAdded, publicTracked));
|
|
5021
5262
|
}
|
|
5022
5263
|
constructor(options){
|
|
5023
5264
|
add_scripts_define_property(this, "manifestPath", void 0);
|
|
@@ -5026,45 +5267,6 @@ exports.modules = {
|
|
|
5026
5267
|
this.includeList = options.includeList || {};
|
|
5027
5268
|
}
|
|
5028
5269
|
}
|
|
5029
|
-
const basic = [
|
|
5030
|
-
'var isBrowser = !!(() => { try { return browser.runtime.getURL("/") } catch(e) {} })()',
|
|
5031
|
-
'var isChrome = !!(() => { try { return chrome.runtime.getURL("/") } catch(e) {} })()'
|
|
5032
|
-
];
|
|
5033
|
-
const weakRuntimeCheck = [
|
|
5034
|
-
...basic,
|
|
5035
|
-
"var runtime = isBrowser ? browser : isChrome ? chrome : { runtime: { getURL: x => x } }"
|
|
5036
|
-
];
|
|
5037
|
-
class AddPublicPathRuntimeModule {
|
|
5038
|
-
apply(compiler) {
|
|
5039
|
-
const { RuntimeGlobals } = compiler.webpack;
|
|
5040
|
-
compiler.hooks.compilation.tap('PublicPathRuntimeModule', (compilation)=>{
|
|
5041
|
-
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap(AddPublicPathRuntimeModule.name, (chunk)=>{
|
|
5042
|
-
const module = add_public_path_runtime_module_PublicPathRuntimeModule(compiler);
|
|
5043
|
-
compilation.addRuntimeModule(chunk, module);
|
|
5044
|
-
return true;
|
|
5045
|
-
});
|
|
5046
|
-
});
|
|
5047
|
-
}
|
|
5048
|
-
}
|
|
5049
|
-
function add_public_path_runtime_module_PublicPathRuntimeModule(compiler) {
|
|
5050
|
-
const { Template, RuntimeModule, RuntimeGlobals } = compiler.webpack;
|
|
5051
|
-
class PublicPathRuntimeModule extends RuntimeModule {
|
|
5052
|
-
generate() {
|
|
5053
|
-
const publicPath = this.compilation?.outputOptions.publicPath;
|
|
5054
|
-
return Template.asString([
|
|
5055
|
-
...weakRuntimeCheck,
|
|
5056
|
-
`var path = ${JSON.stringify(this.compilation?.getPath(publicPath || '', {
|
|
5057
|
-
hash: this.compilation.hash || 'XXXX'
|
|
5058
|
-
}))}`,
|
|
5059
|
-
`${RuntimeGlobals.publicPath} = typeof importScripts === 'function' || !(isBrowser || isChrome) ? path : runtime.runtime.getURL(path);`
|
|
5060
|
-
]);
|
|
5061
|
-
}
|
|
5062
|
-
constructor(){
|
|
5063
|
-
super('publicPath', RuntimeModule.STAGE_BASIC);
|
|
5064
|
-
}
|
|
5065
|
-
}
|
|
5066
|
-
return new PublicPathRuntimeModule();
|
|
5067
|
-
}
|
|
5068
5270
|
function TemplateFn(compilation, Template) {
|
|
5069
5271
|
return {
|
|
5070
5272
|
f: (args, body)=>{
|
|
@@ -5093,9 +5295,9 @@ exports.modules = {
|
|
|
5093
5295
|
`${_let} isChrome, runtime;`,
|
|
5094
5296
|
'try {',
|
|
5095
5297
|
Template.indent([
|
|
5096
|
-
`if (typeof browser !== "undefined" && ${optionalChaining ? 'typeof browser.runtime?.getURL === "function"' : 'typeof browser.runtime === "object" && typeof browser.runtime.getURL === "function"'}) {`,
|
|
5298
|
+
`if (typeof globalThis === "object" && globalThis && typeof globalThis.browser !== "undefined" && ${optionalChaining ? 'typeof globalThis.browser.runtime?.getURL === "function"' : 'typeof globalThis.browser.runtime === "object" && typeof globalThis.browser.runtime.getURL === "function"'}) {`,
|
|
5097
5299
|
Template.indent([
|
|
5098
|
-
'runtime = browser;'
|
|
5300
|
+
'runtime = globalThis.browser;'
|
|
5099
5301
|
]),
|
|
5100
5302
|
'}'
|
|
5101
5303
|
]),
|
|
@@ -5104,10 +5306,10 @@ exports.modules = {
|
|
|
5104
5306
|
Template.indent([
|
|
5105
5307
|
'try {',
|
|
5106
5308
|
Template.indent([
|
|
5107
|
-
`if (typeof chrome !== "undefined" && ${optionalChaining ? 'typeof chrome.runtime?.getURL === "function"' : 'typeof chrome.runtime === "object" && typeof chrome.runtime.getURL === "function"'}) {`,
|
|
5309
|
+
`if (typeof globalThis === "object" && globalThis && typeof globalThis.chrome !== "undefined" && ${optionalChaining ? 'typeof globalThis.chrome.runtime?.getURL === "function"' : 'typeof globalThis.chrome.runtime === "object" && typeof globalThis.chrome.runtime.getURL === "function"'}) {`,
|
|
5108
5310
|
Template.indent([
|
|
5109
5311
|
'isChrome = true;',
|
|
5110
|
-
'runtime = chrome;'
|
|
5312
|
+
'runtime = globalThis.chrome;'
|
|
5111
5313
|
]),
|
|
5112
5314
|
'}'
|
|
5113
5315
|
]),
|
|
@@ -5158,7 +5360,7 @@ exports.modules = {
|
|
|
5158
5360
|
const bundleId = chunkName ? `${chunkName}.js` : '';
|
|
5159
5361
|
const world = bundleId && this.contentScriptsMeta[bundleId] ? this.contentScriptsMeta[bundleId].world : void 0;
|
|
5160
5362
|
const isMainWorld = 'main' === world;
|
|
5161
|
-
const HasExtensionRuntime = `${_const} hasExtensionRuntime = (function(){ try {return ((typeof
|
|
5363
|
+
const HasExtensionRuntime = `${_const} hasExtensionRuntime = (function(){ try {return ((typeof globalThis === "object" && globalThis && globalThis.browser && globalThis.browser.runtime && typeof globalThis.browser.runtime.sendMessage === "function") || (typeof globalThis === "object" && globalThis && globalThis.chrome && globalThis.chrome.runtime && typeof globalThis.chrome.runtime.sendMessage === "function"));} catch (e) { return false; } })();`;
|
|
5162
5364
|
const DynamicImportLoader = `${_const} ${DYNAMIC_IMPORT_LOADER} = ` + f('url, done, key, chunkId', `import(url).then(${f('', [
|
|
5163
5365
|
'if (isNotIframe) return done();',
|
|
5164
5366
|
'try {',
|
|
@@ -5209,6 +5411,7 @@ exports.modules = {
|
|
|
5209
5411
|
const ClassicLoader = `${_const} ${CLASSIC_LOADER} = ` + f('url, done', Template.asString([
|
|
5210
5412
|
`${_const} msg = { type: "WTW_INJECT", file: url };`,
|
|
5211
5413
|
`${_const} onError = ${f('e', 'done(Object.assign(e, { type: "missing" }))')};`,
|
|
5414
|
+
'try {',
|
|
5212
5415
|
`if (${RuntimeGlobalIsBrowser}) {`,
|
|
5213
5416
|
Template.indent([
|
|
5214
5417
|
`${RuntimeGlobal}.runtime.sendMessage(msg).then(done, onError);`
|
|
@@ -5221,7 +5424,8 @@ exports.modules = {
|
|
|
5221
5424
|
'else done();'
|
|
5222
5425
|
])});`
|
|
5223
5426
|
]),
|
|
5224
|
-
'}'
|
|
5427
|
+
'}',
|
|
5428
|
+
'} catch (e) { onError(e); }'
|
|
5225
5429
|
])) + ';';
|
|
5226
5430
|
const ClassicLoaderDisabled = `${_const} ${CLASSIC_LOADER} = ` + f('', [
|
|
5227
5431
|
"throw new Error(\"[webpack-target-webextension] Failed to load async chunk in the content script. No script loader is found. You can either\\n - Set output.environment.dynamicImport to true if your environment supports native ES Module\\n - Specify the background entry to enable the fallback loader\\n - Set module.parser.javascript.dynamicImportMode to 'eager' to inline all async chunks.\");"
|
|
@@ -5323,9 +5527,15 @@ exports.modules = {
|
|
|
5323
5527
|
'try { __extjsBase = document.documentElement.getAttribute("data-extjs-extension-base") || ""; } catch(_) { __extjsBase = ""; }'
|
|
5324
5528
|
]),
|
|
5325
5529
|
"}",
|
|
5530
|
+
'var __extjsRuntimePath = "";',
|
|
5326
5531
|
`if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && typeof ${RuntimeGlobal}.runtime.getURL === "function") {`,
|
|
5327
5532
|
Template.indent([
|
|
5328
|
-
|
|
5533
|
+
`try { __extjsRuntimePath = ${RuntimeGlobal}.runtime.getURL(${path}); } catch (_) { __extjsRuntimePath = ""; }`
|
|
5534
|
+
]),
|
|
5535
|
+
"}",
|
|
5536
|
+
"if (__extjsRuntimePath) {",
|
|
5537
|
+
Template.indent([
|
|
5538
|
+
`${RuntimeGlobals.publicPath} = __extjsRuntimePath;`
|
|
5329
5539
|
]),
|
|
5330
5540
|
"} else if (__extjsBase) {",
|
|
5331
5541
|
Template.indent([
|
|
@@ -5416,8 +5626,10 @@ exports.modules = {
|
|
|
5416
5626
|
"}",
|
|
5417
5627
|
"if (!scriptUrl) {",
|
|
5418
5628
|
Template.indent([
|
|
5629
|
+
'var __extjsRuntimeRoot = "";',
|
|
5419
5630
|
`if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && typeof ${RuntimeGlobal}.runtime.getURL === "function") {`,
|
|
5420
|
-
Template.indent(`
|
|
5631
|
+
Template.indent(`try { __extjsRuntimeRoot = ${RuntimeGlobal}.runtime.getURL("/"); } catch (_) { __extjsRuntimeRoot = ""; }`),
|
|
5632
|
+
Template.indent("scriptUrl = __extjsRuntimeRoot || scriptUrl;"),
|
|
5421
5633
|
"} else {",
|
|
5422
5634
|
Template.indent('scriptUrl = __extjsBase || "";'),
|
|
5423
5635
|
"}"
|
|
@@ -5475,6 +5687,52 @@ exports.modules = {
|
|
|
5475
5687
|
else if ('.' !== part) depth++;
|
|
5476
5688
|
return depth > 0 ? `${'../'.repeat(depth)}${append}` : enforceRelative ? `./${append}` : append;
|
|
5477
5689
|
}
|
|
5690
|
+
function BaseUriRuntimeModule(webpack) {
|
|
5691
|
+
const { RuntimeGlobals, RuntimeModule, Template } = webpack;
|
|
5692
|
+
class BaseUriRuntime extends RuntimeModule {
|
|
5693
|
+
generate() {
|
|
5694
|
+
return Template.asString([
|
|
5695
|
+
'var __extjsBase = "";',
|
|
5696
|
+
"try {",
|
|
5697
|
+
Template.indent([
|
|
5698
|
+
`if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && typeof ${RuntimeGlobal}.runtime.getURL === "function") {`,
|
|
5699
|
+
Template.indent([
|
|
5700
|
+
`__extjsBase = String(${RuntimeGlobal}.runtime.getURL("/"));`
|
|
5701
|
+
]),
|
|
5702
|
+
"}"
|
|
5703
|
+
]),
|
|
5704
|
+
"} catch (_) {}",
|
|
5705
|
+
'if (!__extjsBase && typeof globalThis === "object" && globalThis && globalThis.__EXTJS_EXTENSION_BASE__) {',
|
|
5706
|
+
Template.indent([
|
|
5707
|
+
'__extjsBase = String(globalThis.__EXTJS_EXTENSION_BASE__ || "");'
|
|
5708
|
+
]),
|
|
5709
|
+
"}",
|
|
5710
|
+
'if (!__extjsBase && typeof document === "object" && document && document.documentElement) {',
|
|
5711
|
+
Template.indent([
|
|
5712
|
+
'try { __extjsBase = String(document.documentElement.getAttribute("data-extjs-extension-base") || ""); } catch (_) { __extjsBase = ""; }'
|
|
5713
|
+
]),
|
|
5714
|
+
"}",
|
|
5715
|
+
"if (__extjsBase) {",
|
|
5716
|
+
Template.indent([
|
|
5717
|
+
`${RuntimeGlobals.baseURI} = __extjsBase;`
|
|
5718
|
+
]),
|
|
5719
|
+
'} else if (typeof document !== "undefined" && document.baseURI) {',
|
|
5720
|
+
Template.indent([
|
|
5721
|
+
`${RuntimeGlobals.baseURI} = document.baseURI;`
|
|
5722
|
+
]),
|
|
5723
|
+
"} else {",
|
|
5724
|
+
Template.indent([
|
|
5725
|
+
`${RuntimeGlobals.baseURI} = self.location.href;`
|
|
5726
|
+
]),
|
|
5727
|
+
"}"
|
|
5728
|
+
]);
|
|
5729
|
+
}
|
|
5730
|
+
constructor(){
|
|
5731
|
+
super('baseURI', RuntimeModule.STAGE_BASIC);
|
|
5732
|
+
}
|
|
5733
|
+
}
|
|
5734
|
+
return new BaseUriRuntime();
|
|
5735
|
+
}
|
|
5478
5736
|
function ChunkLoaderFallbackRuntimeModule(webpack) {
|
|
5479
5737
|
const { RuntimeModule, Template } = webpack;
|
|
5480
5738
|
class ChunkLoaderFallbackRuntime extends RuntimeModule {
|
|
@@ -5485,7 +5743,7 @@ exports.modules = {
|
|
|
5485
5743
|
const optionalChain = compilation.outputOptions.environment.optionalChaining;
|
|
5486
5744
|
const _const = compilation.outputOptions.environment.const ? 'const' : 'var';
|
|
5487
5745
|
const _let = compilation.outputOptions.environment.const ? 'let' : 'var';
|
|
5488
|
-
return
|
|
5746
|
+
return `if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && ${RuntimeGlobal}.runtime.onMessage) {${RuntimeGlobal}.runtime.onMessage.addListener(` + f('message, sender, sendResponse', [
|
|
5489
5747
|
optionalChain ? 'if (message?.type != "WTW_INJECT" || typeof sender?.tab?.id != "number") return;' : 'if (!message || message.type != "WTW_INJECT" || !sender || !sender.tab || sender.tab.id == null) return;',
|
|
5490
5748
|
`${_let} file = message.file;`,
|
|
5491
5749
|
'try {',
|
|
@@ -5514,7 +5772,7 @@ exports.modules = {
|
|
|
5514
5772
|
]),
|
|
5515
5773
|
'}',
|
|
5516
5774
|
'return true;'
|
|
5517
|
-
]) +
|
|
5775
|
+
]) + ");}";
|
|
5518
5776
|
}
|
|
5519
5777
|
constructor(){
|
|
5520
5778
|
super('chunk loader fallback', RuntimeModule.STAGE_TRIGGER);
|
|
@@ -5553,8 +5811,13 @@ exports.modules = {
|
|
|
5553
5811
|
compilation.addRuntimeModule(_chunk, LoadScriptRuntimeModule(compiler.webpack, false !== compilation.outputOptions.environment.dynamicImport, false !== options.classicLoader, this.contentScriptsMeta));
|
|
5554
5812
|
return true;
|
|
5555
5813
|
});
|
|
5556
|
-
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.
|
|
5557
|
-
|
|
5814
|
+
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.baseURI).tap(WebExtensionChuckLoaderRuntimePlugin.name, (chunk, set)=>{
|
|
5815
|
+
set.add(RuntimeGlobal);
|
|
5816
|
+
compilation.addRuntimeModule(chunk, BaseUriRuntimeModule(compiler.webpack));
|
|
5817
|
+
return true;
|
|
5818
|
+
});
|
|
5819
|
+
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap(WebExtensionChuckLoaderRuntimePlugin.name, (chunk, set)=>{
|
|
5820
|
+
const { outputOptions } = compilation;
|
|
5558
5821
|
const { publicPath, scriptType } = outputOptions;
|
|
5559
5822
|
if ('auto' === publicPath || '' === publicPath && this.rspackAutoPublicPath) {
|
|
5560
5823
|
const module = AutoPublicPathRuntimeModule(compiler.webpack);
|
|
@@ -5794,7 +6057,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
5794
6057
|
} else code = [
|
|
5795
6058
|
';(() => {',
|
|
5796
6059
|
Template.indent([
|
|
5797
|
-
'const getURL = typeof browser === "object" ? browser.runtime.getURL : chrome.runtime.getURL;',
|
|
6060
|
+
'const getURL = typeof globalThis === "object" && globalThis && typeof globalThis.browser === "object" ? globalThis.browser.runtime.getURL : globalThis.chrome.runtime.getURL;',
|
|
5798
6061
|
`${JSON.stringify(files)}.forEach(file => import(getURL(file)));`
|
|
5799
6062
|
]),
|
|
5800
6063
|
'})();',
|
|
@@ -5982,12 +6245,23 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
5982
6245
|
}
|
|
5983
6246
|
}
|
|
5984
6247
|
const webpack_target_webextension_fork = WebExtensionPlugin;
|
|
6248
|
+
function manifest_getManifestContent(compilation, manifestPath) {
|
|
6249
|
+
return getManifestContent(compilation, manifestPath);
|
|
6250
|
+
}
|
|
5985
6251
|
function scripts_lib_manifest_filterKeysForThisBrowser(manifest, browser) {
|
|
5986
6252
|
return manifest_filterKeysForThisBrowser(manifest, browser);
|
|
5987
6253
|
}
|
|
5988
6254
|
function backgroundIsRequiredMessageOnly(backgroundChunkName) {
|
|
5989
6255
|
return `Check the ${external_pintor_default().yellow(backgroundChunkName.replace('/', '.'))} field in your ${external_pintor_default().yellow('manifest.json')} file.`;
|
|
5990
6256
|
}
|
|
6257
|
+
function scriptsManifestChangeDetected(before, after) {
|
|
6258
|
+
const parts = [
|
|
6259
|
+
"Manifest scripts change detected",
|
|
6260
|
+
before ? `${external_pintor_default().gray('before')} ${external_pintor_default().underline(before)}` : '',
|
|
6261
|
+
after ? `${external_pintor_default().gray('after')} ${external_pintor_default().underline(after)}` : ''
|
|
6262
|
+
].filter(Boolean);
|
|
6263
|
+
return parts.join(' — ');
|
|
6264
|
+
}
|
|
5991
6265
|
function setup_background_entry_define_property(obj, key, value) {
|
|
5992
6266
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
5993
6267
|
value: value,
|
|
@@ -6020,7 +6294,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6020
6294
|
apply(compiler) {
|
|
6021
6295
|
const manifest = JSON.parse(external_fs_.readFileSync(this.manifestPath, 'utf-8'));
|
|
6022
6296
|
const browser = this.browser;
|
|
6023
|
-
const minimumBgScript =
|
|
6297
|
+
const minimumBgScript = (0, develop_context.G)('firefox' === browser || 'gecko-based' === browser ? 'minimum-firefox-file' : 'minimum-chromium-file');
|
|
6024
6298
|
const dirname = external_path_.dirname(this.manifestPath);
|
|
6025
6299
|
let manifestBg = scripts_lib_manifest_filterKeysForThisBrowser(manifest, browser);
|
|
6026
6300
|
manifestBg = manifestBg?.background ?? manifest.background;
|
|
@@ -6063,6 +6337,263 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6063
6337
|
this.browser = options.browser || 'chrome';
|
|
6064
6338
|
}
|
|
6065
6339
|
}
|
|
6340
|
+
function patch_csp_resolveV2Policy(policy) {
|
|
6341
|
+
if (!policy) return;
|
|
6342
|
+
if ('string' == typeof policy) return policy;
|
|
6343
|
+
if ('object' == typeof policy) {
|
|
6344
|
+
const extensionPages = policy.extension_pages;
|
|
6345
|
+
if ('string' == typeof extensionPages) return extensionPages;
|
|
6346
|
+
}
|
|
6347
|
+
}
|
|
6348
|
+
function patch_csp_buildCSP(cspObject) {
|
|
6349
|
+
const directives = Object.entries(cspObject).map(([directive, values])=>`${directive} ${values.join(' ')}`);
|
|
6350
|
+
return directives.join('; ') + '; ';
|
|
6351
|
+
}
|
|
6352
|
+
function patch_csp_patchV2CSP(manifest) {
|
|
6353
|
+
let policy = patch_csp_resolveV2Policy(manifest.content_security_policy);
|
|
6354
|
+
if (!policy) return patch_csp_buildCSP({
|
|
6355
|
+
"script-src": [
|
|
6356
|
+
"'self'",
|
|
6357
|
+
"'unsafe-eval'",
|
|
6358
|
+
'blob:',
|
|
6359
|
+
'filesystem:'
|
|
6360
|
+
],
|
|
6361
|
+
'object-src': [
|
|
6362
|
+
"'self'",
|
|
6363
|
+
'blob:',
|
|
6364
|
+
'filesystem:'
|
|
6365
|
+
]
|
|
6366
|
+
});
|
|
6367
|
+
const csp = external_content_security_policy_parser_default()(policy);
|
|
6368
|
+
if (csp.get("script-src")) {
|
|
6369
|
+
const scriptSrc = csp.get("script-src") || [];
|
|
6370
|
+
if (!scriptSrc.includes("'unsafe-eval'")) scriptSrc.push("'unsafe-eval'");
|
|
6371
|
+
if (!scriptSrc.includes('blob:')) scriptSrc.push('blob:');
|
|
6372
|
+
if (!scriptSrc.includes('filesystem:')) scriptSrc.push('filesystem:');
|
|
6373
|
+
csp.set("script-src", scriptSrc);
|
|
6374
|
+
} else csp.set("script-src", [
|
|
6375
|
+
"'self'",
|
|
6376
|
+
"'unsafe-eval'",
|
|
6377
|
+
'blob:',
|
|
6378
|
+
'filesystem:'
|
|
6379
|
+
]);
|
|
6380
|
+
if (csp.get('object-src')) {
|
|
6381
|
+
const objectSrc = csp.get('object-src') || [];
|
|
6382
|
+
if (!objectSrc.includes('blob:')) objectSrc.push('blob:');
|
|
6383
|
+
if (!objectSrc.includes('filesystem:')) objectSrc.push('filesystem:');
|
|
6384
|
+
csp.set('object-src', objectSrc);
|
|
6385
|
+
} else csp.set('object-src', [
|
|
6386
|
+
"'self'",
|
|
6387
|
+
'blob:',
|
|
6388
|
+
'filesystem:'
|
|
6389
|
+
]);
|
|
6390
|
+
const cspObject = Object.fromEntries(csp.entries());
|
|
6391
|
+
return patch_csp_buildCSP(cspObject);
|
|
6392
|
+
}
|
|
6393
|
+
function patch_csp_patchV3CSP(manifest) {
|
|
6394
|
+
const policy = manifest.content_security_policy;
|
|
6395
|
+
if (!policy) return {
|
|
6396
|
+
extension_pages: patch_csp_buildCSP({
|
|
6397
|
+
"script-src": [
|
|
6398
|
+
"'self'"
|
|
6399
|
+
],
|
|
6400
|
+
'object-src': [
|
|
6401
|
+
"'self'"
|
|
6402
|
+
]
|
|
6403
|
+
})
|
|
6404
|
+
};
|
|
6405
|
+
const csp = external_content_security_policy_parser_default()(policy.extension_pages || '');
|
|
6406
|
+
const defaultDirectives = {
|
|
6407
|
+
"script-src": [
|
|
6408
|
+
"'self'"
|
|
6409
|
+
],
|
|
6410
|
+
'object-src': [
|
|
6411
|
+
"'self'"
|
|
6412
|
+
]
|
|
6413
|
+
};
|
|
6414
|
+
for(const directive in defaultDirectives)if (!csp.get(directive)) csp.set(directive, defaultDirectives[directive]);
|
|
6415
|
+
const cspObject = Object.fromEntries(csp.entries());
|
|
6416
|
+
const extensionPagesPolicy = patch_csp_buildCSP(cspObject);
|
|
6417
|
+
return {
|
|
6418
|
+
extension_pages: extensionPagesPolicy
|
|
6419
|
+
};
|
|
6420
|
+
}
|
|
6421
|
+
function patch_web_resources_patchWebResourcesV2(manifest) {
|
|
6422
|
+
const defaultResources = [
|
|
6423
|
+
'/*.json',
|
|
6424
|
+
'/*.js',
|
|
6425
|
+
'/*.css',
|
|
6426
|
+
'/*.scss',
|
|
6427
|
+
'/*.sass',
|
|
6428
|
+
'/*.less',
|
|
6429
|
+
'*.styl',
|
|
6430
|
+
"/scripts/*.js",
|
|
6431
|
+
"/scripts/*.css",
|
|
6432
|
+
'/hot/*',
|
|
6433
|
+
'/*.png',
|
|
6434
|
+
'/*.jpg',
|
|
6435
|
+
'/*.jpeg',
|
|
6436
|
+
'/*.svg',
|
|
6437
|
+
'/*.gif',
|
|
6438
|
+
'/*.webp',
|
|
6439
|
+
'/*.ico',
|
|
6440
|
+
'/*.avif'
|
|
6441
|
+
];
|
|
6442
|
+
const resources = manifest.web_accessible_resources;
|
|
6443
|
+
if (!resources || 0 === resources.length) return defaultResources;
|
|
6444
|
+
const webResources = new Set(resources);
|
|
6445
|
+
for (const resource of defaultResources)if (!webResources.has(resource)) webResources.add(resource);
|
|
6446
|
+
return Array.from(webResources);
|
|
6447
|
+
}
|
|
6448
|
+
function patch_web_resources_patchWebResourcesV3(manifest) {
|
|
6449
|
+
const defaultResources = [
|
|
6450
|
+
'/*.json',
|
|
6451
|
+
'/*.js',
|
|
6452
|
+
'/*.css',
|
|
6453
|
+
'/*.scss',
|
|
6454
|
+
'/*.sass',
|
|
6455
|
+
'/*.less',
|
|
6456
|
+
'*.styl',
|
|
6457
|
+
"/scripts/*.js",
|
|
6458
|
+
"/scripts/*.css",
|
|
6459
|
+
'/hot/*',
|
|
6460
|
+
'/*.png',
|
|
6461
|
+
'/*.jpg',
|
|
6462
|
+
'/*.jpeg',
|
|
6463
|
+
'/*.svg',
|
|
6464
|
+
'/*.gif',
|
|
6465
|
+
'/*.webp',
|
|
6466
|
+
'/*.ico',
|
|
6467
|
+
'/*.avif'
|
|
6468
|
+
];
|
|
6469
|
+
return [
|
|
6470
|
+
...manifest.web_accessible_resources || [],
|
|
6471
|
+
{
|
|
6472
|
+
resources: defaultResources,
|
|
6473
|
+
matches: [
|
|
6474
|
+
'<all_urls>'
|
|
6475
|
+
]
|
|
6476
|
+
}
|
|
6477
|
+
];
|
|
6478
|
+
}
|
|
6479
|
+
function patch_background_patchBackground(manifest, browser) {
|
|
6480
|
+
if (!manifest.background) {
|
|
6481
|
+
if ('firefox' === browser || 'gecko-based' === browser) return {
|
|
6482
|
+
background: {
|
|
6483
|
+
...manifest.background || {},
|
|
6484
|
+
scripts: [
|
|
6485
|
+
"background/script.js"
|
|
6486
|
+
]
|
|
6487
|
+
}
|
|
6488
|
+
};
|
|
6489
|
+
if (2 === manifest.manifest_version) return {
|
|
6490
|
+
background: {
|
|
6491
|
+
...manifest.background || {},
|
|
6492
|
+
scripts: [
|
|
6493
|
+
"background/script.js"
|
|
6494
|
+
]
|
|
6495
|
+
}
|
|
6496
|
+
};
|
|
6497
|
+
return {
|
|
6498
|
+
background: {
|
|
6499
|
+
...manifest.background || {},
|
|
6500
|
+
service_worker: 'background/service_worker.js'
|
|
6501
|
+
}
|
|
6502
|
+
};
|
|
6503
|
+
}
|
|
6504
|
+
return {
|
|
6505
|
+
background: {
|
|
6506
|
+
...manifest.background
|
|
6507
|
+
}
|
|
6508
|
+
};
|
|
6509
|
+
}
|
|
6510
|
+
function patch_externally_connectable_patchExternallyConnectable(manifest) {
|
|
6511
|
+
if (manifest.externally_connectable && !manifest.externally_connectable.ids) return {
|
|
6512
|
+
externally_connectable: {
|
|
6513
|
+
...manifest.externally_connectable,
|
|
6514
|
+
ids: [
|
|
6515
|
+
...new Set(manifest.externally_connectable.ids || []),
|
|
6516
|
+
'*'
|
|
6517
|
+
]
|
|
6518
|
+
}
|
|
6519
|
+
};
|
|
6520
|
+
if (manifest.externally_connectable && !manifest.externally_connectable.ids) return {
|
|
6521
|
+
externally_connectable: {
|
|
6522
|
+
...manifest.externally_connectable,
|
|
6523
|
+
ids: [
|
|
6524
|
+
'*'
|
|
6525
|
+
]
|
|
6526
|
+
}
|
|
6527
|
+
};
|
|
6528
|
+
return {};
|
|
6529
|
+
}
|
|
6530
|
+
function apply_manifest_dev_defaults_define_property(obj, key, value) {
|
|
6531
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
6532
|
+
value: value,
|
|
6533
|
+
enumerable: true,
|
|
6534
|
+
configurable: true,
|
|
6535
|
+
writable: true
|
|
6536
|
+
});
|
|
6537
|
+
else obj[key] = value;
|
|
6538
|
+
return obj;
|
|
6539
|
+
}
|
|
6540
|
+
class ApplyManifestDevDefaults {
|
|
6541
|
+
generateManifestPatches(compilation) {
|
|
6542
|
+
const canonicalManifest = manifest_getManifestContent(compilation, this.manifestPath);
|
|
6543
|
+
const patchedManifest = {
|
|
6544
|
+
...canonicalManifest,
|
|
6545
|
+
content_security_policy: 3 === canonicalManifest.manifest_version ? patch_csp_patchV3CSP(canonicalManifest) : patch_csp_patchV2CSP(canonicalManifest),
|
|
6546
|
+
...3 === canonicalManifest.manifest_version ? canonicalManifest.permissions ? {
|
|
6547
|
+
permissions: [
|
|
6548
|
+
...new Set([
|
|
6549
|
+
"scripting",
|
|
6550
|
+
'tabs',
|
|
6551
|
+
'management',
|
|
6552
|
+
...canonicalManifest.permissions
|
|
6553
|
+
])
|
|
6554
|
+
]
|
|
6555
|
+
} : {
|
|
6556
|
+
permissions: [
|
|
6557
|
+
"scripting",
|
|
6558
|
+
'tabs',
|
|
6559
|
+
'management'
|
|
6560
|
+
]
|
|
6561
|
+
} : {},
|
|
6562
|
+
...patch_background_patchBackground(canonicalManifest, this.browser),
|
|
6563
|
+
...patch_externally_connectable_patchExternallyConnectable(canonicalManifest),
|
|
6564
|
+
web_accessible_resources: 3 === canonicalManifest.manifest_version ? patch_web_resources_patchWebResourcesV3(canonicalManifest) : patch_web_resources_patchWebResourcesV2(canonicalManifest)
|
|
6565
|
+
};
|
|
6566
|
+
const source = JSON.stringify(patchedManifest, null, 2);
|
|
6567
|
+
const rawSource = new core_.sources.RawSource(source);
|
|
6568
|
+
if (compilation.getAsset('manifest.json')) compilation.updateAsset('manifest.json', rawSource);
|
|
6569
|
+
}
|
|
6570
|
+
apply(compiler) {
|
|
6571
|
+
if (!compiler?.hooks?.thisCompilation) return;
|
|
6572
|
+
compiler.hooks.thisCompilation.tap('run-chromium:apply-manifest-dev-defaults', (compilation)=>{
|
|
6573
|
+
if (!compilation?.hooks?.processAssets) return;
|
|
6574
|
+
compilation.hooks.processAssets.tap({
|
|
6575
|
+
name: 'run-chromium:apply-manifest-dev-defaults',
|
|
6576
|
+
stage: core_.Compilation.PROCESS_ASSETS_STAGE_REPORT + 100
|
|
6577
|
+
}, (_assets)=>{
|
|
6578
|
+
if (!this.manifestPath) {
|
|
6579
|
+
const errorMessage = 'No manifest.json found in your extension bundle. Unable to patch manifest.json.';
|
|
6580
|
+
try {
|
|
6581
|
+
const WebpackErrorCtor = compiler?.rspack?.WebpackError;
|
|
6582
|
+
compilation.errors.push(WebpackErrorCtor ? new WebpackErrorCtor(`run-chromium: ${errorMessage}`) : new Error(`run-chromium: ${errorMessage}`));
|
|
6583
|
+
} catch {}
|
|
6584
|
+
return;
|
|
6585
|
+
}
|
|
6586
|
+
this.generateManifestPatches(compilation);
|
|
6587
|
+
});
|
|
6588
|
+
});
|
|
6589
|
+
}
|
|
6590
|
+
constructor(options){
|
|
6591
|
+
apply_manifest_dev_defaults_define_property(this, "manifestPath", void 0);
|
|
6592
|
+
apply_manifest_dev_defaults_define_property(this, "browser", void 0);
|
|
6593
|
+
this.manifestPath = options.manifestPath;
|
|
6594
|
+
this.browser = options.browser || 'chrome';
|
|
6595
|
+
}
|
|
6596
|
+
}
|
|
6066
6597
|
function setup_reload_strategy_define_property(obj, key, value) {
|
|
6067
6598
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
6068
6599
|
value: value,
|
|
@@ -6108,17 +6639,17 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6108
6639
|
let bridgeOrdinal = 0;
|
|
6109
6640
|
for(let i = 0; i < csList.length; i++){
|
|
6110
6641
|
const cs = csList[i];
|
|
6111
|
-
const bundleId =
|
|
6642
|
+
const bundleId = (0, contracts.f6)(i);
|
|
6112
6643
|
const isMain = cs?.world === 'MAIN';
|
|
6113
6644
|
if (isMain) {
|
|
6114
6645
|
const bridgeIndex = originalCount + bridgeOrdinal++;
|
|
6646
|
+
const bridgeBundleId = (0, contracts.f6)(bridgeIndex);
|
|
6115
6647
|
contentScriptsMeta[bundleId] = {
|
|
6116
6648
|
index: i,
|
|
6117
6649
|
bundleId,
|
|
6118
6650
|
world: 'main',
|
|
6119
|
-
bridgeBundleId
|
|
6651
|
+
bridgeBundleId
|
|
6120
6652
|
};
|
|
6121
|
-
const bridgeBundleId = `content_scripts/content-${bridgeIndex}.js`;
|
|
6122
6653
|
contentScriptsMeta[bridgeBundleId] = {
|
|
6123
6654
|
index: bridgeIndex,
|
|
6124
6655
|
bundleId: bridgeBundleId,
|
|
@@ -6133,12 +6664,17 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6133
6664
|
};
|
|
6134
6665
|
}
|
|
6135
6666
|
} catch {}
|
|
6667
|
+
new ApplyManifestDevDefaults({
|
|
6668
|
+
manifestPath: this.manifestPath,
|
|
6669
|
+
browser: this.browser
|
|
6670
|
+
}).apply(compiler);
|
|
6136
6671
|
new SetupBackgroundEntry({
|
|
6137
6672
|
manifestPath: this.manifestPath,
|
|
6138
6673
|
browser: this.browser
|
|
6139
6674
|
}).apply(compiler);
|
|
6140
6675
|
new webpack_target_webextension_fork({
|
|
6141
6676
|
background: this.getEntryName(patchedManifest),
|
|
6677
|
+
hmrConfig: false,
|
|
6142
6678
|
weakRuntimeCheck: true,
|
|
6143
6679
|
contentScriptsMeta
|
|
6144
6680
|
}).apply(compiler);
|
|
@@ -6150,6 +6686,135 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6150
6686
|
this.browser = options.browser || 'chrome';
|
|
6151
6687
|
}
|
|
6152
6688
|
}
|
|
6689
|
+
const DEV_SERVER_CLIENT_MARKERS = [
|
|
6690
|
+
'@rspack/dev-server/client/index.js?',
|
|
6691
|
+
'@rspack/dev-server/client/utils/ansiHTML.js',
|
|
6692
|
+
'webpack-dev-server',
|
|
6693
|
+
'WebSocketClient'
|
|
6694
|
+
];
|
|
6695
|
+
const DEV_SERVER_HOT_MARKERS = [
|
|
6696
|
+
'[HMR] Waiting for update signal from WDS...',
|
|
6697
|
+
'[HMR] Cannot find update. Need to do a full reload!',
|
|
6698
|
+
'module.hot.check()'
|
|
6699
|
+
];
|
|
6700
|
+
function stripDevServerStartupFromContentScript(source) {
|
|
6701
|
+
let nextSource = source;
|
|
6702
|
+
const startupModuleIds = getStartupModuleIds(source);
|
|
6703
|
+
for (const moduleId of startupModuleIds){
|
|
6704
|
+
const moduleBody = getModuleBody(source, moduleId);
|
|
6705
|
+
if (!moduleBody) continue;
|
|
6706
|
+
const shouldStrip = DEV_SERVER_CLIENT_MARKERS.some((marker)=>moduleBody.includes(marker)) || DEV_SERVER_HOT_MARKERS.some((marker)=>moduleBody.includes(marker));
|
|
6707
|
+
if (shouldStrip) nextSource = stripStartupRequire(nextSource, moduleId);
|
|
6708
|
+
}
|
|
6709
|
+
return stripExtraStartupRequires(nextSource);
|
|
6710
|
+
}
|
|
6711
|
+
function getStartupModuleIds(source) {
|
|
6712
|
+
const startupIndex = source.indexOf('// startup');
|
|
6713
|
+
if (-1 === startupIndex) return [];
|
|
6714
|
+
const startupSection = source.slice(startupIndex);
|
|
6715
|
+
const requirePattern = /__webpack_require__\((\d+)\);/g;
|
|
6716
|
+
const ids = [];
|
|
6717
|
+
let match = null;
|
|
6718
|
+
while(match = requirePattern.exec(startupSection))ids.push(match[1]);
|
|
6719
|
+
return ids;
|
|
6720
|
+
}
|
|
6721
|
+
function getModuleBody(source, moduleId) {
|
|
6722
|
+
const moduleHeaderPattern = new RegExp(`(?:^|\\n)${moduleId}\\([^)]*\\)\\s*\\{`, 'm');
|
|
6723
|
+
const headerMatch = moduleHeaderPattern.exec(source);
|
|
6724
|
+
if (!headerMatch) return null;
|
|
6725
|
+
const moduleStart = headerMatch.index;
|
|
6726
|
+
const nextHeaderPattern = /(?:^|\n)\d+\([^)]*\)\s*\{/g;
|
|
6727
|
+
nextHeaderPattern.lastIndex = moduleStart + headerMatch[0].length;
|
|
6728
|
+
const nextHeaderMatch = nextHeaderPattern.exec(source);
|
|
6729
|
+
return source.slice(moduleStart, nextHeaderMatch ? nextHeaderMatch.index : source.length);
|
|
6730
|
+
}
|
|
6731
|
+
function stripExtraStartupRequires(source) {
|
|
6732
|
+
const startupMarker = '// startup';
|
|
6733
|
+
const startupIndex = source.indexOf(startupMarker);
|
|
6734
|
+
if (-1 === startupIndex) return source;
|
|
6735
|
+
const startupSection = source.slice(startupIndex);
|
|
6736
|
+
const mainEntryMatch = startupSection.match(/var __webpack_exports__ = __webpack_require__\(\d+\);/);
|
|
6737
|
+
if (!mainEntryMatch) return source;
|
|
6738
|
+
const requireMatches = Array.from(startupSection.matchAll(/^\s*__webpack_require__\(\d+\);\s*$/gm));
|
|
6739
|
+
if (requireMatches.length <= 1) return source;
|
|
6740
|
+
const requiresToRemove = requireMatches.slice(1).map((match)=>match[0]);
|
|
6741
|
+
let nextSource = source;
|
|
6742
|
+
for (const requireLine of requiresToRemove)nextSource = nextSource.replace(requireLine, '');
|
|
6743
|
+
return nextSource;
|
|
6744
|
+
}
|
|
6745
|
+
function stripStartupRequire(source, moduleId) {
|
|
6746
|
+
const startupRequirePattern = new RegExp(`^\\s*__webpack_require__\\(${moduleId}\\);\\n?`, 'm');
|
|
6747
|
+
return source.replace(startupRequirePattern, '');
|
|
6748
|
+
}
|
|
6749
|
+
const strip_content_script_dev_server_runtime_CONTENT_SCRIPT_ASSET = /(^|\/)content_scripts\/content-\d+(?:\.[a-f0-9]+)?\.js$/i;
|
|
6750
|
+
class StripContentScriptDevServerRuntime {
|
|
6751
|
+
apply(compiler) {
|
|
6752
|
+
compiler.hooks.thisCompilation.tap(StripContentScriptDevServerRuntime.name, (compilation)=>{
|
|
6753
|
+
compilation.hooks.processAssets.tap({
|
|
6754
|
+
name: StripContentScriptDevServerRuntime.name,
|
|
6755
|
+
stage: core_.Compilation.PROCESS_ASSETS_STAGE_REPORT
|
|
6756
|
+
}, ()=>{
|
|
6757
|
+
for (const asset of compilation.getAssets()){
|
|
6758
|
+
if (!strip_content_script_dev_server_runtime_CONTENT_SCRIPT_ASSET.test(asset.name)) continue;
|
|
6759
|
+
const originalSource = asset.source.source().toString();
|
|
6760
|
+
const strippedSource = stripDevServerStartupFromContentScript(originalSource);
|
|
6761
|
+
if (strippedSource !== originalSource) compilation.updateAsset(asset.name, new core_.sources.RawSource(strippedSource));
|
|
6762
|
+
}
|
|
6763
|
+
});
|
|
6764
|
+
});
|
|
6765
|
+
}
|
|
6766
|
+
}
|
|
6767
|
+
const basic = [
|
|
6768
|
+
'var isBrowser = !!(() => { try { return globalThis.browser.runtime.getURL("/") } catch(e) {} })()',
|
|
6769
|
+
'var isChrome = !!(() => { try { return globalThis.chrome.runtime.getURL("/") } catch(e) {} })()'
|
|
6770
|
+
];
|
|
6771
|
+
const weakRuntimeCheck = [
|
|
6772
|
+
...basic,
|
|
6773
|
+
"var runtime = isBrowser ? globalThis.browser : isChrome ? globalThis.chrome : { runtime: { getURL: x => x } }"
|
|
6774
|
+
];
|
|
6775
|
+
class AddPublicPathRuntimeModule {
|
|
6776
|
+
apply(compiler) {
|
|
6777
|
+
const { RuntimeGlobals } = compiler.webpack;
|
|
6778
|
+
compiler.hooks.compilation.tap('PublicPathRuntimeModule', (compilation)=>{
|
|
6779
|
+
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap(AddPublicPathRuntimeModule.name, (chunk)=>{
|
|
6780
|
+
const module = add_public_path_runtime_module_PublicPathRuntimeModule(compiler);
|
|
6781
|
+
compilation.addRuntimeModule(chunk, module);
|
|
6782
|
+
return true;
|
|
6783
|
+
});
|
|
6784
|
+
});
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
function add_public_path_runtime_module_PublicPathRuntimeModule(compiler) {
|
|
6788
|
+
const { Template, RuntimeModule, RuntimeGlobals } = compiler.webpack;
|
|
6789
|
+
class PublicPathRuntimeModule extends RuntimeModule {
|
|
6790
|
+
generate() {
|
|
6791
|
+
const publicPath = this.compilation?.outputOptions.publicPath;
|
|
6792
|
+
return Template.asString([
|
|
6793
|
+
...weakRuntimeCheck,
|
|
6794
|
+
'var __extjsBase = (typeof globalThis === "object" && globalThis && globalThis.__EXTJS_EXTENSION_BASE__) ? String(globalThis.__EXTJS_EXTENSION_BASE__) : "";',
|
|
6795
|
+
'if (!__extjsBase && typeof document === "object" && document && document.documentElement) {',
|
|
6796
|
+
Template.indent([
|
|
6797
|
+
'try { __extjsBase = document.documentElement.getAttribute("data-extjs-extension-base") || ""; } catch(_) { __extjsBase = ""; }'
|
|
6798
|
+
]),
|
|
6799
|
+
"}",
|
|
6800
|
+
`var path = ${JSON.stringify(this.compilation?.getPath(publicPath || '', {
|
|
6801
|
+
hash: this.compilation.hash || 'XXXX'
|
|
6802
|
+
}))}`,
|
|
6803
|
+
'var __extjsRuntimePath = "";',
|
|
6804
|
+
"if (!(typeof importScripts === 'function') && (isBrowser || isChrome)) {",
|
|
6805
|
+
Template.indent([
|
|
6806
|
+
'try { __extjsRuntimePath = runtime.runtime.getURL(path); } catch (_) { __extjsRuntimePath = ""; }'
|
|
6807
|
+
]),
|
|
6808
|
+
"}",
|
|
6809
|
+
`${RuntimeGlobals.publicPath} = typeof importScripts === 'function' || !(isBrowser || isChrome) ? path : (__extjsRuntimePath || (__extjsBase ? __extjsBase.replace(/\\/+$/, "/") + String(path).replace(/^\\/+/, "") : ""));`
|
|
6810
|
+
]);
|
|
6811
|
+
}
|
|
6812
|
+
constructor(){
|
|
6813
|
+
super('publicPath', RuntimeModule.STAGE_BASIC);
|
|
6814
|
+
}
|
|
6815
|
+
}
|
|
6816
|
+
return new PublicPathRuntimeModule();
|
|
6817
|
+
}
|
|
6153
6818
|
function throw_if_manifest_scripts_change_define_property(obj, key, value) {
|
|
6154
6819
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
6155
6820
|
value: value,
|
|
@@ -6272,6 +6937,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6272
6937
|
}).apply(compiler);
|
|
6273
6938
|
if ('production' === compiler.options.mode) new AddPublicPathRuntimeModule().apply(compiler);
|
|
6274
6939
|
if ('production' !== compiler.options.mode) {
|
|
6940
|
+
new StripContentScriptDevServerRuntime().apply(compiler);
|
|
6275
6941
|
new SetupReloadStrategy({
|
|
6276
6942
|
manifestPath: this.manifestPath,
|
|
6277
6943
|
browser: this.browser
|
|
@@ -7661,6 +8327,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
7661
8327
|
instanceId: options.instanceId
|
|
7662
8328
|
};
|
|
7663
8329
|
}
|
|
8330
|
+
var runtime_options = __webpack_require__("./webpack/plugin-browsers/browsers-lib/runtime-options.ts");
|
|
7664
8331
|
var browsers_lib_messages = __webpack_require__("./webpack/plugin-browsers/browsers-lib/messages.ts");
|
|
7665
8332
|
var chromium_context = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-context/index.ts");
|
|
7666
8333
|
var chromium_launch = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-launch/index.ts");
|
|
@@ -8016,19 +8683,21 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8016
8683
|
return hash.toString(16).padStart(8, '0');
|
|
8017
8684
|
}
|
|
8018
8685
|
function diffDomSnapshots(prev, next) {
|
|
8686
|
+
const prevNodes = Array.isArray(prev?.nodes) ? prev.nodes : [];
|
|
8687
|
+
const nextNodes = Array.isArray(next?.nodes) ? next.nodes : [];
|
|
8019
8688
|
if (!prev) return {
|
|
8020
|
-
added:
|
|
8689
|
+
added: nextNodes.length,
|
|
8021
8690
|
removed: 0,
|
|
8022
8691
|
changed: 0,
|
|
8023
|
-
addedKeys:
|
|
8692
|
+
addedKeys: nextNodes.slice(0, 50).map((n)=>n.key),
|
|
8024
8693
|
removedKeys: [],
|
|
8025
8694
|
changedKeys: []
|
|
8026
8695
|
};
|
|
8027
|
-
const prevMap = new Map(
|
|
8696
|
+
const prevMap = new Map(prevNodes.map((n)=>[
|
|
8028
8697
|
n.key,
|
|
8029
8698
|
n
|
|
8030
8699
|
]));
|
|
8031
|
-
const nextMap = new Map(
|
|
8700
|
+
const nextMap = new Map(nextNodes.map((n)=>[
|
|
8032
8701
|
n.key,
|
|
8033
8702
|
n
|
|
8034
8703
|
]));
|
|
@@ -8135,6 +8804,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8135
8804
|
return '<<<EXTJS_HTML_END>>>';
|
|
8136
8805
|
}
|
|
8137
8806
|
var manifest_readiness = __webpack_require__("./webpack/plugin-browsers/run-chromium/manifest-readiness.ts");
|
|
8807
|
+
var content_script_targets = __webpack_require__("./webpack/plugin-browsers/browsers-lib/content-script-targets.ts");
|
|
8138
8808
|
function chromium_hard_reload_define_property(obj, key, value) {
|
|
8139
8809
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
8140
8810
|
value: value,
|
|
@@ -8164,6 +8834,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8164
8834
|
};
|
|
8165
8835
|
if (compiler.hooks?.watchRun?.tapAsync) compiler.hooks.watchRun.tapAsync('run-browsers:watch', (compilerWithModifiedFiles, done)=>{
|
|
8166
8836
|
try {
|
|
8837
|
+
this.contentReloadGeneration += 1;
|
|
8167
8838
|
const modifiedFiles = compilerWithModifiedFiles?.modifiedFiles || new Set();
|
|
8168
8839
|
const normalizedModifiedFilePaths = Array.from(modifiedFiles).map((filePath)=>String(filePath).replace(/\\/g, '/'));
|
|
8169
8840
|
const compilerContextRoot = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
@@ -8196,9 +8867,34 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8196
8867
|
});
|
|
8197
8868
|
}
|
|
8198
8869
|
}
|
|
8199
|
-
if (hitManifest)
|
|
8200
|
-
|
|
8201
|
-
|
|
8870
|
+
if (hitManifest) {
|
|
8871
|
+
this.pendingContentReloadEntryNames = [];
|
|
8872
|
+
this.ctx.setPendingReloadReason('manifest');
|
|
8873
|
+
} else if (localeChanged) {
|
|
8874
|
+
this.pendingContentReloadEntryNames = [];
|
|
8875
|
+
this.ctx.setPendingReloadReason('locales');
|
|
8876
|
+
} else if (serviceWorkerChanged) {
|
|
8877
|
+
this.pendingContentReloadEntryNames = [];
|
|
8878
|
+
this.ctx.setPendingReloadReason('sw');
|
|
8879
|
+
} else {
|
|
8880
|
+
const changedContentEntries = (0, content_script_targets.JY)(sourceModifiedFilePaths, this.contentScriptSourceDependencyPathsByEntry);
|
|
8881
|
+
this.lastWatchIncludedContentChanges = changedContentEntries.length > 0;
|
|
8882
|
+
if (changedContentEntries.length > 0) {
|
|
8883
|
+
this.pendingContentReloadEntryNames = changedContentEntries;
|
|
8884
|
+
this.awaitingSettledContentBuild = true;
|
|
8885
|
+
globalThis.__EXTJS_PENDING_CHROMIUM_CONTENT_RELOAD__ = true;
|
|
8886
|
+
}
|
|
8887
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] changed content entries: ${this.pendingContentReloadEntryNames.join(', ') || '<none>'}`);
|
|
8888
|
+
if (this.shouldEmitReloadActionEvent()) emitActionEvent('reload_debug', {
|
|
8889
|
+
phase: 'watch',
|
|
8890
|
+
browser: this.options?.browser,
|
|
8891
|
+
sourceModifiedFilePaths,
|
|
8892
|
+
changedContentEntries,
|
|
8893
|
+
pendingContentReloadEntryNames: [
|
|
8894
|
+
...this.pendingContentReloadEntryNames
|
|
8895
|
+
]
|
|
8896
|
+
});
|
|
8897
|
+
}
|
|
8202
8898
|
} catch (error) {
|
|
8203
8899
|
this.logger?.warn?.('[reload-debug] watchRun inspect failed:', String(error));
|
|
8204
8900
|
}
|
|
@@ -8207,17 +8903,139 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8207
8903
|
compiler.hooks.done.tapPromise('run-browsers:module', async (stats)=>{
|
|
8208
8904
|
const hasErrors = 'function' == typeof stats?.hasErrors ? stats.hasErrors() : !!stats?.compilation?.errors?.length;
|
|
8209
8905
|
if (hasErrors) return;
|
|
8906
|
+
const inferredEntryNamesFromSourceSignatures = this.inferContentReloadEntryNamesFromSourceSignatures();
|
|
8907
|
+
const inferredHardReloadReason = this.inferHardReloadReasonFromSourceSignatures(compiler);
|
|
8908
|
+
const nextManifestSourceSignatures = this.collectManifestSourceSignatures(compiler);
|
|
8909
|
+
const nextLocaleSourceSignatures = this.collectLocaleSourceSignatures(compiler);
|
|
8910
|
+
const nextServiceWorkerSourceDependencyPaths = this.collectEntrypointModuleResourcePaths(stats.compilation, 'background/service_worker');
|
|
8911
|
+
const nextServiceWorkerSourceSignatures = this.collectSourceSignaturesFromPaths(nextServiceWorkerSourceDependencyPaths);
|
|
8912
|
+
const nextContentScriptSourceDependencyPaths = this.collectContentScriptSourceDependencyPaths(stats.compilation);
|
|
8913
|
+
const nextContentScriptSourceSignatures = this.collectContentScriptSourceSignatures(nextContentScriptSourceDependencyPaths);
|
|
8914
|
+
const contentScriptOutputRoot = this.ctx.getExtensionRoot() || String(stats?.compilation?.options?.output?.path || '');
|
|
8915
|
+
const nextContentScriptOutputSignatures = this.collectContentScriptOutputSignatures(stats.compilation, contentScriptOutputRoot || void 0);
|
|
8916
|
+
const inferredEntryNamesFromOutputSignatures = this.inferContentReloadEntryNamesFromOutputSignatures(nextContentScriptOutputSignatures);
|
|
8210
8917
|
this.refreshSWFromManifest(stats.compilation);
|
|
8211
|
-
this.
|
|
8918
|
+
this.serviceWorkerSourceDependencyPaths = nextServiceWorkerSourceDependencyPaths;
|
|
8919
|
+
this.serviceWorkerSourceSignatures = nextServiceWorkerSourceSignatures;
|
|
8920
|
+
this.manifestSourceSignatures = nextManifestSourceSignatures;
|
|
8921
|
+
this.localeSourceSignatures = nextLocaleSourceSignatures;
|
|
8922
|
+
this.contentScriptSourceDependencyPathsByEntry = nextContentScriptSourceDependencyPaths;
|
|
8923
|
+
this.contentScriptSourceSignaturesByEntry = nextContentScriptSourceSignatures;
|
|
8924
|
+
this.contentScriptOutputSignaturesByEntry = nextContentScriptOutputSignatures;
|
|
8212
8925
|
if (!this.hasCompletedSuccessfulBuild) {
|
|
8213
8926
|
this.hasCompletedSuccessfulBuild = true;
|
|
8214
8927
|
this.firstSuccessfulBuildAtMs = Date.now();
|
|
8928
|
+
this.pendingContentReloadEntryNames = [];
|
|
8215
8929
|
this.ctx.clearPendingReloadReason();
|
|
8216
8930
|
return;
|
|
8217
8931
|
}
|
|
8932
|
+
const assetsArr = Array.isArray(stats?.compilation?.getAssets?.()) ? stats.compilation.getAssets() : [];
|
|
8933
|
+
const changedAssets = assetsArr.filter((asset)=>asset?.emitted).map((asset)=>String(asset?.name || ''));
|
|
8218
8934
|
const pendingReason = this.ctx.getPendingReloadReason();
|
|
8219
|
-
const
|
|
8220
|
-
|
|
8935
|
+
const inferredAssetReason = this.inferHardReloadReasonFromChangedAssets(this.pendingContentReloadEntryNames.length > 0 ? changedAssets.filter((a)=>'manifest.json' !== String(a || '').replace(/\\/g, '/')) : changedAssets);
|
|
8936
|
+
const reason = pendingReason || inferredHardReloadReason || inferredAssetReason;
|
|
8937
|
+
const inferredEntryNames = Array.from(new Set([
|
|
8938
|
+
...this.inferContentReloadEntryNamesFromChangedAssets(changedAssets),
|
|
8939
|
+
...inferredEntryNamesFromSourceSignatures,
|
|
8940
|
+
...inferredEntryNamesFromOutputSignatures
|
|
8941
|
+
]));
|
|
8942
|
+
const targetEntryNames = this.pendingContentReloadEntryNames.length > 0 ? [
|
|
8943
|
+
...this.pendingContentReloadEntryNames
|
|
8944
|
+
] : inferredEntryNames;
|
|
8945
|
+
if (this.shouldEmitReloadActionEvent()) emitActionEvent('reload_debug', {
|
|
8946
|
+
phase: 'done',
|
|
8947
|
+
browser: this.options?.browser,
|
|
8948
|
+
reason: reason || null,
|
|
8949
|
+
changedAssets,
|
|
8950
|
+
inferredEntryNamesFromSourceSignatures,
|
|
8951
|
+
inferredEntryNamesFromOutputSignatures,
|
|
8952
|
+
pendingContentReloadEntryNames: [
|
|
8953
|
+
...this.pendingContentReloadEntryNames
|
|
8954
|
+
],
|
|
8955
|
+
inferredEntryNames,
|
|
8956
|
+
targetEntryNames
|
|
8957
|
+
});
|
|
8958
|
+
if (!reason) {
|
|
8959
|
+
if (targetEntryNames.length > 0) {
|
|
8960
|
+
const ctrl = this.ctx.getController() ?? await new Promise((resolve)=>{
|
|
8961
|
+
const timeout = setTimeout(()=>resolve(void 0), 8000);
|
|
8962
|
+
this.ctx.onControllerReady((c)=>{
|
|
8963
|
+
clearTimeout(timeout);
|
|
8964
|
+
resolve(c);
|
|
8965
|
+
});
|
|
8966
|
+
});
|
|
8967
|
+
if (!ctrl) return;
|
|
8968
|
+
const selectedEntryNames = [
|
|
8969
|
+
...targetEntryNames
|
|
8970
|
+
];
|
|
8971
|
+
const selectedGeneration = this.contentReloadGeneration;
|
|
8972
|
+
const selectedRules = (0, content_script_targets.Il)((0, content_script_targets.iw)(stats.compilation, this.ctx.getExtensionRoot()), selectedEntryNames);
|
|
8973
|
+
const sourceOverridesByBundleId = this.collectContentScriptSourceOverrides(stats.compilation, selectedRules);
|
|
8974
|
+
if (0 === selectedRules.length) {
|
|
8975
|
+
this.pendingContentReloadEntryNames = [];
|
|
8976
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log('[reload] selected content rules: <none>');
|
|
8977
|
+
return;
|
|
8978
|
+
}
|
|
8979
|
+
if (this.lastWatchIncludedContentChanges && this.contentReloadQuietPeriodMs > 0) {
|
|
8980
|
+
await new Promise((resolve)=>setTimeout(resolve, this.contentReloadQuietPeriodMs));
|
|
8981
|
+
if (selectedGeneration !== this.contentReloadGeneration) {
|
|
8982
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log('[reload] skipping content reinjection during active watch churn');
|
|
8983
|
+
return;
|
|
8984
|
+
}
|
|
8985
|
+
}
|
|
8986
|
+
let reinjectionSourceOverridesByBundleId;
|
|
8987
|
+
const extensionRoot = this.ctx.getExtensionRoot();
|
|
8988
|
+
if (extensionRoot) {
|
|
8989
|
+
const selectedEntryFiles = this.collectEntrypointFiles(stats.compilation, selectedEntryNames, extensionRoot);
|
|
8990
|
+
const expectedAssetSignatures = this.collectAssetTextSignatures(stats.compilation, selectedEntryFiles);
|
|
8991
|
+
const filesReady = await this.waitForStableContentOutputs(extensionRoot, selectedEntryFiles, expectedAssetSignatures);
|
|
8992
|
+
const hasSourceOverrides = Object.keys(sourceOverridesByBundleId).length >= selectedRules.length;
|
|
8993
|
+
reinjectionSourceOverridesByBundleId = filesReady ? void 0 : hasSourceOverrides ? sourceOverridesByBundleId : void 0;
|
|
8994
|
+
if (!filesReady) {
|
|
8995
|
+
if (!hasSourceOverrides) return void this.logger?.warn?.("[reload] content script assets did not stabilize before targeted reload");
|
|
8996
|
+
}
|
|
8997
|
+
}
|
|
8998
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] selected content rules for ${selectedEntryNames.join(', ')}`);
|
|
8999
|
+
const reinjectedTabs = await ctrl.reloadMatchingTabsForContentScripts(selectedRules, {
|
|
9000
|
+
sourceOverridesByBundleId: reinjectionSourceOverridesByBundleId
|
|
9001
|
+
});
|
|
9002
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] reinjected tabs for ${selectedEntryNames.join(', ')}: ${reinjectedTabs}`);
|
|
9003
|
+
ctrl.hardReload().catch(()=>{});
|
|
9004
|
+
if (this.lastWatchIncludedContentChanges && this.contentReloadFollowupMs > 0) {
|
|
9005
|
+
await new Promise((resolve)=>setTimeout(resolve, this.contentReloadFollowupMs));
|
|
9006
|
+
if (selectedGeneration === this.contentReloadGeneration) {
|
|
9007
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] follow-up reinjection for ${selectedEntryNames.join(', ')}`);
|
|
9008
|
+
const followupReinjectedTabs = await ctrl.reloadMatchingTabsForContentScripts(selectedRules, {
|
|
9009
|
+
sourceOverridesByBundleId: reinjectionSourceOverridesByBundleId
|
|
9010
|
+
});
|
|
9011
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] follow-up reinjected tabs for ${selectedEntryNames.join(', ')}: ${followupReinjectedTabs}`);
|
|
9012
|
+
if (this.contentReloadQuietPeriodMs > 0) await new Promise((resolve)=>setTimeout(resolve, this.contentReloadQuietPeriodMs));
|
|
9013
|
+
}
|
|
9014
|
+
}
|
|
9015
|
+
if (this.awaitingSettledContentBuild && this.lastWatchIncludedContentChanges) {
|
|
9016
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log('[reload] preserving pending content reinjection until settled follow-up build');
|
|
9017
|
+
} else {
|
|
9018
|
+
this.pendingContentReloadEntryNames = [];
|
|
9019
|
+
this.awaitingSettledContentBuild = false;
|
|
9020
|
+
}
|
|
9021
|
+
if (this.awaitingSettledContentBuild && !this.lastWatchIncludedContentChanges) {
|
|
9022
|
+
this.pendingContentReloadEntryNames = [];
|
|
9023
|
+
this.awaitingSettledContentBuild = false;
|
|
9024
|
+
}
|
|
9025
|
+
this.broadcastSourceWatchMessage(compiler, {
|
|
9026
|
+
type: 'contentReloaded',
|
|
9027
|
+
browser: this.options?.browser,
|
|
9028
|
+
entries: selectedEntryNames
|
|
9029
|
+
});
|
|
9030
|
+
globalThis.__EXTJS_PENDING_CHROMIUM_CONTENT_RELOAD__ = false;
|
|
9031
|
+
try {
|
|
9032
|
+
await globalThis.__EXTJS_ON_CHROMIUM_CONTENT_RELOADED__?.();
|
|
9033
|
+
} catch {}
|
|
9034
|
+
}
|
|
9035
|
+
return;
|
|
9036
|
+
}
|
|
9037
|
+
this.pendingContentReloadEntryNames = [];
|
|
9038
|
+
globalThis.__EXTJS_PENDING_CHROMIUM_CONTENT_RELOAD__ = false;
|
|
8221
9039
|
this.ctx.clearPendingReloadReason();
|
|
8222
9040
|
const now = Date.now();
|
|
8223
9041
|
if (this.firstSuccessfulBuildAtMs && now - this.firstSuccessfulBuildAtMs < ChromiumHardReloadPlugin.INITIAL_RELOAD_COOLDOWN_MS) return void this.logger?.info?.(`[reload] skipping early reload during startup cooldown (reason:${reason})`);
|
|
@@ -8238,7 +9056,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8238
9056
|
});
|
|
8239
9057
|
const extensionRoot = this.ctx.getExtensionRoot();
|
|
8240
9058
|
if (extensionRoot) {
|
|
8241
|
-
const manifestReady = await (0, manifest_readiness.
|
|
9059
|
+
const manifestReady = await (0, manifest_readiness.fR)(extensionRoot, {
|
|
8242
9060
|
timeoutMs: 8000
|
|
8243
9061
|
});
|
|
8244
9062
|
if (!manifestReady) return void this.logger?.warn?.('[reload] manifest.json did not stabilize before hard reload');
|
|
@@ -8257,6 +9075,40 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8257
9075
|
this.warnedHardReloadFailure = true;
|
|
8258
9076
|
this.logger?.warn?.(browsers_lib_messages.WsE(this.options?.browser));
|
|
8259
9077
|
}
|
|
9078
|
+
if ('function' == typeof ctrl.reloadMatchingTabsForContentScripts) {
|
|
9079
|
+
const allContentRules = (0, content_script_targets.iw)(stats.compilation, extensionRoot);
|
|
9080
|
+
if (allContentRules.length > 0) {
|
|
9081
|
+
let reinjectedTabs = 0;
|
|
9082
|
+
if ('function' == typeof ctrl.reinjectMatchingTabsViaExtensionRuntime) for(let attempt = 0; attempt < 3 && 0 === reinjectedTabs; attempt++){
|
|
9083
|
+
await new Promise((resolve)=>setTimeout(resolve, 0 === attempt ? 1500 : 1000));
|
|
9084
|
+
const runtimeReinjectedTabs = await ctrl.reinjectMatchingTabsViaExtensionRuntime(allContentRules);
|
|
9085
|
+
reinjectedTabs = Math.max(reinjectedTabs, runtimeReinjectedTabs);
|
|
9086
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] extension-runtime reinjected tabs after hard reload: ${runtimeReinjectedTabs}`);
|
|
9087
|
+
}
|
|
9088
|
+
if (0 === reinjectedTabs && 'function' == typeof ctrl.getLastRuntimeReinjectionReport) {
|
|
9089
|
+
const runtimeReport = ctrl.getLastRuntimeReinjectionReport();
|
|
9090
|
+
if (runtimeReport) this.logger?.debug?.(`[reload] extension-runtime reinjection report: ${JSON.stringify(runtimeReport)}`);
|
|
9091
|
+
}
|
|
9092
|
+
if (0 === reinjectedTabs && 'function' == typeof ctrl.reloadMatchingTabsForContentScripts) {
|
|
9093
|
+
reinjectedTabs = await ctrl.reloadMatchingTabsForContentScripts(allContentRules, {
|
|
9094
|
+
allowCoarseCleanup: false
|
|
9095
|
+
});
|
|
9096
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] direct reinjected tabs after hard reload: ${reinjectedTabs}`);
|
|
9097
|
+
}
|
|
9098
|
+
if (reinjectedTabs > 0 && 'function' == typeof ctrl.reloadMatchingTabsForContentScripts) {
|
|
9099
|
+
const pageReloadedTabs = await ctrl.reloadMatchingTabsForContentScripts(allContentRules, {
|
|
9100
|
+
preferPageReload: true
|
|
9101
|
+
});
|
|
9102
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`[reload] page reloaded tabs after direct reinjection: ${pageReloadedTabs}`);
|
|
9103
|
+
}
|
|
9104
|
+
if (0 === reinjectedTabs && 'function' == typeof ctrl.reloadMatchingTabsForContentScripts) for(let attempt = 0; attempt < 3; attempt++){
|
|
9105
|
+
await new Promise((resolve)=>setTimeout(resolve, 0 === attempt ? 1500 : 2000));
|
|
9106
|
+
await ctrl.reloadMatchingTabsForContentScripts(allContentRules, {
|
|
9107
|
+
preferPageReload: true
|
|
9108
|
+
});
|
|
9109
|
+
}
|
|
9110
|
+
}
|
|
9111
|
+
}
|
|
8260
9112
|
});
|
|
8261
9113
|
}
|
|
8262
9114
|
refreshSWFromManifest(compilation) {
|
|
@@ -8273,12 +9125,164 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8273
9125
|
}
|
|
8274
9126
|
} catch {}
|
|
8275
9127
|
}
|
|
8276
|
-
|
|
9128
|
+
collectServiceWorkerSourceSignatures() {
|
|
9129
|
+
return this.collectSourceSignaturesFromPaths(this.serviceWorkerSourceDependencyPaths);
|
|
9130
|
+
}
|
|
9131
|
+
collectManifestSourceSignatures(compiler) {
|
|
9132
|
+
return this.collectSourceSignaturesFromPaths(this.getWatchedManifestSourcePaths(compiler));
|
|
9133
|
+
}
|
|
9134
|
+
collectLocaleSourceSignatures(compiler) {
|
|
9135
|
+
const compilerContextRoot = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
9136
|
+
if (!compilerContextRoot) return new Map();
|
|
9137
|
+
const localesRoot = external_path_.join(compilerContextRoot, 'src', '_locales');
|
|
9138
|
+
const discoveredLocaleFiles = [];
|
|
9139
|
+
const walk = (dirPath)=>{
|
|
9140
|
+
let entries;
|
|
9141
|
+
try {
|
|
9142
|
+
entries = external_fs_.readdirSync(dirPath, {
|
|
9143
|
+
withFileTypes: true
|
|
9144
|
+
});
|
|
9145
|
+
} catch {
|
|
9146
|
+
return;
|
|
9147
|
+
}
|
|
9148
|
+
for (const entry of entries){
|
|
9149
|
+
const absoluteEntryPath = external_path_.join(dirPath, entry.name);
|
|
9150
|
+
if (entry.isDirectory()) {
|
|
9151
|
+
walk(absoluteEntryPath);
|
|
9152
|
+
continue;
|
|
9153
|
+
}
|
|
9154
|
+
if (entry.isFile() && absoluteEntryPath.endsWith('.json')) discoveredLocaleFiles.push(absoluteEntryPath.replace(/\\/g, '/'));
|
|
9155
|
+
}
|
|
9156
|
+
};
|
|
9157
|
+
walk(localesRoot);
|
|
9158
|
+
return this.collectSourceSignaturesFromPaths(discoveredLocaleFiles);
|
|
9159
|
+
}
|
|
9160
|
+
collectSourceSignaturesFromPaths(dependencyPaths) {
|
|
9161
|
+
const signatures = new Map();
|
|
9162
|
+
for (const dependencyPath of dependencyPaths){
|
|
9163
|
+
const normalizedDependencyPath = String(dependencyPath).replace(/\\/g, '/');
|
|
9164
|
+
const signature = this.readSourceFileSignature(normalizedDependencyPath);
|
|
9165
|
+
if (signature) signatures.set(normalizedDependencyPath, signature);
|
|
9166
|
+
}
|
|
9167
|
+
return signatures;
|
|
9168
|
+
}
|
|
9169
|
+
collectContentScriptSourceDependencyPaths(compilation) {
|
|
9170
|
+
return (0, content_script_targets.im)(compilation);
|
|
9171
|
+
}
|
|
9172
|
+
collectContentScriptSourceSignatures(dependencyPathsByEntry) {
|
|
9173
|
+
const nextSignatures = new Map();
|
|
9174
|
+
for (const [entryName, dependencyPaths] of dependencyPathsByEntry.entries()){
|
|
9175
|
+
const signatures = new Map();
|
|
9176
|
+
for (const dependencyPath of dependencyPaths){
|
|
9177
|
+
const signature = this.readSourceFileSignature(dependencyPath);
|
|
9178
|
+
if (signature) signatures.set(dependencyPath, signature);
|
|
9179
|
+
}
|
|
9180
|
+
nextSignatures.set(entryName, signatures);
|
|
9181
|
+
}
|
|
9182
|
+
return nextSignatures;
|
|
9183
|
+
}
|
|
9184
|
+
inferContentReloadEntryNamesFromSourceSignatures() {
|
|
9185
|
+
const changedEntries = new Set();
|
|
9186
|
+
for (const [entryName, dependencySignatures] of this.contentScriptSourceSignaturesByEntry.entries())for (const [dependencyPath, previousSignature] of dependencySignatures){
|
|
9187
|
+
const nextSignature = this.readSourceFileSignature(dependencyPath);
|
|
9188
|
+
if (!nextSignature || nextSignature !== previousSignature) {
|
|
9189
|
+
changedEntries.add(entryName);
|
|
9190
|
+
break;
|
|
9191
|
+
}
|
|
9192
|
+
}
|
|
9193
|
+
return Array.from(changedEntries).sort();
|
|
9194
|
+
}
|
|
9195
|
+
inferContentReloadEntryNamesFromOutputSignatures(nextOutputSignaturesByEntry) {
|
|
9196
|
+
const changedEntries = new Set();
|
|
9197
|
+
for (const [entryName, nextOutputSignatures] of nextOutputSignaturesByEntry.entries()){
|
|
9198
|
+
const previousOutputSignatures = this.contentScriptOutputSignaturesByEntry.get(entryName);
|
|
9199
|
+
if (previousOutputSignatures && 0 !== previousOutputSignatures.size) {
|
|
9200
|
+
if (previousOutputSignatures.size !== nextOutputSignatures.size) {
|
|
9201
|
+
changedEntries.add(entryName);
|
|
9202
|
+
continue;
|
|
9203
|
+
}
|
|
9204
|
+
for (const [outputFile, previousSignature] of previousOutputSignatures){
|
|
9205
|
+
const nextSignature = nextOutputSignatures.get(outputFile);
|
|
9206
|
+
if (!nextSignature || nextSignature !== previousSignature) {
|
|
9207
|
+
changedEntries.add(entryName);
|
|
9208
|
+
break;
|
|
9209
|
+
}
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
9212
|
+
}
|
|
9213
|
+
return Array.from(changedEntries).sort();
|
|
9214
|
+
}
|
|
9215
|
+
inferHardReloadReasonFromSourceSignatures(compiler) {
|
|
9216
|
+
const nextManifestSourceSignatures = this.collectManifestSourceSignatures(compiler);
|
|
9217
|
+
if (this.haveSourceSignaturesChanged(this.manifestSourceSignatures, nextManifestSourceSignatures)) return 'manifest';
|
|
9218
|
+
const nextLocaleSourceSignatures = this.collectLocaleSourceSignatures(compiler);
|
|
9219
|
+
if (this.haveSourceSignaturesChanged(this.localeSourceSignatures, nextLocaleSourceSignatures)) return 'locales';
|
|
9220
|
+
const nextServiceWorkerSourceSignatures = this.collectServiceWorkerSourceSignatures();
|
|
9221
|
+
if (this.haveSourceSignaturesChanged(this.serviceWorkerSourceSignatures, nextServiceWorkerSourceSignatures)) return 'sw';
|
|
9222
|
+
}
|
|
9223
|
+
haveSourceSignaturesChanged(previousSignatures, nextSignatures) {
|
|
9224
|
+
if (0 === previousSignatures.size) return false;
|
|
9225
|
+
if (previousSignatures.size !== nextSignatures.size) return true;
|
|
9226
|
+
for (const [dependencyPath, previousSignature] of previousSignatures){
|
|
9227
|
+
const nextSignature = nextSignatures.get(dependencyPath);
|
|
9228
|
+
if (!nextSignature || nextSignature !== previousSignature) return true;
|
|
9229
|
+
}
|
|
9230
|
+
return false;
|
|
9231
|
+
}
|
|
9232
|
+
inferContentReloadEntryNamesFromChangedAssets(changedAssets) {
|
|
9233
|
+
const entries = new Set();
|
|
9234
|
+
for (const assetName of changedAssets){
|
|
9235
|
+
const normalizedAssetName = String(assetName || '').replace(/\\/g, '/');
|
|
9236
|
+
const canonicalAsset = (0, contracts.es)(normalizedAssetName);
|
|
9237
|
+
if (canonicalAsset) {
|
|
9238
|
+
entries.add((0, contracts.Y0)(canonicalAsset.index));
|
|
9239
|
+
continue;
|
|
9240
|
+
}
|
|
9241
|
+
const hotMatch = /^hot\/content_scripts\/content-(\d+)\.[^.]+\.json$/.exec(normalizedAssetName);
|
|
9242
|
+
if (!hotMatch) {
|
|
9243
|
+
if (!(0, content_script_targets.HE)(normalizedAssetName)) continue;
|
|
9244
|
+
}
|
|
9245
|
+
if (hotMatch) entries.add((0, contracts.Y0)(Number(hotMatch[1])));
|
|
9246
|
+
}
|
|
9247
|
+
return Array.from(entries);
|
|
9248
|
+
}
|
|
9249
|
+
inferHardReloadReasonFromChangedAssets(changedAssets) {
|
|
9250
|
+
for (const assetName of changedAssets){
|
|
9251
|
+
const normalizedAssetName = String(assetName || '').replace(/\\/g, '/');
|
|
9252
|
+
if (normalizedAssetName) {
|
|
9253
|
+
if ('manifest.json' === normalizedAssetName) return 'manifest';
|
|
9254
|
+
if (/(^|\/)_locales\/.+\.json$/i.test(normalizedAssetName)) return 'locales';
|
|
9255
|
+
if (/(^|\/)background\/(service_worker|script)\.(m?js|cjs)$/i.test(normalizedAssetName)) return 'sw';
|
|
9256
|
+
}
|
|
9257
|
+
}
|
|
9258
|
+
}
|
|
9259
|
+
readSourceFileSignature(absoluteFilePath) {
|
|
8277
9260
|
try {
|
|
8278
|
-
const
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
} catch {
|
|
9261
|
+
const stats = external_fs_.statSync(absoluteFilePath);
|
|
9262
|
+
if (!stats.isFile()) return;
|
|
9263
|
+
return `${stats.size}:${stats.mtimeMs}`;
|
|
9264
|
+
} catch {
|
|
9265
|
+
return;
|
|
9266
|
+
}
|
|
9267
|
+
}
|
|
9268
|
+
collectContentScriptOutputSignatures(compilation, extensionRoot) {
|
|
9269
|
+
const outputSignaturesByEntry = new Map();
|
|
9270
|
+
const entrypoints = compilation?.entrypoints;
|
|
9271
|
+
if (!entrypoints || !extensionRoot) return outputSignaturesByEntry;
|
|
9272
|
+
for (const [entryName] of entrypoints.entries()){
|
|
9273
|
+
if (!(0, content_script_targets.wH)(entryName)) continue;
|
|
9274
|
+
const entryFiles = this.collectEntrypointFiles(compilation, [
|
|
9275
|
+
entryName
|
|
9276
|
+
], extensionRoot);
|
|
9277
|
+
const outputSignatures = new Map();
|
|
9278
|
+
for (const entryFile of entryFiles){
|
|
9279
|
+
const absoluteEntryFilePath = external_path_.join(extensionRoot, entryFile);
|
|
9280
|
+
const signature = this.readSourceFileSignature(absoluteEntryFilePath);
|
|
9281
|
+
if (signature) outputSignatures.set(entryFile, signature);
|
|
9282
|
+
}
|
|
9283
|
+
if (outputSignatures.size > 0) outputSignaturesByEntry.set(entryName, outputSignatures);
|
|
9284
|
+
}
|
|
9285
|
+
return outputSignaturesByEntry;
|
|
8282
9286
|
}
|
|
8283
9287
|
collectEntrypointModuleResourcePaths(compilation, entrypointName) {
|
|
8284
9288
|
const collectedResourcePaths = new Set();
|
|
@@ -8291,15 +9295,175 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8291
9295
|
for (const chunk of entrypointChunks){
|
|
8292
9296
|
const modulesIterable = chunkGraph.getChunkModulesIterable?.(chunk) || chunkGraph.getChunkModulesIterableBySourceType?.(chunk, "javascript") || chunkGraph.getChunkModules?.(chunk);
|
|
8293
9297
|
if (modulesIterable) for (const module of modulesIterable){
|
|
8294
|
-
const resourcePath = module?.resource || module?.rootModule?.resource || module?.originalSource?.()?.resource;
|
|
8295
|
-
if (
|
|
9298
|
+
const resourcePath = (0, content_script_targets.Rt)(module?.resource || module?.rootModule?.resource || module?.originalSource?.()?.resource);
|
|
9299
|
+
if (resourcePath) collectedResourcePaths.add(resourcePath);
|
|
8296
9300
|
}
|
|
8297
9301
|
}
|
|
8298
9302
|
return collectedResourcePaths;
|
|
8299
9303
|
}
|
|
9304
|
+
collectEntrypointFiles(compilation, entrypointNames, extensionRoot) {
|
|
9305
|
+
const entrypoints = compilation?.entrypoints;
|
|
9306
|
+
if (!entrypoints) return this.deriveCanonicalContentEntryFiles(entrypointNames, extensionRoot);
|
|
9307
|
+
const collectedFiles = new Set();
|
|
9308
|
+
for (const entrypointName of entrypointNames){
|
|
9309
|
+
const entrypoint = entrypoints.get?.(entrypointName);
|
|
9310
|
+
const entryFiles = 'function' == typeof entrypoint?.getFiles ? entrypoint.getFiles() : [];
|
|
9311
|
+
for (const file of entryFiles){
|
|
9312
|
+
const normalizedFile = String(file || '').replace(/\\/g, '/');
|
|
9313
|
+
if (!(!normalizedFile || normalizedFile.endsWith('.map'))) {
|
|
9314
|
+
if (!normalizedFile.startsWith('hot/')) collectedFiles.add(normalizedFile);
|
|
9315
|
+
}
|
|
9316
|
+
}
|
|
9317
|
+
}
|
|
9318
|
+
if (0 === collectedFiles.size) return this.deriveCanonicalContentEntryFiles(entrypointNames, extensionRoot);
|
|
9319
|
+
return Array.from(collectedFiles);
|
|
9320
|
+
}
|
|
9321
|
+
deriveCanonicalContentEntryFiles(entrypointNames, extensionRoot) {
|
|
9322
|
+
const collectedFiles = new Set();
|
|
9323
|
+
for (const entrypointName of entrypointNames){
|
|
9324
|
+
const normalizedEntrypointName = String(entrypointName || '').replace(/\\/g, '/');
|
|
9325
|
+
if (normalizedEntrypointName) try {
|
|
9326
|
+
const jsRelativePath = `${normalizedEntrypointName}.js`;
|
|
9327
|
+
if (!extensionRoot || external_fs_.existsSync(external_path_.join(extensionRoot, jsRelativePath))) collectedFiles.add(jsRelativePath);
|
|
9328
|
+
if (!extensionRoot) continue;
|
|
9329
|
+
const cssRelativePath = `${normalizedEntrypointName}.css`;
|
|
9330
|
+
if (external_fs_.existsSync(external_path_.join(extensionRoot, cssRelativePath))) collectedFiles.add(cssRelativePath);
|
|
9331
|
+
} catch {}
|
|
9332
|
+
}
|
|
9333
|
+
return Array.from(collectedFiles);
|
|
9334
|
+
}
|
|
9335
|
+
async waitForStableContentOutputs(extensionRoot, entryFiles, expectedAssetSignatures = new Map(), timeoutMs = 8000, pollIntervalMs = 150, stableReadsRequired = 2) {
|
|
9336
|
+
const normalizedEntryFiles = entryFiles.map((file)=>String(file || '').replace(/\\/g, '/')).filter(Boolean);
|
|
9337
|
+
if (0 === normalizedEntryFiles.length) return true;
|
|
9338
|
+
const start = Date.now();
|
|
9339
|
+
let lastSignature = '';
|
|
9340
|
+
let stableReads = 0;
|
|
9341
|
+
while(Date.now() - start < timeoutMs){
|
|
9342
|
+
const referencedFiles = new Set(normalizedEntryFiles);
|
|
9343
|
+
const signatureParts = [];
|
|
9344
|
+
let allFilesReady = true;
|
|
9345
|
+
for (const entryFile of normalizedEntryFiles){
|
|
9346
|
+
const absoluteEntryFilePath = external_path_.join(extensionRoot, entryFile);
|
|
9347
|
+
const source = this.readFileTextSafe(absoluteEntryFilePath);
|
|
9348
|
+
const expectedAssetSignature = expectedAssetSignatures.get(entryFile);
|
|
9349
|
+
const signature = expectedAssetSignature ? this.readTextSignature(source) : this.readStableFileSignature(absoluteEntryFilePath);
|
|
9350
|
+
if (!signature) {
|
|
9351
|
+
allFilesReady = false;
|
|
9352
|
+
break;
|
|
9353
|
+
}
|
|
9354
|
+
if (expectedAssetSignature && signature !== expectedAssetSignature) {
|
|
9355
|
+
allFilesReady = false;
|
|
9356
|
+
break;
|
|
9357
|
+
}
|
|
9358
|
+
signatureParts.push(`${entryFile}:${signature}`);
|
|
9359
|
+
if (entryFile.endsWith('.js')) {
|
|
9360
|
+
if (!source) {
|
|
9361
|
+
allFilesReady = false;
|
|
9362
|
+
break;
|
|
9363
|
+
}
|
|
9364
|
+
for (const referencedFile of this.extractReferencedOutputFiles(source))referencedFiles.add(referencedFile);
|
|
9365
|
+
}
|
|
9366
|
+
}
|
|
9367
|
+
if (!allFilesReady) {
|
|
9368
|
+
lastSignature = '';
|
|
9369
|
+
stableReads = 0;
|
|
9370
|
+
await new Promise((resolve)=>setTimeout(resolve, pollIntervalMs));
|
|
9371
|
+
continue;
|
|
9372
|
+
}
|
|
9373
|
+
for (const referencedFile of referencedFiles){
|
|
9374
|
+
if (normalizedEntryFiles.includes(referencedFile)) continue;
|
|
9375
|
+
const absoluteReferencedFilePath = external_path_.join(extensionRoot, referencedFile);
|
|
9376
|
+
const signature = this.readStableFileSignature(absoluteReferencedFilePath);
|
|
9377
|
+
if (!signature) {
|
|
9378
|
+
allFilesReady = false;
|
|
9379
|
+
break;
|
|
9380
|
+
}
|
|
9381
|
+
signatureParts.push(`${referencedFile}:${signature}`);
|
|
9382
|
+
}
|
|
9383
|
+
if (!allFilesReady) {
|
|
9384
|
+
lastSignature = '';
|
|
9385
|
+
stableReads = 0;
|
|
9386
|
+
await new Promise((resolve)=>setTimeout(resolve, pollIntervalMs));
|
|
9387
|
+
continue;
|
|
9388
|
+
}
|
|
9389
|
+
const currentSignature = signatureParts.sort().join('|');
|
|
9390
|
+
if (currentSignature === lastSignature) stableReads += 1;
|
|
9391
|
+
else {
|
|
9392
|
+
lastSignature = currentSignature;
|
|
9393
|
+
stableReads = 1;
|
|
9394
|
+
}
|
|
9395
|
+
if (stableReads >= stableReadsRequired) return true;
|
|
9396
|
+
await new Promise((resolve)=>setTimeout(resolve, pollIntervalMs));
|
|
9397
|
+
}
|
|
9398
|
+
return false;
|
|
9399
|
+
}
|
|
9400
|
+
readStableFileSignature(absoluteFilePath) {
|
|
9401
|
+
try {
|
|
9402
|
+
const stats = external_fs_.statSync(absoluteFilePath);
|
|
9403
|
+
if (!stats.isFile()) return;
|
|
9404
|
+
return `${stats.size}:${stats.mtimeMs}`;
|
|
9405
|
+
} catch {
|
|
9406
|
+
return;
|
|
9407
|
+
}
|
|
9408
|
+
}
|
|
9409
|
+
readFileTextSafe(absoluteFilePath) {
|
|
9410
|
+
try {
|
|
9411
|
+
return external_fs_.readFileSync(absoluteFilePath, 'utf-8');
|
|
9412
|
+
} catch {
|
|
9413
|
+
return;
|
|
9414
|
+
}
|
|
9415
|
+
}
|
|
9416
|
+
collectAssetTextSignatures(compilation, assetNames) {
|
|
9417
|
+
const signatures = new Map();
|
|
9418
|
+
for (const assetName of assetNames){
|
|
9419
|
+
const normalizedAssetName = String(assetName || '').replace(/\\/g, '/');
|
|
9420
|
+
if (normalizedAssetName) try {
|
|
9421
|
+
const asset = compilation.getAsset?.(normalizedAssetName) || compilation?.assets?.[normalizedAssetName];
|
|
9422
|
+
const source = asset && 'function' == typeof asset.source?.source ? asset.source.source() : asset && 'function' == typeof asset.source ? asset.source() : void 0;
|
|
9423
|
+
const signature = this.readTextSignature('string' == typeof source || Buffer.isBuffer(source) ? source.toString() : void 0);
|
|
9424
|
+
if (signature) signatures.set(normalizedAssetName, signature);
|
|
9425
|
+
} catch {}
|
|
9426
|
+
}
|
|
9427
|
+
return signatures;
|
|
9428
|
+
}
|
|
9429
|
+
collectContentScriptSourceOverrides(compilation, rules) {
|
|
9430
|
+
const overrides = {};
|
|
9431
|
+
for (const rule of rules){
|
|
9432
|
+
const bundleId = (0, contracts.Y0)(rule.index);
|
|
9433
|
+
const assetName = `${bundleId}.js`;
|
|
9434
|
+
try {
|
|
9435
|
+
const asset = compilation.getAsset?.(assetName) || compilation?.assets?.[assetName];
|
|
9436
|
+
const source = asset && 'function' == typeof asset.source?.source ? asset.source.source() : asset && 'function' == typeof asset.source ? asset.source() : void 0;
|
|
9437
|
+
const text = 'string' == typeof source || Buffer.isBuffer(source) ? source.toString() : '';
|
|
9438
|
+
if (text) overrides[bundleId] = text;
|
|
9439
|
+
} catch {}
|
|
9440
|
+
}
|
|
9441
|
+
return overrides;
|
|
9442
|
+
}
|
|
9443
|
+
readTextSignature(source) {
|
|
9444
|
+
if ('string' != typeof source) return;
|
|
9445
|
+
let hash = 0;
|
|
9446
|
+
for(let index = 0; index < source.length; index++)hash = 31 * hash + source.charCodeAt(index) >>> 0;
|
|
9447
|
+
return `${source.length}:${hash.toString(16)}`;
|
|
9448
|
+
}
|
|
9449
|
+
extractReferencedOutputFiles(source) {
|
|
9450
|
+
const matches = source.match(/(?:content_scripts|assets)\/[^"'`\s)]+\.(?:css|js|json|png|jpg|jpeg|svg|gif|webp|ico|avif)/g);
|
|
9451
|
+
return Array.from(new Set(matches || []));
|
|
9452
|
+
}
|
|
8300
9453
|
shouldEmitReloadActionEvent() {
|
|
8301
9454
|
return Boolean(this.options?.source || this.options?.watchSource);
|
|
8302
9455
|
}
|
|
9456
|
+
broadcastSourceWatchMessage(compiler, payload) {
|
|
9457
|
+
const webSocketServer = compiler?.options?.webSocketServer;
|
|
9458
|
+
const clients = webSocketServer?.clients;
|
|
9459
|
+
if (!clients || 'function' != typeof clients.forEach) return;
|
|
9460
|
+
const message = JSON.stringify(payload);
|
|
9461
|
+
clients.forEach((client)=>{
|
|
9462
|
+
try {
|
|
9463
|
+
if ('function' == typeof client?.send) client.send(message);
|
|
9464
|
+
} catch {}
|
|
9465
|
+
});
|
|
9466
|
+
}
|
|
8303
9467
|
constructor(options, ctx){
|
|
8304
9468
|
chromium_hard_reload_define_property(this, "options", void 0);
|
|
8305
9469
|
chromium_hard_reload_define_property(this, "ctx", void 0);
|
|
@@ -8308,17 +9472,89 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8308
9472
|
chromium_hard_reload_define_property(this, "warnedHardReloadFailure", void 0);
|
|
8309
9473
|
chromium_hard_reload_define_property(this, "hasCompletedSuccessfulBuild", void 0);
|
|
8310
9474
|
chromium_hard_reload_define_property(this, "firstSuccessfulBuildAtMs", void 0);
|
|
9475
|
+
chromium_hard_reload_define_property(this, "contentReloadGeneration", void 0);
|
|
9476
|
+
chromium_hard_reload_define_property(this, "contentReloadQuietPeriodMs", void 0);
|
|
9477
|
+
chromium_hard_reload_define_property(this, "contentReloadFollowupMs", void 0);
|
|
9478
|
+
chromium_hard_reload_define_property(this, "lastWatchIncludedContentChanges", void 0);
|
|
9479
|
+
chromium_hard_reload_define_property(this, "awaitingSettledContentBuild", void 0);
|
|
8311
9480
|
chromium_hard_reload_define_property(this, "serviceWorkerSourceDependencyPaths", void 0);
|
|
9481
|
+
chromium_hard_reload_define_property(this, "serviceWorkerSourceSignatures", void 0);
|
|
9482
|
+
chromium_hard_reload_define_property(this, "manifestSourceSignatures", void 0);
|
|
9483
|
+
chromium_hard_reload_define_property(this, "localeSourceSignatures", void 0);
|
|
9484
|
+
chromium_hard_reload_define_property(this, "contentScriptSourceDependencyPathsByEntry", void 0);
|
|
9485
|
+
chromium_hard_reload_define_property(this, "contentScriptSourceSignaturesByEntry", void 0);
|
|
9486
|
+
chromium_hard_reload_define_property(this, "contentScriptOutputSignaturesByEntry", void 0);
|
|
9487
|
+
chromium_hard_reload_define_property(this, "pendingContentReloadEntryNames", void 0);
|
|
8312
9488
|
this.options = options;
|
|
8313
9489
|
this.ctx = ctx;
|
|
8314
9490
|
this.hasCompletedSuccessfulBuild = false;
|
|
8315
9491
|
this.firstSuccessfulBuildAtMs = null;
|
|
9492
|
+
this.contentReloadGeneration = 0;
|
|
9493
|
+
this.contentReloadQuietPeriodMs = 1200;
|
|
9494
|
+
this.contentReloadFollowupMs = 1200;
|
|
9495
|
+
this.lastWatchIncludedContentChanges = false;
|
|
9496
|
+
this.awaitingSettledContentBuild = false;
|
|
8316
9497
|
this.serviceWorkerSourceDependencyPaths = new Set();
|
|
9498
|
+
this.serviceWorkerSourceSignatures = new Map();
|
|
9499
|
+
this.manifestSourceSignatures = new Map();
|
|
9500
|
+
this.localeSourceSignatures = new Map();
|
|
9501
|
+
this.contentScriptSourceDependencyPathsByEntry = new Map();
|
|
9502
|
+
this.contentScriptSourceSignaturesByEntry = new Map();
|
|
9503
|
+
this.contentScriptOutputSignaturesByEntry = new Map();
|
|
9504
|
+
this.pendingContentReloadEntryNames = [];
|
|
8317
9505
|
}
|
|
8318
9506
|
}
|
|
8319
9507
|
chromium_hard_reload_define_property(ChromiumHardReloadPlugin, "INITIAL_RELOAD_COOLDOWN_MS", 5000);
|
|
8320
9508
|
var shared_utils = __webpack_require__("./webpack/plugin-browsers/browsers-lib/shared-utils.ts");
|
|
8321
9509
|
var cdp_client = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-source-inspection/cdp-client.ts");
|
|
9510
|
+
const CONTENT_HTML_HINT_RE = /(id=\"extension-root\"|data-extension-root=|content_script|content_title|js-probe|data-extjs-last-reinject-status=\"mounted\"|data-extjs-reinject-marker=)/i;
|
|
9511
|
+
async function extractPageHtml(cdpClient, sessionId, logSamples = 'true' === process.env.EXTENSION_AUTHOR_MODE, includeShadow = 'open-only') {
|
|
9512
|
+
let html = await cdpClient.getPageHTML(sessionId, includeShadow);
|
|
9513
|
+
if (!html) try {
|
|
9514
|
+
const targets = await cdpClient.getTargets();
|
|
9515
|
+
const fallbackTarget = targets.find((target)=>'page' === target.type && /example\.com|http/.test(String(target.url || '')));
|
|
9516
|
+
if (fallbackTarget && fallbackTarget.targetId) {
|
|
9517
|
+
const newSessionId = await cdpClient.attachToTarget(fallbackTarget.targetId);
|
|
9518
|
+
await cdpClient.waitForContentScriptInjection(newSessionId);
|
|
9519
|
+
const retryHtml = await cdpClient.getPageHTML(newSessionId, includeShadow);
|
|
9520
|
+
if (logSamples) {
|
|
9521
|
+
const sample2 = (retryHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
9522
|
+
console.log(browsers_lib_messages.LcW(sample2));
|
|
9523
|
+
}
|
|
9524
|
+
if (retryHtml) return retryHtml;
|
|
9525
|
+
}
|
|
9526
|
+
} catch {}
|
|
9527
|
+
if (!html || !CONTENT_HTML_HINT_RE.test(html)) for(let i = 0; i < 1; i++){
|
|
9528
|
+
await new Promise((r)=>setTimeout(r, 250));
|
|
9529
|
+
try {
|
|
9530
|
+
const againHtml = await cdpClient.getPageHTML(sessionId, includeShadow);
|
|
9531
|
+
if (logSamples) {
|
|
9532
|
+
const sample3 = (againHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
9533
|
+
console.log(browsers_lib_messages.jUj(sample3));
|
|
9534
|
+
}
|
|
9535
|
+
if (againHtml && CONTENT_HTML_HINT_RE.test(againHtml)) {
|
|
9536
|
+
html = againHtml;
|
|
9537
|
+
break;
|
|
9538
|
+
}
|
|
9539
|
+
} catch {}
|
|
9540
|
+
}
|
|
9541
|
+
if (!html || 0 === html.trim().length) for(let i = 0; i < 2; i++){
|
|
9542
|
+
try {
|
|
9543
|
+
const evaluatedHtml = await cdpClient.evaluate(sessionId, '(() => { try { return String(document.documentElement.outerHTML||"") } catch(e) { return "" } })()');
|
|
9544
|
+
if (logSamples) {
|
|
9545
|
+
const sample4 = (evaluatedHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
9546
|
+
console.log(browsers_lib_messages.jUj(sample4));
|
|
9547
|
+
}
|
|
9548
|
+
if (evaluatedHtml && evaluatedHtml.trim().length > 0) {
|
|
9549
|
+
html = evaluatedHtml;
|
|
9550
|
+
break;
|
|
9551
|
+
}
|
|
9552
|
+
} catch {}
|
|
9553
|
+
await new Promise((r)=>setTimeout(r, 200));
|
|
9554
|
+
}
|
|
9555
|
+
if (logSamples) console.log(browsers_lib_messages.ehY());
|
|
9556
|
+
return html || '';
|
|
9557
|
+
}
|
|
8322
9558
|
var instance_registry = __webpack_require__("./webpack/plugin-browsers/browsers-lib/instance-registry.ts");
|
|
8323
9559
|
var discovery = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-source-inspection/discovery.ts");
|
|
8324
9560
|
async function waitForChromeRemoteDebugging(port, instanceId) {
|
|
@@ -8346,10 +9582,21 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8346
9582
|
}
|
|
8347
9583
|
throw new Error(browsers_lib_messages.olb(port));
|
|
8348
9584
|
}
|
|
9585
|
+
function normalizeInspectableUrl(rawUrl) {
|
|
9586
|
+
try {
|
|
9587
|
+
const parsed = new URL(String(rawUrl || ''));
|
|
9588
|
+
if (('http:' === parsed.protocol || 'https:' === parsed.protocol) && '/' === parsed.pathname) parsed.pathname = '';
|
|
9589
|
+
parsed.hash = '';
|
|
9590
|
+
return parsed.toString();
|
|
9591
|
+
} catch {
|
|
9592
|
+
return String(rawUrl || '').trim().replace(/\/$/, '');
|
|
9593
|
+
}
|
|
9594
|
+
}
|
|
8349
9595
|
async function ensureTargetAndSession(cdpClient, url, options) {
|
|
8350
9596
|
const forceNavigate = Boolean(options?.forceNavigate);
|
|
9597
|
+
const normalizedUrl = normalizeInspectableUrl(url);
|
|
8351
9598
|
const targets = await cdpClient.getTargets();
|
|
8352
|
-
const existingTarget = (targets || []).find((t)=>String(t?.url || '') ===
|
|
9599
|
+
const existingTarget = (targets || []).find((t)=>normalizeInspectableUrl(String(t?.url || '')) === normalizedUrl && 'page' === String(t?.type || ''));
|
|
8353
9600
|
let targetId = '';
|
|
8354
9601
|
if (existingTarget && existingTarget.targetId) {
|
|
8355
9602
|
targetId = String(existingTarget.targetId);
|
|
@@ -8376,70 +9623,23 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8376
9623
|
try {
|
|
8377
9624
|
await cdpClient.enableRuntimeAndLog(String(tempSession));
|
|
8378
9625
|
} catch {}
|
|
8379
|
-
await cdpClient.navigate(String(tempSession), url);
|
|
8380
|
-
}
|
|
8381
|
-
}
|
|
8382
|
-
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(browsers_lib_messages.MjP());
|
|
8383
|
-
const sessionId = String(await cdpClient.attachToTarget(targetId) || '');
|
|
8384
|
-
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
8385
|
-
console.log(browsers_lib_messages.v5i(sessionId));
|
|
8386
|
-
console.log(browsers_lib_messages._JL());
|
|
8387
|
-
}
|
|
8388
|
-
await cdpClient.sendCommand('Page.enable', {}, sessionId);
|
|
8389
|
-
try {
|
|
8390
|
-
await cdpClient.enableRuntimeAndLog(sessionId);
|
|
8391
|
-
} catch {}
|
|
8392
|
-
return {
|
|
8393
|
-
targetId: String(targetId),
|
|
8394
|
-
sessionId: String(sessionId)
|
|
8395
|
-
};
|
|
8396
|
-
}
|
|
8397
|
-
async function extractPageHtml(cdpClient, sessionId, logSamples = 'true' === process.env.EXTENSION_AUTHOR_MODE, includeShadow = 'open-only') {
|
|
8398
|
-
let html = await cdpClient.getPageHTML(sessionId, includeShadow);
|
|
8399
|
-
if (!html) try {
|
|
8400
|
-
const targets = await cdpClient.getTargets();
|
|
8401
|
-
const fallbackTarget = targets.find((target)=>'page' === target.type && /example\.com|http/.test(String(target.url || '')));
|
|
8402
|
-
if (fallbackTarget && fallbackTarget.targetId) {
|
|
8403
|
-
const newSessionId = await cdpClient.attachToTarget(fallbackTarget.targetId);
|
|
8404
|
-
await cdpClient.waitForContentScriptInjection(newSessionId);
|
|
8405
|
-
const retryHtml = await cdpClient.getPageHTML(newSessionId, includeShadow);
|
|
8406
|
-
if (logSamples) {
|
|
8407
|
-
const sample2 = (retryHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
8408
|
-
console.log(browsers_lib_messages.LcW(sample2));
|
|
8409
|
-
}
|
|
8410
|
-
if (retryHtml) return retryHtml;
|
|
9626
|
+
await cdpClient.navigate(String(tempSession), url);
|
|
8411
9627
|
}
|
|
8412
|
-
} catch {}
|
|
8413
|
-
if (!html || !/(id=\"extension-root\"|content_script|content_title|js-probe)/.test(html)) for(let i = 0; i < 3; i++){
|
|
8414
|
-
await new Promise((r)=>setTimeout(r, 500));
|
|
8415
|
-
try {
|
|
8416
|
-
const againHtml = await cdpClient.getPageHTML(sessionId, includeShadow);
|
|
8417
|
-
if (logSamples) {
|
|
8418
|
-
const sample3 = (againHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
8419
|
-
console.log(browsers_lib_messages.jUj(sample3));
|
|
8420
|
-
}
|
|
8421
|
-
if (againHtml && /(id=\"extension-root\"|content_script|content_title|js-probe)/.test(againHtml)) {
|
|
8422
|
-
html = againHtml;
|
|
8423
|
-
break;
|
|
8424
|
-
}
|
|
8425
|
-
} catch {}
|
|
8426
9628
|
}
|
|
8427
|
-
if (
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
console.log(browsers_lib_messages.jUj(sample4));
|
|
8433
|
-
}
|
|
8434
|
-
if (evaluatedHtml && evaluatedHtml.trim().length > 0) {
|
|
8435
|
-
html = evaluatedHtml;
|
|
8436
|
-
break;
|
|
8437
|
-
}
|
|
8438
|
-
} catch {}
|
|
8439
|
-
await new Promise((r)=>setTimeout(r, 400));
|
|
9629
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(browsers_lib_messages.MjP());
|
|
9630
|
+
const sessionId = String(await cdpClient.attachToTarget(targetId) || '');
|
|
9631
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
9632
|
+
console.log(browsers_lib_messages.v5i(sessionId));
|
|
9633
|
+
console.log(browsers_lib_messages._JL());
|
|
8440
9634
|
}
|
|
8441
|
-
|
|
8442
|
-
|
|
9635
|
+
await cdpClient.sendCommand('Page.enable', {}, sessionId);
|
|
9636
|
+
try {
|
|
9637
|
+
await cdpClient.enableRuntimeAndLog(sessionId);
|
|
9638
|
+
} catch {}
|
|
9639
|
+
return {
|
|
9640
|
+
targetId: String(targetId),
|
|
9641
|
+
sessionId: String(sessionId)
|
|
9642
|
+
};
|
|
8443
9643
|
}
|
|
8444
9644
|
function chromium_source_inspection_define_property(obj, key, value) {
|
|
8445
9645
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -8504,7 +9704,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8504
9704
|
const includeShadow = 'off' !== this.devOptions.sourceIncludeShadow;
|
|
8505
9705
|
try {
|
|
8506
9706
|
const payload = await this.cdpClient.evaluate(this.currentSessionId, `(() => {
|
|
8507
|
-
const rootEl = document.querySelector('#extension-root,[data-extension-root="
|
|
9707
|
+
const rootEl = document.querySelector('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])');
|
|
8508
9708
|
if (!rootEl) return null;
|
|
8509
9709
|
const root = (${includeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
8510
9710
|
const maxDepth = 6;
|
|
@@ -8568,6 +9768,28 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8568
9768
|
if (payload && 'object' == typeof payload) return payload;
|
|
8569
9769
|
} catch {}
|
|
8570
9770
|
}
|
|
9771
|
+
async getExtensionRootMeta() {
|
|
9772
|
+
if (!this.cdpClient || !this.currentSessionId) return;
|
|
9773
|
+
try {
|
|
9774
|
+
return await this.cdpClient.getExtensionRootMeta(this.currentSessionId);
|
|
9775
|
+
} catch {
|
|
9776
|
+
return;
|
|
9777
|
+
}
|
|
9778
|
+
}
|
|
9779
|
+
async shouldEmitContentScriptInjected(injectionWaitOk) {
|
|
9780
|
+
if (!injectionWaitOk || !this.cdpClient || !this.currentSessionId) return false;
|
|
9781
|
+
const sessionId = this.currentSessionId;
|
|
9782
|
+
const deadline = Date.now() + 2800;
|
|
9783
|
+
while(Date.now() < deadline){
|
|
9784
|
+
const rootMeta = await this.cdpClient.getExtensionRootMeta(sessionId);
|
|
9785
|
+
const shadow = await this.cdpClient.getShadowStyleSnapshot(sessionId);
|
|
9786
|
+
const hasUserRoot = Boolean(rootMeta && rootMeta.rootCount >= 1);
|
|
9787
|
+
const hasShadowStyles = shadow && 'number' == typeof shadow.count && Number(shadow.count) > 0;
|
|
9788
|
+
if (hasUserRoot || hasShadowStyles) return true;
|
|
9789
|
+
await new Promise((r)=>setTimeout(r, 200));
|
|
9790
|
+
}
|
|
9791
|
+
return this.cdpClient.hasVisibleShadowHostContent(sessionId);
|
|
9792
|
+
}
|
|
8571
9793
|
async getPageMetaSnapshot() {
|
|
8572
9794
|
if (!this.cdpClient || !this.currentSessionId) return {};
|
|
8573
9795
|
try {
|
|
@@ -8629,7 +9851,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8629
9851
|
const includeShadow = 'off' !== this.devOptions.sourceIncludeShadow;
|
|
8630
9852
|
try {
|
|
8631
9853
|
const payload = await this.cdpClient.evaluate(this.currentSessionId, `(() => {
|
|
8632
|
-
const rootEl = document.querySelector('#extension-root,[data-extension-root="
|
|
9854
|
+
const rootEl = document.querySelector('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])');
|
|
8633
9855
|
if (!rootEl) return null;
|
|
8634
9856
|
const root = (${includeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
8635
9857
|
const maxDepth = 4;
|
|
@@ -8849,6 +10071,10 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8849
10071
|
if (this.devOptions.sourceMeta) {
|
|
8850
10072
|
const metaSnapshot = await this.getPageMetaSnapshot();
|
|
8851
10073
|
this.emitEventPayload('page_meta', stage, meta, metaSnapshot);
|
|
10074
|
+
const rootMeta = await this.getExtensionRootMeta();
|
|
10075
|
+
if (rootMeta) this.emitEventPayload('extension_root_meta', stage, meta, rootMeta);
|
|
10076
|
+
const styleSnapshot = await this.getShadowStyleSnapshot();
|
|
10077
|
+
if (styleSnapshot) this.emitEventPayload('shadow_style_output', stage, meta, styleSnapshot);
|
|
8852
10078
|
}
|
|
8853
10079
|
if (Array.isArray(this.devOptions.sourceProbe)) {
|
|
8854
10080
|
const probes = await this.getSelectorProbes(this.devOptions.sourceProbe);
|
|
@@ -8911,6 +10137,14 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8911
10137
|
...payload
|
|
8912
10138
|
}));
|
|
8913
10139
|
}
|
|
10140
|
+
async getShadowStyleSnapshot() {
|
|
10141
|
+
if (!this.cdpClient || !this.currentSessionId) return;
|
|
10142
|
+
try {
|
|
10143
|
+
return await this.cdpClient.getShadowStyleSnapshot(this.currentSessionId);
|
|
10144
|
+
} catch {
|
|
10145
|
+
return;
|
|
10146
|
+
}
|
|
10147
|
+
}
|
|
8914
10148
|
async getCdpPort() {
|
|
8915
10149
|
const instanceId = this.devOptions.instanceId;
|
|
8916
10150
|
return (0, shared_utils.jl)(this.devOptions.port, instanceId);
|
|
@@ -8954,30 +10188,14 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8954
10188
|
await this.emitSourceOutput(String(initialHtml || ''), 'pre_injection');
|
|
8955
10189
|
} catch {}
|
|
8956
10190
|
if (this.isAuthorMode()) console.log(browsers_lib_messages.mOc());
|
|
8957
|
-
await this.cdpClient.waitForContentScriptInjection(this.currentSessionId);
|
|
8958
|
-
|
|
10191
|
+
const injected = await this.cdpClient.waitForContentScriptInjection(this.currentSessionId);
|
|
10192
|
+
const emitInjection = await this.shouldEmitContentScriptInjected(injected);
|
|
10193
|
+
if (emitInjection) emitActionEvent("content_script_injected", {
|
|
8959
10194
|
url
|
|
8960
10195
|
});
|
|
10196
|
+
if (!injected) await this.cdpClient.pollForVisibleShadowHostContent(this.currentSessionId);
|
|
8961
10197
|
try {
|
|
8962
|
-
|
|
8963
|
-
const started = Date.now();
|
|
8964
|
-
while(Date.now() < deadline){
|
|
8965
|
-
const hasRoot = await this.cdpClient.evaluate(this.currentSessionId, `(() => { try {
|
|
8966
|
-
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root="true"]'));
|
|
8967
|
-
if (!hosts.length) return false;
|
|
8968
|
-
for (const h of hosts) {
|
|
8969
|
-
try {
|
|
8970
|
-
const sr = h && h.shadowRoot;
|
|
8971
|
-
if (sr && (String(sr.innerHTML||'').length > 0)) return true;
|
|
8972
|
-
} catch { /* ignore */ }
|
|
8973
|
-
}
|
|
8974
|
-
return false;
|
|
8975
|
-
} catch { return false } })()`);
|
|
8976
|
-
if (hasRoot) break;
|
|
8977
|
-
const elapsed = Date.now() - started;
|
|
8978
|
-
const delay = elapsed < 2000 ? 150 : 500;
|
|
8979
|
-
await new Promise((r)=>setTimeout(r, delay));
|
|
8980
|
-
}
|
|
10198
|
+
await this.waitForContentScriptStyles(this.currentSessionId);
|
|
8981
10199
|
} catch {}
|
|
8982
10200
|
const outputConfig = this.getOutputConfig();
|
|
8983
10201
|
const html = await extractPageHtml(this.cdpClient, this.currentSessionId, this.isAuthorMode(), outputConfig.includeShadow);
|
|
@@ -9011,14 +10229,104 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9011
10229
|
ws.on('message', async (data)=>{
|
|
9012
10230
|
try {
|
|
9013
10231
|
const message = JSON.parse(data);
|
|
9014
|
-
if ('changedFile' === message.type && this.isWatching)
|
|
10232
|
+
if ('changedFile' === message.type && this.isWatching) {
|
|
10233
|
+
if (!this.pendingWatchSourceUpdate) this.pendingWatchSourceRootMeta = await this.getExtensionRootMeta().catch(()=>void 0);
|
|
10234
|
+
this.pendingWatchSourceUpdate = true;
|
|
10235
|
+
} else if ('contentReloaded' === message.type && this.isWatching) {
|
|
10236
|
+
if (this.pendingWatchSourceUpdate) {
|
|
10237
|
+
const previousRootMeta = this.pendingWatchSourceRootMeta;
|
|
10238
|
+
this.pendingWatchSourceUpdate = false;
|
|
10239
|
+
this.pendingWatchSourceRootMeta = void 0;
|
|
10240
|
+
this.scheduleWatchSourceUpdate(previousRootMeta);
|
|
10241
|
+
}
|
|
10242
|
+
}
|
|
9015
10243
|
} catch (error) {}
|
|
9016
10244
|
});
|
|
9017
10245
|
}
|
|
9018
10246
|
stopWatching() {
|
|
9019
10247
|
this.isWatching = false;
|
|
10248
|
+
this.pendingWatchSourceUpdate = false;
|
|
10249
|
+
this.pendingWatchSourceRootMeta = void 0;
|
|
10250
|
+
if (this.watchSourceFlushTimer) {
|
|
10251
|
+
clearTimeout(this.watchSourceFlushTimer);
|
|
10252
|
+
this.watchSourceFlushTimer = null;
|
|
10253
|
+
}
|
|
9020
10254
|
if (this.isAuthorMode()) console.log(browsers_lib_messages.Qx1());
|
|
9021
10255
|
}
|
|
10256
|
+
registerContentReloadSnapshotHook() {
|
|
10257
|
+
globalThis.__EXTJS_ON_CHROMIUM_CONTENT_RELOADED__ = async ()=>{
|
|
10258
|
+
if (!this.currentSessionId || !this.hasInspectedSourceOnce) return;
|
|
10259
|
+
if (this.isWatching) return;
|
|
10260
|
+
if (this.watchSourceFlushTimer) clearTimeout(this.watchSourceFlushTimer);
|
|
10261
|
+
this.watchSourceFlushTimer = setTimeout(async ()=>{
|
|
10262
|
+
this.watchSourceFlushTimer = null;
|
|
10263
|
+
if (this.isFlushingWatchSourceUpdate || !this.currentSessionId) return;
|
|
10264
|
+
this.isFlushingWatchSourceUpdate = true;
|
|
10265
|
+
try {
|
|
10266
|
+
await this.emitImmediateUpdatedSnapshotFromCurrentSession(this.currentSessionId);
|
|
10267
|
+
} finally{
|
|
10268
|
+
this.isFlushingWatchSourceUpdate = false;
|
|
10269
|
+
}
|
|
10270
|
+
}, 0);
|
|
10271
|
+
};
|
|
10272
|
+
}
|
|
10273
|
+
scheduleWatchSourceUpdate(previousRootMeta) {
|
|
10274
|
+
if (this.watchSourceFlushTimer) clearTimeout(this.watchSourceFlushTimer);
|
|
10275
|
+
this.watchSourceFlushTimer = setTimeout(async ()=>{
|
|
10276
|
+
if (this.isFlushingWatchSourceUpdate) return void this.scheduleWatchSourceUpdate(previousRootMeta);
|
|
10277
|
+
this.watchSourceFlushTimer = null;
|
|
10278
|
+
if (!this.currentSessionId) return;
|
|
10279
|
+
this.isFlushingWatchSourceUpdate = true;
|
|
10280
|
+
try {
|
|
10281
|
+
await this.emitUpdatedSnapshotFromCurrentSession(this.currentSessionId, previousRootMeta);
|
|
10282
|
+
} finally{
|
|
10283
|
+
this.isFlushingWatchSourceUpdate = false;
|
|
10284
|
+
}
|
|
10285
|
+
}, 0);
|
|
10286
|
+
}
|
|
10287
|
+
async emitImmediateUpdatedSnapshotFromCurrentSession(sessionId) {
|
|
10288
|
+
if (!this.cdpClient) return;
|
|
10289
|
+
const readBuildSignature = (rootMeta)=>{
|
|
10290
|
+
const builds = [
|
|
10291
|
+
rootMeta?.page?.build,
|
|
10292
|
+
...(rootMeta?.roots || []).map((entry)=>entry?.build),
|
|
10293
|
+
...(rootMeta?.markers || []).map((entry)=>entry?.build),
|
|
10294
|
+
...(rootMeta?.registries || []).map((entry)=>entry?.build)
|
|
10295
|
+
].filter((value)=>'string' == typeof value && value.length > 0).sort();
|
|
10296
|
+
return JSON.stringify(builds);
|
|
10297
|
+
};
|
|
10298
|
+
const previousOutputHash = this.lastOutputHash;
|
|
10299
|
+
const previousRootMeta = await this.getExtensionRootMeta().catch(()=>void 0);
|
|
10300
|
+
const previousBuildSignature = readBuildSignature(previousRootMeta);
|
|
10301
|
+
try {
|
|
10302
|
+
await this.waitForContentScriptStyles(sessionId);
|
|
10303
|
+
} catch {}
|
|
10304
|
+
try {
|
|
10305
|
+
await this.waitForMeaningfulContentScriptContent(sessionId);
|
|
10306
|
+
} catch {}
|
|
10307
|
+
let html = '';
|
|
10308
|
+
const outputConfig = this.getOutputConfig();
|
|
10309
|
+
const deadline = Date.now() + 5000;
|
|
10310
|
+
while(Date.now() < deadline){
|
|
10311
|
+
try {
|
|
10312
|
+
html = await this.cdpClient.getPageHTML(sessionId, outputConfig.includeShadow);
|
|
10313
|
+
} catch {
|
|
10314
|
+
await new Promise((resolve)=>setTimeout(resolve, 250));
|
|
10315
|
+
html = await this.cdpClient.getPageHTML(sessionId, outputConfig.includeShadow);
|
|
10316
|
+
}
|
|
10317
|
+
if (!html) {
|
|
10318
|
+
await new Promise((resolve)=>setTimeout(resolve, 300));
|
|
10319
|
+
html = await this.cdpClient.getPageHTML(sessionId, outputConfig.includeShadow);
|
|
10320
|
+
}
|
|
10321
|
+
const currentRootMeta = await this.getExtensionRootMeta().catch(()=>void 0);
|
|
10322
|
+
const currentBuildSignature = readBuildSignature(currentRootMeta);
|
|
10323
|
+
const htmlChanged = !previousOutputHash || hashStringFNV1a(html || '') !== previousOutputHash;
|
|
10324
|
+
const buildsChanged = previousBuildSignature.length > 2 && currentBuildSignature.length > 2 && previousBuildSignature !== currentBuildSignature;
|
|
10325
|
+
if (htmlChanged || buildsChanged) break;
|
|
10326
|
+
await new Promise((resolve)=>setTimeout(resolve, 350));
|
|
10327
|
+
}
|
|
10328
|
+
await this.emitSourceOutput(html || '', 'updated');
|
|
10329
|
+
}
|
|
9022
10330
|
async handleFileChange() {
|
|
9023
10331
|
if (!this.cdpClient || !this.currentSessionId) return void console.warn(browsers_lib_messages.MfN());
|
|
9024
10332
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
@@ -9029,52 +10337,188 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9029
10337
|
console.log(browsers_lib_messages.$xt());
|
|
9030
10338
|
console.log(browsers_lib_messages.Tev());
|
|
9031
10339
|
}
|
|
10340
|
+
'string' == typeof this.devOptions.source && 'true' !== this.devOptions.source && this.devOptions.source;
|
|
10341
|
+
const previousRootMeta = await this.getExtensionRootMeta();
|
|
10342
|
+
await new Promise((resolve)=>setTimeout(resolve, 1000));
|
|
10343
|
+
await this.waitForContentScriptReinjection(this.currentSessionId, previousRootMeta);
|
|
10344
|
+
try {
|
|
10345
|
+
await this.waitForContentScriptStyles(this.currentSessionId);
|
|
10346
|
+
} catch {}
|
|
10347
|
+
if (this.isAuthorMode()) console.log(browsers_lib_messages.Mcx());
|
|
10348
|
+
await this.emitUpdatedSnapshotFromCurrentSession(this.currentSessionId, previousRootMeta);
|
|
10349
|
+
} catch (error) {
|
|
9032
10350
|
const sourceUrl = 'string' == typeof this.devOptions.source && 'true' !== this.devOptions.source ? this.devOptions.source : '';
|
|
9033
|
-
if (sourceUrl) {
|
|
10351
|
+
if (sourceUrl) try {
|
|
9034
10352
|
emitActionEvent('watch_reinspect_source_url', {
|
|
9035
10353
|
url: sourceUrl
|
|
9036
10354
|
});
|
|
9037
10355
|
const html = await this.inspectSource(sourceUrl, {
|
|
9038
|
-
forceNavigate:
|
|
10356
|
+
forceNavigate: false
|
|
9039
10357
|
});
|
|
9040
10358
|
await this.emitSourceOutput(html || '', 'updated');
|
|
9041
10359
|
return;
|
|
9042
|
-
}
|
|
9043
|
-
await this.cdpClient.waitForContentScriptInjection(this.currentSessionId);
|
|
9044
|
-
if (this.isAuthorMode()) console.log(browsers_lib_messages.Mcx());
|
|
9045
|
-
let html = '';
|
|
9046
|
-
const outputConfig = this.getOutputConfig();
|
|
9047
|
-
try {
|
|
9048
|
-
html = await this.cdpClient.getPageHTML(this.currentSessionId, outputConfig.includeShadow);
|
|
9049
|
-
} catch (e) {
|
|
9050
|
-
await new Promise((r)=>setTimeout(r, 250));
|
|
9051
|
-
try {
|
|
9052
|
-
html = await this.cdpClient.getPageHTML(this.currentSessionId, outputConfig.includeShadow);
|
|
9053
|
-
} catch {}
|
|
9054
|
-
}
|
|
9055
|
-
if (!html) {
|
|
9056
|
-
await new Promise((r)=>setTimeout(r, 300));
|
|
9057
|
-
try {
|
|
9058
|
-
html = await this.cdpClient.getPageHTML(this.currentSessionId, outputConfig.includeShadow);
|
|
9059
|
-
} catch {}
|
|
9060
|
-
}
|
|
9061
|
-
await this.emitSourceOutput(html || '', 'updated');
|
|
9062
|
-
} catch (error) {
|
|
10360
|
+
} catch {}
|
|
9063
10361
|
console.error(browsers_lib_messages.acp(error.message));
|
|
9064
|
-
|
|
10362
|
+
const errorMessage = String(error.message || error || '');
|
|
10363
|
+
if (errorMessage.includes('session') || errorMessage.includes('target') || errorMessage.includes('WebSocket is not open') || errorMessage.includes('connection is closed')) {
|
|
9065
10364
|
console.log(browsers_lib_messages.bGB());
|
|
9066
|
-
await this.reconnectToTarget();
|
|
10365
|
+
await this.reconnectToTarget(sourceUrl || void 0);
|
|
9067
10366
|
}
|
|
9068
10367
|
}
|
|
9069
10368
|
}, 300);
|
|
9070
10369
|
}
|
|
9071
|
-
async
|
|
10370
|
+
async waitForContentScriptReinjection(sessionId, previousRootMeta) {
|
|
10371
|
+
if (!this.cdpClient) return;
|
|
10372
|
+
const readBuildSignature = (rootMeta)=>{
|
|
10373
|
+
const builds = [
|
|
10374
|
+
rootMeta?.page?.build,
|
|
10375
|
+
...(rootMeta?.roots || []).map((entry)=>entry?.build),
|
|
10376
|
+
...(rootMeta?.markers || []).map((entry)=>entry?.build),
|
|
10377
|
+
...(rootMeta?.registries || []).map((entry)=>entry?.build)
|
|
10378
|
+
].filter((value)=>'string' == typeof value && value.length > 0).sort();
|
|
10379
|
+
return JSON.stringify(builds);
|
|
10380
|
+
};
|
|
10381
|
+
const previousGeneration = Number(previousRootMeta?.latestGeneration || 0);
|
|
10382
|
+
const previousBuildSignature = readBuildSignature(previousRootMeta);
|
|
10383
|
+
const deadline = Date.now() + 20000;
|
|
10384
|
+
while(Date.now() < deadline){
|
|
10385
|
+
try {
|
|
10386
|
+
const rootMeta = await this.getExtensionRootMeta();
|
|
10387
|
+
if (rootMeta) {
|
|
10388
|
+
const nextBuildSignature = readBuildSignature(rootMeta);
|
|
10389
|
+
const generationAdvanced = Number(rootMeta.latestGeneration || 0) > previousGeneration;
|
|
10390
|
+
const buildAdvanced = previousBuildSignature.length > 2 && nextBuildSignature.length > 2 && previousBuildSignature !== nextBuildSignature;
|
|
10391
|
+
const pageMounted = rootMeta.page?.status === void 0 || rootMeta.page?.status === 'mounted';
|
|
10392
|
+
if ((generationAdvanced || buildAdvanced) && rootMeta.rootCount >= 1 && rootMeta.markerCount >= 1 && pageMounted) return;
|
|
10393
|
+
}
|
|
10394
|
+
} catch {}
|
|
10395
|
+
await new Promise((resolve)=>setTimeout(resolve, 200));
|
|
10396
|
+
}
|
|
10397
|
+
await this.cdpClient.waitForContentScriptInjection(sessionId);
|
|
10398
|
+
}
|
|
10399
|
+
async emitUpdatedSnapshotFromCurrentSession(sessionId, previousRootMeta) {
|
|
10400
|
+
const readBuildSignature = (rootMeta)=>{
|
|
10401
|
+
const builds = [
|
|
10402
|
+
rootMeta?.page?.build,
|
|
10403
|
+
...(rootMeta?.roots || []).map((entry)=>entry?.build),
|
|
10404
|
+
...(rootMeta?.markers || []).map((entry)=>entry?.build),
|
|
10405
|
+
...(rootMeta?.registries || []).map((entry)=>entry?.build)
|
|
10406
|
+
].filter((value)=>'string' == typeof value && value.length > 0).sort();
|
|
10407
|
+
return JSON.stringify(builds);
|
|
10408
|
+
};
|
|
10409
|
+
await this.waitForContentScriptReinjection(sessionId, previousRootMeta);
|
|
10410
|
+
try {
|
|
10411
|
+
await this.waitForContentScriptStyles(sessionId);
|
|
10412
|
+
} catch {}
|
|
10413
|
+
try {
|
|
10414
|
+
await this.waitForMeaningfulContentScriptContent(sessionId);
|
|
10415
|
+
} catch {}
|
|
10416
|
+
const previousOutputHash = this.lastOutputHash;
|
|
10417
|
+
const previousBuildSignature = readBuildSignature(previousRootMeta);
|
|
10418
|
+
let html = '';
|
|
10419
|
+
const outputConfig = this.getOutputConfig();
|
|
10420
|
+
const deadline = Date.now() + 5000;
|
|
10421
|
+
while(Date.now() < deadline){
|
|
10422
|
+
try {
|
|
10423
|
+
html = await this.cdpClient.getPageHTML(sessionId, outputConfig.includeShadow);
|
|
10424
|
+
} catch {
|
|
10425
|
+
await new Promise((resolve)=>setTimeout(resolve, 250));
|
|
10426
|
+
html = await this.cdpClient.getPageHTML(sessionId, outputConfig.includeShadow);
|
|
10427
|
+
}
|
|
10428
|
+
if (!html) {
|
|
10429
|
+
await new Promise((resolve)=>setTimeout(resolve, 300));
|
|
10430
|
+
html = await this.cdpClient.getPageHTML(sessionId, outputConfig.includeShadow);
|
|
10431
|
+
}
|
|
10432
|
+
const currentRootMeta = await this.getExtensionRootMeta().catch(()=>void 0);
|
|
10433
|
+
const currentBuildSignature = readBuildSignature(currentRootMeta);
|
|
10434
|
+
const htmlChanged = !previousOutputHash || hashStringFNV1a(html || '') !== previousOutputHash;
|
|
10435
|
+
const buildsChanged = previousBuildSignature.length > 2 && currentBuildSignature.length > 2 && previousBuildSignature !== currentBuildSignature;
|
|
10436
|
+
if (htmlChanged || buildsChanged) break;
|
|
10437
|
+
await new Promise((resolve)=>setTimeout(resolve, 350));
|
|
10438
|
+
}
|
|
10439
|
+
await this.emitSourceOutput(html || '', 'updated');
|
|
10440
|
+
}
|
|
10441
|
+
async waitForMeaningfulContentScriptContent(sessionId) {
|
|
10442
|
+
if (!this.cdpClient) return;
|
|
10443
|
+
const deadline = Date.now() + 10000;
|
|
10444
|
+
while(Date.now() < deadline){
|
|
10445
|
+
try {
|
|
10446
|
+
const hasMeaningfulContent = await this.cdpClient.evaluate(sessionId, `(() => { try {
|
|
10447
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
10448
|
+
if (!hosts.length) return false;
|
|
10449
|
+
for (const host of hosts) {
|
|
10450
|
+
const sr = host && host.shadowRoot;
|
|
10451
|
+
if (!sr) continue;
|
|
10452
|
+
const elements = Array.from(sr.querySelectorAll('*')).filter((element) => {
|
|
10453
|
+
const tagName = String(element?.nodeName || '').toLowerCase();
|
|
10454
|
+
return tagName !== 'style' && tagName !== 'script';
|
|
10455
|
+
});
|
|
10456
|
+
const hasMeaningfulText = elements.some((element) => {
|
|
10457
|
+
const text = String(element?.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
10458
|
+
return text.length > 0;
|
|
10459
|
+
});
|
|
10460
|
+
if (hasMeaningfulText) return true;
|
|
10461
|
+
const hasMeaningfulVisualElement = elements.some((element) => {
|
|
10462
|
+
const tagName = String(element?.nodeName || '').toLowerCase();
|
|
10463
|
+
return ['img', 'svg', 'canvas', 'input', 'button', 'textarea', 'select'].includes(tagName);
|
|
10464
|
+
});
|
|
10465
|
+
if (hasMeaningfulVisualElement) return true;
|
|
10466
|
+
}
|
|
10467
|
+
return false;
|
|
10468
|
+
} catch { return false } })()`);
|
|
10469
|
+
if (hasMeaningfulContent) return;
|
|
10470
|
+
} catch {}
|
|
10471
|
+
await new Promise((resolve)=>setTimeout(resolve, 200));
|
|
10472
|
+
}
|
|
10473
|
+
}
|
|
10474
|
+
async waitForContentScriptStyles(sessionId) {
|
|
10475
|
+
if (!this.cdpClient) return;
|
|
10476
|
+
const deadline = Date.now() + 10000;
|
|
10477
|
+
while(Date.now() < deadline){
|
|
10478
|
+
try {
|
|
10479
|
+
const hasStyles = await this.cdpClient.evaluate(sessionId, `(() => { try {
|
|
10480
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
10481
|
+
if (!hosts.length) return false;
|
|
10482
|
+
for (const host of hosts) {
|
|
10483
|
+
const sr = host && host.shadowRoot;
|
|
10484
|
+
if (!sr) continue;
|
|
10485
|
+
const styles = Array.from(sr.querySelectorAll('style'));
|
|
10486
|
+
if (styles.some((styleEl) => String(styleEl.outerHTML || '').includes('<style') && String(styleEl.textContent || '').trim().length > 0)) {
|
|
10487
|
+
return true;
|
|
10488
|
+
}
|
|
10489
|
+
}
|
|
10490
|
+
return false;
|
|
10491
|
+
} catch { return false } })()`);
|
|
10492
|
+
if (hasStyles) return;
|
|
10493
|
+
} catch {}
|
|
10494
|
+
await new Promise((resolve)=>setTimeout(resolve, 200));
|
|
10495
|
+
}
|
|
10496
|
+
}
|
|
10497
|
+
async reconnectToTarget(sourceUrl) {
|
|
9072
10498
|
if (!this.isAuthorMode()) return;
|
|
9073
10499
|
try {
|
|
9074
|
-
if (!this.cdpClient || !this.currentTargetId) return void console.warn(browsers_lib_messages.tVJ());
|
|
9075
10500
|
console.log(browsers_lib_messages.kGe());
|
|
9076
|
-
this.
|
|
9077
|
-
|
|
10501
|
+
if (!this.cdpClient || !this.cdpClient.isConnected()) {
|
|
10502
|
+
try {
|
|
10503
|
+
this.cdpClient?.disconnect();
|
|
10504
|
+
} catch {}
|
|
10505
|
+
this.cdpClient = null;
|
|
10506
|
+
this.currentSessionId = null;
|
|
10507
|
+
await this.initialize();
|
|
10508
|
+
}
|
|
10509
|
+
if (this.cdpClient && this.currentTargetId) {
|
|
10510
|
+
this.currentSessionId = await this.cdpClient.attachToTarget(this.currentTargetId) || null;
|
|
10511
|
+
console.log(browsers_lib_messages.PQY(this.currentSessionId || ''));
|
|
10512
|
+
return;
|
|
10513
|
+
}
|
|
10514
|
+
if (sourceUrl) {
|
|
10515
|
+
await this.inspectSource(sourceUrl, {
|
|
10516
|
+
forceNavigate: false
|
|
10517
|
+
});
|
|
10518
|
+
console.log(browsers_lib_messages.PQY('source-url'));
|
|
10519
|
+
return;
|
|
10520
|
+
}
|
|
10521
|
+
console.warn(browsers_lib_messages.tVJ());
|
|
9078
10522
|
} catch (error) {
|
|
9079
10523
|
console.error(browsers_lib_messages.pcF(error.message));
|
|
9080
10524
|
}
|
|
@@ -9105,19 +10549,32 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9105
10549
|
if (this.devOptions.source && 'string' == typeof this.devOptions.source && 'true' !== this.devOptions.source) urlToInspect = this.devOptions.source;
|
|
9106
10550
|
else if (this.devOptions.startingUrl) urlToInspect = this.devOptions.startingUrl;
|
|
9107
10551
|
else throw new Error(browsers_lib_messages.Pu4());
|
|
10552
|
+
const webSocketServer = compiler.options.webSocketServer;
|
|
10553
|
+
if (this.devOptions.watchSource && this.hasInspectedSourceOnce) {
|
|
10554
|
+
if (webSocketServer) {
|
|
10555
|
+
if (!this.isWatching) await this.startWatching(webSocketServer);
|
|
10556
|
+
return;
|
|
10557
|
+
}
|
|
10558
|
+
if (this.currentSessionId) {
|
|
10559
|
+
if (globalThis.__EXTJS_PENDING_CHROMIUM_CONTENT_RELOAD__) return;
|
|
10560
|
+
const previousRootMeta = await this.getExtensionRootMeta();
|
|
10561
|
+
this.scheduleWatchSourceUpdate(previousRootMeta);
|
|
10562
|
+
return;
|
|
10563
|
+
}
|
|
10564
|
+
}
|
|
9108
10565
|
const html = await this.inspectSource(urlToInspect, {
|
|
9109
10566
|
forceNavigate: this.devOptions.watchSource && this.hasInspectedSourceOnce
|
|
9110
10567
|
});
|
|
9111
10568
|
this.hasInspectedSourceOnce = true;
|
|
9112
10569
|
await this.printHTML(html);
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
}
|
|
10570
|
+
if (this.devOptions.watchSource) {
|
|
10571
|
+
this.registerContentReloadSnapshotHook();
|
|
10572
|
+
if (webSocketServer) await this.startWatching(webSocketServer);
|
|
10573
|
+
else try {
|
|
10574
|
+
const previousRootMeta = await this.getExtensionRootMeta();
|
|
10575
|
+
if (this.currentSessionId) await this.emitUpdatedSnapshotFromCurrentSession(this.currentSessionId, previousRootMeta);
|
|
10576
|
+
} catch {}
|
|
10577
|
+
}
|
|
9121
10578
|
} catch (error) {
|
|
9122
10579
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.error(browsers_lib_messages.b82(error.message));
|
|
9123
10580
|
}
|
|
@@ -9131,7 +10588,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9131
10588
|
chromium_source_inspection_define_property(this, "isInitialized", false);
|
|
9132
10589
|
chromium_source_inspection_define_property(this, "isWatching", false);
|
|
9133
10590
|
chromium_source_inspection_define_property(this, "hasInspectedSourceOnce", false);
|
|
10591
|
+
chromium_source_inspection_define_property(this, "pendingWatchSourceUpdate", false);
|
|
10592
|
+
chromium_source_inspection_define_property(this, "pendingWatchSourceRootMeta", void 0);
|
|
9134
10593
|
chromium_source_inspection_define_property(this, "debounceTimer", null);
|
|
10594
|
+
chromium_source_inspection_define_property(this, "watchSourceFlushTimer", null);
|
|
10595
|
+
chromium_source_inspection_define_property(this, "isFlushingWatchSourceUpdate", false);
|
|
9135
10596
|
chromium_source_inspection_define_property(this, "runtimeMode", void 0);
|
|
9136
10597
|
chromium_source_inspection_define_property(this, "lastOutputHash", void 0);
|
|
9137
10598
|
chromium_source_inspection_define_property(this, "lastByteLength", void 0);
|
|
@@ -9204,38 +10665,8 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9204
10665
|
run_chromium_define_property(this, "logTab", void 0);
|
|
9205
10666
|
run_chromium_define_property(this, "logger", void 0);
|
|
9206
10667
|
run_chromium_define_property(this, "chromiumCtx", void 0);
|
|
9207
|
-
this
|
|
9208
|
-
this.browser = options.browser;
|
|
9209
|
-
this.startingUrl = options.startingUrl;
|
|
9210
|
-
this.preferences = options.preferences;
|
|
9211
|
-
this.profile = options.profile;
|
|
9212
|
-
this.browserFlags = options.browserFlags;
|
|
9213
|
-
this.excludeBrowserFlags = options.excludeBrowserFlags;
|
|
9214
|
-
this.noOpen = options.noOpen;
|
|
10668
|
+
Object.assign(this, (0, runtime_options.pA)(options));
|
|
9215
10669
|
this.chromiumBinary = options.chromiumBinary;
|
|
9216
|
-
this.instanceId = options.instanceId;
|
|
9217
|
-
this.port = options.port;
|
|
9218
|
-
this.source = options.source;
|
|
9219
|
-
this.watchSource = options.watchSource;
|
|
9220
|
-
this.sourceFormat = options.sourceFormat;
|
|
9221
|
-
this.sourceSummary = options.sourceSummary;
|
|
9222
|
-
this.sourceMeta = options.sourceMeta;
|
|
9223
|
-
this.sourceProbe = options.sourceProbe;
|
|
9224
|
-
this.sourceTree = options.sourceTree;
|
|
9225
|
-
this.sourceConsole = options.sourceConsole;
|
|
9226
|
-
this.sourceDom = options.sourceDom;
|
|
9227
|
-
this.sourceMaxBytes = options.sourceMaxBytes;
|
|
9228
|
-
this.sourceRedact = options.sourceRedact;
|
|
9229
|
-
this.sourceIncludeShadow = options.sourceIncludeShadow;
|
|
9230
|
-
this.sourceDiff = options.sourceDiff;
|
|
9231
|
-
this.logLevel = options.logLevel;
|
|
9232
|
-
this.logContexts = options.logContexts;
|
|
9233
|
-
this.logFormat = options.logFormat;
|
|
9234
|
-
this.logTimestamps = options.logTimestamps;
|
|
9235
|
-
this.logColor = options.logColor;
|
|
9236
|
-
this.logUrl = options.logUrl;
|
|
9237
|
-
this.logTab = options.logTab;
|
|
9238
|
-
this.dryRun = options.dryRun;
|
|
9239
10670
|
}
|
|
9240
10671
|
}
|
|
9241
10672
|
var firefox_context = __webpack_require__("./webpack/plugin-browsers/run-firefox/firefox-context/index.ts");
|
|
@@ -9288,17 +10719,65 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9288
10719
|
return obj;
|
|
9289
10720
|
}
|
|
9290
10721
|
class FirefoxHardReloadPlugin {
|
|
10722
|
+
getWatchedManifestSourcePaths(compiler) {
|
|
10723
|
+
const compilerContextRoot = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
10724
|
+
if (!compilerContextRoot) return [];
|
|
10725
|
+
return [
|
|
10726
|
+
`${compilerContextRoot}/manifest.json`,
|
|
10727
|
+
`${compilerContextRoot}/src/manifest.json`
|
|
10728
|
+
];
|
|
10729
|
+
}
|
|
9291
10730
|
apply(compiler) {
|
|
9292
10731
|
if (compiler?.hooks?.watchRun?.tapAsync) compiler.hooks.watchRun.tapAsync('run-browsers:watch', (compilation, done)=>{
|
|
9293
10732
|
try {
|
|
10733
|
+
this.contentReloadGeneration += 1;
|
|
9294
10734
|
const files = compilation?.modifiedFiles || new Set();
|
|
9295
10735
|
const normalized = Array.from(files).map((p)=>String(p).replace(/\\/g, '/'));
|
|
9296
|
-
const
|
|
9297
|
-
const
|
|
9298
|
-
const
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
10736
|
+
const compilerContextRoot = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
10737
|
+
const filesInCurrentCompilerContext = compilerContextRoot ? normalized.filter((filePath)=>filePath === compilerContextRoot || filePath.startsWith(`${compilerContextRoot}/`)) : normalized;
|
|
10738
|
+
const normalizedOutputPath = String(compiler?.options?.output?.path || '').replace(/\\/g, '/');
|
|
10739
|
+
const watchedModifiedFilePaths = compilerContextRoot ? filesInCurrentCompilerContext : normalized;
|
|
10740
|
+
const sourceModifiedFilePaths = watchedModifiedFilePaths.filter((filePath)=>!(normalizedOutputPath && (filePath === normalizedOutputPath || filePath.startsWith(`${normalizedOutputPath}/`))));
|
|
10741
|
+
const normalizedManifestSourcePaths = this.getWatchedManifestSourcePaths(compiler);
|
|
10742
|
+
const hitManifest = sourceModifiedFilePaths.some((filePath)=>{
|
|
10743
|
+
if (normalizedManifestSourcePaths.length > 0) return normalizedManifestSourcePaths.includes(filePath);
|
|
10744
|
+
return /(^|\/)manifest\.json$/i.test(filePath);
|
|
10745
|
+
});
|
|
10746
|
+
const hitLocales = sourceModifiedFilePaths.some((filePath)=>{
|
|
10747
|
+
if (compilerContextRoot) return filePath.startsWith(`${compilerContextRoot}/src/_locales/`);
|
|
10748
|
+
return /(^|\/)__?locales\/.+\.json$/i.test(filePath);
|
|
10749
|
+
});
|
|
10750
|
+
const hitServiceWorker = sourceModifiedFilePaths.some((p)=>/(^|\/)(service_worker|background)\.(m?js|cjs|ts)$/i.test(p));
|
|
10751
|
+
if (hitManifest) {
|
|
10752
|
+
this.pendingContentReloadEntryNames = [];
|
|
10753
|
+
this.ctx.setPendingReloadReason?.('manifest');
|
|
10754
|
+
} else if (hitLocales) {
|
|
10755
|
+
this.pendingContentReloadEntryNames = [];
|
|
10756
|
+
this.ctx.setPendingReloadReason?.('locales');
|
|
10757
|
+
} else if (hitServiceWorker) {
|
|
10758
|
+
this.pendingContentReloadEntryNames = [];
|
|
10759
|
+
this.ctx.setPendingReloadReason?.('sw');
|
|
10760
|
+
} else {
|
|
10761
|
+
const changedContentEntries = (0, content_script_targets.JY)(sourceModifiedFilePaths, this.contentScriptSourceDependencyPathsByEntry);
|
|
10762
|
+
this.lastWatchIncludedContentChanges = changedContentEntries.length > 0;
|
|
10763
|
+
if (changedContentEntries.length > 0) {
|
|
10764
|
+
this.pendingContentReloadEntryNames = changedContentEntries;
|
|
10765
|
+
this.awaitingSettledContentBuild = true;
|
|
10766
|
+
globalThis.__EXTJS_PENDING_FIREFOX_CONTENT_RELOAD__ = true;
|
|
10767
|
+
}
|
|
10768
|
+
if (this.shouldEmitReloadActionEvent()) emitActionEvent('reload_debug', {
|
|
10769
|
+
phase: 'watch',
|
|
10770
|
+
browser: this.host.browser,
|
|
10771
|
+
sourceModifiedFilePaths,
|
|
10772
|
+
hitManifest,
|
|
10773
|
+
hitLocales,
|
|
10774
|
+
hitServiceWorker,
|
|
10775
|
+
changedContentEntries,
|
|
10776
|
+
pendingContentReloadEntryNames: [
|
|
10777
|
+
...this.pendingContentReloadEntryNames
|
|
10778
|
+
]
|
|
10779
|
+
});
|
|
10780
|
+
}
|
|
9302
10781
|
} catch (error) {
|
|
9303
10782
|
this.ctx.logger?.warn?.('[reload] watchRun inspect failed:', String(error));
|
|
9304
10783
|
}
|
|
@@ -9309,43 +10788,600 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9309
10788
|
if (hasErrors) return void done();
|
|
9310
10789
|
try {
|
|
9311
10790
|
const compilation = stats?.compilation;
|
|
9312
|
-
const
|
|
9313
|
-
const
|
|
10791
|
+
const inferredHardReloadReason = this.inferHardReloadReasonFromSourceSignatures(compiler);
|
|
10792
|
+
const nextManifestSourceSignatures = this.collectManifestSourceSignatures(compiler);
|
|
10793
|
+
const nextLocaleSourceSignatures = this.collectLocaleSourceSignatures(compiler);
|
|
10794
|
+
const nextServiceWorkerSourceDependencyPaths = this.collectEntrypointModuleResourcePaths(compilation, 'background/service_worker');
|
|
10795
|
+
const nextServiceWorkerSourceSignatures = this.collectSourceSignaturesFromPaths(nextServiceWorkerSourceDependencyPaths);
|
|
10796
|
+
this.refreshContentScriptSourceDependencyPaths(compilation);
|
|
10797
|
+
this.serviceWorkerSourceDependencyPaths = nextServiceWorkerSourceDependencyPaths;
|
|
10798
|
+
this.serviceWorkerSourceSignatures = nextServiceWorkerSourceSignatures;
|
|
10799
|
+
this.manifestSourceSignatures = nextManifestSourceSignatures;
|
|
10800
|
+
this.localeSourceSignatures = nextLocaleSourceSignatures;
|
|
10801
|
+
const changed = this.collectChangedAssetNames(compilation);
|
|
10802
|
+
const contentScriptOutputRoot = this.ctx.getExtensionRoot() || String(compilation?.options?.output?.path || '');
|
|
10803
|
+
const nextContentScriptOutputSignatures = this.collectContentScriptOutputSignatures(compilation, contentScriptOutputRoot || void 0);
|
|
10804
|
+
const inferredEntryNamesFromOutputSignatures = this.inferContentReloadEntryNamesFromOutputSignatures(nextContentScriptOutputSignatures);
|
|
9314
10805
|
const controller = this.host?.rdpController;
|
|
10806
|
+
if (!this.hasSeenFirstSuccessfulDone) {
|
|
10807
|
+
this.hasSeenFirstSuccessfulDone = true;
|
|
10808
|
+
this.contentScriptOutputSignaturesByEntry = nextContentScriptOutputSignatures;
|
|
10809
|
+
this.pendingContentReloadEntryNames = [];
|
|
10810
|
+
this.awaitingSettledContentBuild = false;
|
|
10811
|
+
this.lastWatchIncludedContentChanges = false;
|
|
10812
|
+
this.ctx.clearPendingReloadReason?.();
|
|
10813
|
+
if (controller && 'function' == typeof controller.reloadMatchingTabsForContentScripts) {
|
|
10814
|
+
const allRules = (0, content_script_targets.iw)(compilation, this.ctx.getExtensionRoot());
|
|
10815
|
+
if (allRules.length > 0) controller.reloadMatchingTabsForContentScripts(allRules).catch(()=>{});
|
|
10816
|
+
}
|
|
10817
|
+
done();
|
|
10818
|
+
return;
|
|
10819
|
+
}
|
|
9315
10820
|
if (controller && 'function' == typeof controller.hardReload) {
|
|
9316
|
-
const
|
|
10821
|
+
const inferredAssetReason = this.inferHardReloadReasonFromChangedAssets(this.pendingContentReloadEntryNames.length > 0 ? changed.filter((a)=>'manifest.json' !== String(a || '').replace(/\\/g, '/')) : changed);
|
|
10822
|
+
const reason = this.ctx.getPendingReloadReason?.() || inferredHardReloadReason || inferredAssetReason;
|
|
10823
|
+
const inferredEntryNames = Array.from(new Set([
|
|
10824
|
+
...this.inferContentReloadEntryNamesFromChangedAssets(changed),
|
|
10825
|
+
...inferredEntryNamesFromOutputSignatures
|
|
10826
|
+
]));
|
|
10827
|
+
this.contentScriptOutputSignaturesByEntry = nextContentScriptOutputSignatures;
|
|
10828
|
+
const targetEntryNames = this.pendingContentReloadEntryNames.length > 0 ? [
|
|
10829
|
+
...this.pendingContentReloadEntryNames
|
|
10830
|
+
] : inferredEntryNames;
|
|
10831
|
+
if (this.shouldEmitReloadActionEvent()) emitActionEvent('reload_debug', {
|
|
10832
|
+
phase: 'done',
|
|
10833
|
+
browser: this.host.browser,
|
|
10834
|
+
reason: reason || null,
|
|
10835
|
+
pendingContentReloadEntryNames: [
|
|
10836
|
+
...this.pendingContentReloadEntryNames
|
|
10837
|
+
],
|
|
10838
|
+
inferredEntryNamesFromOutputSignatures,
|
|
10839
|
+
inferredEntryNames,
|
|
10840
|
+
targetEntryNames,
|
|
10841
|
+
changedAssets: changed
|
|
10842
|
+
});
|
|
10843
|
+
if (!reason && 0 === targetEntryNames.length) {
|
|
10844
|
+
this.pendingContentReloadEntryNames = [];
|
|
10845
|
+
this.awaitingSettledContentBuild = false;
|
|
10846
|
+
this.lastWatchIncludedContentChanges = false;
|
|
10847
|
+
done();
|
|
10848
|
+
return;
|
|
10849
|
+
}
|
|
10850
|
+
if (!reason && targetEntryNames.length > 0 && 'function' == typeof controller.reloadMatchingTabsForContentScripts) {
|
|
10851
|
+
const selectedEntryNames = targetEntryNames;
|
|
10852
|
+
const selectedGeneration = this.contentReloadGeneration;
|
|
10853
|
+
const selectedRules = (0, content_script_targets.Il)((0, content_script_targets.iw)(compilation, this.ctx.getExtensionRoot()), selectedEntryNames);
|
|
10854
|
+
if (selectedRules.length > 0) {
|
|
10855
|
+
if (this.lastWatchIncludedContentChanges && this.contentReloadQuietPeriodMs > 0) {
|
|
10856
|
+
await new Promise((resolve)=>setTimeout(resolve, this.contentReloadQuietPeriodMs));
|
|
10857
|
+
if (selectedGeneration !== this.contentReloadGeneration) return void done();
|
|
10858
|
+
}
|
|
10859
|
+
await controller.reloadMatchingTabsForContentScripts(selectedRules);
|
|
10860
|
+
if (this.lastWatchIncludedContentChanges && this.contentReloadFollowupMs > 0) {
|
|
10861
|
+
await new Promise((resolve)=>setTimeout(resolve, this.contentReloadFollowupMs));
|
|
10862
|
+
if (selectedGeneration === this.contentReloadGeneration) await controller.reloadMatchingTabsForContentScripts(selectedRules);
|
|
10863
|
+
}
|
|
10864
|
+
}
|
|
10865
|
+
globalThis.__EXTJS_PENDING_FIREFOX_CONTENT_RELOAD__ = false;
|
|
10866
|
+
try {
|
|
10867
|
+
await globalThis.__EXTJS_ON_FIREFOX_CONTENT_RELOADED__?.();
|
|
10868
|
+
} catch {}
|
|
10869
|
+
if (this.awaitingSettledContentBuild && this.lastWatchIncludedContentChanges) ;
|
|
10870
|
+
else {
|
|
10871
|
+
this.pendingContentReloadEntryNames = [];
|
|
10872
|
+
this.awaitingSettledContentBuild = false;
|
|
10873
|
+
}
|
|
10874
|
+
if (this.awaitingSettledContentBuild && !this.lastWatchIncludedContentChanges) {
|
|
10875
|
+
this.pendingContentReloadEntryNames = [];
|
|
10876
|
+
this.awaitingSettledContentBuild = false;
|
|
10877
|
+
}
|
|
10878
|
+
done();
|
|
10879
|
+
return;
|
|
10880
|
+
}
|
|
9317
10881
|
if (this.shouldEmitReloadActionEvent()) emitActionEvent('extension_reload', {
|
|
9318
10882
|
reason: reason || 'unknown',
|
|
9319
10883
|
browser: this.host.browser
|
|
9320
10884
|
});
|
|
10885
|
+
this.pendingContentReloadEntryNames = [];
|
|
10886
|
+
globalThis.__EXTJS_PENDING_FIREFOX_CONTENT_RELOAD__ = false;
|
|
10887
|
+
this.ctx.clearPendingReloadReason?.();
|
|
9321
10888
|
await controller.hardReload(stats.compilation, changed);
|
|
10889
|
+
if ('function' == typeof controller.reloadMatchingTabsForContentScripts) {
|
|
10890
|
+
const allContentRules = (0, content_script_targets.iw)(compilation, this.ctx.getExtensionRoot());
|
|
10891
|
+
if (allContentRules.length > 0) await controller.reloadMatchingTabsForContentScripts(allContentRules);
|
|
10892
|
+
}
|
|
10893
|
+
if (this.host.watchSource || this.host.source) this.host.__extjsForceSourceReinspect = true;
|
|
10894
|
+
}
|
|
10895
|
+
} catch {}
|
|
10896
|
+
done();
|
|
10897
|
+
});
|
|
10898
|
+
}
|
|
10899
|
+
shouldEmitReloadActionEvent() {
|
|
10900
|
+
return Boolean(this.host.source || this.host.watchSource);
|
|
10901
|
+
}
|
|
10902
|
+
refreshContentScriptSourceDependencyPaths(compilation) {
|
|
10903
|
+
this.contentScriptSourceDependencyPathsByEntry = (0, content_script_targets.im)(compilation);
|
|
10904
|
+
if (this.shouldEmitReloadActionEvent()) {
|
|
10905
|
+
const summary = Array.from(this.contentScriptSourceDependencyPathsByEntry.entries()).map(([entryName, dependencyPaths])=>{
|
|
10906
|
+
const matches = [
|
|
10907
|
+
...dependencyPaths
|
|
10908
|
+
].filter((dependencyPath)=>/contentapp\.(t|j)sx?$/i.test(dependencyPath));
|
|
10909
|
+
return `${entryName}:${dependencyPaths.size}${matches.length ? `:has-ContentApp=${matches.join('|')}` : ''}`;
|
|
10910
|
+
}).join(', ');
|
|
10911
|
+
emitActionEvent('reload_debug', {
|
|
10912
|
+
phase: 'dependencies',
|
|
10913
|
+
browser: this.host.browser,
|
|
10914
|
+
summary: summary || '<none>'
|
|
10915
|
+
});
|
|
10916
|
+
}
|
|
10917
|
+
}
|
|
10918
|
+
collectManifestSourceSignatures(compiler) {
|
|
10919
|
+
return this.collectSourceSignaturesFromPaths(this.getWatchedManifestSourcePaths(compiler));
|
|
10920
|
+
}
|
|
10921
|
+
collectLocaleSourceSignatures(compiler) {
|
|
10922
|
+
const compilerContextRoot = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
10923
|
+
if (!compilerContextRoot) return new Map();
|
|
10924
|
+
const localesRoot = external_path_.join(compilerContextRoot, 'src', '_locales');
|
|
10925
|
+
const discoveredLocaleFiles = [];
|
|
10926
|
+
const walk = (dirPath)=>{
|
|
10927
|
+
let entries;
|
|
10928
|
+
try {
|
|
10929
|
+
entries = external_fs_.readdirSync(dirPath, {
|
|
10930
|
+
withFileTypes: true
|
|
10931
|
+
});
|
|
10932
|
+
} catch {
|
|
10933
|
+
return;
|
|
10934
|
+
}
|
|
10935
|
+
for (const entry of entries){
|
|
10936
|
+
const absoluteEntryPath = external_path_.join(dirPath, entry.name);
|
|
10937
|
+
if (entry.isDirectory()) {
|
|
10938
|
+
walk(absoluteEntryPath);
|
|
10939
|
+
continue;
|
|
10940
|
+
}
|
|
10941
|
+
if (entry.isFile() && absoluteEntryPath.endsWith('.json')) discoveredLocaleFiles.push(absoluteEntryPath.replace(/\\/g, '/'));
|
|
10942
|
+
}
|
|
10943
|
+
};
|
|
10944
|
+
walk(localesRoot);
|
|
10945
|
+
return this.collectSourceSignaturesFromPaths(discoveredLocaleFiles);
|
|
10946
|
+
}
|
|
10947
|
+
collectSourceSignaturesFromPaths(dependencyPaths) {
|
|
10948
|
+
const signatures = new Map();
|
|
10949
|
+
for (const dependencyPath of dependencyPaths){
|
|
10950
|
+
const normalizedDependencyPath = String(dependencyPath).replace(/\\/g, '/');
|
|
10951
|
+
const signature = this.readSourceFileSignature(normalizedDependencyPath);
|
|
10952
|
+
if (signature) signatures.set(normalizedDependencyPath, signature);
|
|
10953
|
+
}
|
|
10954
|
+
return signatures;
|
|
10955
|
+
}
|
|
10956
|
+
inferHardReloadReasonFromSourceSignatures(compiler) {
|
|
10957
|
+
const nextManifestSourceSignatures = this.collectManifestSourceSignatures(compiler);
|
|
10958
|
+
if (this.haveSourceSignaturesChanged(this.manifestSourceSignatures, nextManifestSourceSignatures)) return 'manifest';
|
|
10959
|
+
const nextLocaleSourceSignatures = this.collectLocaleSourceSignatures(compiler);
|
|
10960
|
+
if (this.haveSourceSignaturesChanged(this.localeSourceSignatures, nextLocaleSourceSignatures)) return 'locales';
|
|
10961
|
+
const nextServiceWorkerSourceSignatures = this.collectSourceSignaturesFromPaths(this.serviceWorkerSourceDependencyPaths);
|
|
10962
|
+
if (this.haveSourceSignaturesChanged(this.serviceWorkerSourceSignatures, nextServiceWorkerSourceSignatures)) return 'sw';
|
|
10963
|
+
}
|
|
10964
|
+
haveSourceSignaturesChanged(previousSignatures, nextSignatures) {
|
|
10965
|
+
if (0 === previousSignatures.size) return false;
|
|
10966
|
+
if (previousSignatures.size !== nextSignatures.size) return true;
|
|
10967
|
+
for (const [dependencyPath, previousSignature] of previousSignatures){
|
|
10968
|
+
const nextSignature = nextSignatures.get(dependencyPath);
|
|
10969
|
+
if (!nextSignature || nextSignature !== previousSignature) return true;
|
|
10970
|
+
}
|
|
10971
|
+
return false;
|
|
10972
|
+
}
|
|
10973
|
+
collectChangedAssetNames(compilation) {
|
|
10974
|
+
const changed = new Set();
|
|
10975
|
+
const assetsArr = Array.isArray(compilation?.getAssets?.()) ? compilation.getAssets() : [];
|
|
10976
|
+
for (const asset of assetsArr){
|
|
10977
|
+
if (!asset?.emitted) continue;
|
|
10978
|
+
const assetName = String(asset?.name || '').replace(/\\/g, '/');
|
|
10979
|
+
if (assetName) changed.add(assetName);
|
|
10980
|
+
}
|
|
10981
|
+
const assetsInfo = compilation?.assetsInfo;
|
|
10982
|
+
if (assetsInfo instanceof Map) for (const key of assetsInfo.keys()){
|
|
10983
|
+
const assetName = String(key || '').replace(/\\/g, '/');
|
|
10984
|
+
if (assetName) changed.add(assetName);
|
|
10985
|
+
}
|
|
10986
|
+
return Array.from(changed);
|
|
10987
|
+
}
|
|
10988
|
+
inferHardReloadReasonFromChangedAssets(changedAssets) {
|
|
10989
|
+
for (const assetName of changedAssets){
|
|
10990
|
+
const normalizedAssetName = String(assetName || '').replace(/\\/g, '/');
|
|
10991
|
+
if (normalizedAssetName) {
|
|
10992
|
+
if ('manifest.json' === normalizedAssetName) return 'manifest';
|
|
10993
|
+
if (/(^|\/)_locales\/.+\.json$/i.test(normalizedAssetName)) return 'locales';
|
|
10994
|
+
if (/(^|\/)background\/(service_worker|script)\.(m?js|cjs)$/i.test(normalizedAssetName)) return 'sw';
|
|
10995
|
+
}
|
|
10996
|
+
}
|
|
10997
|
+
}
|
|
10998
|
+
inferContentReloadEntryNamesFromChangedAssets(changedAssets) {
|
|
10999
|
+
const entries = new Set();
|
|
11000
|
+
for (const assetName of changedAssets){
|
|
11001
|
+
const normalizedAssetName = String(assetName || '').replace(/\\/g, '/');
|
|
11002
|
+
if (!(0, content_script_targets.HE)(normalizedAssetName)) continue;
|
|
11003
|
+
const canonicalAsset = (0, contracts.es)(normalizedAssetName);
|
|
11004
|
+
if (canonicalAsset) entries.add((0, contracts.Y0)(canonicalAsset.index));
|
|
11005
|
+
}
|
|
11006
|
+
return Array.from(entries);
|
|
11007
|
+
}
|
|
11008
|
+
inferContentReloadEntryNamesFromOutputSignatures(nextOutputSignaturesByEntry) {
|
|
11009
|
+
const changedEntries = new Set();
|
|
11010
|
+
for (const [entryName, nextOutputSignatures] of nextOutputSignaturesByEntry.entries()){
|
|
11011
|
+
const previousOutputSignatures = this.contentScriptOutputSignaturesByEntry.get(entryName);
|
|
11012
|
+
if (previousOutputSignatures && 0 !== previousOutputSignatures.size) {
|
|
11013
|
+
if (previousOutputSignatures.size !== nextOutputSignatures.size) {
|
|
11014
|
+
changedEntries.add(entryName);
|
|
11015
|
+
continue;
|
|
11016
|
+
}
|
|
11017
|
+
for (const [outputFile, previousSignature] of previousOutputSignatures){
|
|
11018
|
+
const nextSignature = nextOutputSignatures.get(outputFile);
|
|
11019
|
+
if (!nextSignature || nextSignature !== previousSignature) {
|
|
11020
|
+
changedEntries.add(entryName);
|
|
11021
|
+
break;
|
|
11022
|
+
}
|
|
11023
|
+
}
|
|
11024
|
+
}
|
|
11025
|
+
}
|
|
11026
|
+
return Array.from(changedEntries).sort();
|
|
11027
|
+
}
|
|
11028
|
+
collectEntrypointModuleResourcePaths(compilation, entrypointName) {
|
|
11029
|
+
const collectedResourcePaths = new Set();
|
|
11030
|
+
const entrypoints = compilation?.entrypoints;
|
|
11031
|
+
const entrypoint = entrypoints?.get?.(entrypointName);
|
|
11032
|
+
if (!entrypoint) return collectedResourcePaths;
|
|
11033
|
+
const chunkGraph = compilation?.chunkGraph;
|
|
11034
|
+
if (!chunkGraph) return collectedResourcePaths;
|
|
11035
|
+
const entrypointChunks = Array.from(entrypoint?.chunks || []);
|
|
11036
|
+
for (const chunk of entrypointChunks){
|
|
11037
|
+
const modulesIterable = chunkGraph.getChunkModulesIterable?.(chunk) || chunkGraph.getChunkModulesIterableBySourceType?.(chunk, "javascript") || chunkGraph.getChunkModules?.(chunk);
|
|
11038
|
+
if (modulesIterable) for (const module of modulesIterable){
|
|
11039
|
+
const resourcePath = module?.resource || module?.rootModule?.resource || module?.originalSource?.()?.resource;
|
|
11040
|
+
if ('string' == typeof resourcePath && resourcePath.length > 0) collectedResourcePaths.add(resourcePath.replace(/\\/g, '/'));
|
|
11041
|
+
}
|
|
11042
|
+
}
|
|
11043
|
+
return collectedResourcePaths;
|
|
11044
|
+
}
|
|
11045
|
+
readSourceFileSignature(absoluteFilePath) {
|
|
11046
|
+
try {
|
|
11047
|
+
const stats = external_fs_.statSync(absoluteFilePath);
|
|
11048
|
+
if (!stats.isFile()) return;
|
|
11049
|
+
return `${stats.size}:${stats.mtimeMs}`;
|
|
11050
|
+
} catch {
|
|
11051
|
+
return;
|
|
11052
|
+
}
|
|
11053
|
+
}
|
|
11054
|
+
collectContentScriptOutputSignatures(compilation, extensionRoot) {
|
|
11055
|
+
const outputSignaturesByEntry = new Map();
|
|
11056
|
+
const entrypoints = compilation?.entrypoints;
|
|
11057
|
+
if (!entrypoints || !extensionRoot) return outputSignaturesByEntry;
|
|
11058
|
+
for (const [entryName] of entrypoints.entries()){
|
|
11059
|
+
if (!(0, content_script_targets.wH)(entryName)) continue;
|
|
11060
|
+
const entryFiles = this.collectEntrypointFiles(compilation, [
|
|
11061
|
+
entryName
|
|
11062
|
+
]);
|
|
11063
|
+
const outputSignatures = new Map();
|
|
11064
|
+
for (const entryFile of entryFiles){
|
|
11065
|
+
const absoluteEntryFilePath = external_path_.join(extensionRoot, entryFile);
|
|
11066
|
+
const signature = this.readSourceFileSignature(absoluteEntryFilePath);
|
|
11067
|
+
if (signature) outputSignatures.set(entryFile, signature);
|
|
11068
|
+
}
|
|
11069
|
+
if (outputSignatures.size > 0) outputSignaturesByEntry.set(entryName, outputSignatures);
|
|
11070
|
+
}
|
|
11071
|
+
return outputSignaturesByEntry;
|
|
11072
|
+
}
|
|
11073
|
+
collectEntrypointFiles(compilation, entrypointNames) {
|
|
11074
|
+
const collectedFiles = new Set();
|
|
11075
|
+
const entrypoints = compilation?.entrypoints;
|
|
11076
|
+
if (!entrypoints) return [];
|
|
11077
|
+
for (const entrypointName of entrypointNames){
|
|
11078
|
+
const entrypoint = entrypoints.get?.(entrypointName);
|
|
11079
|
+
const entryFiles = 'function' == typeof entrypoint?.getFiles ? entrypoint.getFiles() : [];
|
|
11080
|
+
for (const file of entryFiles){
|
|
11081
|
+
const normalizedFile = String(file || '').replace(/\\/g, '/');
|
|
11082
|
+
if (!(!normalizedFile || normalizedFile.endsWith('.map'))) {
|
|
11083
|
+
if (!normalizedFile.startsWith('hot/')) collectedFiles.add(normalizedFile);
|
|
11084
|
+
}
|
|
11085
|
+
}
|
|
11086
|
+
}
|
|
11087
|
+
return Array.from(collectedFiles);
|
|
11088
|
+
}
|
|
11089
|
+
async waitForStableContentOutputs(extensionRoot, entryFiles, timeoutMs = 8000, pollIntervalMs = 150, stableReadsRequired = 2) {
|
|
11090
|
+
const normalizedEntryFiles = entryFiles.map((file)=>String(file || '').replace(/\\/g, '/')).filter(Boolean);
|
|
11091
|
+
if (0 === normalizedEntryFiles.length) return true;
|
|
11092
|
+
const start = Date.now();
|
|
11093
|
+
let lastSignature = '';
|
|
11094
|
+
let stableReads = 0;
|
|
11095
|
+
while(Date.now() - start < timeoutMs){
|
|
11096
|
+
const referencedFiles = new Set(normalizedEntryFiles);
|
|
11097
|
+
const signatureParts = [];
|
|
11098
|
+
let allFilesReady = true;
|
|
11099
|
+
for (const entryFile of normalizedEntryFiles){
|
|
11100
|
+
const absoluteEntryFilePath = external_path_.join(extensionRoot, entryFile);
|
|
11101
|
+
const signature = this.readStableFileSignature(absoluteEntryFilePath);
|
|
11102
|
+
if (!signature) {
|
|
11103
|
+
allFilesReady = false;
|
|
11104
|
+
break;
|
|
9322
11105
|
}
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
11106
|
+
signatureParts.push(`${entryFile}:${signature}`);
|
|
11107
|
+
if (entryFile.endsWith('.js')) {
|
|
11108
|
+
const source = this.readFileTextSafe(absoluteEntryFilePath);
|
|
11109
|
+
if (!source) {
|
|
11110
|
+
allFilesReady = false;
|
|
11111
|
+
break;
|
|
11112
|
+
}
|
|
11113
|
+
for (const referencedFile of this.extractReferencedOutputFiles(source))referencedFiles.add(referencedFile);
|
|
11114
|
+
}
|
|
11115
|
+
}
|
|
11116
|
+
if (!allFilesReady) {
|
|
11117
|
+
lastSignature = '';
|
|
11118
|
+
stableReads = 0;
|
|
11119
|
+
await new Promise((resolve)=>setTimeout(resolve, pollIntervalMs));
|
|
11120
|
+
continue;
|
|
11121
|
+
}
|
|
11122
|
+
for (const referencedFile of referencedFiles){
|
|
11123
|
+
if (normalizedEntryFiles.includes(referencedFile)) continue;
|
|
11124
|
+
const absoluteReferencedFilePath = external_path_.join(extensionRoot, referencedFile);
|
|
11125
|
+
const signature = this.readStableFileSignature(absoluteReferencedFilePath);
|
|
11126
|
+
if (!signature) {
|
|
11127
|
+
allFilesReady = false;
|
|
11128
|
+
break;
|
|
11129
|
+
}
|
|
11130
|
+
signatureParts.push(`${referencedFile}:${signature}`);
|
|
11131
|
+
}
|
|
11132
|
+
if (!allFilesReady) {
|
|
11133
|
+
lastSignature = '';
|
|
11134
|
+
stableReads = 0;
|
|
11135
|
+
await new Promise((resolve)=>setTimeout(resolve, pollIntervalMs));
|
|
11136
|
+
continue;
|
|
11137
|
+
}
|
|
11138
|
+
const currentSignature = signatureParts.sort().join('|');
|
|
11139
|
+
if (currentSignature === lastSignature) stableReads += 1;
|
|
11140
|
+
else {
|
|
11141
|
+
lastSignature = currentSignature;
|
|
11142
|
+
stableReads = 1;
|
|
11143
|
+
}
|
|
11144
|
+
if (stableReads >= stableReadsRequired) return true;
|
|
11145
|
+
await new Promise((resolve)=>setTimeout(resolve, pollIntervalMs));
|
|
11146
|
+
}
|
|
11147
|
+
return false;
|
|
9326
11148
|
}
|
|
9327
|
-
|
|
9328
|
-
|
|
11149
|
+
readStableFileSignature(absoluteFilePath) {
|
|
11150
|
+
try {
|
|
11151
|
+
const stats = external_fs_.statSync(absoluteFilePath);
|
|
11152
|
+
if (!stats.isFile()) return;
|
|
11153
|
+
return `${stats.size}:${stats.mtimeMs}`;
|
|
11154
|
+
} catch {
|
|
11155
|
+
return;
|
|
11156
|
+
}
|
|
11157
|
+
}
|
|
11158
|
+
readFileTextSafe(absoluteFilePath) {
|
|
11159
|
+
try {
|
|
11160
|
+
return external_fs_.readFileSync(absoluteFilePath, 'utf-8');
|
|
11161
|
+
} catch {
|
|
11162
|
+
return;
|
|
11163
|
+
}
|
|
11164
|
+
}
|
|
11165
|
+
extractReferencedOutputFiles(source) {
|
|
11166
|
+
const matches = source.match(/(?:content_scripts|assets)\/[^"'`\s)]+\.(?:css|js|json|png|jpg|jpeg|svg|gif|webp|ico|avif)/g);
|
|
11167
|
+
return Array.from(new Set(matches || []));
|
|
9329
11168
|
}
|
|
9330
11169
|
constructor(host, ctx){
|
|
9331
11170
|
firefox_hard_reload_define_property(this, "host", void 0);
|
|
9332
11171
|
firefox_hard_reload_define_property(this, "ctx", void 0);
|
|
11172
|
+
firefox_hard_reload_define_property(this, "hasSeenFirstSuccessfulDone", false);
|
|
11173
|
+
firefox_hard_reload_define_property(this, "serviceWorkerSourceDependencyPaths", new Set());
|
|
11174
|
+
firefox_hard_reload_define_property(this, "serviceWorkerSourceSignatures", new Map());
|
|
11175
|
+
firefox_hard_reload_define_property(this, "manifestSourceSignatures", new Map());
|
|
11176
|
+
firefox_hard_reload_define_property(this, "localeSourceSignatures", new Map());
|
|
11177
|
+
firefox_hard_reload_define_property(this, "contentScriptSourceDependencyPathsByEntry", new Map());
|
|
11178
|
+
firefox_hard_reload_define_property(this, "contentScriptOutputSignaturesByEntry", new Map());
|
|
11179
|
+
firefox_hard_reload_define_property(this, "pendingContentReloadEntryNames", []);
|
|
11180
|
+
firefox_hard_reload_define_property(this, "contentReloadGeneration", 0);
|
|
11181
|
+
firefox_hard_reload_define_property(this, "contentReloadQuietPeriodMs", 1200);
|
|
11182
|
+
firefox_hard_reload_define_property(this, "contentReloadFollowupMs", 1200);
|
|
11183
|
+
firefox_hard_reload_define_property(this, "lastWatchIncludedContentChanges", false);
|
|
11184
|
+
firefox_hard_reload_define_property(this, "awaitingSettledContentBuild", false);
|
|
9333
11185
|
this.host = host;
|
|
9334
11186
|
this.ctx = ctx;
|
|
9335
11187
|
}
|
|
9336
11188
|
}
|
|
11189
|
+
var evaluate = __webpack_require__("./webpack/plugin-browsers/run-firefox/firefox-source-inspection/remote-firefox/evaluate.ts");
|
|
11190
|
+
var remote_firefox_logging = __webpack_require__("./webpack/plugin-browsers/run-firefox/firefox-source-inspection/remote-firefox/logging.ts");
|
|
9337
11191
|
var messaging_client = __webpack_require__("./webpack/plugin-browsers/run-firefox/firefox-source-inspection/remote-firefox/messaging-client.ts");
|
|
9338
|
-
var
|
|
11192
|
+
var external_url_ = __webpack_require__("url");
|
|
9339
11193
|
const TARGET_SCAN_INTERVAL_MS = 250;
|
|
11194
|
+
function guessRepoRoot(startDir) {
|
|
11195
|
+
let dir = external_path_default().resolve(startDir);
|
|
11196
|
+
for(let depth = 0; depth < 24; depth++){
|
|
11197
|
+
if ((0, external_fs_.existsSync)(external_path_default().join(dir, 'programs', 'develop', 'package.json'))) return dir;
|
|
11198
|
+
const parent = external_path_default().dirname(dir);
|
|
11199
|
+
if (parent === dir) break;
|
|
11200
|
+
dir = parent;
|
|
11201
|
+
}
|
|
11202
|
+
dir = external_path_default().resolve(startDir);
|
|
11203
|
+
for(let depth = 0; depth < 16; depth++){
|
|
11204
|
+
if ((0, external_fs_.existsSync)(external_path_default().join(dir, 'pnpm-workspace.yaml')) || (0, external_fs_.existsSync)(external_path_default().join(dir, '.git'))) return dir;
|
|
11205
|
+
const parent = external_path_default().dirname(dir);
|
|
11206
|
+
if (parent === dir) break;
|
|
11207
|
+
dir = parent;
|
|
11208
|
+
}
|
|
11209
|
+
return null;
|
|
11210
|
+
}
|
|
11211
|
+
function guessRepoRootFromThisModule() {
|
|
11212
|
+
try {
|
|
11213
|
+
const here = external_path_default().dirname((0, external_url_.fileURLToPath)(__rslib_import_meta_url__));
|
|
11214
|
+
return guessRepoRoot(here);
|
|
11215
|
+
} catch {
|
|
11216
|
+
return null;
|
|
11217
|
+
}
|
|
11218
|
+
}
|
|
11219
|
+
function appendDebugLogLine(line) {
|
|
11220
|
+
const paths = [];
|
|
11221
|
+
const fromEnv = process.env.EXTENSION_DEBUG_SESSION_LOG;
|
|
11222
|
+
if ('string' == typeof fromEnv && fromEnv.length > 0) paths.push(fromEnv);
|
|
11223
|
+
const repoFromModule = guessRepoRootFromThisModule();
|
|
11224
|
+
if (repoFromModule) paths.push(external_path_default().join(repoFromModule, '.cursor', 'debug-a87efc.log'));
|
|
11225
|
+
const repoFromCwd = guessRepoRoot(process.cwd());
|
|
11226
|
+
if (repoFromCwd) paths.push(external_path_default().join(repoFromCwd, '.cursor', 'debug-a87efc.log'));
|
|
11227
|
+
for (const root of [
|
|
11228
|
+
process.env.INIT_CWD,
|
|
11229
|
+
process.env.PROJECT_ROOT,
|
|
11230
|
+
process.cwd()
|
|
11231
|
+
])if ('string' == typeof root && root.length > 0) paths.push(external_path_default().join(root, '.cursor', 'debug-a87efc.log'));
|
|
11232
|
+
const seen = new Set();
|
|
11233
|
+
for (const filePath of paths)if (!seen.has(filePath)) {
|
|
11234
|
+
seen.add(filePath);
|
|
11235
|
+
try {
|
|
11236
|
+
(0, external_fs_.mkdirSync)(external_path_default().dirname(filePath), {
|
|
11237
|
+
recursive: true
|
|
11238
|
+
});
|
|
11239
|
+
(0, external_fs_.appendFileSync)(filePath, `${line}\n`);
|
|
11240
|
+
return;
|
|
11241
|
+
} catch {}
|
|
11242
|
+
}
|
|
11243
|
+
console.error('[extension-develop][debug-session a87efc] log file write failed', line);
|
|
11244
|
+
}
|
|
11245
|
+
function agentDebugLog(payload) {
|
|
11246
|
+
const line = JSON.stringify({
|
|
11247
|
+
sessionId: 'a87efc',
|
|
11248
|
+
timestamp: Date.now(),
|
|
11249
|
+
...payload
|
|
11250
|
+
});
|
|
11251
|
+
fetch('http://127.0.0.1:7795/ingest/9eb8f923-a325-4455-a46c-a6e706558307', {
|
|
11252
|
+
method: 'POST',
|
|
11253
|
+
headers: {
|
|
11254
|
+
'Content-Type': 'application/json',
|
|
11255
|
+
'X-Debug-Session-Id': 'a87efc'
|
|
11256
|
+
},
|
|
11257
|
+
body: line
|
|
11258
|
+
}).catch(()=>{});
|
|
11259
|
+
appendDebugLogLine(line);
|
|
11260
|
+
}
|
|
11261
|
+
function shouldDeferFallbackUntilExactMatch(normalizedUrl) {
|
|
11262
|
+
try {
|
|
11263
|
+
const parsed = new URL(String(normalizedUrl || ''));
|
|
11264
|
+
return 'http:' === parsed.protocol || 'https:' === parsed.protocol || 'file:' === parsed.protocol || 'moz-extension:' === parsed.protocol || 'chrome-extension:' === parsed.protocol || 'edge:' === parsed.protocol;
|
|
11265
|
+
} catch {
|
|
11266
|
+
return false;
|
|
11267
|
+
}
|
|
11268
|
+
}
|
|
11269
|
+
async function findActorsMatchingLiveHref(client, allTargets, normalizedUrlToInspect) {
|
|
11270
|
+
const withActor = allTargets.filter((t)=>t && 'string' == typeof t.actor);
|
|
11271
|
+
for(let i = withActor.length - 1; i >= 0; i--){
|
|
11272
|
+
const target = withActor[i];
|
|
11273
|
+
const tabActor = String(target.actor);
|
|
11274
|
+
let consoleActor = 'string' == typeof target.consoleActor && target.consoleActor.length > 0 ? target.consoleActor : void 0;
|
|
11275
|
+
if (!consoleActor || consoleActor === tabActor) try {
|
|
11276
|
+
const detail = await client.getTargetFromDescriptor(tabActor);
|
|
11277
|
+
if ('string' == typeof detail.consoleActor && detail.consoleActor.length > 0) consoleActor = detail.consoleActor;
|
|
11278
|
+
} catch {}
|
|
11279
|
+
if (consoleActor) try {
|
|
11280
|
+
const hrefRaw = await client.evaluate(consoleActor, 'String(location.href || "")');
|
|
11281
|
+
const href = 'string' == typeof hrefRaw ? hrefRaw : String(hrefRaw ?? '');
|
|
11282
|
+
if (setup_firefox_inspection_actors_normalizeInspectableUrl(href) === normalizedUrlToInspect) return {
|
|
11283
|
+
tabActor,
|
|
11284
|
+
consoleActor
|
|
11285
|
+
};
|
|
11286
|
+
} catch {}
|
|
11287
|
+
}
|
|
11288
|
+
return null;
|
|
11289
|
+
}
|
|
11290
|
+
function setup_firefox_inspection_actors_normalizeInspectableUrl(rawUrl) {
|
|
11291
|
+
try {
|
|
11292
|
+
const parsed = new URL(String(rawUrl || ''));
|
|
11293
|
+
if (('http:' === parsed.protocol || 'https:' === parsed.protocol) && '/' === parsed.pathname) parsed.pathname = '';
|
|
11294
|
+
parsed.hash = '';
|
|
11295
|
+
return parsed.toString();
|
|
11296
|
+
} catch {
|
|
11297
|
+
return String(rawUrl || '').trim().replace(/\/$/, '');
|
|
11298
|
+
}
|
|
11299
|
+
}
|
|
9340
11300
|
async function selectActors(client, urlToInspect) {
|
|
9341
11301
|
const deadline = Date.now() + 10000;
|
|
9342
11302
|
let triedAddTab = false;
|
|
11303
|
+
const normalizedUrlToInspect = setup_firefox_inspection_actors_normalizeInspectableUrl(urlToInspect);
|
|
9343
11304
|
while(Date.now() < deadline){
|
|
9344
11305
|
const allTargets = await client.getTargets() || [];
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
11306
|
+
const exactMatches = allTargets.filter((target)=>target && 'string' == typeof target.url && setup_firefox_inspection_actors_normalizeInspectableUrl(target.url) === normalizedUrlToInspect && target.actor);
|
|
11307
|
+
const exactMatch = exactMatches.length > 0 ? exactMatches[exactMatches.length - 1] : void 0;
|
|
11308
|
+
if (exactMatch?.actor) {
|
|
11309
|
+
const matchDiagnostics = [];
|
|
11310
|
+
for (const target of exactMatches.slice(-5)){
|
|
11311
|
+
const actor = String(target.actor || '');
|
|
11312
|
+
const consoleActor = String(target.consoleActor || actor);
|
|
11313
|
+
let hostCount;
|
|
11314
|
+
let href;
|
|
11315
|
+
try {
|
|
11316
|
+
const probe = await client.evaluate(consoleActor, `(() => JSON.stringify({
|
|
11317
|
+
href: String(location.href || ''),
|
|
11318
|
+
readyState: String(document.readyState || ''),
|
|
11319
|
+
hostCount: document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])').length
|
|
11320
|
+
}))()`);
|
|
11321
|
+
if ('string' == typeof probe && probe) {
|
|
11322
|
+
const parsed = JSON.parse(probe);
|
|
11323
|
+
hostCount = 'number' == typeof parsed?.hostCount ? parsed.hostCount : void 0;
|
|
11324
|
+
href = 'string' == typeof parsed?.href ? parsed.href : void 0;
|
|
11325
|
+
}
|
|
11326
|
+
} catch {}
|
|
11327
|
+
matchDiagnostics.push({
|
|
11328
|
+
actor,
|
|
11329
|
+
consoleActor,
|
|
11330
|
+
url: target.url || '',
|
|
11331
|
+
href,
|
|
11332
|
+
hostCount
|
|
11333
|
+
});
|
|
11334
|
+
}
|
|
11335
|
+
agentDebugLog({
|
|
11336
|
+
runId: process.env.EXTENSION_INSTANCE_ID || 'firefox-select-actors',
|
|
11337
|
+
hypothesisId: 'H20',
|
|
11338
|
+
location: 'setup-firefox-inspection-actors.ts:exact-match-selection',
|
|
11339
|
+
message: 'Firefox exact URL match selection diagnostics',
|
|
11340
|
+
data: {
|
|
11341
|
+
urlToInspect,
|
|
11342
|
+
selectedActor: exactMatch.actor,
|
|
11343
|
+
selectedConsoleActor: exactMatch.consoleActor || exactMatch.actor,
|
|
11344
|
+
matchDiagnostics
|
|
11345
|
+
}
|
|
11346
|
+
});
|
|
11347
|
+
return {
|
|
11348
|
+
tabActor: exactMatch.actor,
|
|
11349
|
+
consoleActor: exactMatch.consoleActor || exactMatch.actor
|
|
11350
|
+
};
|
|
11351
|
+
}
|
|
11352
|
+
if (shouldDeferFallbackUntilExactMatch(normalizedUrlToInspect)) {
|
|
11353
|
+
const livePair = await findActorsMatchingLiveHref(client, allTargets, normalizedUrlToInspect);
|
|
11354
|
+
if (livePair) {
|
|
11355
|
+
let hostCount;
|
|
11356
|
+
let href;
|
|
11357
|
+
try {
|
|
11358
|
+
const probe = await client.evaluate(livePair.consoleActor, `(() => JSON.stringify({
|
|
11359
|
+
href: String(location.href || ''),
|
|
11360
|
+
readyState: String(document.readyState || ''),
|
|
11361
|
+
hostCount: document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])').length
|
|
11362
|
+
}))()`);
|
|
11363
|
+
if ('string' == typeof probe && probe) {
|
|
11364
|
+
const parsed = JSON.parse(probe);
|
|
11365
|
+
hostCount = 'number' == typeof parsed?.hostCount ? parsed.hostCount : void 0;
|
|
11366
|
+
href = 'string' == typeof parsed?.href ? parsed.href : void 0;
|
|
11367
|
+
}
|
|
11368
|
+
} catch {}
|
|
11369
|
+
agentDebugLog({
|
|
11370
|
+
runId: process.env.EXTENSION_INSTANCE_ID || 'firefox-select-actors',
|
|
11371
|
+
hypothesisId: 'H23',
|
|
11372
|
+
location: 'setup-firefox-inspection-actors.ts:live-href-match',
|
|
11373
|
+
message: 'Firefox actor matched by live location.href (listTabs URL was stale)',
|
|
11374
|
+
data: {
|
|
11375
|
+
urlToInspect,
|
|
11376
|
+
selectedActor: livePair.tabActor,
|
|
11377
|
+
selectedConsoleActor: livePair.consoleActor,
|
|
11378
|
+
href,
|
|
11379
|
+
hostCount
|
|
11380
|
+
}
|
|
11381
|
+
});
|
|
11382
|
+
return livePair;
|
|
11383
|
+
}
|
|
11384
|
+
}
|
|
9349
11385
|
if (!triedAddTab && urlToInspect) {
|
|
9350
11386
|
triedAddTab = true;
|
|
9351
11387
|
try {
|
|
@@ -9359,15 +11395,48 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9359
11395
|
}
|
|
9360
11396
|
}
|
|
9361
11397
|
}
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
11398
|
+
if (!shouldDeferFallbackUntilExactMatch(normalizedUrlToInspect)) {
|
|
11399
|
+
for (const target of allTargets)if (target && ('string' == typeof target.actor || 'number' == typeof target.outerWindowID || 'number' == typeof target.outerWindowId)) {
|
|
11400
|
+
agentDebugLog({
|
|
11401
|
+
runId: process.env.EXTENSION_INSTANCE_ID || 'firefox-select-actors',
|
|
11402
|
+
hypothesisId: 'H21',
|
|
11403
|
+
location: 'setup-firefox-inspection-actors.ts:fallback-selection',
|
|
11404
|
+
message: 'Firefox actor selection fell back to first valid target',
|
|
11405
|
+
data: {
|
|
11406
|
+
urlToInspect,
|
|
11407
|
+
selectedActor: String(target.actor || ''),
|
|
11408
|
+
selectedConsoleActor: String(target.consoleActor || target.actor || ''),
|
|
11409
|
+
targets: allTargets.slice(0, 10).map((item, index)=>({
|
|
11410
|
+
index,
|
|
11411
|
+
actor: String(item?.actor || ''),
|
|
11412
|
+
consoleActor: String(item?.consoleActor || ''),
|
|
11413
|
+
url: String(item?.url || ''),
|
|
11414
|
+
outerWindowID: 'number' == typeof item?.outerWindowID ? item.outerWindowID : void 0,
|
|
11415
|
+
outerWindowId: 'number' == typeof item?.outerWindowId ? item.outerWindowId : void 0
|
|
11416
|
+
}))
|
|
11417
|
+
}
|
|
11418
|
+
});
|
|
11419
|
+
return {
|
|
11420
|
+
tabActor: String(target.actor || ''),
|
|
11421
|
+
consoleActor: String(target.consoleActor || target.actor || '')
|
|
11422
|
+
};
|
|
11423
|
+
}
|
|
11424
|
+
}
|
|
9366
11425
|
await new Promise((r)=>setTimeout(r, TARGET_SCAN_INTERVAL_MS));
|
|
9367
11426
|
}
|
|
9368
11427
|
throw new Error(browsers_lib_messages.Itp());
|
|
9369
11428
|
}
|
|
9370
11429
|
const PAGE_READY_TIMEOUT_MS = 8000;
|
|
11430
|
+
function setup_firefox_inspection_navigation_normalizeInspectableUrl(rawUrl) {
|
|
11431
|
+
try {
|
|
11432
|
+
const parsed = new URL(String(rawUrl || ''));
|
|
11433
|
+
if (('http:' === parsed.protocol || 'https:' === parsed.protocol) && '/' === parsed.pathname) parsed.pathname = '';
|
|
11434
|
+
parsed.hash = '';
|
|
11435
|
+
return parsed.toString();
|
|
11436
|
+
} catch {
|
|
11437
|
+
return String(rawUrl || '').trim().replace(/\/$/, '');
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
9371
11440
|
async function ensureNavigatedAndLoaded(client, urlToInspect, tabActor) {
|
|
9372
11441
|
if (!tabActor) throw new Error(browsers_lib_messages.R4W());
|
|
9373
11442
|
let consoleActor = tabActor;
|
|
@@ -9390,6 +11459,31 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9390
11459
|
console.warn('[RDP] attach(frameActor) failed:', String(err.message || err));
|
|
9391
11460
|
}
|
|
9392
11461
|
}
|
|
11462
|
+
try {
|
|
11463
|
+
const currentUrl = await client.evaluate(consoleActor, 'String(location.href || "")');
|
|
11464
|
+
const sameDocumentTarget = 'string' == typeof currentUrl && setup_firefox_inspection_navigation_normalizeInspectableUrl(currentUrl) === setup_firefox_inspection_navigation_normalizeInspectableUrl(urlToInspect);
|
|
11465
|
+
if (sameDocumentTarget) {
|
|
11466
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE || '1' === process.env.EXTENSION_DEBUG_FIREFOX_INSPECTION) console.log(`[RDP] forcing native same-url reload for ${urlToInspect}`);
|
|
11467
|
+
const detail = await client.getTargetFromDescriptor(tabActor);
|
|
11468
|
+
const targetActor = detail.targetActor || frameActor || tabActor;
|
|
11469
|
+
try {
|
|
11470
|
+
await client.attach(targetActor);
|
|
11471
|
+
} catch (error) {
|
|
11472
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
11473
|
+
const err = error;
|
|
11474
|
+
console.warn('[RDP] attach(targetActor for same-url reload) failed:', String(err.message || err));
|
|
11475
|
+
}
|
|
11476
|
+
}
|
|
11477
|
+
await client.navigate(targetActor, urlToInspect);
|
|
11478
|
+
await client.waitForLoadEvent(targetActor);
|
|
11479
|
+
return;
|
|
11480
|
+
}
|
|
11481
|
+
} catch (error) {
|
|
11482
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
11483
|
+
const err = error;
|
|
11484
|
+
console.warn('[RDP] current URL check before navigate failed:', String(err.message || err));
|
|
11485
|
+
}
|
|
11486
|
+
}
|
|
9393
11487
|
try {
|
|
9394
11488
|
await client.navigateViaScript(consoleActor, urlToInspect);
|
|
9395
11489
|
await client.waitForPageReady(consoleActor, urlToInspect, PAGE_READY_TIMEOUT_MS);
|
|
@@ -9658,6 +11752,10 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9658
11752
|
}
|
|
9659
11753
|
})()`);
|
|
9660
11754
|
this.emitEventPayload('page_meta', stage, meta, metaSnapshot || {});
|
|
11755
|
+
const rootMeta = await this.getExtensionRootMeta();
|
|
11756
|
+
if (rootMeta) this.emitEventPayload('extension_root_meta', stage, meta, rootMeta);
|
|
11757
|
+
const styleSnapshot = await this.getShadowStyleSnapshot();
|
|
11758
|
+
if (styleSnapshot) this.emitEventPayload('shadow_style_output', stage, meta, styleSnapshot);
|
|
9661
11759
|
}
|
|
9662
11760
|
if (Array.isArray(this.devOptions?.sourceProbe)) {
|
|
9663
11761
|
const probes = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
@@ -9692,7 +11790,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9692
11790
|
}
|
|
9693
11791
|
if (this.devOptions?.sourceTree && 'off' !== this.devOptions.sourceTree) {
|
|
9694
11792
|
const tree = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
9695
|
-
const rootEl = document.querySelector('#extension-root,[data-extension-root="
|
|
11793
|
+
const rootEl = document.querySelector('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])');
|
|
9696
11794
|
if (!rootEl) return null;
|
|
9697
11795
|
const root = (${'off' !== this.devOptions.sourceIncludeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
9698
11796
|
const maxDepth = 4;
|
|
@@ -9773,11 +11871,238 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9773
11871
|
if ('string' == typeof json && json.length > 0) return JSON.parse(json);
|
|
9774
11872
|
} catch {}
|
|
9775
11873
|
}
|
|
11874
|
+
async evaluateString(actor, expression) {
|
|
11875
|
+
if (!this.client) return;
|
|
11876
|
+
try {
|
|
11877
|
+
const response = await this.client.evaluateRaw(actor, expression);
|
|
11878
|
+
const value = await (0, evaluate.vA)(this.client, actor, response, {
|
|
11879
|
+
fallbackToFullDocument: false
|
|
11880
|
+
});
|
|
11881
|
+
return 'string' == typeof value ? value : String(value || '');
|
|
11882
|
+
} catch {
|
|
11883
|
+
return;
|
|
11884
|
+
}
|
|
11885
|
+
}
|
|
11886
|
+
async getShadowStyleSnapshot() {
|
|
11887
|
+
if (!this.client || !this.currentConsoleActor) return;
|
|
11888
|
+
try {
|
|
11889
|
+
const count = await this.client.evaluate(this.currentConsoleActor, `(() => {
|
|
11890
|
+
try {
|
|
11891
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
11892
|
+
for (const host of hosts) {
|
|
11893
|
+
const sr = host && host.shadowRoot;
|
|
11894
|
+
if (!sr) continue;
|
|
11895
|
+
const childStyleCount = Array.from(sr.childNodes || []).filter((node) => {
|
|
11896
|
+
try {
|
|
11897
|
+
return (
|
|
11898
|
+
node &&
|
|
11899
|
+
node.nodeType === 1 &&
|
|
11900
|
+
String(node.nodeName || '').toLowerCase() === 'style'
|
|
11901
|
+
)
|
|
11902
|
+
} catch {
|
|
11903
|
+
return false
|
|
11904
|
+
}
|
|
11905
|
+
}).length
|
|
11906
|
+
if (childStyleCount > 0) return childStyleCount
|
|
11907
|
+
return Array.from(sr.querySelectorAll('style')).length;
|
|
11908
|
+
}
|
|
11909
|
+
return 0;
|
|
11910
|
+
} catch {
|
|
11911
|
+
return 0;
|
|
11912
|
+
}
|
|
11913
|
+
})()`);
|
|
11914
|
+
const totalCount = Number(count || 0);
|
|
11915
|
+
const childNodeCss = await this.evaluateString(this.currentConsoleActor, `(() => {
|
|
11916
|
+
try {
|
|
11917
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
11918
|
+
for (const host of hosts) {
|
|
11919
|
+
const sr = host && host.shadowRoot;
|
|
11920
|
+
if (!sr) continue;
|
|
11921
|
+
const css = Array.from(sr.childNodes || [])
|
|
11922
|
+
.map((node) => {
|
|
11923
|
+
try {
|
|
11924
|
+
if (!node || node.nodeType !== 1) return '';
|
|
11925
|
+
if (String(node.nodeName || '').toLowerCase() !== 'style') return '';
|
|
11926
|
+
return String(node.textContent || '');
|
|
11927
|
+
} catch {
|
|
11928
|
+
return '';
|
|
11929
|
+
}
|
|
11930
|
+
})
|
|
11931
|
+
.filter(Boolean)
|
|
11932
|
+
.join('\\n');
|
|
11933
|
+
return css;
|
|
11934
|
+
}
|
|
11935
|
+
return '';
|
|
11936
|
+
} catch {
|
|
11937
|
+
return '';
|
|
11938
|
+
}
|
|
11939
|
+
})()`);
|
|
11940
|
+
const adoptedCss = await this.evaluateString(this.currentConsoleActor, `(() => {
|
|
11941
|
+
try {
|
|
11942
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
11943
|
+
for (const host of hosts) {
|
|
11944
|
+
const sr = host && host.shadowRoot;
|
|
11945
|
+
if (!sr) continue;
|
|
11946
|
+
const sheets = Array.from(sr.adoptedStyleSheets || []);
|
|
11947
|
+
const css = sheets
|
|
11948
|
+
.map((sheet) => {
|
|
11949
|
+
try {
|
|
11950
|
+
return Array.from(sheet.cssRules || [])
|
|
11951
|
+
.map((rule) => String(rule.cssText || ''))
|
|
11952
|
+
.join('\\n');
|
|
11953
|
+
} catch {
|
|
11954
|
+
return '';
|
|
11955
|
+
}
|
|
11956
|
+
})
|
|
11957
|
+
.filter(Boolean)
|
|
11958
|
+
.join('\\n');
|
|
11959
|
+
return css;
|
|
11960
|
+
}
|
|
11961
|
+
return '';
|
|
11962
|
+
} catch {
|
|
11963
|
+
return '';
|
|
11964
|
+
}
|
|
11965
|
+
})()`);
|
|
11966
|
+
const stylesheetCss = await this.evaluateString(this.currentConsoleActor, `(() => {
|
|
11967
|
+
try {
|
|
11968
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
11969
|
+
for (const host of hosts) {
|
|
11970
|
+
const sr = host && host.shadowRoot;
|
|
11971
|
+
if (!sr) continue;
|
|
11972
|
+
const sheets = Array.from(sr.styleSheets || []);
|
|
11973
|
+
const css = sheets
|
|
11974
|
+
.map((sheet) => {
|
|
11975
|
+
try {
|
|
11976
|
+
return Array.from(sheet.cssRules || [])
|
|
11977
|
+
.map((rule) => String(rule.cssText || ''))
|
|
11978
|
+
.join('\\n');
|
|
11979
|
+
} catch {
|
|
11980
|
+
return '';
|
|
11981
|
+
}
|
|
11982
|
+
})
|
|
11983
|
+
.filter(Boolean)
|
|
11984
|
+
.join('\\n');
|
|
11985
|
+
return css;
|
|
11986
|
+
}
|
|
11987
|
+
return '';
|
|
11988
|
+
} catch {
|
|
11989
|
+
return '';
|
|
11990
|
+
}
|
|
11991
|
+
})()`);
|
|
11992
|
+
if ((!Number.isFinite(totalCount) || totalCount <= 0) && !('string' == typeof childNodeCss && childNodeCss.trim().length > 0) && !('string' == typeof adoptedCss && adoptedCss.trim().length > 0) && !('string' == typeof stylesheetCss && stylesheetCss.trim().length > 0)) return;
|
|
11993
|
+
if ('string' == typeof childNodeCss && childNodeCss.trim().length > 0) return {
|
|
11994
|
+
rootMode: 'shadow',
|
|
11995
|
+
count: totalCount > 0 ? totalCount : 1,
|
|
11996
|
+
styles: [
|
|
11997
|
+
{
|
|
11998
|
+
html: `<style>${childNodeCss}</style>`,
|
|
11999
|
+
textLength: childNodeCss.length,
|
|
12000
|
+
textSnippet: childNodeCss.trim().slice(0, 200)
|
|
12001
|
+
}
|
|
12002
|
+
]
|
|
12003
|
+
};
|
|
12004
|
+
if ('string' == typeof adoptedCss && adoptedCss.trim().length > 0) return {
|
|
12005
|
+
rootMode: 'shadow',
|
|
12006
|
+
count: totalCount > 0 ? totalCount : 1,
|
|
12007
|
+
styles: [
|
|
12008
|
+
{
|
|
12009
|
+
html: `<style>${adoptedCss}</style>`,
|
|
12010
|
+
textLength: adoptedCss.length,
|
|
12011
|
+
textSnippet: adoptedCss.trim().slice(0, 200)
|
|
12012
|
+
}
|
|
12013
|
+
]
|
|
12014
|
+
};
|
|
12015
|
+
if ('string' == typeof stylesheetCss && stylesheetCss.trim().length > 0) return {
|
|
12016
|
+
rootMode: 'shadow',
|
|
12017
|
+
count: totalCount > 0 ? totalCount : 1,
|
|
12018
|
+
styles: [
|
|
12019
|
+
{
|
|
12020
|
+
html: `<style>${stylesheetCss}</style>`,
|
|
12021
|
+
textLength: stylesheetCss.length,
|
|
12022
|
+
textSnippet: stylesheetCss.trim().slice(0, 200)
|
|
12023
|
+
}
|
|
12024
|
+
]
|
|
12025
|
+
};
|
|
12026
|
+
const shadowHtml = await this.evaluateString(this.currentConsoleActor, `(() => {
|
|
12027
|
+
try {
|
|
12028
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
12029
|
+
for (const host of hosts) {
|
|
12030
|
+
const sr = host && host.shadowRoot;
|
|
12031
|
+
if (!sr) continue;
|
|
12032
|
+
return String(sr.innerHTML || '');
|
|
12033
|
+
}
|
|
12034
|
+
return '';
|
|
12035
|
+
} catch {
|
|
12036
|
+
return '';
|
|
12037
|
+
}
|
|
12038
|
+
})()`);
|
|
12039
|
+
if ('string' == typeof shadowHtml && shadowHtml.includes('<style')) {
|
|
12040
|
+
const matches = Array.from(shadowHtml.matchAll(/<style[\s\S]*?<\/style>/g)).slice(0, 3);
|
|
12041
|
+
if (matches.length > 0) return {
|
|
12042
|
+
rootMode: 'shadow',
|
|
12043
|
+
count: totalCount,
|
|
12044
|
+
styles: matches.map((match)=>{
|
|
12045
|
+
const html = String(match[0] || '');
|
|
12046
|
+
const text = html.replace(/<style[^>]*>|<\/style>/g, '');
|
|
12047
|
+
return {
|
|
12048
|
+
html,
|
|
12049
|
+
textLength: text.length,
|
|
12050
|
+
textSnippet: text.trim().slice(0, 200)
|
|
12051
|
+
};
|
|
12052
|
+
})
|
|
12053
|
+
};
|
|
12054
|
+
}
|
|
12055
|
+
const styles = [];
|
|
12056
|
+
const sampleCount = Math.min(totalCount, 3);
|
|
12057
|
+
for(let index = 0; index < sampleCount; index++){
|
|
12058
|
+
const selectStyleExpression = `(() => {
|
|
12059
|
+
try {
|
|
12060
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
12061
|
+
for (const host of hosts) {
|
|
12062
|
+
const sr = host && host.shadowRoot;
|
|
12063
|
+
if (!sr) continue;
|
|
12064
|
+
const styleEl = Array.from(sr.querySelectorAll('style'))[${index}];
|
|
12065
|
+
if (!styleEl) return null;
|
|
12066
|
+
return styleEl;
|
|
12067
|
+
}
|
|
12068
|
+
return null;
|
|
12069
|
+
} catch {
|
|
12070
|
+
return null;
|
|
12071
|
+
}
|
|
12072
|
+
})()`;
|
|
12073
|
+
const html = await this.evaluateString(this.currentConsoleActor, `(() => {
|
|
12074
|
+
const styleEl = ${selectStyleExpression};
|
|
12075
|
+
return styleEl ? String(styleEl.outerHTML || '') : '';
|
|
12076
|
+
})()`);
|
|
12077
|
+
const textLength = await this.client.evaluate(this.currentConsoleActor, `(() => {
|
|
12078
|
+
const styleEl = ${selectStyleExpression};
|
|
12079
|
+
return styleEl ? String(styleEl.textContent || '').length : 0;
|
|
12080
|
+
})()`);
|
|
12081
|
+
const textSnippet = await this.evaluateString(this.currentConsoleActor, `(() => {
|
|
12082
|
+
const styleEl = ${selectStyleExpression};
|
|
12083
|
+
return styleEl ? String(styleEl.textContent || '').trim().slice(0, 200) : '';
|
|
12084
|
+
})()`);
|
|
12085
|
+
if ('string' == typeof html && html.length > 0) styles.push({
|
|
12086
|
+
html,
|
|
12087
|
+
textLength: Number(textLength || 0),
|
|
12088
|
+
textSnippet: 'string' == typeof textSnippet ? textSnippet : String(textSnippet || '')
|
|
12089
|
+
});
|
|
12090
|
+
}
|
|
12091
|
+
if (0 === styles.length) return;
|
|
12092
|
+
return {
|
|
12093
|
+
rootMode: 'shadow',
|
|
12094
|
+
count: totalCount,
|
|
12095
|
+
styles
|
|
12096
|
+
};
|
|
12097
|
+
} catch {
|
|
12098
|
+
return;
|
|
12099
|
+
}
|
|
12100
|
+
}
|
|
9776
12101
|
async getDomSnapshot() {
|
|
9777
12102
|
if (!this.client || !this.currentConsoleActor) return;
|
|
9778
12103
|
const includeShadow = this.devOptions?.sourceIncludeShadow !== 'off';
|
|
9779
12104
|
const payload = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
9780
|
-
const rootEl = document.querySelector('#extension-root,[data-extension-root="
|
|
12105
|
+
const rootEl = document.querySelector('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])');
|
|
9781
12106
|
if (!rootEl) return null;
|
|
9782
12107
|
const root = (${includeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
9783
12108
|
const maxDepth = 6;
|
|
@@ -9837,6 +12162,173 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9837
12162
|
truncated,
|
|
9838
12163
|
nodes
|
|
9839
12164
|
};
|
|
12165
|
+
})()`);
|
|
12166
|
+
if (payload && 'object' == typeof payload) return payload;
|
|
12167
|
+
}
|
|
12168
|
+
async getExtensionRootMeta() {
|
|
12169
|
+
if (!this.client || !this.currentConsoleActor) return;
|
|
12170
|
+
const payload = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
12171
|
+
const readGeneration = (node) => {
|
|
12172
|
+
try {
|
|
12173
|
+
const raw = node && node.getAttribute
|
|
12174
|
+
? node.getAttribute('data-extjs-reinject-generation')
|
|
12175
|
+
: '';
|
|
12176
|
+
if (typeof raw !== 'string' || raw.trim() === '') return undefined;
|
|
12177
|
+
const parsed = Number(raw);
|
|
12178
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
12179
|
+
} catch (error) {
|
|
12180
|
+
return undefined;
|
|
12181
|
+
}
|
|
12182
|
+
};
|
|
12183
|
+
const readRegistryGeneration = (entry) => {
|
|
12184
|
+
try {
|
|
12185
|
+
if (!entry) return undefined;
|
|
12186
|
+
if (typeof entry === 'function' && typeof entry.__extjsGeneration === 'number') {
|
|
12187
|
+
return entry.__extjsGeneration;
|
|
12188
|
+
}
|
|
12189
|
+
if (typeof entry === 'object') {
|
|
12190
|
+
if (typeof entry.__extjsGeneration === 'number') return entry.__extjsGeneration;
|
|
12191
|
+
if (typeof entry.generation === 'number') return entry.generation;
|
|
12192
|
+
if (typeof entry.cleanup === 'function' && typeof entry.cleanup.__extjsGeneration === 'number') {
|
|
12193
|
+
return entry.cleanup.__extjsGeneration;
|
|
12194
|
+
}
|
|
12195
|
+
}
|
|
12196
|
+
} catch (error) {
|
|
12197
|
+
return undefined;
|
|
12198
|
+
}
|
|
12199
|
+
return undefined;
|
|
12200
|
+
};
|
|
12201
|
+
const normalize = (node) => ({
|
|
12202
|
+
tag: node && node.tagName ? String(node.tagName).toLowerCase() : 'unknown',
|
|
12203
|
+
id: node && node.id ? String(node.id) : undefined,
|
|
12204
|
+
key: node && node.getAttribute ? node.getAttribute('data-extjs-reinject-key') || undefined : undefined,
|
|
12205
|
+
generation: readGeneration(node),
|
|
12206
|
+
status: node && node.getAttribute ? node.getAttribute('data-extjs-reinject-status') || undefined : undefined,
|
|
12207
|
+
build: node && node.getAttribute ? node.getAttribute('data-extjs-reinject-build') || undefined : undefined
|
|
12208
|
+
});
|
|
12209
|
+
const roots = Array.from(
|
|
12210
|
+
document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])')
|
|
12211
|
+
)
|
|
12212
|
+
.slice(0, 10)
|
|
12213
|
+
.map(normalize);
|
|
12214
|
+
const page = (() => {
|
|
12215
|
+
try {
|
|
12216
|
+
const node = document.documentElement;
|
|
12217
|
+
if (!node || typeof node.getAttribute !== 'function') return undefined;
|
|
12218
|
+
const raw = node.getAttribute('data-extjs-last-reinject-generation');
|
|
12219
|
+
const generation =
|
|
12220
|
+
typeof raw === 'string' && raw.trim() !== '' && Number.isFinite(Number(raw))
|
|
12221
|
+
? Number(raw)
|
|
12222
|
+
: undefined;
|
|
12223
|
+
return {
|
|
12224
|
+
key: node.getAttribute('data-extjs-last-reinject-key') || undefined,
|
|
12225
|
+
generation,
|
|
12226
|
+
status: node.getAttribute('data-extjs-last-reinject-status') || undefined,
|
|
12227
|
+
build: node.getAttribute('data-extjs-last-reinject-build') || undefined
|
|
12228
|
+
};
|
|
12229
|
+
} catch (error) {
|
|
12230
|
+
return undefined;
|
|
12231
|
+
}
|
|
12232
|
+
})();
|
|
12233
|
+
const debug = (() => {
|
|
12234
|
+
try {
|
|
12235
|
+
const node = document.documentElement;
|
|
12236
|
+
if (!node || typeof node.getAttribute !== 'function') return undefined;
|
|
12237
|
+
const parseMaybeNumber = (raw) =>
|
|
12238
|
+
typeof raw === 'string' && raw.trim() !== '' && Number.isFinite(Number(raw))
|
|
12239
|
+
? Number(raw)
|
|
12240
|
+
: undefined;
|
|
12241
|
+
return {
|
|
12242
|
+
stage: node.getAttribute('data-extjs-debug-stage') || undefined,
|
|
12243
|
+
rootCount: parseMaybeNumber(node.getAttribute('data-extjs-debug-root-count')),
|
|
12244
|
+
ownedRootCount: parseMaybeNumber(
|
|
12245
|
+
node.getAttribute('data-extjs-debug-owned-root-count')
|
|
12246
|
+
),
|
|
12247
|
+
markerCount: parseMaybeNumber(
|
|
12248
|
+
node.getAttribute('data-extjs-debug-marker-count')
|
|
12249
|
+
),
|
|
12250
|
+
lastRemoval:
|
|
12251
|
+
node.getAttribute('data-extjs-debug-last-removal') || undefined,
|
|
12252
|
+
lastRemovalSource:
|
|
12253
|
+
node.getAttribute('data-extjs-debug-last-removal-source') ||
|
|
12254
|
+
undefined,
|
|
12255
|
+
lastRemovalKey:
|
|
12256
|
+
node.getAttribute('data-extjs-debug-last-removal-key') ||
|
|
12257
|
+
undefined,
|
|
12258
|
+
lastRemovedNodeTag:
|
|
12259
|
+
node.getAttribute('data-extjs-debug-last-removed-node-tag') ||
|
|
12260
|
+
undefined,
|
|
12261
|
+
lastRemovedNodeId:
|
|
12262
|
+
node.getAttribute('data-extjs-debug-last-removed-node-id') ||
|
|
12263
|
+
undefined,
|
|
12264
|
+
lastRemovedNodeClass:
|
|
12265
|
+
node.getAttribute('data-extjs-debug-last-removed-node-class') ||
|
|
12266
|
+
undefined,
|
|
12267
|
+
lastRemovedNodeDirect:
|
|
12268
|
+
node.getAttribute('data-extjs-debug-last-removed-node-direct') ||
|
|
12269
|
+
undefined,
|
|
12270
|
+
lastRemovalReadyState:
|
|
12271
|
+
node.getAttribute('data-extjs-debug-last-removal-ready-state') ||
|
|
12272
|
+
undefined,
|
|
12273
|
+
lastRemovalUrl:
|
|
12274
|
+
node.getAttribute('data-extjs-debug-last-removal-url') ||
|
|
12275
|
+
undefined,
|
|
12276
|
+
lastRemovalParentTag:
|
|
12277
|
+
node.getAttribute('data-extjs-debug-last-removal-parent-tag') ||
|
|
12278
|
+
undefined,
|
|
12279
|
+
executionCount: parseMaybeNumber(
|
|
12280
|
+
node.getAttribute('data-extjs-debug-execution-count')
|
|
12281
|
+
),
|
|
12282
|
+
lastExecutionStage:
|
|
12283
|
+
node.getAttribute('data-extjs-debug-last-execution-stage') ||
|
|
12284
|
+
undefined,
|
|
12285
|
+
lastExecutionKey:
|
|
12286
|
+
node.getAttribute('data-extjs-debug-last-execution-key') ||
|
|
12287
|
+
undefined,
|
|
12288
|
+
existingRootCountBeforeCleanup: parseMaybeNumber(
|
|
12289
|
+
node.getAttribute(
|
|
12290
|
+
'data-extjs-debug-existing-root-count-before-cleanup'
|
|
12291
|
+
)
|
|
12292
|
+
)
|
|
12293
|
+
};
|
|
12294
|
+
} catch (error) {
|
|
12295
|
+
return undefined;
|
|
12296
|
+
}
|
|
12297
|
+
})();
|
|
12298
|
+
const markers = Array.from(
|
|
12299
|
+
document.querySelectorAll('[data-extjs-reinject-marker="true"]')
|
|
12300
|
+
)
|
|
12301
|
+
.slice(0, 10)
|
|
12302
|
+
.map(normalize);
|
|
12303
|
+
const registry = (typeof globalThis === 'object' && globalThis && globalThis.__EXTENSIONJS_DEV_REINJECT__)
|
|
12304
|
+
? globalThis.__EXTENSIONJS_DEV_REINJECT__
|
|
12305
|
+
: {};
|
|
12306
|
+
const registries = Object.entries(registry || {})
|
|
12307
|
+
.slice(0, 20)
|
|
12308
|
+
.map(([key, entry]) => ({
|
|
12309
|
+
key,
|
|
12310
|
+
generation: readRegistryGeneration(entry),
|
|
12311
|
+
hasCleanup:
|
|
12312
|
+
typeof entry === 'function' ||
|
|
12313
|
+
!!(entry && typeof entry === 'object' && typeof entry.cleanup === 'function')
|
|
12314
|
+
}));
|
|
12315
|
+
const generations = roots
|
|
12316
|
+
.concat(markers)
|
|
12317
|
+
.map((entry) => entry.generation)
|
|
12318
|
+
.concat(typeof page?.generation === 'number' ? [page.generation] : [])
|
|
12319
|
+
.concat(registries.map((entry) => entry.generation))
|
|
12320
|
+
.filter((value) => typeof value === 'number');
|
|
12321
|
+
return {
|
|
12322
|
+
rootCount: roots.length,
|
|
12323
|
+
markerCount: markers.length,
|
|
12324
|
+
registryCount: registries.length,
|
|
12325
|
+
latestGeneration: generations.length ? Math.max(...generations) : 0,
|
|
12326
|
+
debug,
|
|
12327
|
+
page,
|
|
12328
|
+
roots,
|
|
12329
|
+
markers,
|
|
12330
|
+
registries
|
|
12331
|
+
};
|
|
9840
12332
|
})()`);
|
|
9841
12333
|
if (payload && 'object' == typeof payload) return payload;
|
|
9842
12334
|
}
|
|
@@ -9884,7 +12376,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9884
12376
|
await client.connect(port);
|
|
9885
12377
|
this.client = client;
|
|
9886
12378
|
this.setupConsoleCapture();
|
|
9887
|
-
if (this.devOptions?.sourceConsole) await (0,
|
|
12379
|
+
if (this.devOptions?.sourceConsole) await (0, remote_firefox_logging.c)(client);
|
|
9888
12380
|
this.initialized = true;
|
|
9889
12381
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
9890
12382
|
console.log(browsers_lib_messages.X6h());
|
|
@@ -9951,6 +12443,9 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9951
12443
|
const currentTitle = await this.client.evaluate(actorToUse, 'String(document.title)');
|
|
9952
12444
|
if ('string' == typeof currentTitle) meta.title = currentTitle;
|
|
9953
12445
|
} catch {}
|
|
12446
|
+
try {
|
|
12447
|
+
await this.waitForContentScriptStyles(actorToUse);
|
|
12448
|
+
} catch {}
|
|
9954
12449
|
const html = await (0, source_inspect.Lj)(this.client, descriptor, actorToUse) || '';
|
|
9955
12450
|
this.emitSourceOutput(html, 'post_injection', meta);
|
|
9956
12451
|
return;
|
|
@@ -9963,7 +12458,112 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9963
12458
|
}
|
|
9964
12459
|
async waitForContentScriptInjection(consoleActor) {
|
|
9965
12460
|
if (!this.client) return;
|
|
9966
|
-
await (0, source_inspect.NQ)(this.client, consoleActor);
|
|
12461
|
+
return await (0, source_inspect.NQ)(this.client, consoleActor);
|
|
12462
|
+
}
|
|
12463
|
+
async hasVisibleShadowHostContentFirefox() {
|
|
12464
|
+
if (!this.client || !this.currentConsoleActor) return false;
|
|
12465
|
+
try {
|
|
12466
|
+
const v = await this.client.evaluate(this.currentConsoleActor, `(() => { try {
|
|
12467
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
12468
|
+
for (const h of hosts) {
|
|
12469
|
+
const sr = h && h.shadowRoot;
|
|
12470
|
+
if (sr && String(sr.innerHTML || '').trim().length > 0) return true;
|
|
12471
|
+
}
|
|
12472
|
+
return false;
|
|
12473
|
+
} catch { return false } })()`);
|
|
12474
|
+
return Boolean(v);
|
|
12475
|
+
} catch {
|
|
12476
|
+
return false;
|
|
12477
|
+
}
|
|
12478
|
+
}
|
|
12479
|
+
async shouldEmitFirefoxContentScriptInjected(injectionWaitOk) {
|
|
12480
|
+
if (!injectionWaitOk || !this.client || !this.currentConsoleActor) return false;
|
|
12481
|
+
const deadline = Date.now() + 2800;
|
|
12482
|
+
while(Date.now() < deadline){
|
|
12483
|
+
const rootMeta = await this.getExtensionRootMeta();
|
|
12484
|
+
const shadow = await this.getShadowStyleSnapshot();
|
|
12485
|
+
if (rootMeta && rootMeta.rootCount >= 1) return true;
|
|
12486
|
+
if (shadow && 'number' == typeof shadow.count && Number(shadow.count) > 0) return true;
|
|
12487
|
+
await new Promise((r)=>setTimeout(r, 200));
|
|
12488
|
+
}
|
|
12489
|
+
return this.hasVisibleShadowHostContentFirefox();
|
|
12490
|
+
}
|
|
12491
|
+
async reopenTabAndResolveActors(urlToInspect) {
|
|
12492
|
+
if (!this.client) return null;
|
|
12493
|
+
try {
|
|
12494
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE || '1' === process.env.EXTENSION_DEBUG_FIREFOX_INSPECTION) console.log(`[RDP] source inspection reopening fresh tab for ${String(urlToInspect)}`);
|
|
12495
|
+
await this.client.addTab(urlToInspect);
|
|
12496
|
+
await wait(300);
|
|
12497
|
+
const { tabActor, consoleActor } = await this.selectActors(urlToInspect);
|
|
12498
|
+
this.currentTabActor = tabActor;
|
|
12499
|
+
const resolvedConsoleActor = await this.resolveConsoleActor(tabActor, urlToInspect);
|
|
12500
|
+
this.currentConsoleActor = resolvedConsoleActor || consoleActor;
|
|
12501
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE || '1' === process.env.EXTENSION_DEBUG_FIREFOX_INSPECTION) console.log(`[RDP] reopened tabActor=${String(tabActor)} consoleActor=${String(this.currentConsoleActor || '')}`);
|
|
12502
|
+
return {
|
|
12503
|
+
tabActor,
|
|
12504
|
+
consoleActor: this.currentConsoleActor
|
|
12505
|
+
};
|
|
12506
|
+
} catch {
|
|
12507
|
+
return null;
|
|
12508
|
+
}
|
|
12509
|
+
}
|
|
12510
|
+
async waitForContentScriptStyles(consoleActor) {
|
|
12511
|
+
if (!this.client) return;
|
|
12512
|
+
const deadline = Date.now() + 10000;
|
|
12513
|
+
while(Date.now() < deadline){
|
|
12514
|
+
try {
|
|
12515
|
+
const hasStyles = await this.client.evaluate(consoleActor, `(() => { try {
|
|
12516
|
+
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])'));
|
|
12517
|
+
if (!hosts.length) return false;
|
|
12518
|
+
for (const host of hosts) {
|
|
12519
|
+
const sr = host && host.shadowRoot;
|
|
12520
|
+
if (!sr) continue;
|
|
12521
|
+
const styles = Array.from(sr.querySelectorAll('style'));
|
|
12522
|
+
if (styles.some((styleEl) => String(styleEl.outerHTML || '').includes('<style') && String(styleEl.textContent || '').trim().length > 0)) {
|
|
12523
|
+
return true;
|
|
12524
|
+
}
|
|
12525
|
+
const childStyles = Array.from(sr.childNodes || []);
|
|
12526
|
+
if (childStyles.some((node) => {
|
|
12527
|
+
try {
|
|
12528
|
+
return (
|
|
12529
|
+
node &&
|
|
12530
|
+
node.nodeType === 1 &&
|
|
12531
|
+
String(node.nodeName || '').toLowerCase() === 'style' &&
|
|
12532
|
+
String(node.textContent || '').trim().length > 0
|
|
12533
|
+
);
|
|
12534
|
+
} catch {
|
|
12535
|
+
return false;
|
|
12536
|
+
}
|
|
12537
|
+
})) {
|
|
12538
|
+
return true;
|
|
12539
|
+
}
|
|
12540
|
+
const adoptedSheets = Array.from(sr.adoptedStyleSheets || []);
|
|
12541
|
+
if (adoptedSheets.some((sheet) => {
|
|
12542
|
+
try {
|
|
12543
|
+
return Array.from(sheet.cssRules || []).length > 0;
|
|
12544
|
+
} catch {
|
|
12545
|
+
return false;
|
|
12546
|
+
}
|
|
12547
|
+
})) {
|
|
12548
|
+
return true;
|
|
12549
|
+
}
|
|
12550
|
+
const styleSheets = Array.from(sr.styleSheets || []);
|
|
12551
|
+
if (styleSheets.some((sheet) => {
|
|
12552
|
+
try {
|
|
12553
|
+
return Array.from(sheet.cssRules || []).length > 0;
|
|
12554
|
+
} catch {
|
|
12555
|
+
return false;
|
|
12556
|
+
}
|
|
12557
|
+
})) {
|
|
12558
|
+
return true;
|
|
12559
|
+
}
|
|
12560
|
+
}
|
|
12561
|
+
return false;
|
|
12562
|
+
} catch { return false } })()`);
|
|
12563
|
+
if (hasStyles) return;
|
|
12564
|
+
} catch {}
|
|
12565
|
+
await wait(200);
|
|
12566
|
+
}
|
|
9967
12567
|
}
|
|
9968
12568
|
async handleFileChange() {
|
|
9969
12569
|
if (!this.client || !this.currentConsoleActor) return;
|
|
@@ -9977,6 +12577,9 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9977
12577
|
}
|
|
9978
12578
|
if (this.lastUrlToInspect) await this.ensureUrlAndReady(this.currentConsoleActor, this.lastUrlToInspect);
|
|
9979
12579
|
await this.waitForContentScriptInjection(this.currentConsoleActor);
|
|
12580
|
+
try {
|
|
12581
|
+
await this.waitForContentScriptStyles(this.currentConsoleActor);
|
|
12582
|
+
} catch {}
|
|
9980
12583
|
let lastError = null;
|
|
9981
12584
|
for(let attempt = 0; attempt < 3; attempt++){
|
|
9982
12585
|
try {
|
|
@@ -10002,6 +12605,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10002
12605
|
}
|
|
10003
12606
|
}, CHANGE_DEBOUNCE_MS);
|
|
10004
12607
|
}
|
|
12608
|
+
registerContentReloadSnapshotHook() {
|
|
12609
|
+
globalThis.__EXTJS_ON_FIREFOX_CONTENT_RELOADED__ = async ()=>{
|
|
12610
|
+
await this.handleFileChange();
|
|
12611
|
+
};
|
|
12612
|
+
}
|
|
10005
12613
|
apply(compiler) {
|
|
10006
12614
|
if (this.host.dryRun) return;
|
|
10007
12615
|
if ('development' !== compiler.options.mode) return;
|
|
@@ -10012,6 +12620,18 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10012
12620
|
if (!this.initialized) await this.initialize();
|
|
10013
12621
|
const urlToInspect = this.resolveUrlToInspect();
|
|
10014
12622
|
this.lastUrlToInspect = urlToInspect;
|
|
12623
|
+
const forceSourceReinspect = Boolean(this.host.__extjsForceSourceReinspect);
|
|
12624
|
+
if (forceSourceReinspect) {
|
|
12625
|
+
this.host.__extjsForceSourceReinspect = false;
|
|
12626
|
+
this.currentConsoleActor = null;
|
|
12627
|
+
this.currentTabActor = null;
|
|
12628
|
+
}
|
|
12629
|
+
if (this.devOptions?.watchSource && !forceSourceReinspect && this.isWatching && this.currentConsoleActor && this.currentTabActor) {
|
|
12630
|
+
if (globalThis.__EXTJS_PENDING_FIREFOX_CONTENT_RELOAD__) return void done();
|
|
12631
|
+
await this.handleFileChange();
|
|
12632
|
+
done();
|
|
12633
|
+
return;
|
|
12634
|
+
}
|
|
10015
12635
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(browsers_lib_messages.rCC(urlToInspect));
|
|
10016
12636
|
const { tabActor, consoleActor } = await this.selectActors(urlToInspect);
|
|
10017
12637
|
this.currentTabActor = tabActor;
|
|
@@ -10025,15 +12645,61 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10025
12645
|
const resolvedConsoleActor = await this.resolveConsoleActor(tabActor, urlToInspect);
|
|
10026
12646
|
this.currentConsoleActor = resolvedConsoleActor || consoleActor;
|
|
10027
12647
|
if (this.currentConsoleActor) {
|
|
10028
|
-
await this.waitForContentScriptInjection(this.currentConsoleActor);
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
12648
|
+
let injected = await this.waitForContentScriptInjection(this.currentConsoleActor);
|
|
12649
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE || '1' === process.env.EXTENSION_DEBUG_FIREFOX_INSPECTION) console.log(`[RDP] initial content-script wait result=${String(Boolean(injected))} actor=${String(this.currentConsoleActor)}`);
|
|
12650
|
+
if (!injected) {
|
|
12651
|
+
const reopened = await this.reopenTabAndResolveActors(urlToInspect);
|
|
12652
|
+
if (reopened?.consoleActor) {
|
|
12653
|
+
emitActionEvent('navigation_start', {
|
|
12654
|
+
url: urlToInspect
|
|
12655
|
+
});
|
|
12656
|
+
await this.ensureNavigatedAndLoaded(urlToInspect, reopened.tabActor);
|
|
12657
|
+
emitActionEvent('navigation_end', {
|
|
12658
|
+
url: urlToInspect
|
|
12659
|
+
});
|
|
12660
|
+
injected = await this.waitForContentScriptInjection(reopened.consoleActor);
|
|
12661
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE || '1' === process.env.EXTENSION_DEBUG_FIREFOX_INSPECTION) console.log(`[RDP] fresh-tab content-script wait result=${String(Boolean(injected))} actor=${String(reopened.consoleActor)}`);
|
|
12662
|
+
}
|
|
12663
|
+
}
|
|
12664
|
+
try {
|
|
12665
|
+
const actorHref = this.currentConsoleActor ? await this.client?.evaluate(this.currentConsoleActor, 'String(location.href || "")') : void 0;
|
|
12666
|
+
fetch('http://127.0.0.1:7795/ingest/9eb8f923-a325-4455-a46c-a6e706558307', {
|
|
12667
|
+
method: 'POST',
|
|
12668
|
+
headers: {
|
|
12669
|
+
'Content-Type': 'application/json',
|
|
12670
|
+
'X-Debug-Session-Id': 'a87efc'
|
|
12671
|
+
},
|
|
12672
|
+
body: JSON.stringify({
|
|
12673
|
+
sessionId: 'a87efc',
|
|
12674
|
+
runId: process.env.EXTENSION_INSTANCE_ID || 'firefox-source-inspection',
|
|
12675
|
+
hypothesisId: 'H4',
|
|
12676
|
+
location: "firefox-source-inspection/index.ts:before-content-script-event",
|
|
12677
|
+
message: "Firefox content-script event boundary",
|
|
12678
|
+
data: {
|
|
12679
|
+
urlToInspect,
|
|
12680
|
+
currentTabActor: this.currentTabActor,
|
|
12681
|
+
currentConsoleActor: this.currentConsoleActor,
|
|
12682
|
+
injected,
|
|
12683
|
+
actorHref
|
|
12684
|
+
},
|
|
12685
|
+
timestamp: Date.now()
|
|
12686
|
+
})
|
|
12687
|
+
}).catch(()=>{});
|
|
12688
|
+
} catch {}
|
|
12689
|
+
if (injected) {
|
|
12690
|
+
const emitOk = await this.shouldEmitFirefoxContentScriptInjected(injected);
|
|
12691
|
+
if (emitOk) emitActionEvent("content_script_injected", {
|
|
12692
|
+
url: urlToInspect
|
|
12693
|
+
});
|
|
12694
|
+
}
|
|
12695
|
+
try {
|
|
12696
|
+
await this.waitForContentScriptStyles(this.currentConsoleActor);
|
|
12697
|
+
} catch {}
|
|
10032
12698
|
await this.printHTML(this.currentConsoleActor);
|
|
10033
12699
|
}
|
|
10034
12700
|
if (this.devOptions?.watchSource) {
|
|
12701
|
+
this.registerContentReloadSnapshotHook();
|
|
10035
12702
|
this.isWatching = true;
|
|
10036
|
-
await this.handleFileChange();
|
|
10037
12703
|
}
|
|
10038
12704
|
} catch (error) {
|
|
10039
12705
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.error(browsers_lib_messages.b82(error.message));
|
|
@@ -10102,8 +12768,6 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10102
12768
|
run_firefox_define_property(this, "geckoBinary", void 0);
|
|
10103
12769
|
run_firefox_define_property(this, "port", void 0);
|
|
10104
12770
|
run_firefox_define_property(this, "instanceId", void 0);
|
|
10105
|
-
run_firefox_define_property(this, "keepProfileChanges", void 0);
|
|
10106
|
-
run_firefox_define_property(this, "copyFromProfile", void 0);
|
|
10107
12771
|
run_firefox_define_property(this, "source", void 0);
|
|
10108
12772
|
run_firefox_define_property(this, "watchSource", void 0);
|
|
10109
12773
|
run_firefox_define_property(this, "sourceFormat", void 0);
|
|
@@ -10128,38 +12792,8 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10128
12792
|
run_firefox_define_property(this, "logger", void 0);
|
|
10129
12793
|
run_firefox_define_property(this, "firefoxCtx", void 0);
|
|
10130
12794
|
run_firefox_define_property(this, "rdpController", void 0);
|
|
10131
|
-
this
|
|
10132
|
-
this.browser = options.browser;
|
|
10133
|
-
this.startingUrl = options.startingUrl;
|
|
10134
|
-
this.preferences = options.preferences;
|
|
10135
|
-
this.profile = options.profile;
|
|
10136
|
-
this.browserFlags = options.browserFlags;
|
|
10137
|
-
this.excludeBrowserFlags = options.excludeBrowserFlags;
|
|
10138
|
-
this.noOpen = options.noOpen;
|
|
12795
|
+
Object.assign(this, (0, runtime_options.pA)(options));
|
|
10139
12796
|
this.geckoBinary = options.geckoBinary;
|
|
10140
|
-
this.instanceId = options.instanceId;
|
|
10141
|
-
this.port = options.port;
|
|
10142
|
-
this.source = options.source;
|
|
10143
|
-
this.watchSource = options.watchSource;
|
|
10144
|
-
this.sourceFormat = options.sourceFormat;
|
|
10145
|
-
this.sourceSummary = options.sourceSummary;
|
|
10146
|
-
this.sourceMeta = options.sourceMeta;
|
|
10147
|
-
this.sourceProbe = options.sourceProbe;
|
|
10148
|
-
this.sourceTree = options.sourceTree;
|
|
10149
|
-
this.sourceConsole = options.sourceConsole;
|
|
10150
|
-
this.sourceDom = options.sourceDom;
|
|
10151
|
-
this.sourceMaxBytes = options.sourceMaxBytes;
|
|
10152
|
-
this.sourceRedact = options.sourceRedact;
|
|
10153
|
-
this.sourceIncludeShadow = options.sourceIncludeShadow;
|
|
10154
|
-
this.sourceDiff = options.sourceDiff;
|
|
10155
|
-
this.logLevel = options.logLevel;
|
|
10156
|
-
this.logContexts = options.logContexts;
|
|
10157
|
-
this.logFormat = options.logFormat;
|
|
10158
|
-
this.logTimestamps = options.logTimestamps;
|
|
10159
|
-
this.logColor = options.logColor;
|
|
10160
|
-
this.logUrl = options.logUrl;
|
|
10161
|
-
this.logTab = options.logTab;
|
|
10162
|
-
this.dryRun = options.dryRun;
|
|
10163
12797
|
}
|
|
10164
12798
|
}
|
|
10165
12799
|
function plugin_browsers_define_property(obj, key, value) {
|
|
@@ -10224,39 +12858,9 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10224
12858
|
plugin_browsers_define_property(this, "logUrl", void 0);
|
|
10225
12859
|
plugin_browsers_define_property(this, "logTab", void 0);
|
|
10226
12860
|
const normalized = normalizePluginOptions(options);
|
|
10227
|
-
this
|
|
10228
|
-
this.browser = normalized.browser;
|
|
10229
|
-
this.startingUrl = normalized.startingUrl;
|
|
10230
|
-
this.preferences = normalized.preferences;
|
|
10231
|
-
this.profile = normalized.profile;
|
|
10232
|
-
this.browserFlags = normalized.browserFlags;
|
|
10233
|
-
this.excludeBrowserFlags = normalized.excludeBrowserFlags;
|
|
10234
|
-
this.noOpen = normalized.noOpen;
|
|
12861
|
+
Object.assign(this, (0, runtime_options.pA)(normalized));
|
|
10235
12862
|
this.chromiumBinary = normalized.chromiumBinary;
|
|
10236
12863
|
this.geckoBinary = normalized.geckoBinary;
|
|
10237
|
-
this.instanceId = normalized.instanceId;
|
|
10238
|
-
this.port = normalized.port;
|
|
10239
|
-
this.source = normalized.source;
|
|
10240
|
-
this.watchSource = normalized.watchSource;
|
|
10241
|
-
this.sourceFormat = normalized.sourceFormat;
|
|
10242
|
-
this.sourceSummary = normalized.sourceSummary;
|
|
10243
|
-
this.sourceMeta = normalized.sourceMeta;
|
|
10244
|
-
this.sourceProbe = normalized.sourceProbe;
|
|
10245
|
-
this.sourceTree = normalized.sourceTree;
|
|
10246
|
-
this.sourceConsole = normalized.sourceConsole;
|
|
10247
|
-
this.sourceDom = normalized.sourceDom;
|
|
10248
|
-
this.sourceMaxBytes = normalized.sourceMaxBytes;
|
|
10249
|
-
this.sourceRedact = normalized.sourceRedact;
|
|
10250
|
-
this.sourceIncludeShadow = normalized.sourceIncludeShadow;
|
|
10251
|
-
this.sourceDiff = normalized.sourceDiff;
|
|
10252
|
-
this.logLevel = normalized.logLevel;
|
|
10253
|
-
this.logContexts = normalized.logContexts;
|
|
10254
|
-
this.logFormat = normalized.logFormat;
|
|
10255
|
-
this.logTimestamps = normalized.logTimestamps;
|
|
10256
|
-
this.logColor = normalized.logColor;
|
|
10257
|
-
this.logUrl = normalized.logUrl;
|
|
10258
|
-
this.logTab = normalized.logTab;
|
|
10259
|
-
this.dryRun = normalized.dryRun;
|
|
10260
12864
|
if ('chromium-based' === this.browser && !this.chromiumBinary) {
|
|
10261
12865
|
console.error(browsers_lib_messages.nek());
|
|
10262
12866
|
process.exit(1);
|
|
@@ -10426,6 +13030,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10426
13030
|
watchSource: devOptions.watchSource,
|
|
10427
13031
|
sourceFormat: devOptions.sourceFormat,
|
|
10428
13032
|
sourceSummary: devOptions.sourceSummary,
|
|
13033
|
+
sourceMeta: devOptions.sourceMeta,
|
|
13034
|
+
sourceProbe: devOptions.sourceProbe,
|
|
13035
|
+
sourceTree: devOptions.sourceTree,
|
|
13036
|
+
sourceConsole: devOptions.sourceConsole,
|
|
13037
|
+
sourceDom: devOptions.sourceDom,
|
|
10429
13038
|
sourceMaxBytes: devOptions.sourceMaxBytes,
|
|
10430
13039
|
sourceRedact: devOptions.sourceRedact,
|
|
10431
13040
|
sourceIncludeShadow: devOptions.sourceIncludeShadow,
|
|
@@ -10450,6 +13059,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10450
13059
|
clean: devOptions.output.clean,
|
|
10451
13060
|
path: primaryExtensionOutputDir,
|
|
10452
13061
|
publicPath: '/',
|
|
13062
|
+
filename: 'development' === (devOptions.mode || 'development') ? (pathData)=>{
|
|
13063
|
+
const chunkName = pathData.chunk?.name;
|
|
13064
|
+
if ('string' == typeof chunkName && /^content_scripts\/content-\d+$/.test(chunkName)) return `${chunkName}.[fullhash:8].js`;
|
|
13065
|
+
return '[name].js';
|
|
13066
|
+
} : '[name].js',
|
|
10453
13067
|
hotUpdateChunkFilename: 'hot/[id].[fullhash].hot-update.js',
|
|
10454
13068
|
hotUpdateMainFilename: 'hot/[runtime].[fullhash].hot-update.json',
|
|
10455
13069
|
environment: {
|