webpack 5.80.0 → 5.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (105) hide show
  1. package/lib/AsyncDependenciesBlock.js +8 -0
  2. package/lib/CodeGenerationResults.js +2 -2
  3. package/lib/Compilation.js +2 -2
  4. package/lib/ContextModule.js +8 -0
  5. package/lib/CssModule.js +137 -0
  6. package/lib/DefinePlugin.js +81 -44
  7. package/lib/DelegatedModule.js +5 -0
  8. package/lib/DependenciesBlock.js +8 -0
  9. package/lib/Dependency.js +8 -0
  10. package/lib/DllModule.js +8 -0
  11. package/lib/ExportsInfo.js +3 -0
  12. package/lib/ExternalModule.js +8 -0
  13. package/lib/FileSystemInfo.js +8 -0
  14. package/lib/LoaderOptionsPlugin.js +12 -2
  15. package/lib/Module.js +8 -0
  16. package/lib/ModuleBuildError.js +9 -0
  17. package/lib/ModuleError.js +9 -0
  18. package/lib/ModuleFilenameHelpers.js +113 -4
  19. package/lib/ModuleParseError.js +9 -0
  20. package/lib/ModuleTypeConstants.js +21 -0
  21. package/lib/ModuleWarning.js +9 -0
  22. package/lib/NormalModule.js +8 -0
  23. package/lib/NormalModuleFactory.js +15 -3
  24. package/lib/RawModule.js +8 -0
  25. package/lib/WebpackError.js +8 -0
  26. package/lib/asset/RawDataUrlModule.js +8 -0
  27. package/lib/cache/ResolverCachePlugin.js +3 -0
  28. package/lib/config/normalization.js +1 -0
  29. package/lib/container/ContainerEntryModule.js +5 -0
  30. package/lib/container/ContainerExposedDependency.js +9 -0
  31. package/lib/container/FallbackDependency.js +6 -0
  32. package/lib/container/FallbackModule.js +5 -0
  33. package/lib/container/RemoteModule.js +5 -0
  34. package/lib/css/CssModulesPlugin.js +91 -50
  35. package/lib/css/CssParser.js +132 -73
  36. package/lib/css/walkCssTokens.js +27 -47
  37. package/lib/dependencies/AMDDefineDependency.js +8 -0
  38. package/lib/dependencies/AMDRequireArrayDependency.js +8 -0
  39. package/lib/dependencies/AMDRequireContextDependency.js +9 -0
  40. package/lib/dependencies/AMDRequireDependency.js +8 -0
  41. package/lib/dependencies/CachedConstDependency.js +8 -0
  42. package/lib/dependencies/CommonJsDependencyHelpers.js +9 -0
  43. package/lib/dependencies/CommonJsExportRequireDependency.js +8 -0
  44. package/lib/dependencies/CommonJsExportsDependency.js +8 -0
  45. package/lib/dependencies/CommonJsExportsParserPlugin.js +65 -3
  46. package/lib/dependencies/CommonJsFullRequireDependency.js +8 -0
  47. package/lib/dependencies/CommonJsRequireContextDependency.js +9 -0
  48. package/lib/dependencies/CommonJsSelfReferenceDependency.js +8 -0
  49. package/lib/dependencies/ConstDependency.js +8 -0
  50. package/lib/dependencies/ContextDependency.js +8 -0
  51. package/lib/dependencies/ContextElementDependency.js +8 -0
  52. package/lib/dependencies/CreateScriptUrlDependency.js +8 -0
  53. package/lib/dependencies/CssExportDependency.js +8 -0
  54. package/lib/dependencies/CssImportDependency.js +52 -1
  55. package/lib/dependencies/CssLocalIdentifierDependency.js +8 -0
  56. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +8 -0
  57. package/lib/dependencies/CssUrlDependency.js +8 -0
  58. package/lib/dependencies/DllEntryDependency.js +9 -0
  59. package/lib/dependencies/ExportsInfoDependency.js +5 -0
  60. package/lib/dependencies/HarmonyAcceptDependency.js +8 -0
  61. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +8 -0
  62. package/lib/dependencies/HarmonyExportExpressionDependency.js +8 -0
  63. package/lib/dependencies/HarmonyExportHeaderDependency.js +8 -0
  64. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +14 -0
  65. package/lib/dependencies/HarmonyExportSpecifierDependency.js +8 -0
  66. package/lib/dependencies/HarmonyImportDependency.js +8 -0
  67. package/lib/dependencies/HarmonyImportSpecifierDependency.js +8 -0
  68. package/lib/dependencies/ImportContextDependency.js +9 -0
  69. package/lib/dependencies/ImportDependency.js +8 -0
  70. package/lib/dependencies/JsonExportsDependency.js +8 -0
  71. package/lib/dependencies/LocalModuleDependency.js +8 -0
  72. package/lib/dependencies/ModuleDecoratorDependency.js +8 -0
  73. package/lib/dependencies/ModuleDependency.js +8 -0
  74. package/lib/dependencies/ProvidedDependency.js +8 -0
  75. package/lib/dependencies/PureExpressionDependency.js +8 -0
  76. package/lib/dependencies/RequireEnsureDependency.js +8 -0
  77. package/lib/dependencies/RequireHeaderDependency.js +5 -0
  78. package/lib/dependencies/RequireResolveContextDependency.js +9 -0
  79. package/lib/dependencies/RequireResolveHeaderDependency.js +5 -0
  80. package/lib/dependencies/RuntimeRequirementsDependency.js +8 -0
  81. package/lib/dependencies/StaticExportsDependency.js +8 -0
  82. package/lib/dependencies/URLDependency.js +8 -0
  83. package/lib/dependencies/UnsupportedDependency.js +8 -0
  84. package/lib/dependencies/WebAssemblyExportImportedDependency.js +8 -0
  85. package/lib/dependencies/WebAssemblyImportDependency.js +8 -0
  86. package/lib/dependencies/WorkerDependency.js +8 -0
  87. package/lib/index.js +1 -0
  88. package/lib/javascript/JavascriptParser.js +1 -1
  89. package/lib/optimize/RealContentHashPlugin.js +6 -0
  90. package/lib/runtime/AutoPublicPathRuntimeModule.js +6 -1
  91. package/lib/serialization/ObjectMiddleware.js +2 -0
  92. package/lib/sharing/ConsumeSharedModule.js +8 -0
  93. package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -3
  94. package/lib/sharing/ProvideSharedDependency.js +6 -0
  95. package/lib/sharing/ProvideSharedModule.js +5 -0
  96. package/lib/sharing/ShareRuntimeModule.js +7 -4
  97. package/lib/util/LazySet.js +10 -2
  98. package/lib/util/MapHelpers.js +19 -5
  99. package/lib/util/binarySearchBounds.js +49 -0
  100. package/lib/util/internalSerializables.js +1 -0
  101. package/lib/util/semver.js +1 -1
  102. package/package.json +4 -5
  103. package/schemas/WebpackOptions.check.js +1 -1
  104. package/schemas/WebpackOptions.json +8 -0
  105. package/types.d.ts +55 -22
@@ -5,8 +5,14 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { ConcatSource } = require("webpack-sources");
8
+ const { ConcatSource, PrefixSource } = require("webpack-sources");
9
+ const CssModule = require("../CssModule");
9
10
  const HotUpdateChunk = require("../HotUpdateChunk");
11
+ const {
12
+ CSS_MODULE_TYPE,
13
+ CSS_MODULE_TYPE_GLOBAL,
14
+ CSS_MODULE_TYPE_MODULE
15
+ } = require("../ModuleTypeConstants");
10
16
  const RuntimeGlobals = require("../RuntimeGlobals");
11
17
  const SelfModuleFactory = require("../SelfModuleFactory");
12
18
  const CssExportDependency = require("../dependencies/CssExportDependency");
@@ -125,53 +131,56 @@ class CssModulesPlugin {
125
131
  StaticExportsDependency,
126
132
  new StaticExportsDependency.Template()
127
133
  );
128
- normalModuleFactory.hooks.createParser
129
- .for("css")
130
- .tap(plugin, parserOptions => {
131
- validateParserOptions(parserOptions);
132
- return new CssParser();
133
- });
134
- normalModuleFactory.hooks.createParser
135
- .for("css/global")
136
- .tap(plugin, parserOptions => {
137
- validateParserOptions(parserOptions);
138
- return new CssParser({
139
- allowPseudoBlocks: false,
140
- allowModeSwitch: false
134
+ for (const type of [
135
+ CSS_MODULE_TYPE,
136
+ CSS_MODULE_TYPE_GLOBAL,
137
+ CSS_MODULE_TYPE_MODULE
138
+ ]) {
139
+ normalModuleFactory.hooks.createParser
140
+ .for(type)
141
+ .tap(plugin, parserOptions => {
142
+ validateParserOptions(parserOptions);
143
+
144
+ switch (type) {
145
+ case CSS_MODULE_TYPE:
146
+ return new CssParser();
147
+ case CSS_MODULE_TYPE_GLOBAL:
148
+ return new CssParser({
149
+ allowPseudoBlocks: false,
150
+ allowModeSwitch: false
151
+ });
152
+ case CSS_MODULE_TYPE_MODULE:
153
+ return new CssParser({
154
+ defaultMode: "local"
155
+ });
156
+ }
141
157
  });
142
- });
143
- normalModuleFactory.hooks.createParser
144
- .for("css/module")
145
- .tap(plugin, parserOptions => {
146
- validateParserOptions(parserOptions);
147
- return new CssParser({
148
- defaultMode: "local"
158
+ normalModuleFactory.hooks.createGenerator
159
+ .for(type)
160
+ .tap(plugin, generatorOptions => {
161
+ validateGeneratorOptions(generatorOptions);
162
+ return this._exportsOnly
163
+ ? new CssExportsGenerator()
164
+ : new CssGenerator();
149
165
  });
150
- });
151
- normalModuleFactory.hooks.createGenerator
152
- .for("css")
153
- .tap(plugin, generatorOptions => {
154
- validateGeneratorOptions(generatorOptions);
155
- return this._exportsOnly
156
- ? new CssExportsGenerator()
157
- : new CssGenerator();
158
- });
159
- normalModuleFactory.hooks.createGenerator
160
- .for("css/global")
161
- .tap(plugin, generatorOptions => {
162
- validateGeneratorOptions(generatorOptions);
163
- return this._exportsOnly
164
- ? new CssExportsGenerator()
165
- : new CssGenerator();
166
- });
167
- normalModuleFactory.hooks.createGenerator
168
- .for("css/module")
169
- .tap(plugin, generatorOptions => {
170
- validateGeneratorOptions(generatorOptions);
171
- return this._exportsOnly
172
- ? new CssExportsGenerator()
173
- : new CssGenerator();
174
- });
166
+ normalModuleFactory.hooks.createModuleClass
167
+ .for(type)
168
+ .tap(plugin, (createData, resolveData) => {
169
+ if (resolveData.dependencies.length > 0) {
170
+ // When CSS is imported from CSS there is only one dependency
171
+ const dependency = resolveData.dependencies[0];
172
+
173
+ return new CssModule({
174
+ ...createData,
175
+ cssLayer: dependency.layer,
176
+ supports: dependency.supports,
177
+ media: dependency.media
178
+ });
179
+ }
180
+
181
+ return new CssModule(createData);
182
+ });
183
+ }
175
184
  const orderedCssModulesPerChunk = new WeakMap();
176
185
  compilation.hooks.afterCodeGeneration.tap("CssModulesPlugin", () => {
177
186
  const { chunkGraph } = compilation;
@@ -401,16 +410,48 @@ class CssModulesPlugin {
401
410
  try {
402
411
  const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
403
412
 
404
- const s =
413
+ let moduleSource =
405
414
  codeGenResult.sources.get("css") ||
406
415
  codeGenResult.sources.get("css-import");
407
- if (s) {
408
- source.add(s);
416
+
417
+ if (module.media) {
418
+ moduleSource = new ConcatSource(
419
+ `@media ${module.media} {\n`,
420
+ new PrefixSource("\t", moduleSource),
421
+ "}"
422
+ );
423
+ }
424
+
425
+ if (module.supports) {
426
+ moduleSource = new ConcatSource(
427
+ `@supports (${module.supports}) {\n`,
428
+ new PrefixSource("\t", moduleSource),
429
+ "}"
430
+ );
431
+ }
432
+
433
+ // Layer can be anonymous
434
+ if (module.cssLayer !== undefined && module.cssLayer !== null) {
435
+ moduleSource = new ConcatSource(
436
+ `@layer${module.cssLayer ? ` (${module.cssLayer})` : ""} {\n`,
437
+ new PrefixSource("\t", moduleSource),
438
+ "}"
439
+ );
440
+ }
441
+
442
+ if (moduleSource) {
443
+ source.add(moduleSource);
409
444
  source.add("\n");
410
445
  }
411
446
  const exports =
412
447
  codeGenResult.data && codeGenResult.data.get("css-exports");
413
- const moduleId = chunkGraph.getModuleId(module) + "";
448
+ let moduleId = chunkGraph.getModuleId(module) + "";
449
+
450
+ // When `optimization.moduleIds` is `named` the module id is a path, so we need to normalize it between platforms
451
+ if (typeof moduleId === "string") {
452
+ moduleId = moduleId.replace(/\\/g, "/");
453
+ }
454
+
414
455
  metaData.push(
415
456
  `${
416
457
  exports
@@ -30,6 +30,9 @@ const STRING_MULTILINE = /\\[\n\r\f]/g;
30
30
  const TRIM_WHITE_SPACES = /(^[ \t\n\r\f]*|[ \t\n\r\f]*$)/g;
31
31
  const UNESCAPE = /\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g;
32
32
  const IMAGE_SET_FUNCTION = /^(-\w+-)?image-set$/i;
33
+ const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
34
+ const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
35
+ /^(-\w+-)?animation(-name)?$/i;
33
36
 
34
37
  const normalizeUrl = (str, isString) => {
35
38
  // Remove extra spaces and newlines:
@@ -106,10 +109,8 @@ const CSS_MODE_TOP_LEVEL = 0;
106
109
  const CSS_MODE_IN_RULE = 1;
107
110
  const CSS_MODE_IN_LOCAL_RULE = 2;
108
111
  const CSS_MODE_AT_IMPORT_EXPECT_URL = 3;
109
- // TODO implement layer and supports for @import
110
- const CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS = 4;
111
- const CSS_MODE_AT_IMPORT_EXPECT_MEDIA = 5;
112
- const CSS_MODE_AT_OTHER = 6;
112
+ const CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA = 4;
113
+ const CSS_MODE_AT_OTHER = 5;
113
114
 
114
115
  const explainMode = mode => {
115
116
  switch (mode) {
@@ -121,10 +122,8 @@ const explainMode = mode => {
121
122
  return "parsing css rule content (local)";
122
123
  case CSS_MODE_AT_IMPORT_EXPECT_URL:
123
124
  return "parsing @import (expecting url)";
124
- case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS:
125
- return "parsing @import (expecting optionally supports or media query)";
126
- case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
127
- return "parsing @import (expecting optionally media query)";
125
+ case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA:
126
+ return "parsing @import (expecting optionally layer, supports or media query)";
128
127
  case CSS_MODE_AT_OTHER:
129
128
  return "parsing at-rule";
130
129
  default:
@@ -165,14 +164,13 @@ class CssParser extends Parser {
165
164
 
166
165
  const locConverter = new LocConverter(source);
167
166
  let mode = CSS_MODE_TOP_LEVEL;
168
- let modePos = 0;
169
167
  let modeNestingLevel = 0;
170
168
  let modeData = undefined;
171
169
  let singleClassSelector = undefined;
172
170
  let lastIdentifier = undefined;
173
171
  let awaitRightParenthesis = false;
174
172
  /** @type [string, number, number][] */
175
- const functionStack = [];
173
+ let balanced = [];
176
174
  const modeStack = [];
177
175
 
178
176
  const isTopLevelLocal = () =>
@@ -315,8 +313,7 @@ class CssParser extends Parser {
315
313
  module.addDependency(dep);
316
314
  declaredCssVariables.add(name);
317
315
  } else if (
318
- propertyName.toLowerCase() === "animation-name" ||
319
- propertyName.toLowerCase() === "animation"
316
+ OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY.test(propertyName)
320
317
  ) {
321
318
  modeData = "animation";
322
319
  lastIdentifier = undefined;
@@ -338,7 +335,12 @@ class CssParser extends Parser {
338
335
  const eatNameInVar = eatUntil(",)};/");
339
336
  walkCssTokens(source, {
340
337
  isSelector: () => {
341
- return mode !== CSS_MODE_IN_RULE && mode !== CSS_MODE_IN_LOCAL_RULE;
338
+ return (
339
+ mode !== CSS_MODE_IN_RULE &&
340
+ mode !== CSS_MODE_IN_LOCAL_RULE &&
341
+ mode !== CSS_MODE_AT_IMPORT_EXPECT_URL &&
342
+ mode !== CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA
343
+ );
342
344
  },
343
345
  url: (input, start, end, contentStart, contentEnd, isString) => {
344
346
  let value = normalizeUrl(
@@ -348,17 +350,14 @@ class CssParser extends Parser {
348
350
  switch (mode) {
349
351
  case CSS_MODE_AT_IMPORT_EXPECT_URL: {
350
352
  modeData.url = value;
351
- mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
353
+ modeData.lastPos = end;
354
+ mode = CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA;
355
+ break;
356
+ }
357
+ // Do not parse URLs in `supports(...)`
358
+ case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
352
359
  break;
353
360
  }
354
- case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS:
355
- case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
356
- throw new Error(
357
- `Unexpected ${input.slice(
358
- start,
359
- end
360
- )} at ${start} during ${explainMode(mode)}`
361
- );
362
361
  default: {
363
362
  if (
364
363
  // Ignore `url(#highlight)` URLs
@@ -384,17 +383,28 @@ class CssParser extends Parser {
384
383
  switch (mode) {
385
384
  case CSS_MODE_AT_IMPORT_EXPECT_URL: {
386
385
  modeData.url = normalizeUrl(input.slice(start + 1, end - 1), true);
387
- mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
386
+ modeData.lastPos = end;
387
+ const insideURLFunction =
388
+ balanced[balanced.length - 1] &&
389
+ balanced[balanced.length - 1][0] === "url";
390
+
391
+ if (!insideURLFunction) {
392
+ mode = CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA;
393
+ }
394
+ break;
395
+ }
396
+ // Do not parse URLs in `supports(...)`
397
+ case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
388
398
  break;
389
399
  }
390
400
  default: {
391
401
  // TODO move escaped parsing to tokenizer
392
- const lastFunction = functionStack[functionStack.length - 1];
402
+ const last = balanced[balanced.length - 1];
393
403
 
394
404
  if (
395
- lastFunction &&
396
- (lastFunction[0].replace(/\\/g, "").toLowerCase() === "url" ||
397
- IMAGE_SET_FUNCTION.test(lastFunction[0].replace(/\\/g, "")))
405
+ last &&
406
+ (last[0].replace(/\\/g, "").toLowerCase() === "url" ||
407
+ IMAGE_SET_FUNCTION.test(last[0].replace(/\\/g, "")))
398
408
  ) {
399
409
  let value = normalizeUrl(input.slice(start + 1, end - 1), true);
400
410
 
@@ -407,8 +417,7 @@ class CssParser extends Parser {
407
417
  break;
408
418
  }
409
419
 
410
- const isUrl =
411
- lastFunction[0].replace(/\\/g, "").toLowerCase() === "url";
420
+ const isUrl = last[0].replace(/\\/g, "").toLowerCase() === "url";
412
421
  const dep = new CssUrlDependency(
413
422
  value,
414
423
  [start, end],
@@ -436,14 +445,16 @@ class CssParser extends Parser {
436
445
  );
437
446
  }
438
447
  mode = CSS_MODE_AT_IMPORT_EXPECT_URL;
439
- modePos = end;
440
448
  modeData = {
441
- start: start,
449
+ atRuleStart: start,
450
+ lastPos: end,
442
451
  url: undefined,
443
- supports: undefined
452
+ layer: undefined,
453
+ supports: undefined,
454
+ media: undefined
444
455
  };
445
456
  }
446
- if (name === "@keyframes") {
457
+ if (OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name)) {
447
458
  let pos = end;
448
459
  pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
449
460
  if (pos === input.length) return pos;
@@ -482,20 +493,40 @@ class CssParser extends Parser {
482
493
  switch (mode) {
483
494
  case CSS_MODE_AT_IMPORT_EXPECT_URL:
484
495
  throw new Error(`Expected URL for @import at ${start}`);
485
- case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
486
- case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS: {
487
- const { line: sl, column: sc } = locConverter.get(modeData.start);
496
+ case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
497
+ if (modeData.url === undefined) {
498
+ throw new Error(
499
+ `Expected URL for @import at ${modeData.atRuleStart}`
500
+ );
501
+ }
502
+ const semicolonPos = end;
503
+ const { line: sl, column: sc } = locConverter.get(
504
+ modeData.atRuleStart
505
+ );
488
506
  const { line: el, column: ec } = locConverter.get(end);
489
- end = eatWhiteLine(input, end);
490
- const media = input.slice(modePos, start).trim();
507
+ const pos = walkCssTokens.eatWhitespaceAndComments(
508
+ input,
509
+ modeData.lastPos
510
+ );
511
+ // Prevent to consider comments as a part of media query
512
+ if (pos !== semicolonPos - 1) {
513
+ modeData.media = input
514
+ .slice(modeData.lastPos, semicolonPos - 1)
515
+ .trim();
516
+ }
491
517
  const dep = new CssImportDependency(
492
- modeData.url,
518
+ modeData.url.trim(),
493
519
  [modeData.start, end],
520
+ modeData.layer,
494
521
  modeData.supports,
495
- media
522
+ modeData.media && modeData.media.length > 0
523
+ ? modeData.media
524
+ : undefined
496
525
  );
497
526
  dep.setLoc(sl, sc, el, ec);
498
527
  module.addDependency(dep);
528
+ modeData = undefined;
529
+ mode = CSS_MODE_TOP_LEVEL;
499
530
  break;
500
531
  }
501
532
  case CSS_MODE_IN_LOCAL_RULE: {
@@ -570,6 +601,13 @@ class CssParser extends Parser {
570
601
  lastIdentifier = [start, end];
571
602
  }
572
603
  break;
604
+ case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
605
+ if (input.slice(start, end).toLowerCase() === "layer") {
606
+ modeData.layer = "";
607
+ modeData.lastPos = end;
608
+ }
609
+ break;
610
+ }
573
611
  }
574
612
  return end;
575
613
  },
@@ -595,7 +633,40 @@ class CssParser extends Parser {
595
633
  }
596
634
  return end;
597
635
  },
636
+ function: (input, start, end) => {
637
+ let name = input.slice(start, end - 1);
638
+
639
+ balanced.push([name, start, end]);
640
+
641
+ switch (mode) {
642
+ case CSS_MODE_IN_LOCAL_RULE: {
643
+ name = name.toLowerCase();
644
+
645
+ if (name === "var") {
646
+ let pos = walkCssTokens.eatWhitespaceAndComments(input, end);
647
+ if (pos === input.length) return pos;
648
+ const [newPos, name] = eatText(input, pos, eatNameInVar);
649
+ if (!name.startsWith("--")) return end;
650
+ const { line: sl, column: sc } = locConverter.get(pos);
651
+ const { line: el, column: ec } = locConverter.get(newPos);
652
+ const dep = new CssSelfLocalIdentifierDependency(
653
+ name.slice(2),
654
+ [pos, newPos],
655
+ "--",
656
+ declaredCssVariables
657
+ );
658
+ dep.setLoc(sl, sc, el, ec);
659
+ module.addDependency(dep);
660
+ return newPos;
661
+ }
662
+ break;
663
+ }
664
+ }
665
+ return end;
666
+ },
598
667
  leftParenthesis: (input, start, end) => {
668
+ balanced.push(["(", start, end]);
669
+
599
670
  switch (mode) {
600
671
  case CSS_MODE_TOP_LEVEL: {
601
672
  modeStack.push(false);
@@ -605,7 +676,9 @@ class CssParser extends Parser {
605
676
  return end;
606
677
  },
607
678
  rightParenthesis: (input, start, end) => {
608
- functionStack.pop();
679
+ const last = balanced[balanced.length - 1];
680
+
681
+ balanced.pop();
609
682
 
610
683
  switch (mode) {
611
684
  case CSS_MODE_TOP_LEVEL: {
@@ -620,6 +693,23 @@ class CssParser extends Parser {
620
693
  }
621
694
  break;
622
695
  }
696
+ case CSS_MODE_AT_IMPORT_EXPECT_URL: {
697
+ if (last && last[0] === "url") {
698
+ modeData.lastPos = end;
699
+ mode = CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA;
700
+ }
701
+ break;
702
+ }
703
+ case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
704
+ if (last && last[0].toLowerCase() === "layer") {
705
+ modeData.layer = input.slice(last[2], end - 1).trim();
706
+ modeData.lastPos = end;
707
+ } else if (last && last[0].toLowerCase() === "supports") {
708
+ modeData.supports = input.slice(last[2], end - 1).trim();
709
+ modeData.lastPos = end;
710
+ }
711
+ break;
712
+ }
623
713
  }
624
714
 
625
715
  return end;
@@ -651,7 +741,7 @@ class CssParser extends Parser {
651
741
  pseudoFunction: (input, start, end) => {
652
742
  let name = input.slice(start, end - 1);
653
743
 
654
- functionStack.push([name, start, end]);
744
+ balanced.push([name, start, end]);
655
745
 
656
746
  switch (mode) {
657
747
  case CSS_MODE_TOP_LEVEL: {
@@ -676,37 +766,6 @@ class CssParser extends Parser {
676
766
  }
677
767
  return end;
678
768
  },
679
- function: (input, start, end) => {
680
- let name = input.slice(start, end - 1);
681
-
682
- functionStack.push([name, start, end]);
683
-
684
- switch (mode) {
685
- case CSS_MODE_IN_LOCAL_RULE: {
686
- name = name.toLowerCase();
687
-
688
- if (name === "var") {
689
- let pos = walkCssTokens.eatWhitespaceAndComments(input, end);
690
- if (pos === input.length) return pos;
691
- const [newPos, name] = eatText(input, pos, eatNameInVar);
692
- if (!name.startsWith("--")) return end;
693
- const { line: sl, column: sc } = locConverter.get(pos);
694
- const { line: el, column: ec } = locConverter.get(newPos);
695
- const dep = new CssSelfLocalIdentifierDependency(
696
- name.slice(2),
697
- [pos, newPos],
698
- "--",
699
- declaredCssVariables
700
- );
701
- dep.setLoc(sl, sc, el, ec);
702
- module.addDependency(dep);
703
- return newPos;
704
- }
705
- break;
706
- }
707
- }
708
- return end;
709
- },
710
769
  comma: (input, start, end) => {
711
770
  switch (mode) {
712
771
  case CSS_MODE_TOP_LEVEL:
@@ -7,7 +7,7 @@
7
7
 
8
8
  /**
9
9
  * @typedef {Object} CssTokenCallbacks
10
- * @property {function(string, number): boolean} isSelector
10
+ * @property {function(string, number): boolean=} isSelector
11
11
  * @property {function(string, number, number, number, number): number=} url
12
12
  * @property {function(string, number, number): number=} string
13
13
  * @property {function(string, number, number): number=} leftParenthesis
@@ -661,59 +661,39 @@ module.exports = (input, callbacks) => {
661
661
  }
662
662
  };
663
663
 
664
+ /**
665
+ * @param {string} input input
666
+ * @param {number} pos position
667
+ * @returns {number} position after comments
668
+ */
664
669
  module.exports.eatComments = (input, pos) => {
665
- loop: for (;;) {
666
- const cc = input.charCodeAt(pos);
667
- if (cc === CC_SOLIDUS) {
668
- if (pos === input.length) return pos;
669
- let cc = input.charCodeAt(pos + 1);
670
- if (cc !== CC_ASTERISK) return pos;
671
- pos++;
672
- for (;;) {
673
- pos++;
674
- if (pos === input.length) return pos;
675
- cc = input.charCodeAt(pos);
676
- while (cc === CC_ASTERISK) {
677
- pos++;
678
- if (pos === input.length) return pos;
679
- cc = input.charCodeAt(pos);
680
- if (cc === CC_SOLIDUS) {
681
- pos++;
682
- continue loop;
683
- }
684
- }
685
- }
670
+ for (;;) {
671
+ let originalPos = pos;
672
+ pos = consumeComments(input, pos, {});
673
+ if (originalPos === pos) {
674
+ break;
686
675
  }
687
- return pos;
688
676
  }
677
+
678
+ return pos;
689
679
  };
690
680
 
681
+ /**
682
+ * @param {string} input input
683
+ * @param {number} pos position
684
+ * @returns {number} position after whitespace and comments
685
+ */
691
686
  module.exports.eatWhitespaceAndComments = (input, pos) => {
692
- loop: for (;;) {
693
- const cc = input.charCodeAt(pos);
694
- if (cc === CC_SOLIDUS) {
695
- if (pos === input.length) return pos;
696
- let cc = input.charCodeAt(pos + 1);
697
- if (cc !== CC_ASTERISK) return pos;
698
- pos++;
699
- for (;;) {
700
- pos++;
701
- if (pos === input.length) return pos;
702
- cc = input.charCodeAt(pos);
703
- while (cc === CC_ASTERISK) {
704
- pos++;
705
- if (pos === input.length) return pos;
706
- cc = input.charCodeAt(pos);
707
- if (cc === CC_SOLIDUS) {
708
- pos++;
709
- continue loop;
710
- }
711
- }
712
- }
713
- } else if (_isWhiteSpace(cc)) {
687
+ for (;;) {
688
+ let originalPos = pos;
689
+ pos = consumeComments(input, pos, {});
690
+ while (_isWhiteSpace(input.charCodeAt(pos))) {
714
691
  pos++;
715
- continue;
716
692
  }
717
- return pos;
693
+ if (originalPos === pos) {
694
+ break;
695
+ }
718
696
  }
697
+
698
+ return pos;
719
699
  };
@@ -12,6 +12,8 @@ const NullDependency = require("./NullDependency");
12
12
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
13
13
  /** @typedef {import("../Dependency")} Dependency */
14
14
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
15
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
16
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
15
17
 
16
18
  /** @type {Record<string, { definition: string, content: string, requests: string[] }>} */
17
19
  const DEFINITIONS = {
@@ -119,6 +121,9 @@ class AMDDefineDependency extends NullDependency {
119
121
  return "amd define";
120
122
  }
121
123
 
124
+ /**
125
+ * @param {ObjectSerializerContext} context context
126
+ */
122
127
  serialize(context) {
123
128
  const { write } = context;
124
129
  write(this.range);
@@ -130,6 +135,9 @@ class AMDDefineDependency extends NullDependency {
130
135
  super.serialize(context);
131
136
  }
132
137
 
138
+ /**
139
+ * @param {ObjectDeserializerContext} context context
140
+ */
133
141
  deserialize(context) {
134
142
  const { read } = context;
135
143
  this.range = read();
@@ -12,6 +12,8 @@ const NullDependency = require("./NullDependency");
12
12
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
13
13
  /** @typedef {import("../Dependency")} Dependency */
14
14
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
15
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
16
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
15
17
 
16
18
  class AMDRequireArrayDependency extends NullDependency {
17
19
  constructor(depsArray, range) {
@@ -29,6 +31,9 @@ class AMDRequireArrayDependency extends NullDependency {
29
31
  return "amd";
30
32
  }
31
33
 
34
+ /**
35
+ * @param {ObjectSerializerContext} context context
36
+ */
32
37
  serialize(context) {
33
38
  const { write } = context;
34
39
 
@@ -38,6 +43,9 @@ class AMDRequireArrayDependency extends NullDependency {
38
43
  super.serialize(context);
39
44
  }
40
45
 
46
+ /**
47
+ * @param {ObjectDeserializerContext} context context
48
+ */
41
49
  deserialize(context) {
42
50
  const { read } = context;
43
51