extension-develop 4.1.34 → 4.1.35

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.
Files changed (78) hide show
  1. package/dist/206~0.mjs +33 -0
  2. package/dist/363~0.mjs +1 -1
  3. package/dist/469~0.mjs +98 -16
  4. package/dist/519~0.mjs +12 -1
  5. package/dist/771~0.mjs +49 -8
  6. package/dist/832~0.mjs +127 -25
  7. package/dist/840~0.mjs +215 -54
  8. package/dist/846~0.mjs +16 -14
  9. package/dist/852~0.mjs +2 -0
  10. package/dist/88~0.mjs +10 -1
  11. package/dist/command-preview.d.ts +2 -0
  12. package/dist/contract/codes.json +9 -0
  13. package/dist/contracts-entry.d.ts +1 -1
  14. package/dist/contracts.mjs +109 -1
  15. package/dist/css-parse-guard-loader.mjs +7 -2
  16. package/dist/dev-server/control-bridge/log-rule.d.ts +38 -0
  17. package/dist/dev-server/control-bridge/logs-query.d.ts +2 -55
  18. package/dist/dev-server/control-bridge/producer-runtime.d.ts +1 -1
  19. package/dist/dev-server/html-refresh.d.ts +10 -0
  20. package/dist/dev-server/port-manager.d.ts +14 -0
  21. package/dist/dev-server/reserved-listen.d.ts +9 -0
  22. package/dist/dev-server/session-restart.d.ts +1 -1
  23. package/dist/dev-server~0.mjs +155 -30
  24. package/dist/extension-js-devtools/build-stamp.json +2 -2
  25. package/dist/extension-js-devtools/chrome/background/service_worker.js +2 -2
  26. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  27. package/dist/extension-js-devtools/chromium/background/service_worker.js +2 -2
  28. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  29. package/dist/extension-js-devtools/edge/background/service_worker.js +2 -2
  30. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  31. package/dist/extension-js-devtools/firefox/background/scripts.js +2 -2
  32. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  33. package/dist/extension-js-theme/build-stamp.json +2 -2
  34. package/dist/feature-scripts-classic-concat-loader.js +45 -2
  35. package/dist/feature-scripts-classic-concat-loader.mjs +45 -2
  36. package/dist/feature-scripts-classic-traced-globals-loader.mjs +111 -0
  37. package/dist/feature-scripts-content-script-wrapper.js +10 -6
  38. package/dist/feature-scripts-content-script-wrapper.mjs +10 -6
  39. package/dist/lib/config-loader.d.ts +1 -0
  40. package/dist/lib/css-minimizer-options.d.ts +8 -0
  41. package/dist/lib/develop-context.d.ts +1 -1
  42. package/dist/lib/live-dev-session.d.ts +5 -0
  43. package/dist/lib/messages.d.ts +9 -1
  44. package/dist/lib/messaging.d.ts +2 -0
  45. package/dist/lib/package-manager.d.ts +7 -1
  46. package/dist/lib/paths.d.ts +1 -0
  47. package/dist/lib/project.d.ts +10 -2
  48. package/dist/lib/remote-archive.d.ts +11 -0
  49. package/dist/lib/rename-with-retry.d.ts +6 -0
  50. package/dist/lib/session-paths.d.ts +1 -0
  51. package/dist/lib/zip.d.ts +5 -1
  52. package/dist/plugin-browsers/index.d.ts +2 -0
  53. package/dist/plugin-css/css-in-content-script-loader.d.ts +1 -1
  54. package/dist/plugin-css/css-in-html-loader.d.ts +1 -1
  55. package/dist/plugin-css/css-lib/build-css-rules.d.ts +2 -1
  56. package/dist/plugin-css/css-lib/verbatim-css.d.ts +1 -0
  57. package/dist/plugin-js-frameworks/js-tools/typescript.d.ts +1 -0
  58. package/dist/plugin-playwright/index.d.ts +3 -0
  59. package/dist/plugin-special-folders/messages.d.ts +1 -0
  60. package/dist/plugin-special-folders/warn-upon-folder-changes.d.ts +1 -1
  61. package/dist/plugin-web-extension/feature-html/html-lib/options-dialog-floor.d.ts +7 -0
  62. package/dist/plugin-web-extension/feature-html/html-lib/patch-html.d.ts +3 -1
  63. package/dist/plugin-web-extension/feature-html/steps/update-html-file.d.ts +1 -0
  64. package/dist/plugin-web-extension/feature-manifest/steps/apply-dev-defaults-lib/dev-injected-hosts.d.ts +4 -1
  65. package/dist/plugin-web-extension/feature-scripts/messages.d.ts +1 -0
  66. package/dist/plugin-web-extension/feature-scripts/steps/add-content-script-wrapper/classic-concat-loader.d.ts +1 -0
  67. package/dist/plugin-web-extension/feature-scripts/steps/add-content-script-wrapper/content-script-wrapper.d.ts +1 -0
  68. package/dist/plugin-web-extension/feature-scripts/steps/add-content-script-wrapper/index.d.ts +1 -0
  69. package/dist/plugin-web-extension/feature-scripts/steps/classic-traced-globals-loader.d.ts +7 -0
  70. package/dist/plugin-web-extension/feature-scripts/steps/warn-unshipped-runtime-assets.d.ts +32 -0
  71. package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/messages.d.ts +1 -0
  72. package/dist/plugin-web-extension/shared/discover-runtime-surfaces.d.ts +2 -0
  73. package/dist/plugin-web-extension/shared/script-graph.d.ts +4 -0
  74. package/dist/rspack-config~0.mjs +799 -196
  75. package/dist/types.d.ts +7 -1
  76. package/dist/zip~0.mjs +14 -7
  77. package/package.json +3 -3
  78. package/dist/plugin-css/css-lib/is-content-script.d.ts +0 -2
@@ -11,26 +11,27 @@ import { getManifestFieldsData } from "browser-extension-manifest-fields";
11
11
  import content_security_policy_parser from "content-security-policy-parser";
12
12
  import node_fs from "node:fs";
13
13
  import node_path from "node:path";
14
+ import { filterKeysForThisBrowser, findPrefixedManifestVersionKeys, findDroppedVendorKeys, isStaticThemeSource, isValidManifestVersion, isStaticTheme } from "./143~0.mjs";
15
+ import { isChromiumBasedBrowser, isEmulatorBrowser, isWebkitBasedBrowser, stripBom, parseJsonSafe, isGeckoBasedBrowser } from "./937~0.mjs";
14
16
  import { debugLine, isDebug, CODES, humanLine, prefix as messaging_prefix } from "./852~0.mjs";
15
17
  import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset, CONTENT_SCRIPT_CSS_PROBE_MARKER_PREFIX, createContentScriptCssProbeMarkerPattern, getCanonicalContentScriptJsAssetName, isCanonicalContentScriptAsset, EXTENSIONJS_CONTENT_SCRIPT_LAYER } from "./640~0.mjs";
16
- import { manifestGoneDuringSession, publicFolderOffRef, bundlerFatalError, bundlerRecompiling, browserRunnerDisabled, buildBridgeProducerSource, CONTROL_PORT_ASSET_NAME, publicFolderShadowed, specialFoldersSetupSummary, resolveCompanionExtensionDirs, spacerLine, noEntrypointsDetected, specialFolderChangeDetected, recordCodedWarning, messages_ready, serverRestartRequiredFromSpecialFolderMessageOnly, PlaywrightPlugin, publicMustBeAtProjectRoot, InjectBridgeRelay, prependToEmittedAsset, getSpecialFoldersDataForCompiler, publicFileCollidesWithEntry, computeExtensionsToLoad } from "./832~0.mjs";
17
- import { isChromiumBasedBrowser, isEmulatorBrowser, isWebkitBasedBrowser, stripBom, parseJsonSafe, isGeckoBasedBrowser } from "./937~0.mjs";
18
+ import { manifestGoneDuringSession, publicFolderOffRef, bundlerFatalError, bundlerRecompiling, browserRunnerDisabled, buildBridgeProducerSource, CONTROL_PORT_ASSET_NAME, publicFolderShadowed, specialFoldersSetupSummary, resolveCompanionExtensionDirs, spacerLine, noEntrypointsDetected, specialFolderChangeDetected, recordCodedWarning, messages_ready, serverRestartRequiredFromSpecialFolderMessageOnly, PlaywrightPlugin, publicFolderAppeared, publicMustBeAtProjectRoot, InjectBridgeRelay, prependToEmittedAsset, getSpecialFoldersDataForCompiler, publicFileCollidesWithEntry, computeExtensionsToLoad } from "./832~0.mjs";
18
19
  import { renderStatsBlocks, makeSanitizedConsole } from "./stats-handler~0.mjs";
19
- import { sidebarKeyTranslatedForBrowser, missingGeckoDataCollectionPermissions as messages_missingGeckoDataCollectionPermissions, hasMv2SandboxPolicy, safariIdleUnsupported, normalizeManifestOutputPath, edgeStoreKeyDropped, importMetaUrlForEmitPath, dropWebkitUnsupportedKeys, cleanDistSkippedNotFound, fatalManifestShapeFixed, EnvPlugin, manifestVersionLostForBrowser, mv3BrowserActionFoldedIntoAction, safariNotificationsUnsupported, themeImageOutputPath, shouldFoldActionIntoBrowserAction, getManifestContent, isFolder, manifestFilesInTurnedOffPublic, setOriginalManifestContent, isFromFilepathList, mv2SandboxPolicyDropped, safariManagementUnsupported, safariMemberUnsupported, safariDownloadsUnsupported, resolveRootAbsoluteRef, applyIndependentHtmlSurfaces, serverRestartRequiredFromManifestError, safariOffscreenUnsupported, boring, geckoSidePanelUnsupported, isCompilerRestarting, pageActionNotSupportedByBrowser, mv2ActionFoldedIntoBrowserAction, getOriginalManifestContent, cleanDistRemovedSummary, buildCanonicalManifestWithOverrides, themeNotSupportedByBrowser, unixify as paths_unixify, shouldFoldBrowserActionIntoAction, safariIdentityUnsupported, projectConfigChangedRestartRequired, isWebkitUnsupportedPermission, mv3BackgroundPageUnsupported, isHollowContentScript, manifestIncludeSummary, vendorPrefixedKeyDropped, iconOutputPath, externalAssetOutputPath, manifestEmitSuccess, zipPackagingSkipped, manifestLegacyWarningsSummary, pageActionDropReason, manifestDepsTracked, pageActionDroppedForBrowserAction, themeIconOutputPath, safariHistoryUnsupported, safariTabGroupsUnsupported, safariUserScriptsUnsupported, safariOmniboxUnsupported, isManifestAddress, cleanDistStarting, manifestInvalidError, requestDevSessionRestart, omitWebkitDroppedEntries, safariBookmarksUnsupported, getCurrentManifestContent, geckoActionUnsupportedOnMv2, invalidThemeValue, mv3StringPolicyRewritten, sidebarFoldTarget, manifestOverridesSummary, hasMv3StringPolicy, collectRootAbsoluteRefs, manifestFieldMistyped, safariSidePanelUnsupported, contentScriptEntryDroppedForBrowser, legacyManifestPathWarning, setCurrentManifestContent } from "./363~0.mjs";
20
+ import { sidebarKeyTranslatedForBrowser, missingGeckoDataCollectionPermissions as messages_missingGeckoDataCollectionPermissions, hasMv2SandboxPolicy, safariIdleUnsupported, normalizeManifestOutputPath, edgeStoreKeyDropped, importMetaUrlForEmitPath, dropWebkitUnsupportedKeys, cleanDistSkippedNotFound, fatalManifestShapeFixed, EnvPlugin, manifestVersionLostForBrowser, mv3BrowserActionFoldedIntoAction, safariNotificationsUnsupported, themeImageOutputPath, shouldFoldActionIntoBrowserAction, getManifestContent, isFolder, manifestFilesInTurnedOffPublic, setOriginalManifestContent, isFromFilepathList, mv2SandboxPolicyDropped, safariManagementUnsupported, safariMemberUnsupported, OPTIONS_HTML_FEATURE, safariDownloadsUnsupported, resolveRootAbsoluteRef, applyIndependentHtmlSurfaces, serverRestartRequiredFromManifestError, safariOffscreenUnsupported, boring, geckoSidePanelUnsupported, isCompilerRestarting, pageActionNotSupportedByBrowser, mv2ActionFoldedIntoBrowserAction, getOriginalManifestContent, cleanDistRemovedSummary, buildCanonicalManifestWithOverrides, themeNotSupportedByBrowser, unixify as paths_unixify, shouldFoldBrowserActionIntoAction, safariIdentityUnsupported, projectConfigChangedRestartRequired, isWebkitUnsupportedPermission, mv3BackgroundPageUnsupported, isHollowContentScript, manifestIncludeSummary, vendorPrefixedKeyDropped, iconOutputPath, externalAssetOutputPath, manifestEmitSuccess, zipPackagingSkipped, manifestLegacyWarningsSummary, pageActionDropReason, manifestDepsTracked, pageActionDroppedForBrowserAction, themeIconOutputPath, safariHistoryUnsupported, safariTabGroupsUnsupported, safariUserScriptsUnsupported, safariOmniboxUnsupported, isManifestAddress, cleanDistStarting, manifestInvalidError, requestDevSessionRestart, omitWebkitDroppedEntries, safariBookmarksUnsupported, getCurrentManifestContent, geckoActionUnsupportedOnMv2, invalidThemeValue, mv3StringPolicyRewritten, sidebarFoldTarget, manifestOverridesSummary, hasMv3StringPolicy, collectRootAbsoluteRefs, manifestFieldMistyped, safariSidePanelUnsupported, contentScriptEntryDroppedForBrowser, legacyManifestPathWarning, setCurrentManifestContent } from "./363~0.mjs";
20
21
  import { projectConfigCandidatePaths } from "./846~0.mjs";
21
22
  import { REMOTE_SOURCE_PROVENANCE_FILE } from "./zip~0.mjs";
22
23
  import { debugExtensionsToLoad, treeWithSourceFiles, getDirs, codedError, zipSkippedSymlinks, asAbsolute, treeWithDistFilesBrowser, packagingDistributionFiles, displayPath as paths_displayPath, toPosixPath as paths_toPosixPath, debugContextPath, packagingSourceFiles, debugBrowser, debugOutputPath, manifestInvalidJson, treeWithSourceAndDistFiles, noCompanionExtensionsResolved } from "./469~0.mjs";
23
- import { maybeUsePreact, maybeUseReact, jsFrameworksIntegrationsEnabled, RAW_RESOURCE_QUERY, ensureTypeScriptConfig, resolveDevelopInstallRoot, loadLoaderOptions, getUserTypeScriptConfigFile, resolveTranspilePackageDirs, contentScriptEntryForAsset, jsFrameworksHmrSummary, isDevContentScriptStandInAsset, hasDependency, isUsingJsxFramework, defaultSplitChunks, buildDevContentScriptMarkerPrelude, resolveReactRefreshEntry, isUsingTypeScript, classifyEntrySurface, planDevContentScripts, isUsingVue, backgroundIsRequiredMessageOnly, mergeLoaderOptions, recordZipFailure, svelteCompilerRuntimeMismatch, isUsingIntegration as messages_isUsingIntegration, maybeUseVue, maybeUseSolid, DEV_CONTENT_SCRIPTS_RUNTIME_SOURCE, ensureOptionalContractPackageResolved, jsFrameworksConfigsDetected, NOT_RAW_RESOURCE_QUERY, createNodeModulesExclude, recordZipArtifact, resolveDevelopDistFile, swcParserForFile, getJsxImportSource, isUsingReact, DEV_CONTENT_SCRIPT_REGISTRY_ASSET } from "./840~0.mjs";
24
+ import { maybeUsePreact, maybeUseReact, jsFrameworksIntegrationsEnabled, RAW_RESOURCE_QUERY, ensureTypeScriptConfig, resolveDevelopInstallRoot, loadLoaderOptions, getUserTypeScriptConfigFile, resolveTranspilePackageDirs, contentScriptEntryForAsset, jsFrameworksHmrSummary, isDevContentScriptStandInAsset, hasDependency, isUsingJsxFramework, defaultSplitChunks, buildDevContentScriptMarkerPrelude, resolveReactRefreshEntry, isUsingTypeScript, classifyEntrySurface, planDevContentScripts, isUsingVue, backgroundIsRequiredMessageOnly, getUserJsConfigFile, mergeLoaderOptions, recordZipFailure, svelteCompilerRuntimeMismatch, isUsingIntegration as messages_isUsingIntegration, maybeUseVue, maybeUseSolid, DEV_CONTENT_SCRIPTS_RUNTIME_SOURCE, ensureOptionalContractPackageResolved, jsFrameworksConfigsDetected, NOT_RAW_RESOURCE_QUERY, createNodeModulesExclude, recordZipArtifact, resolveDevelopDistFile, swcParserForFile, getJsxImportSource, isUsingReact, DEV_CONTENT_SCRIPT_REGISTRY_ASSET } from "./840~0.mjs";
24
25
  import { cssMinifierDroppedRules, postCssConfigUnreadable, missingSassDependency, deadCssUrlRef, postCssPluginNotResolved, postCssConfigPluginsShape, cssIntegrationsEnabled, cssConfigsDetected, isUsingIntegration } from "./524~0.mjs";
25
26
  import { PROJECT_MANIFEST_FILENAMES, findNearestProjectManifestSync, readProjectDependencies } from "./731~0.mjs";
26
- import { foldersRoots, rememberSpecialFoldersConfig, isScriptsFolderEntry, publicFolderSetting, scriptsFolderRoot } from "./471~0.mjs";
27
- import { filterKeysForThisBrowser, findPrefixedManifestVersionKeys, findDroppedVendorKeys, isStaticThemeSource, isValidManifestVersion, isStaticTheme } from "./143~0.mjs";
28
- import { toResourceKey, isResourceUnderDirs, canonicalizeDir, canonicalizeResourcePath } from "./712~0.mjs";
29
27
  import { publicRootsFor, rememberPublicRoots, publicRelativePath as resolve_public_folder_publicRelativePath, turnedOffPublicFolders, inspectPublicFolders, findPublicFile, publicContainmentRoot, publicResolveRoots } from "./105~0.mjs";
30
28
  import { minifierDroppedTokens, restoreVerbatimCssAssets } from "./88~0.mjs";
31
29
  import { PUBLIC_ROOT_SCHEME } from "./177~0.mjs";
32
30
  import { toPosixPath } from "./273~0.mjs";
33
- import { buildConstantNeverDefined, getURLDependencyMissing, entrySplitAcrossInitialFiles, fetchedFileDependencyMissing, compiledSourceSpelling, importScriptsDependencyMissing, injectedFileDependencyMissing, injectedCompiledSourceLiteral, workerStartedFromPageContext, staticImportDependencyMissing, runtimeSetSurfaceDependencyMissing } from "./519~0.mjs";
31
+ import { foldersRoots, rememberSpecialFoldersConfig, isScriptsFolderEntry, publicFolderSetting, scriptsFolderRoot } from "./471~0.mjs";
32
+ import { toResourceKey, isResourceUnderDirs, canonicalizeDir, canonicalizeResourcePath } from "./712~0.mjs";
33
+ import { buildConstantNeverDefined, getURLDependencyMissing, entrySplitAcrossInitialFiles, fetchedFileDependencyMissing, compiledSourceSpelling, importScriptsDependencyMissing, injectedFileDependencyMissing, injectedCompiledSourceLiteral, workerStartedFromPageContext, staticImportDependencyMissing, runtimeAssetFolderNotShipped, runtimeSetSurfaceDependencyMissing } from "./519~0.mjs";
34
+ import { renameSyncWithRetry } from "./206~0.mjs";
34
35
  import { sessionStateDir } from "./771~0.mjs";
35
36
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
36
37
  import { dirname as __rspack_dirname } from "node:path";
@@ -38,6 +39,40 @@ var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(imp
38
39
  import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
39
40
  import * as __rspack_external_node_path_806ed179 from "node:path";
40
41
  import * as __rspack_external_parse5_utilities_4a00fdd6 from "parse5-utilities";
42
+ const DEFAULT_SWC_TARGETS = [
43
+ 'chrome >= 100'
44
+ ];
45
+ function resolveSwcTargets(rawManifest, browser) {
46
+ if (!rawManifest || 'object' != typeof rawManifest) return [
47
+ ...DEFAULT_SWC_TARGETS
48
+ ];
49
+ const name = String(browser || 'chrome');
50
+ const manifest = filterKeysForThisBrowser(rawManifest, name);
51
+ if (isGeckoBasedBrowser(name)) {
52
+ const geckoMin = manifest.browser_specific_settings?.gecko?.strict_min_version || manifest.applications?.gecko?.strict_min_version;
53
+ const major = parseInt(String(geckoMin ?? '').split('.')[0], 10);
54
+ return Number.isNaN(major) ? [
55
+ ...DEFAULT_SWC_TARGETS
56
+ ] : [
57
+ `firefox >= ${major}`
58
+ ];
59
+ }
60
+ if (isChromiumBasedBrowser(name) && manifest.minimum_chrome_version) return [
61
+ `chrome >= ${manifest.minimum_chrome_version}`
62
+ ];
63
+ return [
64
+ ...DEFAULT_SWC_TARGETS
65
+ ];
66
+ }
67
+ function cssMinimizerOptions(rawManifest, browser) {
68
+ return {
69
+ targets: resolveSwcTargets(rawManifest, browser),
70
+ exclude: {
71
+ dirSelector: true,
72
+ langSelectorList: true
73
+ }
74
+ };
75
+ }
41
76
  function getLoggingPrefix(type) {
42
77
  return messaging_prefix(type);
43
78
  }
@@ -94,7 +129,7 @@ function scannableSourcePath(resource) {
94
129
  function escapeForRegExp(value) {
95
130
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
96
131
  }
97
- function matchesHostPattern(pattern, url) {
132
+ function matchesHostPattern(pattern, url, { ignorePath = false } = {}) {
98
133
  if (!pattern) return false;
99
134
  if ('<all_urls>' === pattern) return true;
100
135
  const parts = /^(\*|https?|file|ftp|urn):\/\/([^/]*)(\/.*)?$/.exec(pattern);
@@ -116,10 +151,16 @@ function matchesHostPattern(pattern, url) {
116
151
  if (parsed.hostname !== base && !parsed.hostname.endsWith(`.${base}`)) return false;
117
152
  } else if (host.toLowerCase() !== parsed.hostname.toLowerCase()) return false;
118
153
  }
154
+ if (ignorePath) return true;
119
155
  const pathPattern = rawPath || '/*';
120
156
  const pathRe = new RegExp(`^${pathPattern.split('*').map(escapeForRegExp).join('.*')}$`);
121
157
  return pathRe.test(parsed.pathname + parsed.search);
122
158
  }
159
+ function matchesHostPermission(pattern, url) {
160
+ return matchesHostPattern(pattern, url, {
161
+ ignorePath: true
162
+ });
163
+ }
123
164
  function isContentScriptModule(module) {
124
165
  return module?.layer === EXTENSIONJS_CONTENT_SCRIPT_LAYER;
125
166
  }
@@ -176,8 +217,8 @@ function findInjectedOnlyHostUses(modules, injected, declared, optional) {
176
217
  continue;
177
218
  }
178
219
  for (const url of findAbsoluteRequestUrls(source)){
179
- if (declared.some((pattern)=>matchesHostPattern(pattern, url))) continue;
180
- const pattern = injected.find((candidate)=>matchesHostPattern(candidate, url));
220
+ if (declared.some((pattern)=>matchesHostPermission(pattern, url))) continue;
221
+ const pattern = injected.find((candidate)=>matchesHostPermission(candidate, url));
181
222
  if (!pattern) continue;
182
223
  let origin;
183
224
  try {
@@ -189,7 +230,7 @@ function findInjectedOnlyHostUses(modules, injected, declared, optional) {
189
230
  url,
190
231
  file: resource,
191
232
  pattern,
192
- optional: optional.some((candidate)=>matchesHostPattern(candidate, url))
233
+ optional: optional.some((candidate)=>matchesHostPermission(candidate, url))
193
234
  });
194
235
  }
195
236
  }
@@ -518,11 +559,13 @@ class FreeReferenceScan {
518
559
  this.visit(current.test, shadowed);
519
560
  if (guardsName(current.test)) return;
520
561
  this.visit(current.consequent, shadowed);
562
+ if (mentionsChrome(current.test)) return;
521
563
  this.visit(current.alternate, shadowed);
522
564
  return;
523
565
  case 'LogicalExpression':
524
566
  this.visit(current.left, shadowed);
525
567
  if (guardsName(current.left)) return;
568
+ if (('||' === current.operator || '??' === current.operator) && mentionsChrome(current.left)) return;
526
569
  this.visit(current.right, shadowed);
527
570
  return;
528
571
  case 'LabeledStatement':
@@ -1910,7 +1953,7 @@ async function resolvePreprocessorLoader(loader, projectPath) {
1910
1953
  }
1911
1954
  async function buildCssRules(projectPath, mode, usage, opts) {
1912
1955
  const { useSass = true, useLess = true } = usage;
1913
- const { nonModuleType, issuer, manifestPath } = opts;
1956
+ const { nonModuleType, issuer, issuerLayer, manifestPath } = opts;
1914
1957
  const fileTypes = [
1915
1958
  {
1916
1959
  test: /\.module\.css$/,
@@ -2023,57 +2066,43 @@ async function buildCssRules(projectPath, mode, usage, opts) {
2023
2066
  test,
2024
2067
  exclude,
2025
2068
  type: ruleType,
2026
- issuer,
2069
+ ...issuer ? {
2070
+ issuer
2071
+ } : {},
2072
+ ...issuerLayer ? {
2073
+ issuerLayer
2074
+ } : {},
2027
2075
  resourceQuery: NOT_RAW_RESOURCE_QUERY,
2028
2076
  use
2029
2077
  };
2030
2078
  }));
2031
2079
  }
2032
- const indexCache = new Map();
2033
- function getContentScriptIndex(manifestPath, projectPath, browser) {
2034
- const scriptsRoot = scriptsFolderRoot(projectPath);
2035
- const cacheKey = `${manifestPath}::${projectPath}::${browser}::${scriptsRoot}`;
2036
- let mtimeMs = -1;
2037
- try {
2038
- mtimeMs = __rspack_external_node_fs_1b05aee1.statSync(manifestPath).mtimeMs;
2039
- } catch {}
2040
- const cached = indexCache.get(cacheKey);
2041
- if (cached && (mtimeMs < 0 || cached.mtimeMs === mtimeMs)) return cached;
2042
- const manifest = filterKeysForThisBrowser(parseJsonSafe(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf8')), browser);
2043
- const manifestDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
2044
- const contentPaths = new Set();
2045
- for (const content of manifest.content_scripts || [])if (content.js?.length) for (const js of content.js)contentPaths.add(toResourceKey(__rspack_external_node_path_806ed179.resolve(manifestDir, js)));
2046
- const index = {
2047
- mtimeMs,
2048
- scriptsDir: scriptsRoot ? canonicalizeDir(scriptsRoot) : void 0,
2049
- contentPaths
2050
- };
2051
- indexCache.set(cacheKey, index);
2052
- return index;
2053
- }
2054
- function isContentScriptEntry(absolutePath, manifestPath, projectPath, browser = 'chrome') {
2055
- if (!absolutePath || !manifestPath || !projectPath) return false;
2056
- if (!__rspack_external_node_fs_1b05aee1.existsSync(manifestPath)) return false;
2057
- const { scriptsDir, contentPaths } = getContentScriptIndex(manifestPath, projectPath, browser);
2058
- const absPathNormalized = toResourceKey(absolutePath);
2059
- const relToScripts = scriptsDir ? __rspack_external_node_path_806ed179.relative(scriptsDir, absPathNormalized) : '';
2060
- const isScriptsFolderScript = relToScripts && !relToScripts.startsWith('..') && !__rspack_external_node_path_806ed179.isAbsolute(relToScripts);
2061
- if (isScriptsFolderScript) return true;
2062
- return contentPaths.has(absPathNormalized);
2063
- }
2064
- async function cssInContentScriptLoader(projectPath, manifestPath, mode, usage = {}, browser = 'chrome') {
2080
+ async function cssInContentScriptLoader(projectPath, manifestPath, mode, usage = {}) {
2065
2081
  return buildCssRules(projectPath, mode, usage, {
2066
2082
  nonModuleType: 'asset/inline',
2067
- issuer: (issuer)=>isContentScriptEntry(issuer, manifestPath, projectPath, browser),
2083
+ issuerLayer: EXTENSIONJS_CONTENT_SCRIPT_LAYER,
2084
+ issuer: /./,
2068
2085
  manifestPath
2069
2086
  });
2070
2087
  }
2071
- async function cssInHtmlLoader(projectPath, mode, manifestPath, usage = {}, browser = 'chrome') {
2072
- return buildCssRules(projectPath, mode, usage, {
2073
- nonModuleType: 'css',
2074
- issuer: (issuer)=>!isContentScriptEntry(issuer, manifestPath, projectPath, browser),
2075
- manifestPath
2076
- });
2088
+ async function cssInHtmlLoader(projectPath, mode, manifestPath, usage = {}) {
2089
+ return [
2090
+ ...await buildCssRules(projectPath, mode, usage, {
2091
+ nonModuleType: 'css',
2092
+ issuerLayer: {
2093
+ not: EXTENSIONJS_CONTENT_SCRIPT_LAYER
2094
+ },
2095
+ manifestPath
2096
+ }),
2097
+ ...await buildCssRules(projectPath, mode, usage, {
2098
+ nonModuleType: 'css',
2099
+ issuerLayer: EXTENSIONJS_CONTENT_SCRIPT_LAYER,
2100
+ issuer: {
2101
+ not: /./
2102
+ },
2103
+ manifestPath
2104
+ })
2105
+ ];
2077
2106
  }
2078
2107
  class CssPlugin {
2079
2108
  static name = 'plugin-css';
@@ -2095,11 +2124,11 @@ class CssPlugin {
2095
2124
  ...await cssInContentScriptLoader(projectPath, manifestPath, mode, {
2096
2125
  useSass: usingSass,
2097
2126
  useLess: usingLess
2098
- }, this.browser),
2127
+ }),
2099
2128
  ...await cssInHtmlLoader(projectPath, mode, manifestPath, {
2100
2129
  useSass: usingSass,
2101
2130
  useLess: usingLess
2102
- }, this.browser),
2131
+ }),
2103
2132
  {
2104
2133
  test: /\.(css|sass|scss|less)$/,
2105
2134
  resourceQuery: /(\?|&)inline(&|$)/,
@@ -2218,7 +2247,11 @@ class CssPlugin {
2218
2247
  __rspack_external_node_path_806ed179.resolve(issuerDir, req),
2219
2248
  ...isBareAssetRef ? roots.map((root)=>__rspack_external_node_path_806ed179.join(root, req)) : []
2220
2249
  ];
2221
- if (candidates.some((candidate)=>__rspack_external_node_fs_1b05aee1.existsSync(candidate))) return;
2250
+ const withCssExtension = __rspack_external_node_path_806ed179.extname(req) ? [] : candidates.map((candidate)=>`${candidate}.css`);
2251
+ if ([
2252
+ ...candidates,
2253
+ ...withCssExtension
2254
+ ].some((candidate)=>__rspack_external_node_fs_1b05aee1.existsSync(candidate))) return;
2222
2255
  if ('true' === process.env.EXTENSION_STRICT_REFS) return;
2223
2256
  const key = `${issuer}|${req}`;
2224
2257
  if (!warned.has(key) && compilation?.warnings) {
@@ -2359,7 +2392,9 @@ function parseHtml(node, onResourceFound) {
2359
2392
  }
2360
2393
  }
2361
2394
  const { childNodes = [] } = node;
2362
- for (const childNode of childNodes)if ('#comment' !== childNode.nodeName && '#text' !== childNode.nodeName) parseHtml(childNode, onResourceFound);
2395
+ for (const childNode of [
2396
+ ...childNodes
2397
+ ])if ('#comment' !== childNode.nodeName && '#text' !== childNode.nodeName) parseHtml(childNode, onResourceFound);
2363
2398
  }
2364
2399
  const cloneParsedHtmlAsset = (assets)=>({
2365
2400
  css: [
@@ -2609,6 +2644,21 @@ const STRING_LIST_FIELDS = [
2609
2644
  'permissions',
2610
2645
  'host_permissions'
2611
2646
  ];
2647
+ const OBJECT_FIELDS = [
2648
+ 'action',
2649
+ 'browser_action',
2650
+ 'page_action',
2651
+ 'background',
2652
+ 'side_panel',
2653
+ 'sidebar_action',
2654
+ 'options_ui',
2655
+ 'sandbox',
2656
+ 'storage',
2657
+ 'theme',
2658
+ 'chrome_url_overrides',
2659
+ 'declarative_net_request',
2660
+ "user_scripts"
2661
+ ];
2612
2662
  function isPlainObject(value) {
2613
2663
  return Boolean(value) && 'object' == typeof value && !Array.isArray(value);
2614
2664
  }
@@ -2630,6 +2680,14 @@ function findMistypedManifestFields(manifest) {
2630
2680
  received: describeValue(value)
2631
2681
  });
2632
2682
  };
2683
+ for (const field of OBJECT_FIELDS){
2684
+ const value = source[field];
2685
+ if (!(void 0 === value || isPlainObject(value))) mistyped.push({
2686
+ field,
2687
+ expected: 'an object',
2688
+ received: describeValue(value)
2689
+ });
2690
+ }
2633
2691
  const contentScripts = source.content_scripts;
2634
2692
  expectArray("content_scripts", contentScripts, "an array of content script objects");
2635
2693
  if (Array.isArray(contentScripts)) contentScripts.forEach((entry, index)=>{
@@ -3035,31 +3093,6 @@ async function maybeUseSvelte(projectPath, mode) {
3035
3093
  alias: Object.keys(alias).length > 0 ? alias : void 0
3036
3094
  };
3037
3095
  }
3038
- const DEFAULT_SWC_TARGETS = [
3039
- 'chrome >= 100'
3040
- ];
3041
- function resolveSwcTargets(rawManifest, browser) {
3042
- if (!rawManifest || 'object' != typeof rawManifest) return [
3043
- ...DEFAULT_SWC_TARGETS
3044
- ];
3045
- const name = String(browser || 'chrome');
3046
- const manifest = filterKeysForThisBrowser(rawManifest, name);
3047
- if (isGeckoBasedBrowser(name)) {
3048
- const geckoMin = manifest.browser_specific_settings?.gecko?.strict_min_version || manifest.applications?.gecko?.strict_min_version;
3049
- const major = parseInt(String(geckoMin ?? '').split('.')[0], 10);
3050
- return Number.isNaN(major) ? [
3051
- ...DEFAULT_SWC_TARGETS
3052
- ] : [
3053
- `firefox >= ${major}`
3054
- ];
3055
- }
3056
- if (isChromiumBasedBrowser(name) && manifest.minimum_chrome_version) return [
3057
- `chrome >= ${manifest.minimum_chrome_version}`
3058
- ];
3059
- return [
3060
- ...DEFAULT_SWC_TARGETS
3061
- ];
3062
- }
3063
3096
  class JsFrameworksPlugin {
3064
3097
  static name = 'plugin-js-frameworks';
3065
3098
  manifestPath;
@@ -3380,8 +3413,9 @@ class JsFrameworksPlugin {
3380
3413
  plugin.apply(compiler);
3381
3414
  });
3382
3415
  this.patchReactRefreshRules(compiler.options.module.rules);
3383
- if (isUsingTypeScript(projectPath) || !!tsConfigPath) compiler.options.resolve.tsConfig = {
3384
- configFile: tsConfigPath
3416
+ const resolveConfigPath = tsConfigPath ?? getUserJsConfigFile(projectPath);
3417
+ if (isUsingTypeScript(projectPath) || !!resolveConfigPath) compiler.options.resolve.tsConfig = {
3418
+ configFile: resolveConfigPath
3385
3419
  };
3386
3420
  if (isDebug()) {
3387
3421
  const integrations = [];
@@ -5420,6 +5454,14 @@ function warUnreachableResource(resource, entryName) {
5420
5454
  lines.push(`Learn more: ${pintor.underline('https://extension.js.org/docs/implementation-guide/web-accessible-resources?utm_source=cli')}`);
5421
5455
  return lines.join('\n');
5422
5456
  }
5457
+ function warInjectedScriptExposed(file, resources) {
5458
+ const lines = [];
5459
+ lines.push(`${pintor.underline(file)} names ${resources.map((r)=>pintor.blue(r)).join(', ')}, which no ${pintor.blue('web_accessible_resources')} group lists.`);
5460
+ lines.push(`The build exposes it to ${pintor.blue('<all_urls>')} because the scripting API can inject this file into any page.`);
5461
+ lines.push(`To narrow it, list it in ${pintor.blue('web_accessible_resources')} in ${pintor.blue('manifest.json')} with the matches the script runs on.`);
5462
+ lines.push(`Learn more: ${pintor.underline('https://extension.js.org/docs/implementation-guide/web-accessible-resources?utm_source=cli')}`);
5463
+ return lines.join('\n');
5464
+ }
5423
5465
  function entryImportsSummary(entryCount, totalResources) {
5424
5466
  return `${messaging_prefix('debug')} war entryImports entries=${String(entryCount)} resources=${String(totalResources)}`;
5425
5467
  }
@@ -5461,6 +5503,54 @@ function emitDirectoryAsAssets(compilation, absDir, baseDir) {
5461
5503
  };
5462
5504
  walk(absDir);
5463
5505
  }
5506
+ const GLOB_SKIP_DIRS = new Set([
5507
+ 'node_modules',
5508
+ '.git',
5509
+ 'dist'
5510
+ ]);
5511
+ const GLOB_SKIP_SOURCES = /\.(?:ts|tsx|mts|cts|jsx|vue|svelte|scss|sass|less)$/i;
5512
+ function emitGlobMatches(compilation, manifestDir, projectPath, res) {
5513
+ const pattern = paths_unixify(res).replace(/^\.?\//, '');
5514
+ const prefix = pattern.slice(0, pattern.indexOf('*')).replace(/[^/]*$/, '');
5515
+ const folder = prefix.replace(/\/+$/, '');
5516
+ if (!folder || /^public(\/|$)/i.test(folder)) return;
5517
+ if (__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(projectPath, 'public', folder))) return;
5518
+ const base = __rspack_external_node_path_806ed179.join(manifestDir, folder);
5519
+ if (!isDirectory(base)) return;
5520
+ const matcher = new RegExp(`^${pattern.split('*').map((part)=>part.replace(/[.+?^${}()|[\]\\]/g, '\\$&')).join('.*')}$`);
5521
+ const walk = (dir)=>{
5522
+ let entries;
5523
+ try {
5524
+ entries = __rspack_external_node_fs_1b05aee1.readdirSync(dir, {
5525
+ withFileTypes: true
5526
+ });
5527
+ } catch {
5528
+ return;
5529
+ }
5530
+ for (const entry of entries){
5531
+ const full = __rspack_external_node_path_806ed179.join(dir, entry.name);
5532
+ if (entry.isDirectory()) {
5533
+ if (!GLOB_SKIP_DIRS.has(entry.name)) walk(full);
5534
+ continue;
5535
+ }
5536
+ if (!entry.isFile()) continue;
5537
+ const outName = paths_unixify(__rspack_external_node_path_806ed179.relative(manifestDir, full));
5538
+ if (!(!matcher.test(outName) || GLOB_SKIP_SOURCES.test(outName))) {
5539
+ if (!compilation.getAsset(outName)) compilation.emitAsset(outName, new core_sources.RawSource(__rspack_external_node_fs_1b05aee1.readFileSync(full)));
5540
+ compilation.fileDependencies.add(full);
5541
+ }
5542
+ }
5543
+ };
5544
+ walk(base);
5545
+ compilation.contextDependencies?.add(base);
5546
+ }
5547
+ function isDirectory(abs) {
5548
+ try {
5549
+ return __rspack_external_node_fs_1b05aee1.statSync(abs).isDirectory();
5550
+ } catch {
5551
+ return false;
5552
+ }
5553
+ }
5464
5554
  function emitFileAsAsset(compilation, absPath) {
5465
5555
  const content = __rspack_external_node_fs_1b05aee1.readFileSync(absPath);
5466
5556
  const outName = bundledAssetOutputName(absPath, content, compilation.outputOptions);
@@ -5636,7 +5726,11 @@ function resolveUserDeclaredWAR(compilation, manifestPath, manifest, browser) {
5636
5726
  const escapesPublic = normalizedOutput.split('/').includes('..');
5637
5727
  if (!escapesPublic && __rspack_external_node_fs_1b05aee1.existsSync(publicCandidate)) return void pushResource(matches, normalizedOutput, extra);
5638
5728
  __rspack_external_node_path_806ed179.isAbsolute(res) || __rspack_external_node_path_806ed179.join(manifestDir, isPublicRootLike(res) ? toPublicOutput(res) : res);
5639
- if (/[*?[\]{}]/.test(res)) return void pushResource(matches, res, extra);
5729
+ if (/[*?[\]{}]/.test(res)) {
5730
+ emitGlobMatches(compilation, manifestDir, projectPath, res);
5731
+ pushResource(matches, res, extra);
5732
+ return;
5733
+ }
5640
5734
  if (isPublicRootLike(res)) {
5641
5735
  const output = normalizeManifestOutputPath(res);
5642
5736
  const publicAbs = __rspack_external_node_path_806ed179.join(projectPath, 'public', output);
@@ -5992,28 +6086,37 @@ class TraceRuntimeLoadedFiles {
5992
6086
  const seen = run.seen.importScripts;
5993
6087
  for(let depth = 0; depth < MAX_TRACE_DEPTH && pending.length; depth++){
5994
6088
  const next = [];
5995
- for (const content of pending)for (const literal of extractImportScriptsLiterals(content)){
5996
- const sourceRel = resolveExtensionPath(literal, sourceWorkerPath);
5997
- const distRel = resolveExtensionPath(literal, EMITTED_WORKER_PATH);
5998
- if (!sourceRel || !distRel || seen.has(distRel)) continue;
5999
- seen.add(distRel);
6000
- const plan = planTracedFile({
6001
- manifestDir: run.manifestDir,
6002
- sourceRel,
6003
- distRel,
6004
- loadsAs: 'classic',
6005
- hasAsset: run.hasAsset
6089
+ for (const content of pending){
6090
+ const listed = importScriptsListedPaths(content).filter((literal)=>{
6091
+ const rel = resolveExtensionPath(literal, sourceWorkerPath);
6092
+ return Boolean(rel) && trace_runtime_loaded_files_isFile(__rspack_external_node_path_806ed179.join(run.manifestDir, String(rel)));
6006
6093
  });
6007
- const copied = run.apply(plan, {
6008
- context: 'importScripts',
6009
- onMissing: ()=>run.warn('ImportScriptsDependencyMissing', EMITTED_WORKER_PATH, importScriptsDependencyMissing(sourceWorkerPath, literal, sourceRel)),
6010
- onSourceSpelling: (emitPath)=>run.warn('ImportScriptsCompiledSource', EMITTED_WORKER_PATH, compiledSourceSpelling(EMITTED_WORKER_PATH, 'importScripts', literal, emitPath))
6011
- });
6012
- if (null != copied) {
6013
- next.push(copied);
6014
- run.workerScope.add(distRel);
6094
+ for (const literal of [
6095
+ ...extractImportScriptsLiterals(content),
6096
+ ...listed
6097
+ ]){
6098
+ const sourceRel = resolveExtensionPath(literal, sourceWorkerPath);
6099
+ const distRel = resolveExtensionPath(literal, EMITTED_WORKER_PATH);
6100
+ if (!sourceRel || !distRel || seen.has(distRel)) continue;
6101
+ seen.add(distRel);
6102
+ const plan = planTracedFile({
6103
+ manifestDir: run.manifestDir,
6104
+ sourceRel,
6105
+ distRel,
6106
+ loadsAs: 'classic',
6107
+ hasAsset: run.hasAsset
6108
+ });
6109
+ const copied = run.apply(plan, {
6110
+ context: 'importScripts',
6111
+ onMissing: ()=>run.warn('ImportScriptsDependencyMissing', EMITTED_WORKER_PATH, importScriptsDependencyMissing(sourceWorkerPath, literal, sourceRel)),
6112
+ onSourceSpelling: (emitPath)=>run.warn('ImportScriptsCompiledSource', EMITTED_WORKER_PATH, compiledSourceSpelling(EMITTED_WORKER_PATH, 'importScripts', literal, emitPath))
6113
+ });
6114
+ if (null != copied) {
6115
+ next.push(copied);
6116
+ run.workerScope.add(distRel);
6117
+ }
6118
+ if ('missing' !== plan.kind && sourceRel.endsWith('.js')) copyIfExists(run.compilation, __rspack_external_node_path_806ed179.join(run.manifestDir, sourceRel.replace(/\.js$/, '_bg.wasm')), distRel.replace(/\.js$/, '_bg.wasm'));
6015
6119
  }
6016
- if ('missing' !== plan.kind && sourceRel.endsWith('.js')) copyIfExists(run.compilation, __rspack_external_node_path_806ed179.join(run.manifestDir, sourceRel.replace(/\.js$/, '_bg.wasm')), distRel.replace(/\.js$/, '_bg.wasm'));
6017
6120
  }
6018
6121
  pending = next;
6019
6122
  }
@@ -6095,6 +6198,13 @@ class TraceRuntimeLoadedFiles {
6095
6198
  const surfacePages = this.surfacePageOutputs(run.manifestDir);
6096
6199
  let shippedByWar;
6097
6200
  const seen = run.seen.getURL;
6201
+ const pageSources = new Map([
6202
+ ...surfacePages
6203
+ ].map(([sourceRel, output])=>[
6204
+ output,
6205
+ sourceRel
6206
+ ]));
6207
+ const relocatedSurfaceRefs = [];
6098
6208
  let pending = run.jsAssets(only).map((asset)=>({
6099
6209
  kind: 'js',
6100
6210
  content: asset.source.source().toString(),
@@ -6110,7 +6220,7 @@ class TraceRuntimeLoadedFiles {
6110
6220
  })),
6111
6221
  ...extractRuntimeSurfaceLiterals(item.content).map((literal)=>({
6112
6222
  literal,
6113
- baseRel: '',
6223
+ baseRel: item.copied ? '' : movedPageSourceBase(run, pageSources, item.assetName, literal),
6114
6224
  isRuntimeSurface: true
6115
6225
  })),
6116
6226
  ...item.copied ? extractStaticImportLiterals(item.content).map((literal)=>({
@@ -6125,7 +6235,13 @@ class TraceRuntimeLoadedFiles {
6125
6235
  const assetName = 'js' === item.kind ? item.assetName : item.baseRel;
6126
6236
  for (const { literal, baseRel, isStaticImport, isRuntimeSurface } of refs){
6127
6237
  const distRel = resolveExtensionPath(literal, baseRel);
6128
- if (!distRel || seen.has(distRel)) continue;
6238
+ if (!distRel) continue;
6239
+ if (isRuntimeSurface && baseRel && 'js' === item.kind) relocatedSurfaceRefs.push({
6240
+ assetName: item.assetName,
6241
+ literal,
6242
+ distRel
6243
+ });
6244
+ if (seen.has(distRel)) continue;
6129
6245
  seen.add(distRel);
6130
6246
  if (declaredSurfaces.has(distRel)) {
6131
6247
  const output = surfacePages.get(distRel);
@@ -6168,6 +6284,10 @@ class TraceRuntimeLoadedFiles {
6168
6284
  }
6169
6285
  pending = next;
6170
6286
  }
6287
+ for (const ref of relocatedSurfaceRefs){
6288
+ const target = declaredSurfaces.has(ref.distRel) ? surfacePages.get(ref.distRel) || ref.distRel : ref.distRel;
6289
+ if (run.hasAsset(target)) rewriteStringLiteral(run.compilation, ref.assetName, ref.literal, `/${target}`);
6290
+ }
6171
6291
  }
6172
6292
  traceWebpackChunkSiblings(run, only) {
6173
6293
  const { compilation, manifestDir, entrySourceDirs } = run;
@@ -6400,7 +6520,7 @@ async function compileTracedFile(host, request) {
6400
6520
  const isModule = 'module' === request.format;
6401
6521
  const chunkLoading = isModule ? 'import' : 'importScripts' === request.context ? "import-scripts" : 'jsonp';
6402
6522
  const stylesheetScript = /\.css$/i.test(request.emitPath) ? `${request.emitPath}.js` : void 0;
6403
- const entry = new EntryPlugin(compiler.context, request.sourcePath, {
6523
+ const entry = new EntryPlugin(compiler.context, isModule ? request.sourcePath : `${request.sourcePath}${CLASSIC_GLOBALS_QUERY}`, {
6404
6524
  name: request.emitPath.replace(/\.[^./]+$/, ''),
6405
6525
  filename: stylesheetScript || request.emitPath,
6406
6526
  chunkLoading,
@@ -6438,7 +6558,12 @@ async function compileTracedFile(host, request) {
6438
6558
  child.options.module = {
6439
6559
  ...child.options.module,
6440
6560
  parser: withEagerDynamicImports(child.options.module.parser),
6441
- rules: withoutDevRefresh(child.options.module.rules)
6561
+ rules: [
6562
+ ...isModule ? [] : [
6563
+ classicGlobalsRule()
6564
+ ],
6565
+ ...withoutDevRefresh(child.options.module.rules)
6566
+ ]
6442
6567
  };
6443
6568
  await new Promise((resolve)=>{
6444
6569
  child.runAsChild((error, _entries, childCompilation)=>{
@@ -6478,6 +6603,16 @@ function withEagerDynamicImports(parser) {
6478
6603
  };
6479
6604
  return next;
6480
6605
  }
6606
+ const CLASSIC_GLOBALS_QUERY = '?__extensionjs_traced_classic__';
6607
+ function classicGlobalsRule() {
6608
+ return {
6609
+ resourceQuery: /[?&]__extensionjs_traced_classic__/,
6610
+ enforce: 'post',
6611
+ use: {
6612
+ loader: resolveDevelopDistFile("feature-scripts-classic-traced-globals-loader")
6613
+ }
6614
+ };
6615
+ }
6481
6616
  const isRefreshLoader = (use)=>'function' == typeof use ? false : /react-refresh/.test(String('string' == typeof use ? use : use.loader || ''));
6482
6617
  function withoutDevRefresh(rules) {
6483
6618
  return rules.map((rule)=>{
@@ -6558,6 +6693,27 @@ function compiledSourceEmittedPath(distRel) {
6558
6693
  function unixify(filePath) {
6559
6694
  return filePath.replace(/\\/g, '/');
6560
6695
  }
6696
+ function movedPageSourceBase(run, pageSources, assetName, literal) {
6697
+ if (!/^\.\.?\//.test(literal.trim())) return '';
6698
+ const entryName = assetName.replace(/\.js$/i, '');
6699
+ const pageSource = pageSources.get(`${entryName}.html`);
6700
+ const entryDir = run.entrySourceDirs.get(entryName);
6701
+ const entryDirRel = entryDir ? unixify(__rspack_external_node_path_806ed179.relative(run.manifestDir, entryDir)) : void 0;
6702
+ const sourceRel = pageSource || (void 0 === entryDirRel ? '' : entryDirRel ? `${entryDirRel}/index.js` : 'index.js');
6703
+ if (!sourceRel || sourceRel.startsWith('..')) return '';
6704
+ const sourceDirRel = __rspack_external_node_path_806ed179.posix.dirname(sourceRel);
6705
+ if (sourceDirRel === __rspack_external_node_path_806ed179.posix.dirname(unixify(assetName))) return '';
6706
+ return sourceRel.replace(/^\.\//, '');
6707
+ }
6708
+ function rewriteStringLiteral(compilation, assetName, literal, replacement) {
6709
+ const asset = compilation.getAsset(assetName);
6710
+ if (!asset) return;
6711
+ const escaped = literal.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
6712
+ const quoted = new RegExp(`(['"\`])${escaped}\\1`, 'g');
6713
+ const content = asset.source.source().toString();
6714
+ const updated = content.replace(quoted, (_match, quote)=>`${quote}${replacement}${quote}`);
6715
+ if (updated !== content) compilation.updateAsset(assetName, new core_sources.RawSource(updated));
6716
+ }
6561
6717
  function resolveExtensionPath(literal, basePath) {
6562
6718
  const trimmed = literal.trim();
6563
6719
  if (!trimmed) return null;
@@ -6731,13 +6887,75 @@ function extractImportScriptsLiterals(source) {
6731
6887
  while(match = callRe.exec(code)){
6732
6888
  const args = readBalancedArgs(code, match.index + match[0].length - 1);
6733
6889
  if (null == args) continue;
6734
- for (const arg of splitTopLevelArgs(args)){
6735
- const literal = pureStringLiteral(arg);
6736
- if (null != literal) literals.push(literal);
6737
- }
6890
+ for (const arg of splitTopLevelArgs(args))literals.push(...conditionalStringLiterals(arg));
6738
6891
  }
6739
6892
  return literals;
6740
6893
  }
6894
+ function conditionalStringLiterals(expression, depth = 0) {
6895
+ const literal = pureStringLiteral(expression);
6896
+ if (null != literal) return [
6897
+ literal
6898
+ ];
6899
+ if (depth > 8) return [];
6900
+ const trimmed = expression.trim();
6901
+ const unwrapped = trimmed.startsWith('(') && readBalancedArgs(trimmed, 0) === trimmed.slice(1, -1) ? trimmed.slice(1, -1) : trimmed;
6902
+ const branches = splitTopLevelConditional(unwrapped);
6903
+ if (!branches) return [];
6904
+ return [
6905
+ ...conditionalStringLiterals(branches[0], depth + 1),
6906
+ ...conditionalStringLiterals(branches[1], depth + 1)
6907
+ ];
6908
+ }
6909
+ function splitTopLevelConditional(expression) {
6910
+ let depth = 0;
6911
+ let question = -1;
6912
+ let pending = 0;
6913
+ for(let i = 0; i < expression.length; i++){
6914
+ const char = expression[i];
6915
+ if ('"' === char || "'" === char || '`' === char) {
6916
+ i = skipString(expression, i, expression.length);
6917
+ continue;
6918
+ }
6919
+ if ('(' === char || '[' === char || '{' === char) depth++;
6920
+ if (')' === char || ']' === char || '}' === char) depth--;
6921
+ if (0 !== depth) continue;
6922
+ const next = expression[i + 1];
6923
+ if ('?' === char && '?' !== next && '.' !== next) if (question < 0) question = i;
6924
+ else pending++;
6925
+ else if ('?' === char && ('?' === next || '.' === next)) i++;
6926
+ else if (':' === char && question >= 0) {
6927
+ if (pending > 0) {
6928
+ pending--;
6929
+ continue;
6930
+ }
6931
+ return [
6932
+ expression.slice(question + 1, i),
6933
+ expression.slice(i + 1)
6934
+ ];
6935
+ }
6936
+ }
6937
+ return null;
6938
+ }
6939
+ function importScriptsListedPaths(source) {
6940
+ const code = blankComments(source);
6941
+ const callRe = /\bimportScripts\s*\(/g;
6942
+ let computed = false;
6943
+ let call;
6944
+ while(!computed && (call = callRe.exec(code))){
6945
+ const args = readBalancedArgs(code, call.index + call[0].length - 1);
6946
+ if (null == args) continue;
6947
+ computed = splitTopLevelArgs(args).some((arg)=>null == pureStringLiteral(arg));
6948
+ }
6949
+ if (!computed) return [];
6950
+ const paths = [];
6951
+ const scriptString = /(['"])((?:\\.|(?!\1)[^\\\n])*?\.m?js)\1/g;
6952
+ let match;
6953
+ while(match = scriptString.exec(code)){
6954
+ const value = unescapeStringBody(match[2]);
6955
+ if (!/^[a-z][\w+.-]*:/i.test(value)) paths.push(value);
6956
+ }
6957
+ return paths;
6958
+ }
6741
6959
  function arrayPropStringLiterals(args, prop) {
6742
6960
  const literals = [];
6743
6961
  const arrayRe = new RegExp(`(?<![\\w$.])["']?${prop}["']?\\s*:\\s*\\[([^\\]]*)\\]`, 'g');
@@ -7012,7 +7230,8 @@ async function emitRootAbsoluteRefs(compilation, context, publicDir, publicIsOff
7012
7230
  const plan = planRootAbsoluteRef(ref, context, publicDir, hasAsset);
7013
7231
  if (!plan) continue;
7014
7232
  const spelledAs = 'spelledAs' in plan ? plan.spelledAs : void 0;
7015
- if (spelledAs && !warned.has(ref)) {
7233
+ if (spelledAs && 'html' === origin.kind) rewriteHtmlRef(compilation, origin.asset, ref, `/${plan.emitPath}`);
7234
+ else if (spelledAs && !warned.has(ref)) {
7016
7235
  warned.add(ref);
7017
7236
  emit_root_absolute_refs_warn(compilation, origin.asset, compiledSourceSpelling(origin.asset, 'css' === origin.kind ? 'a CSS url()' : 'an HTML src/href attribute', ref, plan.emitPath));
7018
7237
  }
@@ -7051,6 +7270,16 @@ async function emitRootAbsoluteRefs(compilation, context, publicDir, publicIsOff
7051
7270
  if (0 === emitted) return;
7052
7271
  }
7053
7272
  }
7273
+ function rewriteHtmlRef(compilation, assetName, ref, replacement) {
7274
+ const asset = compilation.getAsset(assetName);
7275
+ if (!asset) return;
7276
+ const escaped = ref.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7277
+ const quoted = new RegExp(`=(\\s*)(["'])${escaped}\\2`, 'g');
7278
+ const bare = new RegExp(`=(\\s*)${escaped}(?=[\\s>])`, 'g');
7279
+ const html = String(asset.source.source());
7280
+ const updated = html.replace(quoted, (_match, space, quote)=>`=${space}${quote}${replacement}${quote}`).replace(bare, (_match, space)=>`=${space}${replacement}`);
7281
+ if (updated !== html) compilation.updateAsset(assetName, new rspack.sources.RawSource(updated));
7282
+ }
7054
7283
  function emit_root_absolute_refs_warn(compilation, file, message, name = 'RootAbsoluteRefCompiledSource') {
7055
7284
  const warning = new core_WebpackError(message);
7056
7285
  warning.name = name;
@@ -7151,10 +7380,15 @@ class WarnUponFolderChanges {
7151
7380
  };
7152
7381
  for (const folderPath of Object.values(roots))if (__rspack_external_node_fs_1b05aee1.existsSync(folderPath)) walk(folderPath);
7153
7382
  }
7154
- getContextDependencyPaths(projectPath) {
7155
- const dependencies = new Set();
7156
- for (const folderPath of Object.values(foldersRoots(projectPath)))dependencies.add(__rspack_external_node_fs_1b05aee1.existsSync(folderPath) ? folderPath : projectPath);
7157
- return Array.from(dependencies);
7383
+ getWatchedFolders(projectPath) {
7384
+ const present = new Set();
7385
+ const missing = new Set();
7386
+ for (const folderPath of Object.values(foldersRoots(projectPath)))if (__rspack_external_node_fs_1b05aee1.existsSync(folderPath)) present.add(folderPath);
7387
+ else missing.add(folderPath);
7388
+ return {
7389
+ present: Array.from(present),
7390
+ missing: Array.from(missing)
7391
+ };
7158
7392
  }
7159
7393
  throwCompilationError(compilation, folder, filePath, isAddition) {
7160
7394
  const addingOrRemoving = isAddition ? 'Adding' : 'Removing';
@@ -7225,7 +7459,9 @@ class WarnUponFolderChanges {
7225
7459
  });
7226
7460
  compiler.hooks.thisCompilation.tap('special-folders:warn-upon-folder-changes', (compilation)=>{
7227
7461
  const projectPath = compiler.options.context || process.cwd();
7228
- for (const dependencyPath of this.getContextDependencyPaths(projectPath))compilation.contextDependencies?.add(dependencyPath);
7462
+ const folders = this.getWatchedFolders(projectPath);
7463
+ for (const folderPath of folders.present)compilation.contextDependencies?.add(folderPath);
7464
+ for (const folderPath of folders.missing)compilation.missingDependencies?.add(folderPath);
7229
7465
  this.applyPendingChanges(compilation);
7230
7466
  });
7231
7467
  }
@@ -7255,10 +7491,18 @@ class SpecialFoldersPlugin {
7255
7491
  }, ()=>emitRootAbsoluteRefs(compilation, __rspack_external_node_path_806ed179.dirname(manifestPath), publicDir, !readsPublicFolder));
7256
7492
  });
7257
7493
  if (readsPublicFolder) {
7258
- const watching = Boolean(compiler.options.watchOptions);
7494
+ const copierWired = __rspack_external_node_fs_1b05aee1.existsSync(publicDir);
7495
+ let pickupRequested = false;
7259
7496
  compiler.hooks.thisCompilation.tap(SpecialFoldersPlugin.name, (compilation)=>{
7260
- const folderToWatch = __rspack_external_node_fs_1b05aee1.existsSync(publicDir) ? publicDir : watching ? __rspack_external_node_path_806ed179.dirname(publicDir) : void 0;
7261
- if (folderToWatch) compilation.contextDependencies?.add(folderToWatch);
7497
+ if (__rspack_external_node_fs_1b05aee1.existsSync(publicDir)) compilation.contextDependencies?.add(publicDir);
7498
+ else compilation.missingDependencies?.add(publicDir);
7499
+ if (!copierWired && !pickupRequested && __rspack_external_node_fs_1b05aee1.existsSync(publicDir)) {
7500
+ pickupRequested = true;
7501
+ if (!requestDevSessionRestart(compiler, {
7502
+ reason: 'public',
7503
+ pathAfter: publicDir
7504
+ })) pushLayoutWarning(compiler, compilation, 'PublicFolderAppearedWarning', publicFolderAppeared(publicDir, context));
7505
+ }
7262
7506
  compilation.hooks.processAssets.tap({
7263
7507
  name: `${SpecialFoldersPlugin.name}:guards`,
7264
7508
  stage: compilation.constructor.PROCESS_ASSETS_STAGE_PRE_PROCESS
@@ -7282,7 +7526,7 @@ class SpecialFoldersPlugin {
7282
7526
  ].map((name)=>`${publicLocales}/**/${name}`),
7283
7527
  ...localeDirsWithoutMessages(publicLocales).map((dir)=>`${publicLocales}/${__rspack_external_node_path_806ed179.basename(dir)}/**`)
7284
7528
  ];
7285
- new rspack.CopyRspackPlugin({
7529
+ if (copierWired) new rspack.CopyRspackPlugin({
7286
7530
  patterns: [
7287
7531
  {
7288
7532
  from: publicDir,
@@ -7294,6 +7538,7 @@ class SpecialFoldersPlugin {
7294
7538
  }
7295
7539
  ]
7296
7540
  }).apply(compiler);
7541
+ const watching = Boolean(compiler.options.watchOptions);
7297
7542
  if (watching && 'development' === compiler.options.mode) new PruneRemovedPublicFiles(publicDir).apply(compiler);
7298
7543
  if (isDebug()) debugLine(specialFoldersSetupSummary(true, true, copyIgnore.length));
7299
7544
  }
@@ -7415,11 +7660,62 @@ class StaticAssetsPlugin {
7415
7660
  }
7416
7661
  }
7417
7662
  };
7663
+ const SCOPE_KEYS = [
7664
+ 'include',
7665
+ 'exclude',
7666
+ 'resource',
7667
+ 'issuer',
7668
+ 'issuerLayer'
7669
+ ];
7670
+ const hasEffect = (rule)=>Boolean(rule && (void 0 !== rule.type || void 0 !== rule.use || void 0 !== rule.loader));
7671
+ const hasScope = (rule)=>Boolean(rule && SCOPE_KEYS.some((key)=>void 0 !== rule[key]));
7418
7672
  const isFullCustomRuleFor = (thisRule, sample)=>{
7419
7673
  const rule = thisRule;
7420
- return Boolean(rule && rule.test instanceof RegExp && rule.test.test(sample) && (void 0 !== rule.type || void 0 !== rule.use) && void 0 === rule.resourceQuery);
7674
+ return Boolean(rule && rule.test instanceof RegExp && rule.test.test(sample) && hasEffect(rule) && void 0 === rule.resourceQuery && !hasScope(rule));
7675
+ };
7676
+ const isPartialRuleFor = (thisRule, sample)=>{
7677
+ const rule = thisRule;
7678
+ if (!rule || !hasEffect(rule) || isFullCustomRuleFor(rule, sample)) return false;
7679
+ if (rule.test instanceof RegExp) return rule.test.test(sample) && hasScope(rule);
7680
+ const assetTyped = 'string' == typeof rule.type && rule.type.startsWith('asset');
7681
+ return assetTyped && (void 0 !== rule.test || hasScope(rule));
7682
+ };
7683
+ const scopeConditionsOf = (rule)=>{
7684
+ const conditions = {};
7685
+ for (const key of [
7686
+ 'test',
7687
+ 'resourceQuery',
7688
+ ...SCOPE_KEYS
7689
+ ])if (rule?.[key] !== void 0) conditions[key] = rule[key];
7690
+ return conditions;
7421
7691
  };
7422
- const scopedQueriesFor = (sample)=>compiler.options.module.rules.map((thisRule)=>thisRule).filter((rule)=>Boolean(rule && rule.test instanceof RegExp && rule.test.test(sample) && (void 0 !== rule.type || void 0 !== rule.use) && rule.resourceQuery instanceof RegExp)).map((rule)=>rule?.resourceQuery);
7692
+ const partialScopesFor = (extensions)=>{
7693
+ const seen = new Set();
7694
+ const scopes = [];
7695
+ for (const thisRule of compiler.options.module.rules)if (!seen.has(thisRule)) {
7696
+ if (extensions.some((ext)=>isPartialRuleFor(thisRule, `.${ext}`))) {
7697
+ seen.add(thisRule);
7698
+ scopes.push(scopeConditionsOf(thisRule));
7699
+ }
7700
+ }
7701
+ return scopes;
7702
+ };
7703
+ const withPartialScopes = (rule, extensions)=>{
7704
+ const scopes = partialScopesFor(extensions);
7705
+ if (!scopes.length) return rule;
7706
+ const { test, resourceQuery, ...effects } = rule;
7707
+ return {
7708
+ test,
7709
+ ...resourceQuery ? {
7710
+ resourceQuery
7711
+ } : {},
7712
+ oneOf: [
7713
+ ...scopes,
7714
+ effects
7715
+ ]
7716
+ };
7717
+ };
7718
+ const scopedQueriesFor = (sample)=>compiler.options.module.rules.map((thisRule)=>thisRule).filter((rule)=>Boolean(rule && rule.test instanceof RegExp && rule.test.test(sample) && hasEffect(rule) && rule.resourceQuery instanceof RegExp && !hasScope(rule))).map((rule)=>rule?.resourceQuery);
7423
7719
  const IMAGE_EXTENSIONS = [
7424
7720
  'png',
7425
7721
  'jpg',
@@ -7466,7 +7762,7 @@ class StaticAssetsPlugin {
7466
7762
  const remaining = unclaimedExtensions(extensions);
7467
7763
  if (!remaining.length) return null;
7468
7764
  const scoped = scopedQueriesForAll(remaining);
7469
- return {
7765
+ return withPartialScopes({
7470
7766
  test: new RegExp(`\\.(${remaining.join('|')})$`, 'i'),
7471
7767
  type: 'asset',
7472
7768
  generator: {
@@ -7484,7 +7780,7 @@ class StaticAssetsPlugin {
7484
7780
  not: scoped
7485
7781
  }
7486
7782
  } : {}
7487
- };
7783
+ }, remaining);
7488
7784
  };
7489
7785
  const hasCustomSvgRule = 0 === unclaimedExtensions([
7490
7786
  'svg'
@@ -7503,12 +7799,14 @@ class StaticAssetsPlugin {
7503
7799
  const svgScopedQueries = scopedQueriesFor('.svg');
7504
7800
  const loaders = [
7505
7801
  ...hasCustomSvgRule ? [] : [
7506
- svgScopedQueries.length ? {
7802
+ withPartialScopes(svgScopedQueries.length ? {
7507
7803
  ...defaultSvgRule,
7508
7804
  resourceQuery: {
7509
7805
  not: svgScopedQueries
7510
7806
  }
7511
- } : defaultSvgRule
7807
+ } : defaultSvgRule, [
7808
+ 'svg'
7809
+ ])
7512
7810
  ],
7513
7811
  ...imagesRule ? [
7514
7812
  imagesRule
@@ -7914,6 +8212,28 @@ function injectJsScript(bodyNode, feature, firstScriptAttrs, siblingScripts = []
7914
8212
  for (const src of siblingScripts)__rspack_external_parse5_utilities_4a00fdd6.append(bodyNode, createScriptTag(src, firstScriptAttrs));
7915
8213
  __rspack_external_parse5_utilities_4a00fdd6.append(bodyNode, createScriptTag(getFilePath(feature, '.js', true), firstScriptAttrs));
7916
8214
  }
8215
+ const OPTIONS_DIALOG_FLOOR_PX = 32;
8216
+ const OPTIONS_DIALOG_FLOOR_MARK = 'options-dialog-floor';
8217
+ const OPTIONS_DIALOG_FLOOR_CSS = `html{min-height:${OPTIONS_DIALOG_FLOOR_PX}px}`;
8218
+ function needsOptionsDialogFloor(manifest, browser, feature) {
8219
+ if (feature !== OPTIONS_HTML_FEATURE) return false;
8220
+ if (!isChromiumBasedBrowser(String(browser || ''))) return false;
8221
+ const optionsUi = manifest?.options_ui;
8222
+ const page = optionsUi?.page;
8223
+ if ('string' != typeof page || !page.trim()) return false;
8224
+ return optionsUi?.open_in_tab !== true;
8225
+ }
8226
+ function injectOptionsDialogFloor(headNode) {
8227
+ const styleTag = __rspack_external_parse5_utilities_4a00fdd6.createNode('style');
8228
+ styleTag.attrs = [
8229
+ {
8230
+ name: 'data-extension-js',
8231
+ value: OPTIONS_DIALOG_FLOOR_MARK
8232
+ }
8233
+ ];
8234
+ __rspack_external_parse5_utilities_4a00fdd6.setText(styleTag, OPTIONS_DIALOG_FLOOR_CSS);
8235
+ __rspack_external_parse5_utilities_4a00fdd6.prepend(headNode, styleTag);
8236
+ }
7917
8237
  function warnIfPublicRootAssetMissing(compilation, htmlEntry, cleanPath, manifestDir) {
7918
8238
  const projectDir = manifestDir || __rspack_external_node_path_806ed179.dirname(__rspack_external_node_path_806ed179.dirname(htmlEntry));
7919
8239
  const publicDir = publicContainmentRoot(__rspack_external_node_path_806ed179.join(projectDir, 'manifest.json'), compilation.compiler?.options?.context || projectDir);
@@ -7936,7 +8256,7 @@ function insertBefore(reference, node) {
7936
8256
  node.parentNode = parent;
7937
8257
  parent.childNodes.splice(index, 0, node);
7938
8258
  }
7939
- function patchHtml(compilation, feature, htmlEntry, includeList, manifestDir, siblingScripts = [], html) {
8259
+ function patchHtml(compilation, feature, htmlEntry, includeList, manifestDir, siblingScripts = [], html, options = {}) {
7940
8260
  const htmlFile = 'string' == typeof html ? html : __rspack_external_node_fs_1b05aee1.readFileSync(htmlEntry, {
7941
8261
  encoding: 'utf8'
7942
8262
  });
@@ -7990,6 +8310,7 @@ function patchHtml(compilation, feature, htmlEntry, includeList, manifestDir, si
7990
8310
  });
7991
8311
  if ('head' === htmlChildNode.nodeName) {
7992
8312
  if (hasCssEntry) injectCssLink(htmlChildNode, feature, firstLinkAttrs, cssHrefOverride);
8313
+ if (options.optionsDialogFloor) injectOptionsDialogFloor(htmlChildNode);
7993
8314
  }
7994
8315
  if ('body' === htmlChildNode.nodeName) bodyNode = htmlChildNode;
7995
8316
  }
@@ -8745,11 +9066,19 @@ class UpdateHtmlFile {
8745
9066
  this.includeList = options.includeList;
8746
9067
  this.browser = options.browser;
8747
9068
  }
9069
+ readManifestForBrowser() {
9070
+ try {
9071
+ return filterKeysForThisBrowser(JSON.parse(stripBom(__rspack_external_node_fs_1b05aee1.readFileSync(this.manifestPath, 'utf-8'))), this.browser || 'chrome');
9072
+ } catch {
9073
+ return;
9074
+ }
9075
+ }
8748
9076
  apply(compiler) {
8749
9077
  compiler.hooks.thisCompilation.tap('html:update-html-file', (compilation)=>{
8750
9078
  const run = ()=>{
8751
9079
  const htmlEntries = this.includeList || {};
8752
9080
  const projectDir = __rspack_external_node_path_806ed179.dirname(this.manifestPath);
9081
+ const manifest = this.readManifestForBrowser();
8753
9082
  for (const [feature, resource] of Object.entries(htmlEntries)){
8754
9083
  if (!resource || 'string' != typeof resource) continue;
8755
9084
  const resolved = __rspack_external_node_path_806ed179.isAbsolute(resource) ? resource : resource.startsWith('/') ? __rspack_external_node_path_806ed179.join(projectDir, resource.slice(1)) : __rspack_external_node_path_806ed179.join(projectDir, resource);
@@ -8759,7 +9088,9 @@ class UpdateHtmlFile {
8759
9088
  const existing = 'function' == typeof getAssetFn ? getAssetFn.call(compilation, assetFilename) : compilation.assets?.[assetFilename];
8760
9089
  if (!existing) continue;
8761
9090
  const currentHtml = readAssetSource(existing);
8762
- const updated = patchHtml(compilation, feature, resolved, this.includeList || {}, projectDir, siblingScriptsFor(compilation, feature), currentHtml);
9091
+ const updated = patchHtml(compilation, feature, resolved, this.includeList || {}, projectDir, siblingScriptsFor(compilation, feature), currentHtml, {
9092
+ optionsDialogFloor: needsOptionsDialogFloor(manifest, this.browser, feature)
9093
+ });
8763
9094
  const updatedHtml = 'string' == typeof updated ? updated : updated && 'string' == typeof updated.html ? updated.html : null;
8764
9095
  if ('string' == typeof updatedHtml) compilation.updateAsset(assetFilename, new core_sources.RawSource(updatedHtml));
8765
9096
  }
@@ -10125,16 +10456,13 @@ function patchExternallyConnectable(manifest) {
10125
10456
  };
10126
10457
  return {};
10127
10458
  }
10459
+ const MATCH_PATTERN_ORIGIN = /^([a-z*][a-z0-9+.*-]*):\/\/([^/?#]*)/i;
10128
10460
  function cleanMatches(matches) {
10129
10461
  return matches.map((match)=>{
10130
- try {
10131
- const url = new URL(match.replace(/^\*:\/\//, 'https://'));
10132
- if (match.endsWith(url.pathname)) return `${match.substring(0, match.length - url.pathname.length)}/*`;
10133
- if ('/' === url.pathname) return `${match}/*`;
10134
- return match;
10135
- } catch {
10136
- return match;
10137
- }
10462
+ const origin = MATCH_PATTERN_ORIGIN.exec(match);
10463
+ if (!origin) return match;
10464
+ const [, scheme, host] = origin;
10465
+ return `${scheme}://${host}/*`;
10138
10466
  });
10139
10467
  }
10140
10468
  const DEV_RUNTIME_RESOURCES = [
@@ -10858,17 +11186,24 @@ function generateManifestPatches(compilation, manifestPath, entryImports, browse
10858
11186
  }
10859
11187
  }
10860
11188
  }
10861
- const addInjectedScriptResources = (resources)=>{
10862
- if (0 === resources.length) return;
11189
+ const authorDeclared = 3 === canonicalManifest.manifest_version ? resolved.v3.flatMap((group)=>Array.from(group.resources)) : Array.from(resolved.v2);
11190
+ const declaredByAuthor = (resource)=>authorDeclared.includes(resource) || isCoveredByExistingGlobs(authorDeclared, resource);
11191
+ const widenedByEntry = new Map();
11192
+ const addInjectedScriptResources = (entryName, resources)=>{
11193
+ const undeclared = resources.filter((resource)=>!declaredByAuthor(resource));
11194
+ if (0 === undeclared.length) return;
11195
+ const widened = widenedByEntry.get(entryName) || new Set();
11196
+ for (const resource of undeclared)widened.add(resource);
11197
+ widenedByEntry.set(entryName, widened);
10863
11198
  if (3 === canonicalManifest.manifest_version) return void mergeIntoV3Group(webAccessibleResourcesV3, cleanMatches([
10864
11199
  '<all_urls>'
10865
- ]), resources);
10866
- for (const resource of resources)if (!webAccessibleResourcesV2.includes(resource)) webAccessibleResourcesV2.push(resource);
11200
+ ]), undeclared);
11201
+ for (const resource of undeclared)if (!webAccessibleResourcesV2.includes(resource)) webAccessibleResourcesV2.push(resource);
10867
11202
  };
10868
11203
  for (const [entryName, resources] of Object.entries(entryImports)){
10869
11204
  const contentScript = canonicalManifest.content_scripts?.find((script)=>script.js?.some((jsFile)=>jsFile.includes(entryName)));
10870
11205
  if (!contentScript && isInjectedScriptEntry(entryName)) {
10871
- addInjectedScriptResources(resources.filter((resource)=>!resource.endsWith('.map') && !resource.endsWith('.js')));
11206
+ addInjectedScriptResources(entryName, resources.filter((resource)=>!resource.endsWith('.map') && !resource.endsWith('.js')));
10872
11207
  continue;
10873
11208
  }
10874
11209
  if (contentScript) {
@@ -10893,12 +11228,19 @@ function generateManifestPatches(compilation, manifestPath, entryImports, browse
10893
11228
  for (const [entryName, chunkFiles] of Object.entries(asyncChunks)){
10894
11229
  const contentScript = canonicalManifest.content_scripts?.find((script)=>script.js?.some((jsFile)=>jsFile.includes(entryName)));
10895
11230
  if (!contentScript) {
10896
- if (isInjectedScriptEntry(entryName)) addInjectedScriptResources(chunkFiles);
11231
+ if (isInjectedScriptEntry(entryName)) addInjectedScriptResources(entryName, chunkFiles);
10897
11232
  continue;
10898
11233
  }
10899
11234
  if (3 === canonicalManifest.manifest_version) mergeIntoV3Group(webAccessibleResourcesV3, cleanMatches(contentScript.matches || []), chunkFiles);
10900
11235
  else for (const file of chunkFiles)if (!webAccessibleResourcesV2.includes(file)) webAccessibleResourcesV2.push(file);
10901
11236
  }
11237
+ if (3 === canonicalManifest.manifest_version && 'production' === (compilation.options?.mode || 'development')) for (const [entryName, widened] of widenedByEntry){
11238
+ compilation.warnings = compilation.warnings || [];
11239
+ const warning = new core_WebpackError(warInjectedScriptExposed(`${entryName}.js`, Array.from(widened).sort()));
11240
+ warning.name = 'InjectedScriptResourceExposedWarning';
11241
+ warning.file = 'manifest.json';
11242
+ compilation.warnings.push(warning);
11243
+ }
10902
11244
  const contentSheetKeys = Object.keys(compilation.assets || {}).filter((k)=>k.startsWith("content_scripts/") && k.endsWith('.css'));
10903
11245
  const contentSheetTargets = Array.from(new Set(contentSheetKeys.flatMap((cssKey)=>emittedFilesReferencedByCss(compilation, cssKey)))).sort();
10904
11246
  if (3 === canonicalManifest.manifest_version) {
@@ -11121,7 +11463,7 @@ function writeFileAtomically(targetPath, content) {
11121
11463
  });
11122
11464
  try {
11123
11465
  __rspack_external_node_fs_1b05aee1.writeFileSync(tempPath, content, 'utf-8');
11124
- __rspack_external_node_fs_1b05aee1.renameSync(tempPath, targetPath);
11466
+ renameSyncWithRetry(tempPath, targetPath);
11125
11467
  } finally{
11126
11468
  try {
11127
11469
  if (__rspack_external_node_fs_1b05aee1.existsSync(tempPath)) __rspack_external_node_fs_1b05aee1.unlinkSync(tempPath);
@@ -13035,7 +13377,7 @@ class WarnUndeclaredPermissions {
13035
13377
  const relative = __rspack_external_node_path_806ed179.relative(__rspack_external_node_path_806ed179.dirname(this.manifestPath), file);
13036
13378
  const gated = partiallyGatedNote(api);
13037
13379
  const outcome = gated ? `in the packaged build${gated.replace(/^ Only part of the namespace is gated:/, ',')}` : 'in the packaged build that call fails.';
13038
- const text = `manifest.json does not declare the "${api}" permission, but ${relative} uses chrome.${api}. Nothing grants it here, so ${outcome} Add "${api}" to permissions in manifest.json.`;
13380
+ const text = 'tabs' === api && declared.has('activeTab') ? `manifest.json does not declare the "tabs" permission, but ${relative} uses chrome.tabs. "activeTab" is declared, and it grants url, title and favIconUrl for the tab the person invoked the extension on (toolbar click, shortcut, context menu) and captureVisibleTab of that tab; a read of any other tab comes back without those fields. Add "tabs" only if the code reads tabs the person did not invoke it on.` : `manifest.json does not declare the "${api}" permission, but ${relative} uses chrome.${api}. Nothing grants it here, so ${outcome} Add "${api}" to permissions in manifest.json.`;
13039
13381
  const WebpackErrorCtor = compiler.rspack?.WebpackError;
13040
13382
  const warning = WebpackErrorCtor ? new WebpackErrorCtor(text) : new Error(text);
13041
13383
  warning.name = 'UndeclaredPermissionWarning';
@@ -13204,10 +13546,12 @@ class AddContentScriptWrapper {
13204
13546
  manifestPath;
13205
13547
  browser;
13206
13548
  includeList;
13549
+ devSession;
13207
13550
  constructor(options){
13208
13551
  this.manifestPath = options.manifestPath;
13209
13552
  this.browser = options.browser || 'chrome';
13210
13553
  this.includeList = options.includeList || {};
13554
+ this.devSession = options.devSession;
13211
13555
  }
13212
13556
  resolveLoader() {
13213
13557
  return resolveDevelopDistFile("feature-scripts-content-script-wrapper");
@@ -13235,6 +13579,9 @@ class AddContentScriptWrapper {
13235
13579
  const loaderOptions = {
13236
13580
  manifestPath: this.manifestPath,
13237
13581
  mode: compiler.options.mode,
13582
+ ...'boolean' == typeof this.devSession ? {
13583
+ devSession: this.devSession
13584
+ } : {},
13238
13585
  browser: this.browser,
13239
13586
  mainWorldScripts,
13240
13587
  scriptsFolder: scriptsRoot ? canonicalizeDir(scriptsRoot) : false
@@ -14230,6 +14577,185 @@ class WarnSplitInitialChunks {
14230
14577
  });
14231
14578
  }
14232
14579
  }
14580
+ const ASSET_EXTENSIONS = new Set([
14581
+ '.png',
14582
+ '.jpg',
14583
+ '.jpeg',
14584
+ '.gif',
14585
+ '.svg',
14586
+ '.webp',
14587
+ '.avif',
14588
+ '.ico',
14589
+ '.bmp',
14590
+ '.woff',
14591
+ '.woff2',
14592
+ '.ttf',
14593
+ '.otf',
14594
+ '.eot',
14595
+ '.mp3',
14596
+ '.wav',
14597
+ '.ogg',
14598
+ '.mp4',
14599
+ '.webm',
14600
+ '.json',
14601
+ '.txt',
14602
+ '.csv',
14603
+ '.wasm'
14604
+ ]);
14605
+ const SKIPPED_FOLDERS = new Set([
14606
+ 'node_modules',
14607
+ 'dist',
14608
+ 'public'
14609
+ ]);
14610
+ const MAX_LITERAL_LENGTH = 200;
14611
+ const MAX_FOLDERS_REPORTED = 10;
14612
+ function hasAssetExtension(name) {
14613
+ return ASSET_EXTENSIONS.has(__rspack_external_node_path_806ed179.posix.extname(name).toLowerCase());
14614
+ }
14615
+ function stripLeadingNavigation(literal) {
14616
+ let rel = literal;
14617
+ while(/^(?:\.{1,2}\/|\/)/.test(rel))rel = rel.replace(/^(?:\.{1,2}\/|\/)/, '');
14618
+ return rel;
14619
+ }
14620
+ function extractPathLiterals(text) {
14621
+ const found = [];
14622
+ const quoted = /(["'])((?:(?!\1)[^\\\n\r])*)\1|`([^`\\$\n\r]*)(?:\$\{|`)/g;
14623
+ for (const match of text.matchAll(quoted)){
14624
+ const value = match[2] ?? match[3];
14625
+ if (value && value.length <= MAX_LITERAL_LENGTH) found.push(value);
14626
+ }
14627
+ return found;
14628
+ }
14629
+ function toRuntimePathReference(literal) {
14630
+ if (/^[a-z][a-z0-9+.-]*:/i.test(literal)) return;
14631
+ if (!/^[\w@./-]+$/.test(literal)) return;
14632
+ const rel = stripLeadingNavigation(literal);
14633
+ if (!rel || rel.startsWith('.')) return;
14634
+ const segments = rel.split('/');
14635
+ if (segments.some((segment)=>'..' === segment || '.' === segment)) return;
14636
+ if (SKIPPED_FOLDERS.has(segments[0])) return;
14637
+ const lastSlash = rel.lastIndexOf('/');
14638
+ const folder = -1 === lastSlash ? '' : rel.slice(0, lastSlash);
14639
+ const tail = rel.slice(lastSlash + 1);
14640
+ if (tail && hasAssetExtension(tail)) return {
14641
+ literal,
14642
+ folder,
14643
+ namePrefix: tail,
14644
+ file: rel
14645
+ };
14646
+ if (!folder) return;
14647
+ return {
14648
+ literal,
14649
+ folder,
14650
+ namePrefix: tail
14651
+ };
14652
+ }
14653
+ function listAssetFiles(dir, cache) {
14654
+ const cached = cache.get(dir);
14655
+ if (cached) return cached;
14656
+ let names = [];
14657
+ try {
14658
+ names = __rspack_external_node_fs_1b05aee1.readdirSync(dir, {
14659
+ withFileTypes: true
14660
+ }).filter((entry)=>entry.isFile() && hasAssetExtension(entry.name)).map((entry)=>entry.name);
14661
+ } catch {
14662
+ names = [];
14663
+ }
14664
+ cache.set(dir, names);
14665
+ return names;
14666
+ }
14667
+ function findUnshippedFolders(options) {
14668
+ const byFolder = new Map();
14669
+ const checked = new Set();
14670
+ const listings = new Map();
14671
+ for (const { assetName, text } of options.sources)for (const literal of extractPathLiterals(text)){
14672
+ const reference = toRuntimePathReference(literal);
14673
+ if (!reference) continue;
14674
+ const key = `${reference.folder}\0${reference.file ?? reference.namePrefix}`;
14675
+ if (checked.has(key)) continue;
14676
+ checked.add(key);
14677
+ const folderPath = __rspack_external_node_path_806ed179.join(options.extensionRoot, reference.folder);
14678
+ const names = reference.file ? [
14679
+ __rspack_external_node_path_806ed179.posix.basename(reference.file)
14680
+ ] : listAssetFiles(folderPath, listings).filter((name)=>name.startsWith(reference.namePrefix));
14681
+ for (const name of names){
14682
+ const distRel = reference.folder ? `${reference.folder}/${name}` : name;
14683
+ const absolutePath = __rspack_external_node_path_806ed179.join(options.extensionRoot, distRel);
14684
+ if (!__rspack_external_node_fs_1b05aee1.existsSync(absolutePath)) continue;
14685
+ if (!__rspack_external_node_fs_1b05aee1.statSync(absolutePath).isFile()) continue;
14686
+ if (options.isShipped(distRel)) continue;
14687
+ if (options.isBundled(absolutePath)) continue;
14688
+ const entry = byFolder.get(reference.folder) ?? {
14689
+ folder: reference.folder,
14690
+ literal,
14691
+ assetName,
14692
+ missing: []
14693
+ };
14694
+ if (!entry.missing.includes(distRel)) entry.missing.push(distRel);
14695
+ byFolder.set(reference.folder, entry);
14696
+ }
14697
+ }
14698
+ return foldNestedFolders([
14699
+ ...byFolder.values()
14700
+ ]);
14701
+ }
14702
+ function foldNestedFolders(entries) {
14703
+ const sorted = [
14704
+ ...entries
14705
+ ].sort((a, b)=>a.folder.length - b.folder.length || a.folder.localeCompare(b.folder));
14706
+ const kept = [];
14707
+ for (const entry of sorted){
14708
+ const parent = kept.find((candidate)=>'' !== candidate.folder && entry.folder.startsWith(`${candidate.folder}/`));
14709
+ if (parent) parent.missing.push(...entry.missing);
14710
+ else kept.push(entry);
14711
+ }
14712
+ return kept.sort((a, b)=>a.folder.localeCompare(b.folder));
14713
+ }
14714
+ function collectBundledFiles(compilation) {
14715
+ const bundled = new Set();
14716
+ for (const file of compilation.fileDependencies)bundled.add(file);
14717
+ for (const module of compilation.modules){
14718
+ const resource = module.resource;
14719
+ if (resource) bundled.add(resource.split('?')[0]);
14720
+ }
14721
+ return bundled;
14722
+ }
14723
+ class WarnUnshippedRuntimeAssets {
14724
+ manifestPath;
14725
+ constructor(options){
14726
+ this.manifestPath = options.manifestPath;
14727
+ }
14728
+ apply(compiler) {
14729
+ if (!compiler?.hooks?.thisCompilation?.tap) return;
14730
+ compiler.hooks.thisCompilation.tap(WarnUnshippedRuntimeAssets.name, (compilation)=>{
14731
+ compilation.hooks.afterProcessAssets.tap(WarnUnshippedRuntimeAssets.name, ()=>this.report(compilation));
14732
+ });
14733
+ }
14734
+ report(compilation) {
14735
+ const extensionRoot = __rspack_external_node_path_806ed179.dirname(this.manifestPath);
14736
+ const shipped = new Set(compilation.getAssets().map((asset)=>asset.name.replace(/\\/g, '/')));
14737
+ let bundled;
14738
+ const sources = compilation.getAssets().filter((asset)=>/\.(?:m?js|html?)$/i.test(asset.name)).map((asset)=>({
14739
+ assetName: asset.name.replace(/\\/g, '/'),
14740
+ text: asset.source.source().toString()
14741
+ }));
14742
+ const folders = findUnshippedFolders({
14743
+ extensionRoot,
14744
+ sources,
14745
+ isShipped: (distRel)=>shipped.has(distRel),
14746
+ isBundled: (absolutePath)=>{
14747
+ bundled ??= collectBundledFiles(compilation);
14748
+ return bundled.has(absolutePath);
14749
+ }
14750
+ });
14751
+ for (const folder of folders.slice(0, MAX_FOLDERS_REPORTED)){
14752
+ const warning = new core_WebpackError(runtimeAssetFolderNotShipped(folder.assetName, folder.literal, folder.folder, folder.missing));
14753
+ warning.name = 'RuntimeAssetFolderNotShipped';
14754
+ warning.file = folder.assetName;
14755
+ compilation.warnings.push(warning);
14756
+ }
14757
+ }
14758
+ }
14233
14759
  class ScriptsPlugin {
14234
14760
  manifestPath;
14235
14761
  includeList;
@@ -14266,7 +14792,8 @@ class ScriptsPlugin {
14266
14792
  new AddContentScriptWrapper({
14267
14793
  manifestPath: this.manifestPath,
14268
14794
  includeList: this.includeList || {},
14269
- browser: this.browser
14795
+ browser: this.browser,
14796
+ devSession: this.devSession
14270
14797
  }).apply(compiler);
14271
14798
  if ('production' === compiler.options.mode) new AddPublicPathRuntimeModule().apply(compiler);
14272
14799
  new ValidateEmittedScriptSyntax().apply(compiler);
@@ -14278,6 +14805,9 @@ class ScriptsPlugin {
14278
14805
  devSession: this.devSession,
14279
14806
  define: this.define
14280
14807
  }).apply(compiler);
14808
+ new WarnUnshippedRuntimeAssets({
14809
+ manifestPath: this.manifestPath
14810
+ }).apply(compiler);
14281
14811
  }
14282
14812
  }
14283
14813
  class CollectContentEntryImports {
@@ -14340,10 +14870,9 @@ function discoverWebAccessiblePages(manifestPath, browser = 'chrome', projectPat
14340
14870
  }
14341
14871
  return pages;
14342
14872
  }
14343
- const PANELS_CREATE_PATTERN = /panels\s*\.\s*create\s*\(\s*(['"`])(?:(?!\1).)*\1\s*,\s*(['"`])(?:(?!\2).)*\2\s*,\s*(['"`])((?:(?!\3).)*)\3/g;
14344
14873
  const SCRIPT_SRC_PATTERN = /<script[^>]*\ssrc\s*=\s*["']([^"']+)["']/gi;
14345
14874
  const RELATIVE_IMPORT_PATTERN = /(?:import\s[^'"]*|import\s*\(\s*|require\s*\(\s*|from\s*)['"](\.{1,2}\/[^'"]+)['"]/g;
14346
- const discover_devtools_panels_SOURCE_SIBLING_EXTENSIONS = [
14875
+ const script_graph_SOURCE_SIBLING_EXTENSIONS = [
14347
14876
  '.ts',
14348
14877
  '.mts',
14349
14878
  '.tsx',
@@ -14360,25 +14889,18 @@ function readScriptSource(absPath) {
14360
14889
  const direct = readIfFile(absPath);
14361
14890
  if (void 0 !== direct) return direct;
14362
14891
  const parsed = __rspack_external_node_path_806ed179.parse(absPath);
14363
- for (const ext of discover_devtools_panels_SOURCE_SIBLING_EXTENSIONS){
14892
+ for (const ext of script_graph_SOURCE_SIBLING_EXTENSIONS){
14364
14893
  const sibling = readIfFile(__rspack_external_node_path_806ed179.join(parsed.dir, parsed.name + ext));
14365
14894
  if (void 0 !== sibling) return sibling;
14366
14895
  }
14367
14896
  }
14368
- function collectPanelLiterals(source) {
14369
- const literals = [];
14370
- for (const match of source.matchAll(PANELS_CREATE_PATTERN)){
14371
- const literal = String(match[4] || '').trim();
14372
- if (literal) literals.push(literal);
14373
- }
14374
- return literals;
14375
- }
14376
14897
  function collectRelativeImports(source) {
14377
14898
  const specifiers = [];
14378
14899
  for (const match of source.matchAll(RELATIVE_IMPORT_PATTERN))specifiers.push(match[1]);
14379
14900
  return specifiers;
14380
14901
  }
14381
- function scanScriptGraph(entryAbsPath, found) {
14902
+ function scanScriptGraph(entryAbsPath, collect) {
14903
+ const found = [];
14382
14904
  const queue = [
14383
14905
  {
14384
14906
  file: entryAbsPath,
@@ -14392,7 +14914,7 @@ function scanScriptGraph(entryAbsPath, found) {
14392
14914
  seen.add(file);
14393
14915
  const source = readScriptSource(file);
14394
14916
  if (void 0 === source) continue;
14395
- found.push(...collectPanelLiterals(source));
14917
+ found.push(...collect(source));
14396
14918
  if (depth >= MAX_IMPORT_DEPTH) continue;
14397
14919
  for (const specifier of collectRelativeImports(source)){
14398
14920
  const resolved = __rspack_external_node_path_806ed179.resolve(__rspack_external_node_path_806ed179.dirname(file), specifier);
@@ -14403,29 +14925,24 @@ function scanScriptGraph(entryAbsPath, found) {
14403
14925
  });
14404
14926
  }
14405
14927
  }
14928
+ return found;
14406
14929
  }
14407
- function discoverDevtoolsPanelPages(manifestPath, browser = 'chrome') {
14408
- const projectDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
14409
- let devtoolsPage = '';
14410
- try {
14411
- const manifest = filterKeysForThisBrowser(JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf-8')), browser);
14412
- if ('string' == typeof manifest?.devtools_page) devtoolsPage = manifest.devtools_page;
14413
- } catch {}
14414
- if (!devtoolsPage) return {};
14415
- const devtoolsHtmlPath = __rspack_external_node_path_806ed179.join(projectDir, devtoolsPage.replace(/^\/+/, ''));
14416
- const devtoolsHtml = readIfFile(devtoolsHtmlPath);
14417
- if (void 0 === devtoolsHtml) return {};
14418
- const literals = [];
14419
- literals.push(...collectPanelLiterals(devtoolsHtml));
14420
- for (const match of devtoolsHtml.matchAll(SCRIPT_SRC_PATTERN)){
14930
+ function scanPageScripts(htmlAbsPath, projectDir, collect) {
14931
+ const html = readIfFile(htmlAbsPath);
14932
+ if (void 0 === html) return [];
14933
+ const found = collect(html);
14934
+ for (const match of html.matchAll(SCRIPT_SRC_PATTERN)){
14421
14935
  const src = String(match[1] || '');
14422
14936
  if (/^(https?:)?\/\//i.test(src)) continue;
14423
- const scriptAbs = src.startsWith('/') ? __rspack_external_node_path_806ed179.join(projectDir, src.slice(1)) : __rspack_external_node_path_806ed179.resolve(__rspack_external_node_path_806ed179.dirname(devtoolsHtmlPath), src);
14424
- scanScriptGraph(scriptAbs, literals);
14937
+ const scriptAbs = src.startsWith('/') ? __rspack_external_node_path_806ed179.join(projectDir, src.slice(1)) : __rspack_external_node_path_806ed179.resolve(__rspack_external_node_path_806ed179.dirname(htmlAbsPath), src);
14938
+ found.push(...scanScriptGraph(scriptAbs, collect));
14425
14939
  }
14940
+ return found;
14941
+ }
14942
+ function rootRelativePages(literals, projectDir) {
14426
14943
  const pages = {};
14427
14944
  for (const literal of literals){
14428
- const rootRel = literal.replace(/^\.?\/+/, '');
14945
+ const rootRel = literal.replace(/^\.?\/+/, '').split(/[?#]/)[0];
14429
14946
  if (!rootRel || !/\.html?$/i.test(rootRel)) continue;
14430
14947
  const absPage = __rspack_external_node_path_806ed179.join(projectDir, rootRel);
14431
14948
  const relToProject = __rspack_external_node_path_806ed179.relative(projectDir, absPage);
@@ -14436,6 +14953,60 @@ function discoverDevtoolsPanelPages(manifestPath, browser = 'chrome') {
14436
14953
  }
14437
14954
  return pages;
14438
14955
  }
14956
+ const PANELS_CREATE_PATTERN = /panels\s*\.\s*create\s*\(\s*(['"`])(?:(?!\1).)*\1\s*,\s*(['"`])(?:(?!\2).)*\2\s*,\s*(['"`])((?:(?!\3).)*)\3/g;
14957
+ function collectPanelLiterals(source) {
14958
+ const literals = [];
14959
+ for (const match of source.matchAll(PANELS_CREATE_PATTERN)){
14960
+ const literal = String(match[4] || '').trim();
14961
+ if (literal) literals.push(literal);
14962
+ }
14963
+ return literals;
14964
+ }
14965
+ function discoverDevtoolsPanelPages(manifestPath, browser = 'chrome') {
14966
+ const projectDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
14967
+ let devtoolsPage = '';
14968
+ try {
14969
+ const manifest = filterKeysForThisBrowser(JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf-8')), browser);
14970
+ if ('string' == typeof manifest?.devtools_page) devtoolsPage = manifest.devtools_page;
14971
+ } catch {}
14972
+ if (!devtoolsPage) return {};
14973
+ const devtoolsHtmlPath = __rspack_external_node_path_806ed179.join(projectDir, devtoolsPage.replace(/^\/+/, ''));
14974
+ return rootRelativePages(scanPageScripts(devtoolsHtmlPath, projectDir, collectPanelLiterals), projectDir);
14975
+ }
14976
+ const MAX_PAGE_HOPS = 4;
14977
+ function seedFiles(list) {
14978
+ return Object.values(list).flatMap((value)=>Array.isArray(value) ? value : value ? [
14979
+ value
14980
+ ] : []);
14981
+ }
14982
+ function literalsFrom(file, projectDir) {
14983
+ return /\.html?$/i.test(file) ? scanPageScripts(file, projectDir, extractRuntimeSurfaceLiterals) : scanScriptGraph(file, extractRuntimeSurfaceLiterals);
14984
+ }
14985
+ function discoverRuntimeSurfacePages(manifestPath, manifestScripts, manifestPages) {
14986
+ const projectDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
14987
+ const declared = new Set(seedFiles(manifestPages).map((p)=>__rspack_external_node_path_806ed179.resolve(p)));
14988
+ const pages = {};
14989
+ const visited = new Set();
14990
+ let frontier = [
14991
+ ...seedFiles(manifestScripts),
14992
+ ...seedFiles(manifestPages)
14993
+ ];
14994
+ for(let hop = 0; hop < MAX_PAGE_HOPS && frontier.length; hop++){
14995
+ const next = [];
14996
+ for (const file of frontier){
14997
+ const abs = __rspack_external_node_path_806ed179.resolve(file);
14998
+ if (visited.has(abs)) continue;
14999
+ visited.add(abs);
15000
+ const found = rootRelativePages(literalsFrom(abs, projectDir), projectDir);
15001
+ for (const [key, page] of Object.entries(found))if (!declared.has(__rspack_external_node_path_806ed179.resolve(page)) && !pages[key]) {
15002
+ pages[key] = page;
15003
+ next.push(page);
15004
+ }
15005
+ }
15006
+ frontier = next;
15007
+ }
15008
+ return pages;
15009
+ }
14439
15010
  const isCriticalJsonFeatureKey = isCriticalJsonFeature;
14440
15011
  function toComparablePath(value) {
14441
15012
  return 'string' == typeof value ? value : JSON.stringify(value);
@@ -14724,6 +15295,7 @@ class plugin_web_extension_WebExtensionPlugin {
14724
15295
  manifestPath,
14725
15296
  browser: this.browser,
14726
15297
  includeList: {
15298
+ ...discoverRuntimeSurfacePages(manifestPath, manifestFieldsData.scripts, manifestFieldsData.html),
14727
15299
  ...discoverWebAccessiblePages(manifestPath, this.browser, projectPath),
14728
15300
  ...ownedPages,
14729
15301
  ...omitOwnedPages(specialFoldersData.pages, ownedPages)
@@ -14783,6 +15355,8 @@ function webpackConfig(projectStructure, devOptions) {
14783
15355
  throw codedError(CODES.E_MANIFEST_INVALID, manifestInvalidJson(manifestPath, error));
14784
15356
  }
14785
15357
  const manifest = filterKeysForThisBrowser(rawManifest, devOptions.browser);
15358
+ const mistypedFields = findMistypedManifestFields(manifest);
15359
+ if (mistypedFields.length > 0) throw codedError(CODES.E_MANIFEST_INVALID, mistypedFields.map((entry)=>manifestFieldMistyped(entry.field, entry.expected, entry.received)).join('\n\n'));
14786
15360
  const primaryExtensionOutputDir = asAbsolute(__rspack_external_node_path_806ed179.isAbsolute(devOptions.output.path) ? devOptions.output.path : __rspack_external_node_path_806ed179.resolve(packageJsonDir, devOptions.output.path));
14787
15361
  const publishedExtensionOutputDir = devOptions.output.finalPath ? asAbsolute(__rspack_external_node_path_806ed179.isAbsolute(devOptions.output.finalPath) ? devOptions.output.finalPath : __rspack_external_node_path_806ed179.resolve(packageJsonDir, devOptions.output.finalPath)) : primaryExtensionOutputDir;
14788
15362
  const companionUnpackedExtensionDirs = resolveCompanionExtensionDirs({
@@ -14942,6 +15516,38 @@ function webpackConfig(projectStructure, devOptions) {
14942
15516
  browsersPlugin.extensionsToLoad = unpackedExtensionDirsToLoad;
14943
15517
  plugins.push(browsersPlugin);
14944
15518
  }
15519
+ const modeCondition = 'production' === (devOptions.mode || 'development') ? 'production' : 'development';
15520
+ const importResolve = {
15521
+ conditionNames: [
15522
+ 'browser',
15523
+ 'import',
15524
+ 'module',
15525
+ modeCondition,
15526
+ 'default'
15527
+ ]
15528
+ };
15529
+ const requireResolve = {
15530
+ conditionNames: [
15531
+ 'browser',
15532
+ 'require',
15533
+ 'module',
15534
+ modeCondition,
15535
+ 'default'
15536
+ ]
15537
+ };
15538
+ const cssImportResolve = {
15539
+ conditionNames: [
15540
+ modeCondition,
15541
+ 'style'
15542
+ ],
15543
+ extensions: [
15544
+ '.css'
15545
+ ],
15546
+ mainFields: [
15547
+ 'style',
15548
+ '...'
15549
+ ]
15550
+ };
14945
15551
  return {
14946
15552
  mode: devOptions.mode || 'development',
14947
15553
  entry: {},
@@ -15026,25 +15632,21 @@ function webpackConfig(projectStructure, devOptions) {
15026
15632
  'import',
15027
15633
  'require',
15028
15634
  'module',
15635
+ modeCondition,
15029
15636
  'default'
15030
15637
  ],
15031
15638
  byDependency: {
15032
- esm: {
15033
- conditionNames: [
15034
- 'browser',
15035
- 'import',
15036
- 'module',
15037
- 'default'
15038
- ]
15039
- },
15040
- commonjs: {
15041
- conditionNames: [
15042
- 'browser',
15043
- 'require',
15044
- 'module',
15045
- 'default'
15046
- ]
15047
- }
15639
+ esm: importResolve,
15640
+ wasm: importResolve,
15641
+ loaderImport: importResolve,
15642
+ worker: importResolve,
15643
+ commonjs: requireResolve,
15644
+ amd: requireResolve,
15645
+ loader: requireResolve,
15646
+ unknown: requireResolve,
15647
+ 'css-import': cssImportResolve,
15648
+ 'css-import-local-module': cssImportResolve,
15649
+ 'css-import-global-module': cssImportResolve
15048
15650
  },
15049
15651
  aliasFields: [
15050
15652
  'browser'
@@ -15156,7 +15758,8 @@ function webpackConfig(projectStructure, devOptions) {
15156
15758
  extractComments: true
15157
15759
  }),
15158
15760
  new LightningCssMinimizerRspackPlugin({
15159
- removeUnusedLocalIdents: false
15761
+ removeUnusedLocalIdents: false,
15762
+ minimizerOptions: cssMinimizerOptions(rawManifest, devOptions.browser)
15160
15763
  })
15161
15764
  ],
15162
15765
  sideEffects: true,