1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const Parser = require("../Parser");
|
9 | const ConstDependency = require("../dependencies/ConstDependency");
|
10 | const CssExportDependency = require("../dependencies/CssExportDependency");
|
11 | const CssImportDependency = require("../dependencies/CssImportDependency");
|
12 | const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
|
13 | const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency");
|
14 | const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
15 | const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
|
16 | const walkCssTokens = require("./walkCssTokens");
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | const CC_LEFT_CURLY = "{".charCodeAt(0);
|
22 | const CC_RIGHT_CURLY = "}".charCodeAt(0);
|
23 | const CC_COLON = ":".charCodeAt(0);
|
24 | const CC_SLASH = "/".charCodeAt(0);
|
25 | const CC_SEMICOLON = ";".charCodeAt(0);
|
26 |
|
27 | const cssUnescape = str => {
|
28 | return str.replace(/\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g, match => {
|
29 | if (match.length > 2) {
|
30 | return String.fromCharCode(parseInt(match.slice(1).trim(), 16));
|
31 | } else {
|
32 | return match[1];
|
33 | }
|
34 | });
|
35 | };
|
36 |
|
37 | class LocConverter {
|
38 | constructor(input) {
|
39 | this._input = input;
|
40 | this.line = 1;
|
41 | this.column = 0;
|
42 | this.pos = 0;
|
43 | }
|
44 |
|
45 | get(pos) {
|
46 | if (this.pos !== pos) {
|
47 | if (this.pos < pos) {
|
48 | const str = this._input.slice(this.pos, pos);
|
49 | let i = str.lastIndexOf("\n");
|
50 | if (i === -1) {
|
51 | this.column += str.length;
|
52 | } else {
|
53 | this.column = str.length - i - 1;
|
54 | this.line++;
|
55 | while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1)
|
56 | this.line++;
|
57 | }
|
58 | } else {
|
59 | let i = this._input.lastIndexOf("\n", this.pos);
|
60 | while (i >= pos) {
|
61 | this.line--;
|
62 | i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1;
|
63 | }
|
64 | this.column = pos - i;
|
65 | }
|
66 | this.pos = pos;
|
67 | }
|
68 | return this;
|
69 | }
|
70 | }
|
71 |
|
72 | const CSS_MODE_TOP_LEVEL = 0;
|
73 | const CSS_MODE_IN_RULE = 1;
|
74 | const CSS_MODE_IN_LOCAL_RULE = 2;
|
75 | const CSS_MODE_AT_IMPORT_EXPECT_URL = 3;
|
76 |
|
77 | const CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS = 4;
|
78 | const CSS_MODE_AT_IMPORT_EXPECT_MEDIA = 5;
|
79 | const CSS_MODE_AT_OTHER = 6;
|
80 |
|
81 | const explainMode = mode => {
|
82 | switch (mode) {
|
83 | case CSS_MODE_TOP_LEVEL:
|
84 | return "parsing top level css";
|
85 | case CSS_MODE_IN_RULE:
|
86 | return "parsing css rule content (global)";
|
87 | case CSS_MODE_IN_LOCAL_RULE:
|
88 | return "parsing css rule content (local)";
|
89 | case CSS_MODE_AT_IMPORT_EXPECT_URL:
|
90 | return "parsing @import (expecting url)";
|
91 | case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS:
|
92 | return "parsing @import (expecting optionally supports or media query)";
|
93 | case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
|
94 | return "parsing @import (expecting optionally media query)";
|
95 | case CSS_MODE_AT_OTHER:
|
96 | return "parsing at-rule";
|
97 | default:
|
98 | return mode;
|
99 | }
|
100 | };
|
101 |
|
102 | class CssParser extends Parser {
|
103 | constructor({
|
104 | allowPseudoBlocks = true,
|
105 | allowModeSwitch = true,
|
106 | defaultMode = "global"
|
107 | } = {}) {
|
108 | super();
|
109 | this.allowPseudoBlocks = allowPseudoBlocks;
|
110 | this.allowModeSwitch = allowModeSwitch;
|
111 | this.defaultMode = defaultMode;
|
112 | }
|
113 |
|
114 | |
115 |
|
116 |
|
117 |
|
118 |
|
119 | parse(source, state) {
|
120 | if (Buffer.isBuffer(source)) {
|
121 | source = source.toString("utf-8");
|
122 | } else if (typeof source === "object") {
|
123 | throw new Error("webpackAst is unexpected for the CssParser");
|
124 | }
|
125 | if (source[0] === "\ufeff") {
|
126 | source = source.slice(1);
|
127 | }
|
128 |
|
129 | const module = state.module;
|
130 |
|
131 | const declaredCssVariables = new Set();
|
132 |
|
133 | const locConverter = new LocConverter(source);
|
134 | let mode = CSS_MODE_TOP_LEVEL;
|
135 | let modePos = 0;
|
136 | let modeNestingLevel = 0;
|
137 | let modeData = undefined;
|
138 | let singleClassSelector = undefined;
|
139 | let lastIdentifier = undefined;
|
140 | const modeStack = [];
|
141 | const isTopLevelLocal = () =>
|
142 | modeData === "local" ||
|
143 | (this.defaultMode === "local" && modeData === undefined);
|
144 | const eatWhiteLine = (input, pos) => {
|
145 | for (;;) {
|
146 | const cc = input.charCodeAt(pos);
|
147 | if (cc === 32 || cc === 9) {
|
148 | pos++;
|
149 | continue;
|
150 | }
|
151 | if (cc === 10) pos++;
|
152 | break;
|
153 | }
|
154 | return pos;
|
155 | };
|
156 | const eatUntil = chars => {
|
157 | const charCodes = Array.from({ length: chars.length }, (_, i) =>
|
158 | chars.charCodeAt(i)
|
159 | );
|
160 | const arr = Array.from(
|
161 | { length: charCodes.reduce((a, b) => Math.max(a, b), 0) + 1 },
|
162 | () => false
|
163 | );
|
164 | charCodes.forEach(cc => (arr[cc] = true));
|
165 | return (input, pos) => {
|
166 | for (;;) {
|
167 | const cc = input.charCodeAt(pos);
|
168 | if (cc < arr.length && arr[cc]) {
|
169 | return pos;
|
170 | }
|
171 | pos++;
|
172 | if (pos === input.length) return pos;
|
173 | }
|
174 | };
|
175 | };
|
176 | const eatText = (input, pos, eater) => {
|
177 | let text = "";
|
178 | for (;;) {
|
179 | if (input.charCodeAt(pos) === CC_SLASH) {
|
180 | const newPos = walkCssTokens.eatComments(input, pos);
|
181 | if (pos !== newPos) {
|
182 | pos = newPos;
|
183 | if (pos === input.length) break;
|
184 | } else {
|
185 | text += "/";
|
186 | pos++;
|
187 | if (pos === input.length) break;
|
188 | }
|
189 | }
|
190 | const newPos = eater(input, pos);
|
191 | if (pos !== newPos) {
|
192 | text += input.slice(pos, newPos);
|
193 | pos = newPos;
|
194 | } else {
|
195 | break;
|
196 | }
|
197 | if (pos === input.length) break;
|
198 | }
|
199 | return [pos, text.trimRight()];
|
200 | };
|
201 | const eatExportName = eatUntil(":};/");
|
202 | const eatExportValue = eatUntil("};/");
|
203 | const parseExports = (input, pos) => {
|
204 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
205 | const cc = input.charCodeAt(pos);
|
206 | if (cc !== CC_LEFT_CURLY)
|
207 | throw new Error(
|
208 | `Unexpected ${input[pos]} at ${pos} during parsing of ':export' (expected '{')`
|
209 | );
|
210 | pos++;
|
211 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
212 | for (;;) {
|
213 | if (input.charCodeAt(pos) === CC_RIGHT_CURLY) break;
|
214 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
215 | if (pos === input.length) return pos;
|
216 | let start = pos;
|
217 | let name;
|
218 | [pos, name] = eatText(input, pos, eatExportName);
|
219 | if (pos === input.length) return pos;
|
220 | if (input.charCodeAt(pos) !== CC_COLON) {
|
221 | throw new Error(
|
222 | `Unexpected ${input[pos]} at ${pos} during parsing of export name in ':export' (expected ':')`
|
223 | );
|
224 | }
|
225 | pos++;
|
226 | if (pos === input.length) return pos;
|
227 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
228 | if (pos === input.length) return pos;
|
229 | let value;
|
230 | [pos, value] = eatText(input, pos, eatExportValue);
|
231 | if (pos === input.length) return pos;
|
232 | const cc = input.charCodeAt(pos);
|
233 | if (cc === CC_SEMICOLON) {
|
234 | pos++;
|
235 | if (pos === input.length) return pos;
|
236 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
237 | if (pos === input.length) return pos;
|
238 | } else if (cc !== CC_RIGHT_CURLY) {
|
239 | throw new Error(
|
240 | `Unexpected ${input[pos]} at ${pos} during parsing of export value in ':export' (expected ';' or '}')`
|
241 | );
|
242 | }
|
243 | const dep = new CssExportDependency(name, value);
|
244 | const { line: sl, column: sc } = locConverter.get(start);
|
245 | const { line: el, column: ec } = locConverter.get(pos);
|
246 | dep.setLoc(sl, sc, el, ec);
|
247 | module.addDependency(dep);
|
248 | }
|
249 | pos++;
|
250 | if (pos === input.length) return pos;
|
251 | pos = eatWhiteLine(input, pos);
|
252 | return pos;
|
253 | };
|
254 | const eatPropertyName = eatUntil(":{};");
|
255 | const processLocalDeclaration = (input, pos) => {
|
256 | modeData = undefined;
|
257 | const start = pos;
|
258 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
259 | const propertyNameStart = pos;
|
260 | const [propertyNameEnd, propertyName] = eatText(
|
261 | input,
|
262 | pos,
|
263 | eatPropertyName
|
264 | );
|
265 | if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return start;
|
266 | pos = propertyNameEnd + 1;
|
267 | if (propertyName.startsWith("--")) {
|
268 |
|
269 | const { line: sl, column: sc } = locConverter.get(propertyNameStart);
|
270 | const { line: el, column: ec } = locConverter.get(propertyNameEnd);
|
271 | const name = propertyName.slice(2);
|
272 | const dep = new CssLocalIdentifierDependency(
|
273 | name,
|
274 | [propertyNameStart, propertyNameEnd],
|
275 | "--"
|
276 | );
|
277 | dep.setLoc(sl, sc, el, ec);
|
278 | module.addDependency(dep);
|
279 | declaredCssVariables.add(name);
|
280 | } else if (
|
281 | propertyName === "animation-name" ||
|
282 | propertyName === "animation"
|
283 | ) {
|
284 | modeData = "animation";
|
285 | lastIdentifier = undefined;
|
286 | }
|
287 | return pos;
|
288 | };
|
289 | const processDeclarationValueDone = (input, pos) => {
|
290 | if (modeData === "animation" && lastIdentifier) {
|
291 | const { line: sl, column: sc } = locConverter.get(lastIdentifier[0]);
|
292 | const { line: el, column: ec } = locConverter.get(lastIdentifier[1]);
|
293 | const name = input.slice(lastIdentifier[0], lastIdentifier[1]);
|
294 | const dep = new CssSelfLocalIdentifierDependency(name, lastIdentifier);
|
295 | dep.setLoc(sl, sc, el, ec);
|
296 | module.addDependency(dep);
|
297 | }
|
298 | };
|
299 | const eatKeyframes = eatUntil("{};/");
|
300 | const eatNameInVar = eatUntil(",)};/");
|
301 | walkCssTokens(source, {
|
302 | isSelector: () => {
|
303 | return mode !== CSS_MODE_IN_RULE && mode !== CSS_MODE_IN_LOCAL_RULE;
|
304 | },
|
305 | url: (input, start, end, contentStart, contentEnd) => {
|
306 | const value = cssUnescape(input.slice(contentStart, contentEnd));
|
307 | switch (mode) {
|
308 | case CSS_MODE_AT_IMPORT_EXPECT_URL: {
|
309 | modeData.url = value;
|
310 | mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
|
311 | break;
|
312 | }
|
313 | case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS:
|
314 | case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
|
315 | throw new Error(
|
316 | `Unexpected ${input.slice(
|
317 | start,
|
318 | end
|
319 | )} at ${start} during ${explainMode(mode)}`
|
320 | );
|
321 | default: {
|
322 | const dep = new CssUrlDependency(value, [start, end], "url");
|
323 | const { line: sl, column: sc } = locConverter.get(start);
|
324 | const { line: el, column: ec } = locConverter.get(end);
|
325 | dep.setLoc(sl, sc, el, ec);
|
326 | module.addDependency(dep);
|
327 | module.addCodeGenerationDependency(dep);
|
328 | break;
|
329 | }
|
330 | }
|
331 | return end;
|
332 | },
|
333 | string: (input, start, end) => {
|
334 | switch (mode) {
|
335 | case CSS_MODE_AT_IMPORT_EXPECT_URL: {
|
336 | modeData.url = cssUnescape(input.slice(start + 1, end - 1));
|
337 | mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
|
338 | break;
|
339 | }
|
340 | }
|
341 | return end;
|
342 | },
|
343 | atKeyword: (input, start, end) => {
|
344 | const name = input.slice(start, end);
|
345 | if (name === "@namespace") {
|
346 | throw new Error("@namespace is not supported in bundled CSS");
|
347 | }
|
348 | if (name === "@import") {
|
349 | if (mode !== CSS_MODE_TOP_LEVEL) {
|
350 | throw new Error(
|
351 | `Unexpected @import at ${start} during ${explainMode(mode)}`
|
352 | );
|
353 | }
|
354 | mode = CSS_MODE_AT_IMPORT_EXPECT_URL;
|
355 | modePos = end;
|
356 | modeData = {
|
357 | start: start,
|
358 | url: undefined,
|
359 | supports: undefined
|
360 | };
|
361 | }
|
362 | if (name === "@keyframes") {
|
363 | let pos = end;
|
364 | pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
|
365 | if (pos === input.length) return pos;
|
366 | const [newPos, name] = eatText(input, pos, eatKeyframes);
|
367 | const { line: sl, column: sc } = locConverter.get(pos);
|
368 | const { line: el, column: ec } = locConverter.get(newPos);
|
369 | const dep = new CssLocalIdentifierDependency(name, [pos, newPos]);
|
370 | dep.setLoc(sl, sc, el, ec);
|
371 | module.addDependency(dep);
|
372 | pos = newPos;
|
373 | if (pos === input.length) return pos;
|
374 | if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
|
375 | throw new Error(
|
376 | `Unexpected ${input[pos]} at ${pos} during parsing of @keyframes (expected '{')`
|
377 | );
|
378 | }
|
379 | mode = CSS_MODE_IN_LOCAL_RULE;
|
380 | modeNestingLevel = 1;
|
381 | return pos + 1;
|
382 | }
|
383 | return end;
|
384 | },
|
385 | semicolon: (input, start, end) => {
|
386 | switch (mode) {
|
387 | case CSS_MODE_AT_IMPORT_EXPECT_URL:
|
388 | throw new Error(`Expected URL for @import at ${start}`);
|
389 | case CSS_MODE_AT_IMPORT_EXPECT_MEDIA:
|
390 | case CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS: {
|
391 | const { line: sl, column: sc } = locConverter.get(modeData.start);
|
392 | const { line: el, column: ec } = locConverter.get(end);
|
393 | end = eatWhiteLine(input, end);
|
394 | const media = input.slice(modePos, start).trim();
|
395 | const dep = new CssImportDependency(
|
396 | modeData.url,
|
397 | [modeData.start, end],
|
398 | modeData.supports,
|
399 | media
|
400 | );
|
401 | dep.setLoc(sl, sc, el, ec);
|
402 | module.addDependency(dep);
|
403 | break;
|
404 | }
|
405 | case CSS_MODE_IN_LOCAL_RULE: {
|
406 | processDeclarationValueDone(input, start);
|
407 | return processLocalDeclaration(input, end);
|
408 | }
|
409 | case CSS_MODE_IN_RULE: {
|
410 | return end;
|
411 | }
|
412 | }
|
413 | mode = CSS_MODE_TOP_LEVEL;
|
414 | modeData = undefined;
|
415 | singleClassSelector = undefined;
|
416 | return end;
|
417 | },
|
418 | leftCurlyBracket: (input, start, end) => {
|
419 | switch (mode) {
|
420 | case CSS_MODE_TOP_LEVEL:
|
421 | mode = isTopLevelLocal()
|
422 | ? CSS_MODE_IN_LOCAL_RULE
|
423 | : CSS_MODE_IN_RULE;
|
424 | modeNestingLevel = 1;
|
425 | if (mode === CSS_MODE_IN_LOCAL_RULE)
|
426 | return processLocalDeclaration(input, end);
|
427 | break;
|
428 | case CSS_MODE_IN_RULE:
|
429 | case CSS_MODE_IN_LOCAL_RULE:
|
430 | modeNestingLevel++;
|
431 | break;
|
432 | }
|
433 | return end;
|
434 | },
|
435 | rightCurlyBracket: (input, start, end) => {
|
436 | switch (mode) {
|
437 | case CSS_MODE_IN_LOCAL_RULE:
|
438 | processDeclarationValueDone(input, start);
|
439 |
|
440 | case CSS_MODE_IN_RULE:
|
441 | if (--modeNestingLevel === 0) {
|
442 | mode = CSS_MODE_TOP_LEVEL;
|
443 | modeData = undefined;
|
444 | singleClassSelector = undefined;
|
445 | }
|
446 | break;
|
447 | }
|
448 | return end;
|
449 | },
|
450 | id: (input, start, end) => {
|
451 | singleClassSelector = false;
|
452 | switch (mode) {
|
453 | case CSS_MODE_TOP_LEVEL:
|
454 | if (isTopLevelLocal()) {
|
455 | const name = input.slice(start + 1, end);
|
456 | const dep = new CssLocalIdentifierDependency(name, [
|
457 | start + 1,
|
458 | end
|
459 | ]);
|
460 | const { line: sl, column: sc } = locConverter.get(start);
|
461 | const { line: el, column: ec } = locConverter.get(end);
|
462 | dep.setLoc(sl, sc, el, ec);
|
463 | module.addDependency(dep);
|
464 | }
|
465 | break;
|
466 | }
|
467 | return end;
|
468 | },
|
469 | identifier: (input, start, end) => {
|
470 | singleClassSelector = false;
|
471 | switch (mode) {
|
472 | case CSS_MODE_IN_LOCAL_RULE:
|
473 | if (modeData === "animation") {
|
474 | lastIdentifier = [start, end];
|
475 | }
|
476 | break;
|
477 | }
|
478 | return end;
|
479 | },
|
480 | class: (input, start, end) => {
|
481 | switch (mode) {
|
482 | case CSS_MODE_TOP_LEVEL: {
|
483 | if (isTopLevelLocal()) {
|
484 | const name = input.slice(start + 1, end);
|
485 | const dep = new CssLocalIdentifierDependency(name, [
|
486 | start + 1,
|
487 | end
|
488 | ]);
|
489 | const { line: sl, column: sc } = locConverter.get(start);
|
490 | const { line: el, column: ec } = locConverter.get(end);
|
491 | dep.setLoc(sl, sc, el, ec);
|
492 | module.addDependency(dep);
|
493 | if (singleClassSelector === undefined) singleClassSelector = name;
|
494 | } else {
|
495 | singleClassSelector = false;
|
496 | }
|
497 | break;
|
498 | }
|
499 | }
|
500 | return end;
|
501 | },
|
502 | leftParenthesis: (input, start, end) => {
|
503 | switch (mode) {
|
504 | case CSS_MODE_TOP_LEVEL: {
|
505 | modeStack.push(false);
|
506 | break;
|
507 | }
|
508 | }
|
509 | return end;
|
510 | },
|
511 | rightParenthesis: (input, start, end) => {
|
512 | switch (mode) {
|
513 | case CSS_MODE_TOP_LEVEL: {
|
514 | const newModeData = modeStack.pop();
|
515 | if (newModeData !== false) {
|
516 | modeData = newModeData;
|
517 | const dep = new ConstDependency("", [start, end]);
|
518 | module.addPresentationalDependency(dep);
|
519 | }
|
520 | break;
|
521 | }
|
522 | }
|
523 | return end;
|
524 | },
|
525 | pseudoClass: (input, start, end) => {
|
526 | singleClassSelector = false;
|
527 | switch (mode) {
|
528 | case CSS_MODE_TOP_LEVEL: {
|
529 | const name = input.slice(start, end);
|
530 | if (this.allowModeSwitch && name === ":global") {
|
531 | modeData = "global";
|
532 | const dep = new ConstDependency("", [start, end]);
|
533 | module.addPresentationalDependency(dep);
|
534 | } else if (this.allowModeSwitch && name === ":local") {
|
535 | modeData = "local";
|
536 | const dep = new ConstDependency("", [start, end]);
|
537 | module.addPresentationalDependency(dep);
|
538 | } else if (this.allowPseudoBlocks && name === ":export") {
|
539 | const pos = parseExports(input, end);
|
540 | const dep = new ConstDependency("", [start, pos]);
|
541 | module.addPresentationalDependency(dep);
|
542 | return pos;
|
543 | }
|
544 | break;
|
545 | }
|
546 | }
|
547 | return end;
|
548 | },
|
549 | pseudoFunction: (input, start, end) => {
|
550 | switch (mode) {
|
551 | case CSS_MODE_TOP_LEVEL: {
|
552 | const name = input.slice(start, end - 1);
|
553 | if (this.allowModeSwitch && name === ":global") {
|
554 | modeStack.push(modeData);
|
555 | modeData = "global";
|
556 | const dep = new ConstDependency("", [start, end]);
|
557 | module.addPresentationalDependency(dep);
|
558 | } else if (this.allowModeSwitch && name === ":local") {
|
559 | modeStack.push(modeData);
|
560 | modeData = "local";
|
561 | const dep = new ConstDependency("", [start, end]);
|
562 | module.addPresentationalDependency(dep);
|
563 | } else {
|
564 | modeStack.push(false);
|
565 | }
|
566 | break;
|
567 | }
|
568 | }
|
569 | return end;
|
570 | },
|
571 | function: (input, start, end) => {
|
572 | switch (mode) {
|
573 | case CSS_MODE_IN_LOCAL_RULE: {
|
574 | const name = input.slice(start, end - 1);
|
575 | if (name === "var") {
|
576 | let pos = walkCssTokens.eatWhitespaceAndComments(input, end);
|
577 | if (pos === input.length) return pos;
|
578 | const [newPos, name] = eatText(input, pos, eatNameInVar);
|
579 | if (!name.startsWith("--")) return end;
|
580 | const { line: sl, column: sc } = locConverter.get(pos);
|
581 | const { line: el, column: ec } = locConverter.get(newPos);
|
582 | const dep = new CssSelfLocalIdentifierDependency(
|
583 | name.slice(2),
|
584 | [pos, newPos],
|
585 | "--",
|
586 | declaredCssVariables
|
587 | );
|
588 | dep.setLoc(sl, sc, el, ec);
|
589 | module.addDependency(dep);
|
590 | return newPos;
|
591 | }
|
592 | break;
|
593 | }
|
594 | }
|
595 | return end;
|
596 | },
|
597 | comma: (input, start, end) => {
|
598 | switch (mode) {
|
599 | case CSS_MODE_TOP_LEVEL:
|
600 | modeData = undefined;
|
601 | modeStack.length = 0;
|
602 | break;
|
603 | case CSS_MODE_IN_LOCAL_RULE:
|
604 | processDeclarationValueDone(input, start);
|
605 | break;
|
606 | }
|
607 | return end;
|
608 | }
|
609 | });
|
610 |
|
611 | module.buildInfo.strict = true;
|
612 | module.buildMeta.exportsType = "namespace";
|
613 | module.addDependency(new StaticExportsDependency([], true));
|
614 | return state;
|
615 | }
|
616 | }
|
617 |
|
618 | module.exports = CssParser;
|