extension-develop 3.10.2 → 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} +3121 -494
- 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 +2072 -1755
- 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
|
}
|
|
@@ -2665,6 +2861,11 @@ exports.modules = {
|
|
|
2665
2861
|
function isCanonicalContentScriptCss(resource) {
|
|
2666
2862
|
return /^content_scripts\/content-\d+\.css$/.test(resource);
|
|
2667
2863
|
}
|
|
2864
|
+
function toCanonicalContentScriptCss(jsFile) {
|
|
2865
|
+
const normalized = String(jsFile || '');
|
|
2866
|
+
if (!/^content_scripts\/content-\d+\.js$/.test(normalized)) return;
|
|
2867
|
+
return normalized.replace(/\.js$/, '.css');
|
|
2868
|
+
}
|
|
2668
2869
|
function generateManifestPatches(compilation, manifestPath, entryImports, browser) {
|
|
2669
2870
|
const canonicalManifest = getManifestContent(compilation, manifestPath);
|
|
2670
2871
|
const resolved = resolveUserDeclaredWAR(compilation, manifestPath, canonicalManifest, browser);
|
|
@@ -2817,9 +3018,17 @@ exports.modules = {
|
|
|
2817
3018
|
for (const r of fontAssets)if (!webAccessibleResourcesV2.includes(r)) webAccessibleResourcesV2.push(r);
|
|
2818
3019
|
}
|
|
2819
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
|
+
}
|
|
2820
3031
|
if (3 === canonicalManifest.manifest_version) {
|
|
2821
|
-
const assetKeys = Object.keys(compilation.assets || {});
|
|
2822
|
-
const cssUnderContentScripts = assetKeys.filter((k)=>k.startsWith("content_scripts/")).filter((k)=>k.endsWith('.css')).sort();
|
|
2823
3032
|
if (cssUnderContentScripts.length > 0) {
|
|
2824
3033
|
const allMatches = Array.from(new Set((canonicalManifest.content_scripts || []).flatMap((cs)=>cs.matches || [])));
|
|
2825
3034
|
const normalizedMatches = cleanMatches(allMatches);
|
|
@@ -2847,6 +3056,8 @@ exports.modules = {
|
|
|
2847
3056
|
});
|
|
2848
3057
|
}
|
|
2849
3058
|
}
|
|
3059
|
+
} else if (2 === canonicalManifest.manifest_version) {
|
|
3060
|
+
for (const resource of cssUnderContentScripts)if (!webAccessibleResourcesV2.includes(resource)) webAccessibleResourcesV2.push(resource);
|
|
2850
3061
|
}
|
|
2851
3062
|
if (3 === canonicalManifest.manifest_version) {
|
|
2852
3063
|
if (webAccessibleResourcesV3.length > 0) canonicalManifest.web_accessible_resources = webAccessibleResourcesV3.map((entry)=>({
|
|
@@ -3123,6 +3334,7 @@ exports.modules = {
|
|
|
3123
3334
|
permissions: [
|
|
3124
3335
|
...new Set([
|
|
3125
3336
|
"scripting",
|
|
3337
|
+
'tabs',
|
|
3126
3338
|
'management',
|
|
3127
3339
|
...canonicalManifest.permissions || []
|
|
3128
3340
|
])
|
|
@@ -3130,6 +3342,7 @@ exports.modules = {
|
|
|
3130
3342
|
} : {
|
|
3131
3343
|
permissions: [
|
|
3132
3344
|
"scripting",
|
|
3345
|
+
'tabs',
|
|
3133
3346
|
'management'
|
|
3134
3347
|
]
|
|
3135
3348
|
} : {},
|
|
@@ -4227,6 +4440,51 @@ exports.modules = {
|
|
|
4227
4440
|
this.browser = options.browser;
|
|
4228
4441
|
}
|
|
4229
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");
|
|
4230
4488
|
function add_scripts_and_styles_to_compilation_define_property(obj, key, value) {
|
|
4231
4489
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
4232
4490
|
value: value,
|
|
@@ -4244,6 +4502,7 @@ exports.modules = {
|
|
|
4244
4502
|
const projectRoot = compiler.options.context || manifestDir;
|
|
4245
4503
|
const publicDir = external_path_.join(projectRoot, 'public');
|
|
4246
4504
|
const hasPublicDir = external_fs_.existsSync(publicDir);
|
|
4505
|
+
const devServerHmrImports = 'development' === compiler.options.mode ? getDevServerHmrImports(compiler) : [];
|
|
4247
4506
|
for (const field of Object.entries(htmlEntries)){
|
|
4248
4507
|
const [feature, resource] = field;
|
|
4249
4508
|
if (resource) {
|
|
@@ -4258,7 +4517,8 @@ exports.modules = {
|
|
|
4258
4517
|
...cssAssets
|
|
4259
4518
|
];
|
|
4260
4519
|
if ('development' === compiler.options.mode) {
|
|
4261
|
-
|
|
4520
|
+
if (devServerHmrImports.length > 0) fileAssets.unshift(...devServerHmrImports);
|
|
4521
|
+
const hmrScript = (0, develop_context.G)("minimum-script-file");
|
|
4262
4522
|
fileAssets.push(hmrScript);
|
|
4263
4523
|
}
|
|
4264
4524
|
if (external_fs_.existsSync(resource)) compiler.options.entry = {
|
|
@@ -4675,24 +4935,40 @@ exports.modules = {
|
|
|
4675
4935
|
includeList,
|
|
4676
4936
|
browser: this.browser
|
|
4677
4937
|
}).apply(compiler);
|
|
4678
|
-
if ('production' !== (compiler.options.mode || 'development'))
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
{
|
|
4688
|
-
loader: external_path_.resolve(__dirname, "ensure-hmr-for-scripts"),
|
|
4689
|
-
options: {
|
|
4690
|
-
manifestPath: this.manifestPath,
|
|
4691
|
-
includeList
|
|
4692
|
-
}
|
|
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)));
|
|
4693
4947
|
}
|
|
4694
|
-
|
|
4695
|
-
|
|
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
|
+
}
|
|
4696
4972
|
new AddToFileDependencies({
|
|
4697
4973
|
manifestPath: this.manifestPath,
|
|
4698
4974
|
includeList,
|
|
@@ -4756,6 +5032,29 @@ exports.modules = {
|
|
|
4756
5032
|
});
|
|
4757
5033
|
return fileAssets;
|
|
4758
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
|
+
}
|
|
4759
5058
|
function findPackageRoot(startDir) {
|
|
4760
5059
|
let current = startDir;
|
|
4761
5060
|
for(let i = 0; i < 15; i++){
|
|
@@ -4799,12 +5098,11 @@ exports.modules = {
|
|
|
4799
5098
|
const cs = contentScripts[i];
|
|
4800
5099
|
if (cs?.world !== 'MAIN') continue;
|
|
4801
5100
|
const bridgeIndex = originalCount + bridgeOrdinal++;
|
|
4802
|
-
bridgeScripts[
|
|
5101
|
+
bridgeScripts[(0, contracts.Y0)(bridgeIndex)] = bridgeSource;
|
|
4803
5102
|
}
|
|
4804
5103
|
} catch {}
|
|
4805
5104
|
return bridgeScripts;
|
|
4806
5105
|
}
|
|
4807
|
-
var package_json = __webpack_require__("./webpack/webpack-lib/package-json.ts");
|
|
4808
5106
|
function add_content_script_wrapper_define_property(obj, key, value) {
|
|
4809
5107
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
4810
5108
|
value: value,
|
|
@@ -4819,20 +5117,12 @@ exports.modules = {
|
|
|
4819
5117
|
static getBridgeScripts(manifestPath) {
|
|
4820
5118
|
return getMainWorldBridgeScripts(manifestPath);
|
|
4821
5119
|
}
|
|
4822
|
-
resolveLoader(
|
|
4823
|
-
|
|
4824
|
-
const candidates = [
|
|
4825
|
-
`${base}.cjs`,
|
|
4826
|
-
`${base}.js`,
|
|
4827
|
-
`${base}.mjs`,
|
|
4828
|
-
base
|
|
4829
|
-
];
|
|
4830
|
-
for (const candidate of candidates)if (external_fs_.existsSync(candidate)) return candidate;
|
|
4831
|
-
return base;
|
|
5120
|
+
resolveLoader() {
|
|
5121
|
+
return (0, develop_context.G)("feature-scripts-content-script-wrapper");
|
|
4832
5122
|
}
|
|
4833
5123
|
apply(compiler) {
|
|
4834
5124
|
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
4835
|
-
const packageJsonPath = (
|
|
5125
|
+
const packageJsonPath = findNearestPackageJsonSync(this.manifestPath);
|
|
4836
5126
|
const packageJsonDir = packageJsonPath ? external_path_.dirname(packageJsonPath) : manifestDir;
|
|
4837
5127
|
const includeDirs = packageJsonDir === manifestDir ? [
|
|
4838
5128
|
manifestDir
|
|
@@ -4848,7 +5138,7 @@ exports.modules = {
|
|
|
4848
5138
|
],
|
|
4849
5139
|
use: [
|
|
4850
5140
|
{
|
|
4851
|
-
loader: this.resolveLoader(
|
|
5141
|
+
loader: this.resolveLoader(),
|
|
4852
5142
|
options: {
|
|
4853
5143
|
manifestPath: this.manifestPath,
|
|
4854
5144
|
mode: compiler.options.mode
|
|
@@ -4856,41 +5146,6 @@ exports.modules = {
|
|
|
4856
5146
|
}
|
|
4857
5147
|
]
|
|
4858
5148
|
});
|
|
4859
|
-
if ('production' !== compiler.options.mode) {
|
|
4860
|
-
compiler.options.module.rules.push({
|
|
4861
|
-
test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
|
|
4862
|
-
include: includeDirs,
|
|
4863
|
-
exclude: [
|
|
4864
|
-
/([\\/])node_modules\1/
|
|
4865
|
-
],
|
|
4866
|
-
use: [
|
|
4867
|
-
{
|
|
4868
|
-
loader: this.resolveLoader('warn-no-default-export'),
|
|
4869
|
-
options: {
|
|
4870
|
-
manifestPath: this.manifestPath,
|
|
4871
|
-
mode: compiler.options.mode
|
|
4872
|
-
}
|
|
4873
|
-
}
|
|
4874
|
-
],
|
|
4875
|
-
enforce: 'pre'
|
|
4876
|
-
});
|
|
4877
|
-
compiler.options.module.rules.push({
|
|
4878
|
-
test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
|
|
4879
|
-
include: includeDirs,
|
|
4880
|
-
exclude: [
|
|
4881
|
-
/([\\/])node_modules\1/
|
|
4882
|
-
],
|
|
4883
|
-
use: [
|
|
4884
|
-
{
|
|
4885
|
-
loader: this.resolveLoader('add-hmr-accept-code'),
|
|
4886
|
-
options: {
|
|
4887
|
-
manifestPath: this.manifestPath,
|
|
4888
|
-
mode: compiler.options.mode
|
|
4889
|
-
}
|
|
4890
|
-
}
|
|
4891
|
-
]
|
|
4892
|
-
});
|
|
4893
|
-
}
|
|
4894
5149
|
}
|
|
4895
5150
|
constructor(options){
|
|
4896
5151
|
add_content_script_wrapper_define_property(this, "manifestPath", void 0);
|
|
@@ -4899,17 +5154,6 @@ exports.modules = {
|
|
|
4899
5154
|
this.browser = options.browser || 'chrome';
|
|
4900
5155
|
}
|
|
4901
5156
|
}
|
|
4902
|
-
function scriptsEntriesSummary(entriesAdded, publicTracked) {
|
|
4903
|
-
return `Scripts entries — added=${external_pintor_default().gray(String(entriesAdded))}, publicTracked=${external_pintor_default().gray(String(publicTracked))}`;
|
|
4904
|
-
}
|
|
4905
|
-
function scriptsManifestChangeDetected(before, after) {
|
|
4906
|
-
const parts = [
|
|
4907
|
-
"Manifest scripts change detected",
|
|
4908
|
-
before ? `${external_pintor_default().gray('before')} ${external_pintor_default().underline(before)}` : '',
|
|
4909
|
-
after ? `${external_pintor_default().gray('after')} ${external_pintor_default().underline(after)}` : ''
|
|
4910
|
-
].filter(Boolean);
|
|
4911
|
-
return parts.join(' — ');
|
|
4912
|
-
}
|
|
4913
5157
|
function add_scripts_define_property(obj, key, value) {
|
|
4914
5158
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
4915
5159
|
value: value,
|
|
@@ -4921,14 +5165,22 @@ exports.modules = {
|
|
|
4921
5165
|
return obj;
|
|
4922
5166
|
}
|
|
4923
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
|
+
}
|
|
4924
5177
|
class AddScripts {
|
|
4925
5178
|
apply(compiler) {
|
|
4926
5179
|
const bridgeScripts = AddContentScriptWrapper.getBridgeScripts(this.manifestPath);
|
|
4927
|
-
const
|
|
5180
|
+
const scriptFields = {
|
|
4928
5181
|
...this.includeList,
|
|
4929
5182
|
...bridgeScripts
|
|
4930
5183
|
};
|
|
4931
|
-
const scriptFields = mergedIncludeList;
|
|
4932
5184
|
if (compiler?.hooks?.thisCompilation?.tap) compiler.hooks.thisCompilation.tap("scripts:validate-include-list", (compilation)=>{
|
|
4933
5185
|
try {
|
|
4934
5186
|
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
@@ -4939,20 +5191,19 @@ exports.modules = {
|
|
|
4939
5191
|
raw
|
|
4940
5192
|
] : [];
|
|
4941
5193
|
for (const entry of rawEntries){
|
|
4942
|
-
if (!entry || 'string' != typeof entry) continue;
|
|
4943
|
-
if (add_scripts_isRemoteUrl(entry)) continue;
|
|
5194
|
+
if (!entry || 'string' != typeof entry || add_scripts_isRemoteUrl(entry)) continue;
|
|
4944
5195
|
let resolved = entry;
|
|
4945
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);
|
|
4946
5197
|
if (external_fs_.existsSync(resolved)) continue;
|
|
4947
5198
|
const isPublicRoot = entry.startsWith('/') && !external_path_.isAbsolute(entry);
|
|
4948
5199
|
const displayPath = isPublicRoot ? outputRoot ? external_path_.join(outputRoot, entry.slice(1)) : entry : resolved;
|
|
4949
|
-
const
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
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'));
|
|
4956
5207
|
err.file = 'manifest.json';
|
|
4957
5208
|
err.name = 'ScriptsMissingFile';
|
|
4958
5209
|
(compilation.errors ||= []).push(err);
|
|
@@ -4963,15 +5214,18 @@ exports.modules = {
|
|
|
4963
5214
|
const newEntries = {};
|
|
4964
5215
|
const manifestDir = external_path_.dirname(this.manifestPath);
|
|
4965
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
|
+
}
|
|
4966
5223
|
const resolveEntryPath = (entry)=>{
|
|
4967
|
-
if (!entry) return entry;
|
|
4968
|
-
if (add_scripts_isRemoteUrl(entry)) return entry;
|
|
5224
|
+
if (!entry || add_scripts_isRemoteUrl(entry)) return entry;
|
|
4969
5225
|
if (entry.startsWith('/') && !external_path_.isAbsolute(entry)) return external_path_.join(projectPath, entry.slice(1));
|
|
4970
5226
|
if (external_path_.isAbsolute(entry)) return entry;
|
|
4971
5227
|
return external_path_.join(manifestDir, entry);
|
|
4972
5228
|
};
|
|
4973
|
-
let entriesAdded = 0;
|
|
4974
|
-
let publicTracked = 0;
|
|
4975
5229
|
for (const [feature, scriptPath] of Object.entries(scriptFields)){
|
|
4976
5230
|
const rawEntries = Array.isArray(scriptPath) ? scriptPath || [] : scriptPath ? [
|
|
4977
5231
|
scriptPath
|
|
@@ -4979,32 +5233,32 @@ exports.modules = {
|
|
|
4979
5233
|
const resolvedEntries = rawEntries.map(resolveEntryPath);
|
|
4980
5234
|
const scriptImports = getScriptEntries(resolvedEntries);
|
|
4981
5235
|
const cssImports = getCssEntries(resolvedEntries);
|
|
4982
|
-
const
|
|
4983
|
-
...
|
|
4984
|
-
|
|
5236
|
+
const entryImports = [
|
|
5237
|
+
...new Set([
|
|
5238
|
+
...scriptImports,
|
|
5239
|
+
...cssImports
|
|
5240
|
+
])
|
|
4985
5241
|
];
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
}
|
|
5000
|
-
|
|
5001
|
-
}
|
|
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
|
+
};
|
|
5002
5257
|
}
|
|
5003
5258
|
compiler.options.entry = {
|
|
5004
5259
|
...compiler.options.entry,
|
|
5005
5260
|
...newEntries
|
|
5006
5261
|
};
|
|
5007
|
-
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(scriptsEntriesSummary(entriesAdded, publicTracked));
|
|
5008
5262
|
}
|
|
5009
5263
|
constructor(options){
|
|
5010
5264
|
add_scripts_define_property(this, "manifestPath", void 0);
|
|
@@ -5013,45 +5267,6 @@ exports.modules = {
|
|
|
5013
5267
|
this.includeList = options.includeList || {};
|
|
5014
5268
|
}
|
|
5015
5269
|
}
|
|
5016
|
-
const basic = [
|
|
5017
|
-
'var isBrowser = !!(() => { try { return browser.runtime.getURL("/") } catch(e) {} })()',
|
|
5018
|
-
'var isChrome = !!(() => { try { return chrome.runtime.getURL("/") } catch(e) {} })()'
|
|
5019
|
-
];
|
|
5020
|
-
const weakRuntimeCheck = [
|
|
5021
|
-
...basic,
|
|
5022
|
-
"var runtime = isBrowser ? browser : isChrome ? chrome : { runtime: { getURL: x => x } }"
|
|
5023
|
-
];
|
|
5024
|
-
class AddPublicPathRuntimeModule {
|
|
5025
|
-
apply(compiler) {
|
|
5026
|
-
const { RuntimeGlobals } = compiler.webpack;
|
|
5027
|
-
compiler.hooks.compilation.tap('PublicPathRuntimeModule', (compilation)=>{
|
|
5028
|
-
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap(AddPublicPathRuntimeModule.name, (chunk)=>{
|
|
5029
|
-
const module = add_public_path_runtime_module_PublicPathRuntimeModule(compiler);
|
|
5030
|
-
compilation.addRuntimeModule(chunk, module);
|
|
5031
|
-
return true;
|
|
5032
|
-
});
|
|
5033
|
-
});
|
|
5034
|
-
}
|
|
5035
|
-
}
|
|
5036
|
-
function add_public_path_runtime_module_PublicPathRuntimeModule(compiler) {
|
|
5037
|
-
const { Template, RuntimeModule, RuntimeGlobals } = compiler.webpack;
|
|
5038
|
-
class PublicPathRuntimeModule extends RuntimeModule {
|
|
5039
|
-
generate() {
|
|
5040
|
-
const publicPath = this.compilation?.outputOptions.publicPath;
|
|
5041
|
-
return Template.asString([
|
|
5042
|
-
...weakRuntimeCheck,
|
|
5043
|
-
`var path = ${JSON.stringify(this.compilation?.getPath(publicPath || '', {
|
|
5044
|
-
hash: this.compilation.hash || 'XXXX'
|
|
5045
|
-
}))}`,
|
|
5046
|
-
`${RuntimeGlobals.publicPath} = typeof importScripts === 'function' || !(isBrowser || isChrome) ? path : runtime.runtime.getURL(path);`
|
|
5047
|
-
]);
|
|
5048
|
-
}
|
|
5049
|
-
constructor(){
|
|
5050
|
-
super('publicPath', RuntimeModule.STAGE_BASIC);
|
|
5051
|
-
}
|
|
5052
|
-
}
|
|
5053
|
-
return new PublicPathRuntimeModule();
|
|
5054
|
-
}
|
|
5055
5270
|
function TemplateFn(compilation, Template) {
|
|
5056
5271
|
return {
|
|
5057
5272
|
f: (args, body)=>{
|
|
@@ -5080,9 +5295,9 @@ exports.modules = {
|
|
|
5080
5295
|
`${_let} isChrome, runtime;`,
|
|
5081
5296
|
'try {',
|
|
5082
5297
|
Template.indent([
|
|
5083
|
-
`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"'}) {`,
|
|
5084
5299
|
Template.indent([
|
|
5085
|
-
'runtime = browser;'
|
|
5300
|
+
'runtime = globalThis.browser;'
|
|
5086
5301
|
]),
|
|
5087
5302
|
'}'
|
|
5088
5303
|
]),
|
|
@@ -5091,10 +5306,10 @@ exports.modules = {
|
|
|
5091
5306
|
Template.indent([
|
|
5092
5307
|
'try {',
|
|
5093
5308
|
Template.indent([
|
|
5094
|
-
`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"'}) {`,
|
|
5095
5310
|
Template.indent([
|
|
5096
5311
|
'isChrome = true;',
|
|
5097
|
-
'runtime = chrome;'
|
|
5312
|
+
'runtime = globalThis.chrome;'
|
|
5098
5313
|
]),
|
|
5099
5314
|
'}'
|
|
5100
5315
|
]),
|
|
@@ -5145,7 +5360,7 @@ exports.modules = {
|
|
|
5145
5360
|
const bundleId = chunkName ? `${chunkName}.js` : '';
|
|
5146
5361
|
const world = bundleId && this.contentScriptsMeta[bundleId] ? this.contentScriptsMeta[bundleId].world : void 0;
|
|
5147
5362
|
const isMainWorld = 'main' === world;
|
|
5148
|
-
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; } })();`;
|
|
5149
5364
|
const DynamicImportLoader = `${_const} ${DYNAMIC_IMPORT_LOADER} = ` + f('url, done, key, chunkId', `import(url).then(${f('', [
|
|
5150
5365
|
'if (isNotIframe) return done();',
|
|
5151
5366
|
'try {',
|
|
@@ -5196,6 +5411,7 @@ exports.modules = {
|
|
|
5196
5411
|
const ClassicLoader = `${_const} ${CLASSIC_LOADER} = ` + f('url, done', Template.asString([
|
|
5197
5412
|
`${_const} msg = { type: "WTW_INJECT", file: url };`,
|
|
5198
5413
|
`${_const} onError = ${f('e', 'done(Object.assign(e, { type: "missing" }))')};`,
|
|
5414
|
+
'try {',
|
|
5199
5415
|
`if (${RuntimeGlobalIsBrowser}) {`,
|
|
5200
5416
|
Template.indent([
|
|
5201
5417
|
`${RuntimeGlobal}.runtime.sendMessage(msg).then(done, onError);`
|
|
@@ -5208,7 +5424,8 @@ exports.modules = {
|
|
|
5208
5424
|
'else done();'
|
|
5209
5425
|
])});`
|
|
5210
5426
|
]),
|
|
5211
|
-
'}'
|
|
5427
|
+
'}',
|
|
5428
|
+
'} catch (e) { onError(e); }'
|
|
5212
5429
|
])) + ';';
|
|
5213
5430
|
const ClassicLoaderDisabled = `${_const} ${CLASSIC_LOADER} = ` + f('', [
|
|
5214
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.\");"
|
|
@@ -5310,9 +5527,15 @@ exports.modules = {
|
|
|
5310
5527
|
'try { __extjsBase = document.documentElement.getAttribute("data-extjs-extension-base") || ""; } catch(_) { __extjsBase = ""; }'
|
|
5311
5528
|
]),
|
|
5312
5529
|
"}",
|
|
5530
|
+
'var __extjsRuntimePath = "";',
|
|
5313
5531
|
`if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && typeof ${RuntimeGlobal}.runtime.getURL === "function") {`,
|
|
5314
5532
|
Template.indent([
|
|
5315
|
-
|
|
5533
|
+
`try { __extjsRuntimePath = ${RuntimeGlobal}.runtime.getURL(${path}); } catch (_) { __extjsRuntimePath = ""; }`
|
|
5534
|
+
]),
|
|
5535
|
+
"}",
|
|
5536
|
+
"if (__extjsRuntimePath) {",
|
|
5537
|
+
Template.indent([
|
|
5538
|
+
`${RuntimeGlobals.publicPath} = __extjsRuntimePath;`
|
|
5316
5539
|
]),
|
|
5317
5540
|
"} else if (__extjsBase) {",
|
|
5318
5541
|
Template.indent([
|
|
@@ -5403,8 +5626,10 @@ exports.modules = {
|
|
|
5403
5626
|
"}",
|
|
5404
5627
|
"if (!scriptUrl) {",
|
|
5405
5628
|
Template.indent([
|
|
5629
|
+
'var __extjsRuntimeRoot = "";',
|
|
5406
5630
|
`if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && typeof ${RuntimeGlobal}.runtime.getURL === "function") {`,
|
|
5407
|
-
Template.indent(`
|
|
5631
|
+
Template.indent(`try { __extjsRuntimeRoot = ${RuntimeGlobal}.runtime.getURL("/"); } catch (_) { __extjsRuntimeRoot = ""; }`),
|
|
5632
|
+
Template.indent("scriptUrl = __extjsRuntimeRoot || scriptUrl;"),
|
|
5408
5633
|
"} else {",
|
|
5409
5634
|
Template.indent('scriptUrl = __extjsBase || "";'),
|
|
5410
5635
|
"}"
|
|
@@ -5462,6 +5687,52 @@ exports.modules = {
|
|
|
5462
5687
|
else if ('.' !== part) depth++;
|
|
5463
5688
|
return depth > 0 ? `${'../'.repeat(depth)}${append}` : enforceRelative ? `./${append}` : append;
|
|
5464
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
|
+
}
|
|
5465
5736
|
function ChunkLoaderFallbackRuntimeModule(webpack) {
|
|
5466
5737
|
const { RuntimeModule, Template } = webpack;
|
|
5467
5738
|
class ChunkLoaderFallbackRuntime extends RuntimeModule {
|
|
@@ -5472,7 +5743,7 @@ exports.modules = {
|
|
|
5472
5743
|
const optionalChain = compilation.outputOptions.environment.optionalChaining;
|
|
5473
5744
|
const _const = compilation.outputOptions.environment.const ? 'const' : 'var';
|
|
5474
5745
|
const _let = compilation.outputOptions.environment.const ? 'let' : 'var';
|
|
5475
|
-
return
|
|
5746
|
+
return `if (${RuntimeGlobal} && ${RuntimeGlobal}.runtime && ${RuntimeGlobal}.runtime.onMessage) {${RuntimeGlobal}.runtime.onMessage.addListener(` + f('message, sender, sendResponse', [
|
|
5476
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;',
|
|
5477
5748
|
`${_let} file = message.file;`,
|
|
5478
5749
|
'try {',
|
|
@@ -5501,7 +5772,7 @@ exports.modules = {
|
|
|
5501
5772
|
]),
|
|
5502
5773
|
'}',
|
|
5503
5774
|
'return true;'
|
|
5504
|
-
]) +
|
|
5775
|
+
]) + ");}";
|
|
5505
5776
|
}
|
|
5506
5777
|
constructor(){
|
|
5507
5778
|
super('chunk loader fallback', RuntimeModule.STAGE_TRIGGER);
|
|
@@ -5540,6 +5811,11 @@ exports.modules = {
|
|
|
5540
5811
|
compilation.addRuntimeModule(_chunk, LoadScriptRuntimeModule(compiler.webpack, false !== compilation.outputOptions.environment.dynamicImport, false !== options.classicLoader, this.contentScriptsMeta));
|
|
5541
5812
|
return true;
|
|
5542
5813
|
});
|
|
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
|
+
});
|
|
5543
5819
|
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap(WebExtensionChuckLoaderRuntimePlugin.name, (chunk, set)=>{
|
|
5544
5820
|
const { outputOptions } = compilation;
|
|
5545
5821
|
const { publicPath, scriptType } = outputOptions;
|
|
@@ -5781,7 +6057,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
5781
6057
|
} else code = [
|
|
5782
6058
|
';(() => {',
|
|
5783
6059
|
Template.indent([
|
|
5784
|
-
'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;',
|
|
5785
6061
|
`${JSON.stringify(files)}.forEach(file => import(getURL(file)));`
|
|
5786
6062
|
]),
|
|
5787
6063
|
'})();',
|
|
@@ -5969,12 +6245,23 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
5969
6245
|
}
|
|
5970
6246
|
}
|
|
5971
6247
|
const webpack_target_webextension_fork = WebExtensionPlugin;
|
|
6248
|
+
function manifest_getManifestContent(compilation, manifestPath) {
|
|
6249
|
+
return getManifestContent(compilation, manifestPath);
|
|
6250
|
+
}
|
|
5972
6251
|
function scripts_lib_manifest_filterKeysForThisBrowser(manifest, browser) {
|
|
5973
6252
|
return manifest_filterKeysForThisBrowser(manifest, browser);
|
|
5974
6253
|
}
|
|
5975
6254
|
function backgroundIsRequiredMessageOnly(backgroundChunkName) {
|
|
5976
6255
|
return `Check the ${external_pintor_default().yellow(backgroundChunkName.replace('/', '.'))} field in your ${external_pintor_default().yellow('manifest.json')} file.`;
|
|
5977
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
|
+
}
|
|
5978
6265
|
function setup_background_entry_define_property(obj, key, value) {
|
|
5979
6266
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
5980
6267
|
value: value,
|
|
@@ -6007,7 +6294,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6007
6294
|
apply(compiler) {
|
|
6008
6295
|
const manifest = JSON.parse(external_fs_.readFileSync(this.manifestPath, 'utf-8'));
|
|
6009
6296
|
const browser = this.browser;
|
|
6010
|
-
const minimumBgScript =
|
|
6297
|
+
const minimumBgScript = (0, develop_context.G)('firefox' === browser || 'gecko-based' === browser ? 'minimum-firefox-file' : 'minimum-chromium-file');
|
|
6011
6298
|
const dirname = external_path_.dirname(this.manifestPath);
|
|
6012
6299
|
let manifestBg = scripts_lib_manifest_filterKeysForThisBrowser(manifest, browser);
|
|
6013
6300
|
manifestBg = manifestBg?.background ?? manifest.background;
|
|
@@ -6050,6 +6337,263 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6050
6337
|
this.browser = options.browser || 'chrome';
|
|
6051
6338
|
}
|
|
6052
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
|
+
}
|
|
6053
6597
|
function setup_reload_strategy_define_property(obj, key, value) {
|
|
6054
6598
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
6055
6599
|
value: value,
|
|
@@ -6095,17 +6639,17 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6095
6639
|
let bridgeOrdinal = 0;
|
|
6096
6640
|
for(let i = 0; i < csList.length; i++){
|
|
6097
6641
|
const cs = csList[i];
|
|
6098
|
-
const bundleId =
|
|
6642
|
+
const bundleId = (0, contracts.f6)(i);
|
|
6099
6643
|
const isMain = cs?.world === 'MAIN';
|
|
6100
6644
|
if (isMain) {
|
|
6101
6645
|
const bridgeIndex = originalCount + bridgeOrdinal++;
|
|
6646
|
+
const bridgeBundleId = (0, contracts.f6)(bridgeIndex);
|
|
6102
6647
|
contentScriptsMeta[bundleId] = {
|
|
6103
6648
|
index: i,
|
|
6104
6649
|
bundleId,
|
|
6105
6650
|
world: 'main',
|
|
6106
|
-
bridgeBundleId
|
|
6651
|
+
bridgeBundleId
|
|
6107
6652
|
};
|
|
6108
|
-
const bridgeBundleId = `content_scripts/content-${bridgeIndex}.js`;
|
|
6109
6653
|
contentScriptsMeta[bridgeBundleId] = {
|
|
6110
6654
|
index: bridgeIndex,
|
|
6111
6655
|
bundleId: bridgeBundleId,
|
|
@@ -6120,12 +6664,17 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6120
6664
|
};
|
|
6121
6665
|
}
|
|
6122
6666
|
} catch {}
|
|
6667
|
+
new ApplyManifestDevDefaults({
|
|
6668
|
+
manifestPath: this.manifestPath,
|
|
6669
|
+
browser: this.browser
|
|
6670
|
+
}).apply(compiler);
|
|
6123
6671
|
new SetupBackgroundEntry({
|
|
6124
6672
|
manifestPath: this.manifestPath,
|
|
6125
6673
|
browser: this.browser
|
|
6126
6674
|
}).apply(compiler);
|
|
6127
6675
|
new webpack_target_webextension_fork({
|
|
6128
6676
|
background: this.getEntryName(patchedManifest),
|
|
6677
|
+
hmrConfig: false,
|
|
6129
6678
|
weakRuntimeCheck: true,
|
|
6130
6679
|
contentScriptsMeta
|
|
6131
6680
|
}).apply(compiler);
|
|
@@ -6137,6 +6686,135 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6137
6686
|
this.browser = options.browser || 'chrome';
|
|
6138
6687
|
}
|
|
6139
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
|
+
}
|
|
6140
6818
|
function throw_if_manifest_scripts_change_define_property(obj, key, value) {
|
|
6141
6819
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
6142
6820
|
value: value,
|
|
@@ -6259,6 +6937,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
6259
6937
|
}).apply(compiler);
|
|
6260
6938
|
if ('production' === compiler.options.mode) new AddPublicPathRuntimeModule().apply(compiler);
|
|
6261
6939
|
if ('production' !== compiler.options.mode) {
|
|
6940
|
+
new StripContentScriptDevServerRuntime().apply(compiler);
|
|
6262
6941
|
new SetupReloadStrategy({
|
|
6263
6942
|
manifestPath: this.manifestPath,
|
|
6264
6943
|
browser: this.browser
|
|
@@ -7648,6 +8327,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
7648
8327
|
instanceId: options.instanceId
|
|
7649
8328
|
};
|
|
7650
8329
|
}
|
|
8330
|
+
var runtime_options = __webpack_require__("./webpack/plugin-browsers/browsers-lib/runtime-options.ts");
|
|
7651
8331
|
var browsers_lib_messages = __webpack_require__("./webpack/plugin-browsers/browsers-lib/messages.ts");
|
|
7652
8332
|
var chromium_context = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-context/index.ts");
|
|
7653
8333
|
var chromium_launch = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-launch/index.ts");
|
|
@@ -8003,19 +8683,21 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8003
8683
|
return hash.toString(16).padStart(8, '0');
|
|
8004
8684
|
}
|
|
8005
8685
|
function diffDomSnapshots(prev, next) {
|
|
8686
|
+
const prevNodes = Array.isArray(prev?.nodes) ? prev.nodes : [];
|
|
8687
|
+
const nextNodes = Array.isArray(next?.nodes) ? next.nodes : [];
|
|
8006
8688
|
if (!prev) return {
|
|
8007
|
-
added:
|
|
8689
|
+
added: nextNodes.length,
|
|
8008
8690
|
removed: 0,
|
|
8009
8691
|
changed: 0,
|
|
8010
|
-
addedKeys:
|
|
8692
|
+
addedKeys: nextNodes.slice(0, 50).map((n)=>n.key),
|
|
8011
8693
|
removedKeys: [],
|
|
8012
8694
|
changedKeys: []
|
|
8013
8695
|
};
|
|
8014
|
-
const prevMap = new Map(
|
|
8696
|
+
const prevMap = new Map(prevNodes.map((n)=>[
|
|
8015
8697
|
n.key,
|
|
8016
8698
|
n
|
|
8017
8699
|
]));
|
|
8018
|
-
const nextMap = new Map(
|
|
8700
|
+
const nextMap = new Map(nextNodes.map((n)=>[
|
|
8019
8701
|
n.key,
|
|
8020
8702
|
n
|
|
8021
8703
|
]));
|
|
@@ -8122,6 +8804,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8122
8804
|
return '<<<EXTJS_HTML_END>>>';
|
|
8123
8805
|
}
|
|
8124
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");
|
|
8125
8808
|
function chromium_hard_reload_define_property(obj, key, value) {
|
|
8126
8809
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
8127
8810
|
value: value,
|
|
@@ -8151,6 +8834,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8151
8834
|
};
|
|
8152
8835
|
if (compiler.hooks?.watchRun?.tapAsync) compiler.hooks.watchRun.tapAsync('run-browsers:watch', (compilerWithModifiedFiles, done)=>{
|
|
8153
8836
|
try {
|
|
8837
|
+
this.contentReloadGeneration += 1;
|
|
8154
8838
|
const modifiedFiles = compilerWithModifiedFiles?.modifiedFiles || new Set();
|
|
8155
8839
|
const normalizedModifiedFilePaths = Array.from(modifiedFiles).map((filePath)=>String(filePath).replace(/\\/g, '/'));
|
|
8156
8840
|
const compilerContextRoot = String(compiler?.options?.context || '').replace(/\\/g, '/');
|
|
@@ -8183,9 +8867,34 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8183
8867
|
});
|
|
8184
8868
|
}
|
|
8185
8869
|
}
|
|
8186
|
-
if (hitManifest)
|
|
8187
|
-
|
|
8188
|
-
|
|
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
|
+
}
|
|
8189
8898
|
} catch (error) {
|
|
8190
8899
|
this.logger?.warn?.('[reload-debug] watchRun inspect failed:', String(error));
|
|
8191
8900
|
}
|
|
@@ -8194,17 +8903,139 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8194
8903
|
compiler.hooks.done.tapPromise('run-browsers:module', async (stats)=>{
|
|
8195
8904
|
const hasErrors = 'function' == typeof stats?.hasErrors ? stats.hasErrors() : !!stats?.compilation?.errors?.length;
|
|
8196
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);
|
|
8197
8917
|
this.refreshSWFromManifest(stats.compilation);
|
|
8198
|
-
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;
|
|
8199
8925
|
if (!this.hasCompletedSuccessfulBuild) {
|
|
8200
8926
|
this.hasCompletedSuccessfulBuild = true;
|
|
8201
8927
|
this.firstSuccessfulBuildAtMs = Date.now();
|
|
8928
|
+
this.pendingContentReloadEntryNames = [];
|
|
8202
8929
|
this.ctx.clearPendingReloadReason();
|
|
8203
8930
|
return;
|
|
8204
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 || ''));
|
|
8205
8934
|
const pendingReason = this.ctx.getPendingReloadReason();
|
|
8206
|
-
const
|
|
8207
|
-
|
|
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;
|
|
8208
9039
|
this.ctx.clearPendingReloadReason();
|
|
8209
9040
|
const now = Date.now();
|
|
8210
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})`);
|
|
@@ -8225,7 +9056,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8225
9056
|
});
|
|
8226
9057
|
const extensionRoot = this.ctx.getExtensionRoot();
|
|
8227
9058
|
if (extensionRoot) {
|
|
8228
|
-
const manifestReady = await (0, manifest_readiness.
|
|
9059
|
+
const manifestReady = await (0, manifest_readiness.fR)(extensionRoot, {
|
|
8229
9060
|
timeoutMs: 8000
|
|
8230
9061
|
});
|
|
8231
9062
|
if (!manifestReady) return void this.logger?.warn?.('[reload] manifest.json did not stabilize before hard reload');
|
|
@@ -8244,6 +9075,40 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8244
9075
|
this.warnedHardReloadFailure = true;
|
|
8245
9076
|
this.logger?.warn?.(browsers_lib_messages.WsE(this.options?.browser));
|
|
8246
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
|
+
}
|
|
8247
9112
|
});
|
|
8248
9113
|
}
|
|
8249
9114
|
refreshSWFromManifest(compilation) {
|
|
@@ -8260,12 +9125,164 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8260
9125
|
}
|
|
8261
9126
|
} catch {}
|
|
8262
9127
|
}
|
|
8263
|
-
|
|
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) {
|
|
8264
9260
|
try {
|
|
8265
|
-
const
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
} 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;
|
|
8269
9286
|
}
|
|
8270
9287
|
collectEntrypointModuleResourcePaths(compilation, entrypointName) {
|
|
8271
9288
|
const collectedResourcePaths = new Set();
|
|
@@ -8278,15 +9295,175 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8278
9295
|
for (const chunk of entrypointChunks){
|
|
8279
9296
|
const modulesIterable = chunkGraph.getChunkModulesIterable?.(chunk) || chunkGraph.getChunkModulesIterableBySourceType?.(chunk, "javascript") || chunkGraph.getChunkModules?.(chunk);
|
|
8280
9297
|
if (modulesIterable) for (const module of modulesIterable){
|
|
8281
|
-
const resourcePath = module?.resource || module?.rootModule?.resource || module?.originalSource?.()?.resource;
|
|
8282
|
-
if (
|
|
9298
|
+
const resourcePath = (0, content_script_targets.Rt)(module?.resource || module?.rootModule?.resource || module?.originalSource?.()?.resource);
|
|
9299
|
+
if (resourcePath) collectedResourcePaths.add(resourcePath);
|
|
8283
9300
|
}
|
|
8284
9301
|
}
|
|
8285
9302
|
return collectedResourcePaths;
|
|
8286
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
|
+
}
|
|
8287
9453
|
shouldEmitReloadActionEvent() {
|
|
8288
9454
|
return Boolean(this.options?.source || this.options?.watchSource);
|
|
8289
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
|
+
}
|
|
8290
9467
|
constructor(options, ctx){
|
|
8291
9468
|
chromium_hard_reload_define_property(this, "options", void 0);
|
|
8292
9469
|
chromium_hard_reload_define_property(this, "ctx", void 0);
|
|
@@ -8295,17 +9472,89 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8295
9472
|
chromium_hard_reload_define_property(this, "warnedHardReloadFailure", void 0);
|
|
8296
9473
|
chromium_hard_reload_define_property(this, "hasCompletedSuccessfulBuild", void 0);
|
|
8297
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);
|
|
8298
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);
|
|
8299
9488
|
this.options = options;
|
|
8300
9489
|
this.ctx = ctx;
|
|
8301
9490
|
this.hasCompletedSuccessfulBuild = false;
|
|
8302
9491
|
this.firstSuccessfulBuildAtMs = null;
|
|
9492
|
+
this.contentReloadGeneration = 0;
|
|
9493
|
+
this.contentReloadQuietPeriodMs = 1200;
|
|
9494
|
+
this.contentReloadFollowupMs = 1200;
|
|
9495
|
+
this.lastWatchIncludedContentChanges = false;
|
|
9496
|
+
this.awaitingSettledContentBuild = false;
|
|
8303
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 = [];
|
|
8304
9505
|
}
|
|
8305
9506
|
}
|
|
8306
9507
|
chromium_hard_reload_define_property(ChromiumHardReloadPlugin, "INITIAL_RELOAD_COOLDOWN_MS", 5000);
|
|
8307
9508
|
var shared_utils = __webpack_require__("./webpack/plugin-browsers/browsers-lib/shared-utils.ts");
|
|
8308
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
|
+
}
|
|
8309
9558
|
var instance_registry = __webpack_require__("./webpack/plugin-browsers/browsers-lib/instance-registry.ts");
|
|
8310
9559
|
var discovery = __webpack_require__("./webpack/plugin-browsers/run-chromium/chromium-source-inspection/discovery.ts");
|
|
8311
9560
|
async function waitForChromeRemoteDebugging(port, instanceId) {
|
|
@@ -8333,10 +9582,21 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8333
9582
|
}
|
|
8334
9583
|
throw new Error(browsers_lib_messages.olb(port));
|
|
8335
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
|
+
}
|
|
8336
9595
|
async function ensureTargetAndSession(cdpClient, url, options) {
|
|
8337
9596
|
const forceNavigate = Boolean(options?.forceNavigate);
|
|
9597
|
+
const normalizedUrl = normalizeInspectableUrl(url);
|
|
8338
9598
|
const targets = await cdpClient.getTargets();
|
|
8339
|
-
const existingTarget = (targets || []).find((t)=>String(t?.url || '') ===
|
|
9599
|
+
const existingTarget = (targets || []).find((t)=>normalizeInspectableUrl(String(t?.url || '')) === normalizedUrl && 'page' === String(t?.type || ''));
|
|
8340
9600
|
let targetId = '';
|
|
8341
9601
|
if (existingTarget && existingTarget.targetId) {
|
|
8342
9602
|
targetId = String(existingTarget.targetId);
|
|
@@ -8363,70 +9623,23 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8363
9623
|
try {
|
|
8364
9624
|
await cdpClient.enableRuntimeAndLog(String(tempSession));
|
|
8365
9625
|
} catch {}
|
|
8366
|
-
await cdpClient.navigate(String(tempSession), url);
|
|
8367
|
-
}
|
|
8368
|
-
}
|
|
8369
|
-
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(browsers_lib_messages.MjP());
|
|
8370
|
-
const sessionId = String(await cdpClient.attachToTarget(targetId) || '');
|
|
8371
|
-
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
8372
|
-
console.log(browsers_lib_messages.v5i(sessionId));
|
|
8373
|
-
console.log(browsers_lib_messages._JL());
|
|
8374
|
-
}
|
|
8375
|
-
await cdpClient.sendCommand('Page.enable', {}, sessionId);
|
|
8376
|
-
try {
|
|
8377
|
-
await cdpClient.enableRuntimeAndLog(sessionId);
|
|
8378
|
-
} catch {}
|
|
8379
|
-
return {
|
|
8380
|
-
targetId: String(targetId),
|
|
8381
|
-
sessionId: String(sessionId)
|
|
8382
|
-
};
|
|
8383
|
-
}
|
|
8384
|
-
async function extractPageHtml(cdpClient, sessionId, logSamples = 'true' === process.env.EXTENSION_AUTHOR_MODE, includeShadow = 'open-only') {
|
|
8385
|
-
let html = await cdpClient.getPageHTML(sessionId, includeShadow);
|
|
8386
|
-
if (!html) try {
|
|
8387
|
-
const targets = await cdpClient.getTargets();
|
|
8388
|
-
const fallbackTarget = targets.find((target)=>'page' === target.type && /example\.com|http/.test(String(target.url || '')));
|
|
8389
|
-
if (fallbackTarget && fallbackTarget.targetId) {
|
|
8390
|
-
const newSessionId = await cdpClient.attachToTarget(fallbackTarget.targetId);
|
|
8391
|
-
await cdpClient.waitForContentScriptInjection(newSessionId);
|
|
8392
|
-
const retryHtml = await cdpClient.getPageHTML(newSessionId, includeShadow);
|
|
8393
|
-
if (logSamples) {
|
|
8394
|
-
const sample2 = (retryHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
8395
|
-
console.log(browsers_lib_messages.LcW(sample2));
|
|
8396
|
-
}
|
|
8397
|
-
if (retryHtml) return retryHtml;
|
|
9626
|
+
await cdpClient.navigate(String(tempSession), url);
|
|
8398
9627
|
}
|
|
8399
|
-
} catch {}
|
|
8400
|
-
if (!html || !/(id=\"extension-root\"|content_script|content_title|js-probe)/.test(html)) for(let i = 0; i < 3; i++){
|
|
8401
|
-
await new Promise((r)=>setTimeout(r, 500));
|
|
8402
|
-
try {
|
|
8403
|
-
const againHtml = await cdpClient.getPageHTML(sessionId, includeShadow);
|
|
8404
|
-
if (logSamples) {
|
|
8405
|
-
const sample3 = (againHtml || '').slice(0, 200).replace(/\n/g, ' ');
|
|
8406
|
-
console.log(browsers_lib_messages.jUj(sample3));
|
|
8407
|
-
}
|
|
8408
|
-
if (againHtml && /(id=\"extension-root\"|content_script|content_title|js-probe)/.test(againHtml)) {
|
|
8409
|
-
html = againHtml;
|
|
8410
|
-
break;
|
|
8411
|
-
}
|
|
8412
|
-
} catch {}
|
|
8413
9628
|
}
|
|
8414
|
-
if (
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
console.log(browsers_lib_messages.jUj(sample4));
|
|
8420
|
-
}
|
|
8421
|
-
if (evaluatedHtml && evaluatedHtml.trim().length > 0) {
|
|
8422
|
-
html = evaluatedHtml;
|
|
8423
|
-
break;
|
|
8424
|
-
}
|
|
8425
|
-
} catch {}
|
|
8426
|
-
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());
|
|
8427
9634
|
}
|
|
8428
|
-
|
|
8429
|
-
|
|
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
|
+
};
|
|
8430
9643
|
}
|
|
8431
9644
|
function chromium_source_inspection_define_property(obj, key, value) {
|
|
8432
9645
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -8491,7 +9704,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8491
9704
|
const includeShadow = 'off' !== this.devOptions.sourceIncludeShadow;
|
|
8492
9705
|
try {
|
|
8493
9706
|
const payload = await this.cdpClient.evaluate(this.currentSessionId, `(() => {
|
|
8494
|
-
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"])');
|
|
8495
9708
|
if (!rootEl) return null;
|
|
8496
9709
|
const root = (${includeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
8497
9710
|
const maxDepth = 6;
|
|
@@ -8555,6 +9768,28 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8555
9768
|
if (payload && 'object' == typeof payload) return payload;
|
|
8556
9769
|
} catch {}
|
|
8557
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
|
+
}
|
|
8558
9793
|
async getPageMetaSnapshot() {
|
|
8559
9794
|
if (!this.cdpClient || !this.currentSessionId) return {};
|
|
8560
9795
|
try {
|
|
@@ -8616,7 +9851,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8616
9851
|
const includeShadow = 'off' !== this.devOptions.sourceIncludeShadow;
|
|
8617
9852
|
try {
|
|
8618
9853
|
const payload = await this.cdpClient.evaluate(this.currentSessionId, `(() => {
|
|
8619
|
-
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"])');
|
|
8620
9855
|
if (!rootEl) return null;
|
|
8621
9856
|
const root = (${includeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
8622
9857
|
const maxDepth = 4;
|
|
@@ -8836,6 +10071,10 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8836
10071
|
if (this.devOptions.sourceMeta) {
|
|
8837
10072
|
const metaSnapshot = await this.getPageMetaSnapshot();
|
|
8838
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);
|
|
8839
10078
|
}
|
|
8840
10079
|
if (Array.isArray(this.devOptions.sourceProbe)) {
|
|
8841
10080
|
const probes = await this.getSelectorProbes(this.devOptions.sourceProbe);
|
|
@@ -8898,6 +10137,14 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8898
10137
|
...payload
|
|
8899
10138
|
}));
|
|
8900
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
|
+
}
|
|
8901
10148
|
async getCdpPort() {
|
|
8902
10149
|
const instanceId = this.devOptions.instanceId;
|
|
8903
10150
|
return (0, shared_utils.jl)(this.devOptions.port, instanceId);
|
|
@@ -8941,30 +10188,14 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8941
10188
|
await this.emitSourceOutput(String(initialHtml || ''), 'pre_injection');
|
|
8942
10189
|
} catch {}
|
|
8943
10190
|
if (this.isAuthorMode()) console.log(browsers_lib_messages.mOc());
|
|
8944
|
-
await this.cdpClient.waitForContentScriptInjection(this.currentSessionId);
|
|
8945
|
-
|
|
10191
|
+
const injected = await this.cdpClient.waitForContentScriptInjection(this.currentSessionId);
|
|
10192
|
+
const emitInjection = await this.shouldEmitContentScriptInjected(injected);
|
|
10193
|
+
if (emitInjection) emitActionEvent("content_script_injected", {
|
|
8946
10194
|
url
|
|
8947
10195
|
});
|
|
10196
|
+
if (!injected) await this.cdpClient.pollForVisibleShadowHostContent(this.currentSessionId);
|
|
8948
10197
|
try {
|
|
8949
|
-
|
|
8950
|
-
const started = Date.now();
|
|
8951
|
-
while(Date.now() < deadline){
|
|
8952
|
-
const hasRoot = await this.cdpClient.evaluate(this.currentSessionId, `(() => { try {
|
|
8953
|
-
const hosts = Array.from(document.querySelectorAll('#extension-root,[data-extension-root="true"]'));
|
|
8954
|
-
if (!hosts.length) return false;
|
|
8955
|
-
for (const h of hosts) {
|
|
8956
|
-
try {
|
|
8957
|
-
const sr = h && h.shadowRoot;
|
|
8958
|
-
if (sr && (String(sr.innerHTML||'').length > 0)) return true;
|
|
8959
|
-
} catch { /* ignore */ }
|
|
8960
|
-
}
|
|
8961
|
-
return false;
|
|
8962
|
-
} catch { return false } })()`);
|
|
8963
|
-
if (hasRoot) break;
|
|
8964
|
-
const elapsed = Date.now() - started;
|
|
8965
|
-
const delay = elapsed < 2000 ? 150 : 500;
|
|
8966
|
-
await new Promise((r)=>setTimeout(r, delay));
|
|
8967
|
-
}
|
|
10198
|
+
await this.waitForContentScriptStyles(this.currentSessionId);
|
|
8968
10199
|
} catch {}
|
|
8969
10200
|
const outputConfig = this.getOutputConfig();
|
|
8970
10201
|
const html = await extractPageHtml(this.cdpClient, this.currentSessionId, this.isAuthorMode(), outputConfig.includeShadow);
|
|
@@ -8998,14 +10229,104 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
8998
10229
|
ws.on('message', async (data)=>{
|
|
8999
10230
|
try {
|
|
9000
10231
|
const message = JSON.parse(data);
|
|
9001
|
-
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
|
+
}
|
|
9002
10243
|
} catch (error) {}
|
|
9003
10244
|
});
|
|
9004
10245
|
}
|
|
9005
10246
|
stopWatching() {
|
|
9006
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
|
+
}
|
|
9007
10254
|
if (this.isAuthorMode()) console.log(browsers_lib_messages.Qx1());
|
|
9008
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
|
+
}
|
|
9009
10330
|
async handleFileChange() {
|
|
9010
10331
|
if (!this.cdpClient || !this.currentSessionId) return void console.warn(browsers_lib_messages.MfN());
|
|
9011
10332
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
@@ -9016,52 +10337,188 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9016
10337
|
console.log(browsers_lib_messages.$xt());
|
|
9017
10338
|
console.log(browsers_lib_messages.Tev());
|
|
9018
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) {
|
|
9019
10350
|
const sourceUrl = 'string' == typeof this.devOptions.source && 'true' !== this.devOptions.source ? this.devOptions.source : '';
|
|
9020
|
-
if (sourceUrl) {
|
|
10351
|
+
if (sourceUrl) try {
|
|
9021
10352
|
emitActionEvent('watch_reinspect_source_url', {
|
|
9022
10353
|
url: sourceUrl
|
|
9023
10354
|
});
|
|
9024
10355
|
const html = await this.inspectSource(sourceUrl, {
|
|
9025
|
-
forceNavigate:
|
|
10356
|
+
forceNavigate: false
|
|
9026
10357
|
});
|
|
9027
10358
|
await this.emitSourceOutput(html || '', 'updated');
|
|
9028
10359
|
return;
|
|
9029
|
-
}
|
|
9030
|
-
await this.cdpClient.waitForContentScriptInjection(this.currentSessionId);
|
|
9031
|
-
if (this.isAuthorMode()) console.log(browsers_lib_messages.Mcx());
|
|
9032
|
-
let html = '';
|
|
9033
|
-
const outputConfig = this.getOutputConfig();
|
|
9034
|
-
try {
|
|
9035
|
-
html = await this.cdpClient.getPageHTML(this.currentSessionId, outputConfig.includeShadow);
|
|
9036
|
-
} catch (e) {
|
|
9037
|
-
await new Promise((r)=>setTimeout(r, 250));
|
|
9038
|
-
try {
|
|
9039
|
-
html = await this.cdpClient.getPageHTML(this.currentSessionId, outputConfig.includeShadow);
|
|
9040
|
-
} catch {}
|
|
9041
|
-
}
|
|
9042
|
-
if (!html) {
|
|
9043
|
-
await new Promise((r)=>setTimeout(r, 300));
|
|
9044
|
-
try {
|
|
9045
|
-
html = await this.cdpClient.getPageHTML(this.currentSessionId, outputConfig.includeShadow);
|
|
9046
|
-
} catch {}
|
|
9047
|
-
}
|
|
9048
|
-
await this.emitSourceOutput(html || '', 'updated');
|
|
9049
|
-
} catch (error) {
|
|
10360
|
+
} catch {}
|
|
9050
10361
|
console.error(browsers_lib_messages.acp(error.message));
|
|
9051
|
-
|
|
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')) {
|
|
9052
10364
|
console.log(browsers_lib_messages.bGB());
|
|
9053
|
-
await this.reconnectToTarget();
|
|
10365
|
+
await this.reconnectToTarget(sourceUrl || void 0);
|
|
9054
10366
|
}
|
|
9055
10367
|
}
|
|
9056
10368
|
}, 300);
|
|
9057
10369
|
}
|
|
9058
|
-
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) {
|
|
9059
10498
|
if (!this.isAuthorMode()) return;
|
|
9060
10499
|
try {
|
|
9061
|
-
if (!this.cdpClient || !this.currentTargetId) return void console.warn(browsers_lib_messages.tVJ());
|
|
9062
10500
|
console.log(browsers_lib_messages.kGe());
|
|
9063
|
-
this.
|
|
9064
|
-
|
|
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());
|
|
9065
10522
|
} catch (error) {
|
|
9066
10523
|
console.error(browsers_lib_messages.pcF(error.message));
|
|
9067
10524
|
}
|
|
@@ -9092,19 +10549,32 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9092
10549
|
if (this.devOptions.source && 'string' == typeof this.devOptions.source && 'true' !== this.devOptions.source) urlToInspect = this.devOptions.source;
|
|
9093
10550
|
else if (this.devOptions.startingUrl) urlToInspect = this.devOptions.startingUrl;
|
|
9094
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
|
+
}
|
|
9095
10565
|
const html = await this.inspectSource(urlToInspect, {
|
|
9096
10566
|
forceNavigate: this.devOptions.watchSource && this.hasInspectedSourceOnce
|
|
9097
10567
|
});
|
|
9098
10568
|
this.hasInspectedSourceOnce = true;
|
|
9099
10569
|
await this.printHTML(html);
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
}
|
|
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
|
+
}
|
|
9108
10578
|
} catch (error) {
|
|
9109
10579
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.error(browsers_lib_messages.b82(error.message));
|
|
9110
10580
|
}
|
|
@@ -9118,7 +10588,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9118
10588
|
chromium_source_inspection_define_property(this, "isInitialized", false);
|
|
9119
10589
|
chromium_source_inspection_define_property(this, "isWatching", false);
|
|
9120
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);
|
|
9121
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);
|
|
9122
10596
|
chromium_source_inspection_define_property(this, "runtimeMode", void 0);
|
|
9123
10597
|
chromium_source_inspection_define_property(this, "lastOutputHash", void 0);
|
|
9124
10598
|
chromium_source_inspection_define_property(this, "lastByteLength", void 0);
|
|
@@ -9191,38 +10665,8 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9191
10665
|
run_chromium_define_property(this, "logTab", void 0);
|
|
9192
10666
|
run_chromium_define_property(this, "logger", void 0);
|
|
9193
10667
|
run_chromium_define_property(this, "chromiumCtx", void 0);
|
|
9194
|
-
this
|
|
9195
|
-
this.browser = options.browser;
|
|
9196
|
-
this.startingUrl = options.startingUrl;
|
|
9197
|
-
this.preferences = options.preferences;
|
|
9198
|
-
this.profile = options.profile;
|
|
9199
|
-
this.browserFlags = options.browserFlags;
|
|
9200
|
-
this.excludeBrowserFlags = options.excludeBrowserFlags;
|
|
9201
|
-
this.noOpen = options.noOpen;
|
|
10668
|
+
Object.assign(this, (0, runtime_options.pA)(options));
|
|
9202
10669
|
this.chromiumBinary = options.chromiumBinary;
|
|
9203
|
-
this.instanceId = options.instanceId;
|
|
9204
|
-
this.port = options.port;
|
|
9205
|
-
this.source = options.source;
|
|
9206
|
-
this.watchSource = options.watchSource;
|
|
9207
|
-
this.sourceFormat = options.sourceFormat;
|
|
9208
|
-
this.sourceSummary = options.sourceSummary;
|
|
9209
|
-
this.sourceMeta = options.sourceMeta;
|
|
9210
|
-
this.sourceProbe = options.sourceProbe;
|
|
9211
|
-
this.sourceTree = options.sourceTree;
|
|
9212
|
-
this.sourceConsole = options.sourceConsole;
|
|
9213
|
-
this.sourceDom = options.sourceDom;
|
|
9214
|
-
this.sourceMaxBytes = options.sourceMaxBytes;
|
|
9215
|
-
this.sourceRedact = options.sourceRedact;
|
|
9216
|
-
this.sourceIncludeShadow = options.sourceIncludeShadow;
|
|
9217
|
-
this.sourceDiff = options.sourceDiff;
|
|
9218
|
-
this.logLevel = options.logLevel;
|
|
9219
|
-
this.logContexts = options.logContexts;
|
|
9220
|
-
this.logFormat = options.logFormat;
|
|
9221
|
-
this.logTimestamps = options.logTimestamps;
|
|
9222
|
-
this.logColor = options.logColor;
|
|
9223
|
-
this.logUrl = options.logUrl;
|
|
9224
|
-
this.logTab = options.logTab;
|
|
9225
|
-
this.dryRun = options.dryRun;
|
|
9226
10670
|
}
|
|
9227
10671
|
}
|
|
9228
10672
|
var firefox_context = __webpack_require__("./webpack/plugin-browsers/run-firefox/firefox-context/index.ts");
|
|
@@ -9275,17 +10719,65 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9275
10719
|
return obj;
|
|
9276
10720
|
}
|
|
9277
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
|
+
}
|
|
9278
10730
|
apply(compiler) {
|
|
9279
10731
|
if (compiler?.hooks?.watchRun?.tapAsync) compiler.hooks.watchRun.tapAsync('run-browsers:watch', (compilation, done)=>{
|
|
9280
10732
|
try {
|
|
10733
|
+
this.contentReloadGeneration += 1;
|
|
9281
10734
|
const files = compilation?.modifiedFiles || new Set();
|
|
9282
10735
|
const normalized = Array.from(files).map((p)=>String(p).replace(/\\/g, '/'));
|
|
9283
|
-
const
|
|
9284
|
-
const
|
|
9285
|
-
const
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
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
|
+
}
|
|
9289
10781
|
} catch (error) {
|
|
9290
10782
|
this.ctx.logger?.warn?.('[reload] watchRun inspect failed:', String(error));
|
|
9291
10783
|
}
|
|
@@ -9296,43 +10788,600 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9296
10788
|
if (hasErrors) return void done();
|
|
9297
10789
|
try {
|
|
9298
10790
|
const compilation = stats?.compilation;
|
|
9299
|
-
const
|
|
9300
|
-
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);
|
|
9301
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
|
+
}
|
|
9302
10820
|
if (controller && 'function' == typeof controller.hardReload) {
|
|
9303
|
-
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
|
+
}
|
|
9304
10881
|
if (this.shouldEmitReloadActionEvent()) emitActionEvent('extension_reload', {
|
|
9305
10882
|
reason: reason || 'unknown',
|
|
9306
10883
|
browser: this.host.browser
|
|
9307
10884
|
});
|
|
10885
|
+
this.pendingContentReloadEntryNames = [];
|
|
10886
|
+
globalThis.__EXTJS_PENDING_FIREFOX_CONTENT_RELOAD__ = false;
|
|
10887
|
+
this.ctx.clearPendingReloadReason?.();
|
|
9308
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;
|
|
9309
11105
|
}
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
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;
|
|
9313
11148
|
}
|
|
9314
|
-
|
|
9315
|
-
|
|
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 || []));
|
|
9316
11168
|
}
|
|
9317
11169
|
constructor(host, ctx){
|
|
9318
11170
|
firefox_hard_reload_define_property(this, "host", void 0);
|
|
9319
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);
|
|
9320
11185
|
this.host = host;
|
|
9321
11186
|
this.ctx = ctx;
|
|
9322
11187
|
}
|
|
9323
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");
|
|
9324
11191
|
var messaging_client = __webpack_require__("./webpack/plugin-browsers/run-firefox/firefox-source-inspection/remote-firefox/messaging-client.ts");
|
|
9325
|
-
var
|
|
11192
|
+
var external_url_ = __webpack_require__("url");
|
|
9326
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
|
+
}
|
|
9327
11300
|
async function selectActors(client, urlToInspect) {
|
|
9328
11301
|
const deadline = Date.now() + 10000;
|
|
9329
11302
|
let triedAddTab = false;
|
|
11303
|
+
const normalizedUrlToInspect = setup_firefox_inspection_actors_normalizeInspectableUrl(urlToInspect);
|
|
9330
11304
|
while(Date.now() < deadline){
|
|
9331
11305
|
const allTargets = await client.getTargets() || [];
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
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
|
+
}
|
|
9336
11385
|
if (!triedAddTab && urlToInspect) {
|
|
9337
11386
|
triedAddTab = true;
|
|
9338
11387
|
try {
|
|
@@ -9346,15 +11395,48 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9346
11395
|
}
|
|
9347
11396
|
}
|
|
9348
11397
|
}
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
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
|
+
}
|
|
9353
11425
|
await new Promise((r)=>setTimeout(r, TARGET_SCAN_INTERVAL_MS));
|
|
9354
11426
|
}
|
|
9355
11427
|
throw new Error(browsers_lib_messages.Itp());
|
|
9356
11428
|
}
|
|
9357
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
|
+
}
|
|
9358
11440
|
async function ensureNavigatedAndLoaded(client, urlToInspect, tabActor) {
|
|
9359
11441
|
if (!tabActor) throw new Error(browsers_lib_messages.R4W());
|
|
9360
11442
|
let consoleActor = tabActor;
|
|
@@ -9377,6 +11459,31 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9377
11459
|
console.warn('[RDP] attach(frameActor) failed:', String(err.message || err));
|
|
9378
11460
|
}
|
|
9379
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
|
+
}
|
|
9380
11487
|
try {
|
|
9381
11488
|
await client.navigateViaScript(consoleActor, urlToInspect);
|
|
9382
11489
|
await client.waitForPageReady(consoleActor, urlToInspect, PAGE_READY_TIMEOUT_MS);
|
|
@@ -9645,6 +11752,10 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9645
11752
|
}
|
|
9646
11753
|
})()`);
|
|
9647
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);
|
|
9648
11759
|
}
|
|
9649
11760
|
if (Array.isArray(this.devOptions?.sourceProbe)) {
|
|
9650
11761
|
const probes = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
@@ -9679,7 +11790,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9679
11790
|
}
|
|
9680
11791
|
if (this.devOptions?.sourceTree && 'off' !== this.devOptions.sourceTree) {
|
|
9681
11792
|
const tree = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
9682
|
-
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"])');
|
|
9683
11794
|
if (!rootEl) return null;
|
|
9684
11795
|
const root = (${'off' !== this.devOptions.sourceIncludeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
9685
11796
|
const maxDepth = 4;
|
|
@@ -9760,11 +11871,238 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9760
11871
|
if ('string' == typeof json && json.length > 0) return JSON.parse(json);
|
|
9761
11872
|
} catch {}
|
|
9762
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
|
+
}
|
|
9763
12101
|
async getDomSnapshot() {
|
|
9764
12102
|
if (!this.client || !this.currentConsoleActor) return;
|
|
9765
12103
|
const includeShadow = this.devOptions?.sourceIncludeShadow !== 'off';
|
|
9766
12104
|
const payload = await this.evaluateJson(this.currentConsoleActor, `(() => {
|
|
9767
|
-
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"])');
|
|
9768
12106
|
if (!rootEl) return null;
|
|
9769
12107
|
const root = (${includeShadow ? 'rootEl.shadowRoot || rootEl' : 'rootEl'});
|
|
9770
12108
|
const maxDepth = 6;
|
|
@@ -9824,6 +12162,173 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9824
12162
|
truncated,
|
|
9825
12163
|
nodes
|
|
9826
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
|
+
};
|
|
9827
12332
|
})()`);
|
|
9828
12333
|
if (payload && 'object' == typeof payload) return payload;
|
|
9829
12334
|
}
|
|
@@ -9871,7 +12376,7 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9871
12376
|
await client.connect(port);
|
|
9872
12377
|
this.client = client;
|
|
9873
12378
|
this.setupConsoleCapture();
|
|
9874
|
-
if (this.devOptions?.sourceConsole) await (0,
|
|
12379
|
+
if (this.devOptions?.sourceConsole) await (0, remote_firefox_logging.c)(client);
|
|
9875
12380
|
this.initialized = true;
|
|
9876
12381
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) {
|
|
9877
12382
|
console.log(browsers_lib_messages.X6h());
|
|
@@ -9938,6 +12443,9 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9938
12443
|
const currentTitle = await this.client.evaluate(actorToUse, 'String(document.title)');
|
|
9939
12444
|
if ('string' == typeof currentTitle) meta.title = currentTitle;
|
|
9940
12445
|
} catch {}
|
|
12446
|
+
try {
|
|
12447
|
+
await this.waitForContentScriptStyles(actorToUse);
|
|
12448
|
+
} catch {}
|
|
9941
12449
|
const html = await (0, source_inspect.Lj)(this.client, descriptor, actorToUse) || '';
|
|
9942
12450
|
this.emitSourceOutput(html, 'post_injection', meta);
|
|
9943
12451
|
return;
|
|
@@ -9950,7 +12458,112 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9950
12458
|
}
|
|
9951
12459
|
async waitForContentScriptInjection(consoleActor) {
|
|
9952
12460
|
if (!this.client) return;
|
|
9953
|
-
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
|
+
}
|
|
9954
12567
|
}
|
|
9955
12568
|
async handleFileChange() {
|
|
9956
12569
|
if (!this.client || !this.currentConsoleActor) return;
|
|
@@ -9964,6 +12577,9 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9964
12577
|
}
|
|
9965
12578
|
if (this.lastUrlToInspect) await this.ensureUrlAndReady(this.currentConsoleActor, this.lastUrlToInspect);
|
|
9966
12579
|
await this.waitForContentScriptInjection(this.currentConsoleActor);
|
|
12580
|
+
try {
|
|
12581
|
+
await this.waitForContentScriptStyles(this.currentConsoleActor);
|
|
12582
|
+
} catch {}
|
|
9967
12583
|
let lastError = null;
|
|
9968
12584
|
for(let attempt = 0; attempt < 3; attempt++){
|
|
9969
12585
|
try {
|
|
@@ -9989,6 +12605,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9989
12605
|
}
|
|
9990
12606
|
}, CHANGE_DEBOUNCE_MS);
|
|
9991
12607
|
}
|
|
12608
|
+
registerContentReloadSnapshotHook() {
|
|
12609
|
+
globalThis.__EXTJS_ON_FIREFOX_CONTENT_RELOADED__ = async ()=>{
|
|
12610
|
+
await this.handleFileChange();
|
|
12611
|
+
};
|
|
12612
|
+
}
|
|
9992
12613
|
apply(compiler) {
|
|
9993
12614
|
if (this.host.dryRun) return;
|
|
9994
12615
|
if ('development' !== compiler.options.mode) return;
|
|
@@ -9999,6 +12620,18 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
9999
12620
|
if (!this.initialized) await this.initialize();
|
|
10000
12621
|
const urlToInspect = this.resolveUrlToInspect();
|
|
10001
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
|
+
}
|
|
10002
12635
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(browsers_lib_messages.rCC(urlToInspect));
|
|
10003
12636
|
const { tabActor, consoleActor } = await this.selectActors(urlToInspect);
|
|
10004
12637
|
this.currentTabActor = tabActor;
|
|
@@ -10012,15 +12645,61 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10012
12645
|
const resolvedConsoleActor = await this.resolveConsoleActor(tabActor, urlToInspect);
|
|
10013
12646
|
this.currentConsoleActor = resolvedConsoleActor || consoleActor;
|
|
10014
12647
|
if (this.currentConsoleActor) {
|
|
10015
|
-
await this.waitForContentScriptInjection(this.currentConsoleActor);
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
|
|
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 {}
|
|
10019
12698
|
await this.printHTML(this.currentConsoleActor);
|
|
10020
12699
|
}
|
|
10021
12700
|
if (this.devOptions?.watchSource) {
|
|
12701
|
+
this.registerContentReloadSnapshotHook();
|
|
10022
12702
|
this.isWatching = true;
|
|
10023
|
-
await this.handleFileChange();
|
|
10024
12703
|
}
|
|
10025
12704
|
} catch (error) {
|
|
10026
12705
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.error(browsers_lib_messages.b82(error.message));
|
|
@@ -10089,8 +12768,6 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10089
12768
|
run_firefox_define_property(this, "geckoBinary", void 0);
|
|
10090
12769
|
run_firefox_define_property(this, "port", void 0);
|
|
10091
12770
|
run_firefox_define_property(this, "instanceId", void 0);
|
|
10092
|
-
run_firefox_define_property(this, "keepProfileChanges", void 0);
|
|
10093
|
-
run_firefox_define_property(this, "copyFromProfile", void 0);
|
|
10094
12771
|
run_firefox_define_property(this, "source", void 0);
|
|
10095
12772
|
run_firefox_define_property(this, "watchSource", void 0);
|
|
10096
12773
|
run_firefox_define_property(this, "sourceFormat", void 0);
|
|
@@ -10115,38 +12792,8 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10115
12792
|
run_firefox_define_property(this, "logger", void 0);
|
|
10116
12793
|
run_firefox_define_property(this, "firefoxCtx", void 0);
|
|
10117
12794
|
run_firefox_define_property(this, "rdpController", void 0);
|
|
10118
|
-
this
|
|
10119
|
-
this.browser = options.browser;
|
|
10120
|
-
this.startingUrl = options.startingUrl;
|
|
10121
|
-
this.preferences = options.preferences;
|
|
10122
|
-
this.profile = options.profile;
|
|
10123
|
-
this.browserFlags = options.browserFlags;
|
|
10124
|
-
this.excludeBrowserFlags = options.excludeBrowserFlags;
|
|
10125
|
-
this.noOpen = options.noOpen;
|
|
12795
|
+
Object.assign(this, (0, runtime_options.pA)(options));
|
|
10126
12796
|
this.geckoBinary = options.geckoBinary;
|
|
10127
|
-
this.instanceId = options.instanceId;
|
|
10128
|
-
this.port = options.port;
|
|
10129
|
-
this.source = options.source;
|
|
10130
|
-
this.watchSource = options.watchSource;
|
|
10131
|
-
this.sourceFormat = options.sourceFormat;
|
|
10132
|
-
this.sourceSummary = options.sourceSummary;
|
|
10133
|
-
this.sourceMeta = options.sourceMeta;
|
|
10134
|
-
this.sourceProbe = options.sourceProbe;
|
|
10135
|
-
this.sourceTree = options.sourceTree;
|
|
10136
|
-
this.sourceConsole = options.sourceConsole;
|
|
10137
|
-
this.sourceDom = options.sourceDom;
|
|
10138
|
-
this.sourceMaxBytes = options.sourceMaxBytes;
|
|
10139
|
-
this.sourceRedact = options.sourceRedact;
|
|
10140
|
-
this.sourceIncludeShadow = options.sourceIncludeShadow;
|
|
10141
|
-
this.sourceDiff = options.sourceDiff;
|
|
10142
|
-
this.logLevel = options.logLevel;
|
|
10143
|
-
this.logContexts = options.logContexts;
|
|
10144
|
-
this.logFormat = options.logFormat;
|
|
10145
|
-
this.logTimestamps = options.logTimestamps;
|
|
10146
|
-
this.logColor = options.logColor;
|
|
10147
|
-
this.logUrl = options.logUrl;
|
|
10148
|
-
this.logTab = options.logTab;
|
|
10149
|
-
this.dryRun = options.dryRun;
|
|
10150
12797
|
}
|
|
10151
12798
|
}
|
|
10152
12799
|
function plugin_browsers_define_property(obj, key, value) {
|
|
@@ -10211,39 +12858,9 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10211
12858
|
plugin_browsers_define_property(this, "logUrl", void 0);
|
|
10212
12859
|
plugin_browsers_define_property(this, "logTab", void 0);
|
|
10213
12860
|
const normalized = normalizePluginOptions(options);
|
|
10214
|
-
this
|
|
10215
|
-
this.browser = normalized.browser;
|
|
10216
|
-
this.startingUrl = normalized.startingUrl;
|
|
10217
|
-
this.preferences = normalized.preferences;
|
|
10218
|
-
this.profile = normalized.profile;
|
|
10219
|
-
this.browserFlags = normalized.browserFlags;
|
|
10220
|
-
this.excludeBrowserFlags = normalized.excludeBrowserFlags;
|
|
10221
|
-
this.noOpen = normalized.noOpen;
|
|
12861
|
+
Object.assign(this, (0, runtime_options.pA)(normalized));
|
|
10222
12862
|
this.chromiumBinary = normalized.chromiumBinary;
|
|
10223
12863
|
this.geckoBinary = normalized.geckoBinary;
|
|
10224
|
-
this.instanceId = normalized.instanceId;
|
|
10225
|
-
this.port = normalized.port;
|
|
10226
|
-
this.source = normalized.source;
|
|
10227
|
-
this.watchSource = normalized.watchSource;
|
|
10228
|
-
this.sourceFormat = normalized.sourceFormat;
|
|
10229
|
-
this.sourceSummary = normalized.sourceSummary;
|
|
10230
|
-
this.sourceMeta = normalized.sourceMeta;
|
|
10231
|
-
this.sourceProbe = normalized.sourceProbe;
|
|
10232
|
-
this.sourceTree = normalized.sourceTree;
|
|
10233
|
-
this.sourceConsole = normalized.sourceConsole;
|
|
10234
|
-
this.sourceDom = normalized.sourceDom;
|
|
10235
|
-
this.sourceMaxBytes = normalized.sourceMaxBytes;
|
|
10236
|
-
this.sourceRedact = normalized.sourceRedact;
|
|
10237
|
-
this.sourceIncludeShadow = normalized.sourceIncludeShadow;
|
|
10238
|
-
this.sourceDiff = normalized.sourceDiff;
|
|
10239
|
-
this.logLevel = normalized.logLevel;
|
|
10240
|
-
this.logContexts = normalized.logContexts;
|
|
10241
|
-
this.logFormat = normalized.logFormat;
|
|
10242
|
-
this.logTimestamps = normalized.logTimestamps;
|
|
10243
|
-
this.logColor = normalized.logColor;
|
|
10244
|
-
this.logUrl = normalized.logUrl;
|
|
10245
|
-
this.logTab = normalized.logTab;
|
|
10246
|
-
this.dryRun = normalized.dryRun;
|
|
10247
12864
|
if ('chromium-based' === this.browser && !this.chromiumBinary) {
|
|
10248
12865
|
console.error(browsers_lib_messages.nek());
|
|
10249
12866
|
process.exit(1);
|
|
@@ -10413,6 +13030,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10413
13030
|
watchSource: devOptions.watchSource,
|
|
10414
13031
|
sourceFormat: devOptions.sourceFormat,
|
|
10415
13032
|
sourceSummary: devOptions.sourceSummary,
|
|
13033
|
+
sourceMeta: devOptions.sourceMeta,
|
|
13034
|
+
sourceProbe: devOptions.sourceProbe,
|
|
13035
|
+
sourceTree: devOptions.sourceTree,
|
|
13036
|
+
sourceConsole: devOptions.sourceConsole,
|
|
13037
|
+
sourceDom: devOptions.sourceDom,
|
|
10416
13038
|
sourceMaxBytes: devOptions.sourceMaxBytes,
|
|
10417
13039
|
sourceRedact: devOptions.sourceRedact,
|
|
10418
13040
|
sourceIncludeShadow: devOptions.sourceIncludeShadow,
|
|
@@ -10437,6 +13059,11 @@ Set background.noDynamicEntryWarning to true to disable this warning.
|
|
|
10437
13059
|
clean: devOptions.output.clean,
|
|
10438
13060
|
path: primaryExtensionOutputDir,
|
|
10439
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',
|
|
10440
13067
|
hotUpdateChunkFilename: 'hot/[id].[fullhash].hot-update.js',
|
|
10441
13068
|
hotUpdateMainFilename: 'hot/[runtime].[fullhash].hot-update.json',
|
|
10442
13069
|
environment: {
|