webpack 5.81.0 → 5.82.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.
- package/bin/webpack.js +13 -2
- package/lib/Compilation.js +2 -0
- package/lib/CssModule.js +39 -7
- package/lib/WebpackOptionsApply.js +33 -40
- package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
- package/lib/config/defaults.js +1 -0
- package/lib/css/CssGenerator.js +4 -0
- package/lib/css/CssLoadingRuntimeModule.js +9 -2
- package/lib/css/CssModulesPlugin.js +136 -33
- package/lib/css/CssParser.js +144 -80
- package/lib/css/walkCssTokens.js +96 -20
- package/lib/debug/ProfilingPlugin.js +2 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
- package/lib/javascript/BasicEvaluatedExpression.js +108 -1
- package/lib/javascript/JavascriptParser.js +132 -11
- package/lib/json/JsonData.js +25 -0
- package/lib/json/JsonGenerator.js +15 -3
- package/lib/json/JsonModulesPlugin.js +1 -0
- package/lib/json/JsonParser.js +2 -1
- package/lib/library/ModuleLibraryPlugin.js +2 -1
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +4 -0
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +22 -3
- package/lib/schemes/DataUriPlugin.js +4 -0
- package/lib/schemes/HttpUriPlugin.js +38 -0
- package/lib/sharing/utils.js +293 -7
- package/lib/stats/DefaultStatsPrinterPlugin.js +25 -0
- package/lib/util/StackedCacheMap.js +6 -0
- package/lib/util/StringXor.js +51 -0
- package/lib/util/compileBooleanMatcher.js +31 -0
- package/lib/util/deprecation.js +8 -0
- package/lib/util/identifier.js +4 -0
- package/lib/util/numberHash.js +75 -21
- package/lib/util/propertyAccess.js +5 -0
- package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -0
- package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
- package/package.json +1 -1
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +25 -0
- package/types.d.ts +121 -26
package/lib/css/CssParser.js
CHANGED
@@ -5,7 +5,9 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const ModuleDependencyWarning = require("../ModuleDependencyWarning");
|
8
9
|
const Parser = require("../Parser");
|
10
|
+
const WebpackError = require("../WebpackError");
|
9
11
|
const ConstDependency = require("../dependencies/ConstDependency");
|
10
12
|
const CssExportDependency = require("../dependencies/CssExportDependency");
|
11
13
|
const CssImportDependency = require("../dependencies/CssImportDependency");
|
@@ -34,6 +36,11 @@ const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
|
|
34
36
|
const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
|
35
37
|
/^(-\w+-)?animation(-name)?$/i;
|
36
38
|
|
39
|
+
/**
|
40
|
+
* @param {string} str url string
|
41
|
+
* @param {boolean} isString is url wrapped in quotes
|
42
|
+
* @returns {string} normalized url
|
43
|
+
*/
|
37
44
|
const normalizeUrl = (str, isString) => {
|
38
45
|
// Remove extra spaces and newlines:
|
39
46
|
// `url("im\
|
@@ -71,6 +78,9 @@ const normalizeUrl = (str, isString) => {
|
|
71
78
|
};
|
72
79
|
|
73
80
|
class LocConverter {
|
81
|
+
/**
|
82
|
+
* @param {string} input input
|
83
|
+
*/
|
74
84
|
constructor(input) {
|
75
85
|
this._input = input;
|
76
86
|
this.line = 1;
|
@@ -78,6 +88,10 @@ class LocConverter {
|
|
78
88
|
this.pos = 0;
|
79
89
|
}
|
80
90
|
|
91
|
+
/**
|
92
|
+
* @param {number} pos position
|
93
|
+
* @returns {LocConverter} location converter
|
94
|
+
*/
|
81
95
|
get(pos) {
|
82
96
|
if (this.pos !== pos) {
|
83
97
|
if (this.pos < pos) {
|
@@ -110,26 +124,8 @@ const CSS_MODE_IN_RULE = 1;
|
|
110
124
|
const CSS_MODE_IN_LOCAL_RULE = 2;
|
111
125
|
const CSS_MODE_AT_IMPORT_EXPECT_URL = 3;
|
112
126
|
const CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA = 4;
|
113
|
-
const
|
114
|
-
|
115
|
-
const explainMode = mode => {
|
116
|
-
switch (mode) {
|
117
|
-
case CSS_MODE_TOP_LEVEL:
|
118
|
-
return "parsing top level css";
|
119
|
-
case CSS_MODE_IN_RULE:
|
120
|
-
return "parsing css rule content (global)";
|
121
|
-
case CSS_MODE_IN_LOCAL_RULE:
|
122
|
-
return "parsing css rule content (local)";
|
123
|
-
case CSS_MODE_AT_IMPORT_EXPECT_URL:
|
124
|
-
return "parsing @import (expecting url)";
|
125
|
-
case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA:
|
126
|
-
return "parsing @import (expecting optionally layer, supports or media query)";
|
127
|
-
case CSS_MODE_AT_OTHER:
|
128
|
-
return "parsing at-rule";
|
129
|
-
default:
|
130
|
-
return mode;
|
131
|
-
}
|
132
|
-
};
|
127
|
+
const CSS_MODE_AT_IMPORT_INVALID = 5;
|
128
|
+
const CSS_MODE_AT_NAMESPACE_INVALID = 6;
|
133
129
|
|
134
130
|
class CssParser extends Parser {
|
135
131
|
constructor({
|
@@ -143,6 +139,25 @@ class CssParser extends Parser {
|
|
143
139
|
this.defaultMode = defaultMode;
|
144
140
|
}
|
145
141
|
|
142
|
+
/**
|
143
|
+
* @param {ParserState} state parser state
|
144
|
+
* @param {string} message warning message
|
145
|
+
* @param {LocConverter} locConverter location converter
|
146
|
+
* @param {number} start start offset
|
147
|
+
* @param {number} end end offset
|
148
|
+
*/
|
149
|
+
_emitWarning(state, message, locConverter, start, end) {
|
150
|
+
const { line: sl, column: sc } = locConverter.get(start);
|
151
|
+
const { line: el, column: ec } = locConverter.get(end);
|
152
|
+
|
153
|
+
state.current.addWarning(
|
154
|
+
new ModuleDependencyWarning(state.module, new WebpackError(message), {
|
155
|
+
start: { line: sl, column: sc },
|
156
|
+
end: { line: el, column: ec }
|
157
|
+
})
|
158
|
+
);
|
159
|
+
}
|
160
|
+
|
146
161
|
/**
|
147
162
|
* @param {string | Buffer | PreparsedAst} source the source to parse
|
148
163
|
* @param {ParserState} state the parser state
|
@@ -163,11 +178,18 @@ class CssParser extends Parser {
|
|
163
178
|
const declaredCssVariables = new Set();
|
164
179
|
|
165
180
|
const locConverter = new LocConverter(source);
|
181
|
+
/** @type {number} */
|
166
182
|
let mode = CSS_MODE_TOP_LEVEL;
|
183
|
+
/** @type {number} */
|
167
184
|
let modeNestingLevel = 0;
|
185
|
+
/** @type {boolean} */
|
186
|
+
let allowImportAtRule = true;
|
168
187
|
let modeData = undefined;
|
188
|
+
/** @type {string | boolean | undefined} */
|
169
189
|
let singleClassSelector = undefined;
|
190
|
+
/** @type {[number, number] | undefined} */
|
170
191
|
let lastIdentifier = undefined;
|
192
|
+
/** @type {boolean} */
|
171
193
|
let awaitRightParenthesis = false;
|
172
194
|
/** @type [string, number, number][] */
|
173
195
|
let balanced = [];
|
@@ -176,18 +198,6 @@ class CssParser extends Parser {
|
|
176
198
|
const isTopLevelLocal = () =>
|
177
199
|
modeData === "local" ||
|
178
200
|
(this.defaultMode === "local" && modeData === undefined);
|
179
|
-
const eatWhiteLine = (input, pos) => {
|
180
|
-
for (;;) {
|
181
|
-
const cc = input.charCodeAt(pos);
|
182
|
-
if (cc === 32 || cc === 9) {
|
183
|
-
pos++;
|
184
|
-
continue;
|
185
|
-
}
|
186
|
-
if (cc === 10) pos++;
|
187
|
-
break;
|
188
|
-
}
|
189
|
-
return pos;
|
190
|
-
};
|
191
201
|
const eatUntil = chars => {
|
192
202
|
const charCodes = Array.from({ length: chars.length }, (_, i) =>
|
193
203
|
chars.charCodeAt(i)
|
@@ -238,10 +248,16 @@ class CssParser extends Parser {
|
|
238
248
|
const parseExports = (input, pos) => {
|
239
249
|
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
240
250
|
const cc = input.charCodeAt(pos);
|
241
|
-
if (cc !== CC_LEFT_CURLY)
|
242
|
-
|
243
|
-
|
251
|
+
if (cc !== CC_LEFT_CURLY) {
|
252
|
+
this._emitWarning(
|
253
|
+
state,
|
254
|
+
`Unexpected '${input[pos]}' at ${pos} during parsing of ':export' (expected '{')`,
|
255
|
+
locConverter,
|
256
|
+
pos,
|
257
|
+
pos
|
244
258
|
);
|
259
|
+
return pos;
|
260
|
+
}
|
245
261
|
pos++;
|
246
262
|
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
247
263
|
for (;;) {
|
@@ -253,9 +269,14 @@ class CssParser extends Parser {
|
|
253
269
|
[pos, name] = eatText(input, pos, eatExportName);
|
254
270
|
if (pos === input.length) return pos;
|
255
271
|
if (input.charCodeAt(pos) !== CC_COLON) {
|
256
|
-
|
257
|
-
|
272
|
+
this._emitWarning(
|
273
|
+
state,
|
274
|
+
`Unexpected '${input[pos]}' at ${pos} during parsing of export name in ':export' (expected ':')`,
|
275
|
+
locConverter,
|
276
|
+
start,
|
277
|
+
pos
|
258
278
|
);
|
279
|
+
return pos;
|
259
280
|
}
|
260
281
|
pos++;
|
261
282
|
if (pos === input.length) return pos;
|
@@ -271,9 +292,14 @@ class CssParser extends Parser {
|
|
271
292
|
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
272
293
|
if (pos === input.length) return pos;
|
273
294
|
} else if (cc !== CC_RIGHT_CURLY) {
|
274
|
-
|
275
|
-
|
295
|
+
this._emitWarning(
|
296
|
+
state,
|
297
|
+
`Unexpected '${input[pos]}' at ${pos} during parsing of export value in ':export' (expected ';' or '}')`,
|
298
|
+
locConverter,
|
299
|
+
start,
|
300
|
+
pos
|
276
301
|
);
|
302
|
+
return pos;
|
277
303
|
}
|
278
304
|
const dep = new CssExportDependency(name, value);
|
279
305
|
const { line: sl, column: sc } = locConverter.get(start);
|
@@ -283,7 +309,7 @@ class CssParser extends Parser {
|
|
283
309
|
}
|
284
310
|
pos++;
|
285
311
|
if (pos === input.length) return pos;
|
286
|
-
pos = eatWhiteLine(input, pos);
|
312
|
+
pos = walkCssTokens.eatWhiteLine(input, pos);
|
287
313
|
return pos;
|
288
314
|
};
|
289
315
|
const eatPropertyName = eatUntil(":{};");
|
@@ -339,14 +365,13 @@ class CssParser extends Parser {
|
|
339
365
|
mode !== CSS_MODE_IN_RULE &&
|
340
366
|
mode !== CSS_MODE_IN_LOCAL_RULE &&
|
341
367
|
mode !== CSS_MODE_AT_IMPORT_EXPECT_URL &&
|
342
|
-
mode !== CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA
|
368
|
+
mode !== CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA &&
|
369
|
+
mode !== CSS_MODE_AT_IMPORT_INVALID &&
|
370
|
+
mode !== CSS_MODE_AT_NAMESPACE_INVALID
|
343
371
|
);
|
344
372
|
},
|
345
|
-
url: (input, start, end, contentStart, contentEnd
|
346
|
-
let value = normalizeUrl(
|
347
|
-
input.slice(contentStart, contentEnd),
|
348
|
-
isString
|
349
|
-
);
|
373
|
+
url: (input, start, end, contentStart, contentEnd) => {
|
374
|
+
let value = normalizeUrl(input.slice(contentStart, contentEnd), false);
|
350
375
|
switch (mode) {
|
351
376
|
case CSS_MODE_AT_IMPORT_EXPECT_URL: {
|
352
377
|
modeData.url = value;
|
@@ -358,13 +383,14 @@ class CssParser extends Parser {
|
|
358
383
|
case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
|
359
384
|
break;
|
360
385
|
}
|
386
|
+
// Do not parse URLs in import between rules
|
387
|
+
case CSS_MODE_AT_NAMESPACE_INVALID:
|
388
|
+
case CSS_MODE_AT_IMPORT_INVALID: {
|
389
|
+
break;
|
390
|
+
}
|
361
391
|
default: {
|
362
|
-
|
363
|
-
|
364
|
-
/^#/.test(value) ||
|
365
|
-
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
|
366
|
-
value.length === 0
|
367
|
-
) {
|
392
|
+
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
|
393
|
+
if (value.length === 0) {
|
368
394
|
break;
|
369
395
|
}
|
370
396
|
|
@@ -408,12 +434,8 @@ class CssParser extends Parser {
|
|
408
434
|
) {
|
409
435
|
let value = normalizeUrl(input.slice(start + 1, end - 1), true);
|
410
436
|
|
411
|
-
|
412
|
-
|
413
|
-
/^#/.test(value) ||
|
414
|
-
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
|
415
|
-
value.length === 0
|
416
|
-
) {
|
437
|
+
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
|
438
|
+
if (value.length === 0) {
|
417
439
|
break;
|
418
440
|
}
|
419
441
|
|
@@ -436,14 +458,28 @@ class CssParser extends Parser {
|
|
436
458
|
atKeyword: (input, start, end) => {
|
437
459
|
const name = input.slice(start, end).toLowerCase();
|
438
460
|
if (name === "@namespace") {
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
461
|
+
mode = CSS_MODE_AT_NAMESPACE_INVALID;
|
462
|
+
this._emitWarning(
|
463
|
+
state,
|
464
|
+
"@namespace is not supported in bundled CSS",
|
465
|
+
locConverter,
|
466
|
+
start,
|
467
|
+
end
|
468
|
+
);
|
469
|
+
return end;
|
470
|
+
} else if (name === "@import") {
|
471
|
+
if (!allowImportAtRule) {
|
472
|
+
mode = CSS_MODE_AT_IMPORT_INVALID;
|
473
|
+
this._emitWarning(
|
474
|
+
state,
|
475
|
+
"Any @import rules must precede all other rules",
|
476
|
+
locConverter,
|
477
|
+
start,
|
478
|
+
end
|
445
479
|
);
|
480
|
+
return end;
|
446
481
|
}
|
482
|
+
|
447
483
|
mode = CSS_MODE_AT_IMPORT_EXPECT_URL;
|
448
484
|
modeData = {
|
449
485
|
atRuleStart: start,
|
@@ -453,37 +489,50 @@ class CssParser extends Parser {
|
|
453
489
|
supports: undefined,
|
454
490
|
media: undefined
|
455
491
|
};
|
456
|
-
}
|
457
|
-
|
492
|
+
} else if (
|
493
|
+
isTopLevelLocal() &&
|
494
|
+
OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name)
|
495
|
+
) {
|
458
496
|
let pos = end;
|
459
497
|
pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
460
498
|
if (pos === input.length) return pos;
|
461
499
|
const [newPos, name] = eatText(input, pos, eatKeyframes);
|
500
|
+
if (newPos === input.length) return newPos;
|
501
|
+
if (input.charCodeAt(newPos) !== CC_LEFT_CURLY) {
|
502
|
+
this._emitWarning(
|
503
|
+
state,
|
504
|
+
`Unexpected '${input[newPos]}' at ${newPos} during parsing of @keyframes (expected '{')`,
|
505
|
+
locConverter,
|
506
|
+
start,
|
507
|
+
end
|
508
|
+
);
|
509
|
+
|
510
|
+
return newPos;
|
511
|
+
}
|
462
512
|
const { line: sl, column: sc } = locConverter.get(pos);
|
463
513
|
const { line: el, column: ec } = locConverter.get(newPos);
|
464
514
|
const dep = new CssLocalIdentifierDependency(name, [pos, newPos]);
|
465
515
|
dep.setLoc(sl, sc, el, ec);
|
466
516
|
module.addDependency(dep);
|
467
517
|
pos = newPos;
|
468
|
-
if (pos === input.length) return pos;
|
469
|
-
if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
|
470
|
-
throw new Error(
|
471
|
-
`Unexpected ${input[pos]} at ${pos} during parsing of @keyframes (expected '{')`
|
472
|
-
);
|
473
|
-
}
|
474
518
|
mode = CSS_MODE_IN_LOCAL_RULE;
|
475
519
|
modeNestingLevel = 1;
|
476
520
|
return pos + 1;
|
477
|
-
}
|
478
|
-
|
521
|
+
} else if (name === "@media" || name === "@supports") {
|
522
|
+
// TODO handle nested CSS syntax
|
479
523
|
let pos = end;
|
480
524
|
const [newPos] = eatText(input, pos, eatAtRuleNested);
|
481
525
|
pos = newPos;
|
482
526
|
if (pos === input.length) return pos;
|
483
527
|
if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
|
484
|
-
|
485
|
-
|
528
|
+
this._emitWarning(
|
529
|
+
state,
|
530
|
+
`Unexpected ${input[pos]} at ${pos} during parsing of @media or @supports (expected '{')`,
|
531
|
+
locConverter,
|
532
|
+
start,
|
533
|
+
pos
|
486
534
|
);
|
535
|
+
return pos;
|
487
536
|
}
|
488
537
|
return pos + 1;
|
489
538
|
}
|
@@ -491,15 +540,29 @@ class CssParser extends Parser {
|
|
491
540
|
},
|
492
541
|
semicolon: (input, start, end) => {
|
493
542
|
switch (mode) {
|
494
|
-
case CSS_MODE_AT_IMPORT_EXPECT_URL:
|
495
|
-
|
543
|
+
case CSS_MODE_AT_IMPORT_EXPECT_URL: {
|
544
|
+
this._emitWarning(
|
545
|
+
state,
|
546
|
+
`Expected URL for @import at ${start}`,
|
547
|
+
locConverter,
|
548
|
+
start,
|
549
|
+
end
|
550
|
+
);
|
551
|
+
return end;
|
552
|
+
}
|
496
553
|
case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
|
497
554
|
if (modeData.url === undefined) {
|
498
|
-
|
499
|
-
|
555
|
+
this._emitWarning(
|
556
|
+
state,
|
557
|
+
`Expected URL for @import at ${modeData.atRuleStart}`,
|
558
|
+
locConverter,
|
559
|
+
modeData.atRuleStart,
|
560
|
+
modeData.lastPos
|
500
561
|
);
|
562
|
+
return end;
|
501
563
|
}
|
502
564
|
const semicolonPos = end;
|
565
|
+
end = walkCssTokens.eatWhiteLine(input, end + 1);
|
503
566
|
const { line: sl, column: sc } = locConverter.get(
|
504
567
|
modeData.atRuleStart
|
505
568
|
);
|
@@ -545,6 +608,7 @@ class CssParser extends Parser {
|
|
545
608
|
leftCurlyBracket: (input, start, end) => {
|
546
609
|
switch (mode) {
|
547
610
|
case CSS_MODE_TOP_LEVEL:
|
611
|
+
allowImportAtRule = false;
|
548
612
|
mode = isTopLevelLocal()
|
549
613
|
? CSS_MODE_IN_LOCAL_RULE
|
550
614
|
: CSS_MODE_IN_RULE;
|
package/lib/css/walkCssTokens.js
CHANGED
@@ -76,6 +76,10 @@ const CC_HYPHEN_MINUS = "-".charCodeAt(0);
|
|
76
76
|
const CC_LESS_THAN_SIGN = "<".charCodeAt(0);
|
77
77
|
const CC_GREATER_THAN_SIGN = ">".charCodeAt(0);
|
78
78
|
|
79
|
+
/**
|
80
|
+
* @param {number} cc char code
|
81
|
+
* @returns {boolean} true, if cc is a newline
|
82
|
+
*/
|
79
83
|
const _isNewLine = cc => {
|
80
84
|
return (
|
81
85
|
cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
|
@@ -84,6 +88,7 @@ const _isNewLine = cc => {
|
|
84
88
|
|
85
89
|
/** @type {CharHandler} */
|
86
90
|
const consumeSpace = (input, pos, callbacks) => {
|
91
|
+
/** @type {number} */
|
87
92
|
let cc;
|
88
93
|
do {
|
89
94
|
pos++;
|
@@ -92,16 +97,36 @@ const consumeSpace = (input, pos, callbacks) => {
|
|
92
97
|
return pos;
|
93
98
|
};
|
94
99
|
|
95
|
-
|
100
|
+
/**
|
101
|
+
* @param {number} cc char code
|
102
|
+
* @returns {boolean} true, if cc is a newline
|
103
|
+
*/
|
104
|
+
const _isNewline = cc => {
|
96
105
|
return (
|
97
|
-
cc === CC_LINE_FEED ||
|
98
|
-
cc === CC_CARRIAGE_RETURN ||
|
99
|
-
cc === CC_FORM_FEED ||
|
100
|
-
cc === CC_TAB ||
|
101
|
-
cc === CC_SPACE
|
106
|
+
cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
|
102
107
|
);
|
103
108
|
};
|
104
109
|
|
110
|
+
/**
|
111
|
+
* @param {number} cc char code
|
112
|
+
* @returns {boolean} true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE)
|
113
|
+
*/
|
114
|
+
const _isSpace = cc => {
|
115
|
+
return cc === CC_TAB || cc === CC_SPACE;
|
116
|
+
};
|
117
|
+
|
118
|
+
/**
|
119
|
+
* @param {number} cc char code
|
120
|
+
* @returns {boolean} true, if cc is a whitespace
|
121
|
+
*/
|
122
|
+
const _isWhiteSpace = cc => {
|
123
|
+
return _isNewline(cc) || _isSpace(cc);
|
124
|
+
};
|
125
|
+
|
126
|
+
/**
|
127
|
+
* @param {number} cc char code
|
128
|
+
* @returns {boolean} true, if cc is a start code point of an identifier
|
129
|
+
*/
|
105
130
|
const _isIdentStartCodePoint = cc => {
|
106
131
|
return (
|
107
132
|
(cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
|
@@ -145,21 +170,27 @@ const consumeComments = (input, pos, callbacks) => {
|
|
145
170
|
};
|
146
171
|
|
147
172
|
/** @type {function(number): CharHandler} */
|
148
|
-
const consumeString =
|
173
|
+
const consumeString = quote_cc => (input, pos, callbacks) => {
|
149
174
|
const start = pos;
|
150
|
-
pos = _consumeString(input, pos,
|
175
|
+
pos = _consumeString(input, pos, quote_cc);
|
151
176
|
if (callbacks.string !== undefined) {
|
152
177
|
pos = callbacks.string(input, start, pos);
|
153
178
|
}
|
154
179
|
return pos;
|
155
180
|
};
|
156
181
|
|
157
|
-
|
182
|
+
/**
|
183
|
+
* @param {string} input input
|
184
|
+
* @param {number} pos position
|
185
|
+
* @param {number} quote_cc quote char code
|
186
|
+
* @returns {number} new position
|
187
|
+
*/
|
188
|
+
const _consumeString = (input, pos, quote_cc) => {
|
158
189
|
pos++;
|
159
190
|
for (;;) {
|
160
191
|
if (pos === input.length) return pos;
|
161
192
|
const cc = input.charCodeAt(pos);
|
162
|
-
if (cc ===
|
193
|
+
if (cc === quote_cc) return pos + 1;
|
163
194
|
if (_isNewLine(cc)) {
|
164
195
|
// bad string
|
165
196
|
return pos;
|
@@ -176,6 +207,10 @@ const _consumeString = (input, pos, end) => {
|
|
176
207
|
}
|
177
208
|
};
|
178
209
|
|
210
|
+
/**
|
211
|
+
* @param {number} cc char code
|
212
|
+
* @returns {boolean} is identifier start code
|
213
|
+
*/
|
179
214
|
const _isIdentifierStartCode = cc => {
|
180
215
|
return (
|
181
216
|
cc === CC_LOW_LINE ||
|
@@ -185,16 +220,30 @@ const _isIdentifierStartCode = cc => {
|
|
185
220
|
);
|
186
221
|
};
|
187
222
|
|
223
|
+
/**
|
224
|
+
* @param {number} first first code point
|
225
|
+
* @param {number} second second code point
|
226
|
+
* @returns {boolean} true if two code points are a valid escape
|
227
|
+
*/
|
188
228
|
const _isTwoCodePointsAreValidEscape = (first, second) => {
|
189
229
|
if (first !== CC_REVERSE_SOLIDUS) return false;
|
190
230
|
if (_isNewLine(second)) return false;
|
191
231
|
return true;
|
192
232
|
};
|
193
233
|
|
234
|
+
/**
|
235
|
+
* @param {number} cc char code
|
236
|
+
* @returns {boolean} is digit
|
237
|
+
*/
|
194
238
|
const _isDigit = cc => {
|
195
239
|
return cc >= CC_0 && cc <= CC_9;
|
196
240
|
};
|
197
241
|
|
242
|
+
/**
|
243
|
+
* @param {string} input input
|
244
|
+
* @param {number} pos position
|
245
|
+
* @returns {boolean} true, if input at pos starts an identifier
|
246
|
+
*/
|
198
247
|
const _startsIdentifier = (input, pos) => {
|
199
248
|
const cc = input.charCodeAt(pos);
|
200
249
|
if (cc === CC_HYPHEN_MINUS) {
|
@@ -220,7 +269,7 @@ const consumeNumberSign = (input, pos, callbacks) => {
|
|
220
269
|
pos++;
|
221
270
|
if (pos === input.length) return pos;
|
222
271
|
if (callbacks.isSelector(input, pos) && _startsIdentifier(input, pos)) {
|
223
|
-
pos = _consumeIdentifier(input, pos);
|
272
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
224
273
|
if (callbacks.id !== undefined) {
|
225
274
|
return callbacks.id(input, start, pos);
|
226
275
|
}
|
@@ -244,7 +293,7 @@ const consumeMinus = (input, pos, callbacks) => {
|
|
244
293
|
if (cc === CC_GREATER_THAN_SIGN) {
|
245
294
|
return pos + 1;
|
246
295
|
} else {
|
247
|
-
pos = _consumeIdentifier(input, pos);
|
296
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
248
297
|
if (callbacks.identifier !== undefined) {
|
249
298
|
return callbacks.identifier(input, start, pos);
|
250
299
|
}
|
@@ -253,7 +302,7 @@ const consumeMinus = (input, pos, callbacks) => {
|
|
253
302
|
if (pos + 1 === input.length) return pos;
|
254
303
|
const cc = input.charCodeAt(pos + 1);
|
255
304
|
if (_isNewLine(cc)) return pos;
|
256
|
-
pos = _consumeIdentifier(input, pos);
|
305
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
257
306
|
if (callbacks.identifier !== undefined) {
|
258
307
|
return callbacks.identifier(input, start, pos);
|
259
308
|
}
|
@@ -272,16 +321,17 @@ const consumeDot = (input, pos, callbacks) => {
|
|
272
321
|
if (_isDigit(cc)) return consumeNumericToken(input, pos - 2, callbacks);
|
273
322
|
if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
|
274
323
|
return pos;
|
275
|
-
pos = _consumeIdentifier(input, pos);
|
324
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
276
325
|
if (callbacks.class !== undefined) return callbacks.class(input, start, pos);
|
277
326
|
return pos;
|
278
327
|
};
|
279
328
|
|
280
329
|
/** @type {CharHandler} */
|
281
330
|
const consumeNumericToken = (input, pos, callbacks) => {
|
282
|
-
pos = _consumeNumber(input, pos);
|
331
|
+
pos = _consumeNumber(input, pos, callbacks);
|
283
332
|
if (pos === input.length) return pos;
|
284
|
-
if (_startsIdentifier(input, pos))
|
333
|
+
if (_startsIdentifier(input, pos))
|
334
|
+
return _consumeIdentifier(input, pos, callbacks);
|
285
335
|
const cc = input.charCodeAt(pos);
|
286
336
|
if (cc === CC_PERCENTAGE) return pos + 1;
|
287
337
|
return pos;
|
@@ -290,7 +340,7 @@ const consumeNumericToken = (input, pos, callbacks) => {
|
|
290
340
|
/** @type {CharHandler} */
|
291
341
|
const consumeOtherIdentifier = (input, pos, callbacks) => {
|
292
342
|
const start = pos;
|
293
|
-
pos = _consumeIdentifier(input, pos);
|
343
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
294
344
|
if (
|
295
345
|
pos !== input.length &&
|
296
346
|
!callbacks.isSelector(input, pos) &&
|
@@ -311,7 +361,7 @@ const consumeOtherIdentifier = (input, pos, callbacks) => {
|
|
311
361
|
/** @type {CharHandler} */
|
312
362
|
const consumePotentialUrl = (input, pos, callbacks) => {
|
313
363
|
const start = pos;
|
314
|
-
pos = _consumeIdentifier(input, pos);
|
364
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
315
365
|
const nextPos = pos + 1;
|
316
366
|
if (
|
317
367
|
pos === start + 3 &&
|
@@ -331,6 +381,7 @@ const consumePotentialUrl = (input, pos, callbacks) => {
|
|
331
381
|
return nextPos;
|
332
382
|
} else {
|
333
383
|
const contentStart = pos;
|
384
|
+
/** @type {number} */
|
334
385
|
let contentEnd;
|
335
386
|
for (;;) {
|
336
387
|
if (cc === CC_REVERSE_SOLIDUS) {
|
@@ -380,7 +431,7 @@ const consumePotentialPseudo = (input, pos, callbacks) => {
|
|
380
431
|
pos++;
|
381
432
|
if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
|
382
433
|
return pos;
|
383
|
-
pos = _consumeIdentifier(input, pos);
|
434
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
384
435
|
let cc = input.charCodeAt(pos);
|
385
436
|
if (cc === CC_LEFT_PARENTHESIS) {
|
386
437
|
pos++;
|
@@ -449,6 +500,7 @@ const consumeComma = (input, pos, callbacks) => {
|
|
449
500
|
return pos;
|
450
501
|
};
|
451
502
|
|
503
|
+
/** @type {CharHandler} */
|
452
504
|
const _consumeIdentifier = (input, pos) => {
|
453
505
|
for (;;) {
|
454
506
|
const cc = input.charCodeAt(pos);
|
@@ -468,6 +520,7 @@ const _consumeIdentifier = (input, pos) => {
|
|
468
520
|
}
|
469
521
|
};
|
470
522
|
|
523
|
+
/** @type {CharHandler} */
|
471
524
|
const _consumeNumber = (input, pos) => {
|
472
525
|
pos++;
|
473
526
|
if (pos === input.length) return pos;
|
@@ -526,12 +579,13 @@ const consumeLessThan = (input, pos, callbacks) => {
|
|
526
579
|
return pos + 1;
|
527
580
|
};
|
528
581
|
|
582
|
+
/** @type {CharHandler} */
|
529
583
|
const consumeAt = (input, pos, callbacks) => {
|
530
584
|
const start = pos;
|
531
585
|
pos++;
|
532
586
|
if (pos === input.length) return pos;
|
533
587
|
if (_startsIdentifier(input, pos)) {
|
534
|
-
pos = _consumeIdentifier(input, pos);
|
588
|
+
pos = _consumeIdentifier(input, pos, callbacks);
|
535
589
|
if (callbacks.atKeyword !== undefined) {
|
536
590
|
pos = callbacks.atKeyword(input, start, pos);
|
537
591
|
}
|
@@ -697,3 +751,25 @@ module.exports.eatWhitespaceAndComments = (input, pos) => {
|
|
697
751
|
|
698
752
|
return pos;
|
699
753
|
};
|
754
|
+
|
755
|
+
/**
|
756
|
+
* @param {string} input input
|
757
|
+
* @param {number} pos position
|
758
|
+
* @returns {number} position after whitespace
|
759
|
+
*/
|
760
|
+
module.exports.eatWhiteLine = (input, pos) => {
|
761
|
+
for (;;) {
|
762
|
+
const cc = input.charCodeAt(pos);
|
763
|
+
if (_isSpace(cc)) {
|
764
|
+
pos++;
|
765
|
+
continue;
|
766
|
+
}
|
767
|
+
if (_isNewLine(cc)) pos++;
|
768
|
+
// For `\r\n`
|
769
|
+
if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos + 1) === CC_LINE_FEED)
|
770
|
+
pos++;
|
771
|
+
break;
|
772
|
+
}
|
773
|
+
|
774
|
+
return pos;
|
775
|
+
};
|
@@ -100,6 +100,8 @@ class Profiler {
|
|
100
100
|
return this.sendCommand("Profiler.stop").then(({ profile }) => {
|
101
101
|
const hrtime = process.hrtime();
|
102
102
|
const endTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000);
|
103
|
+
// Avoid coverage problems due indirect changes
|
104
|
+
/* istanbul ignore next */
|
103
105
|
if (profile.startTime < this._startTime || profile.endTime > endTime) {
|
104
106
|
// In some cases timestamps mismatch and we need to adjust them
|
105
107
|
// Both process.hrtime and the inspector timestamps claim to be relative
|