summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/css
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-10-31 15:37:35 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-10-31 15:37:35 +0800
commitd5f14083061f2ce6a42313188443a42e30796320 (patch)
treecc6a9889e08b29595a76a33b9e7b4ef84866468b /node_modules/webpack/lib/css
parentb1a6ea021f29f182b62f9f81024a3d8ac8621b7f (diff)
added make browserlist(autoprefixer) work fixed
Diffstat (limited to 'node_modules/webpack/lib/css')
-rw-r--r--node_modules/webpack/lib/css/CssExportsGenerator.js148
-rw-r--r--node_modules/webpack/lib/css/CssGenerator.js113
-rw-r--r--node_modules/webpack/lib/css/CssLoadingRuntimeModule.js473
-rw-r--r--node_modules/webpack/lib/css/CssModulesPlugin.js641
-rw-r--r--node_modules/webpack/lib/css/CssParser.js1033
-rw-r--r--node_modules/webpack/lib/css/walkCssTokens.js790
6 files changed, 3198 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/css/CssExportsGenerator.js b/node_modules/webpack/lib/css/CssExportsGenerator.js
new file mode 100644
index 00000000..0fc400e0
--- /dev/null
+++ b/node_modules/webpack/lib/css/CssExportsGenerator.js
@@ -0,0 +1,148 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const { ReplaceSource, RawSource, ConcatSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const Generator = require("../Generator");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../util/Hash")} Hash */
+
+/**
+ * @template T
+ * @typedef {import("../InitFragment")<T>} InitFragment
+ */
+
+const TYPES = new Set(["javascript"]);
+
+class CssExportsGenerator extends Generator {
+ constructor() {
+ super();
+ }
+
+ // TODO add getConcatenationBailoutReason to allow concatenation
+ // but how to make it have a module id
+
+ /**
+ * @param {NormalModule} module module for which the code should be generated
+ * @param {GenerateContext} generateContext context for generate
+ * @returns {Source} generated code
+ */
+ generate(module, generateContext) {
+ const source = new ReplaceSource(new RawSource(""));
+ /** @type {InitFragment<TODO>[]} */
+ const initFragments = [];
+ const cssExports = new Map();
+
+ generateContext.runtimeRequirements.add(RuntimeGlobals.module);
+
+ const runtimeRequirements = new Set();
+
+ const templateContext = {
+ runtimeTemplate: generateContext.runtimeTemplate,
+ dependencyTemplates: generateContext.dependencyTemplates,
+ moduleGraph: generateContext.moduleGraph,
+ chunkGraph: generateContext.chunkGraph,
+ module,
+ runtime: generateContext.runtime,
+ runtimeRequirements: runtimeRequirements,
+ concatenationScope: generateContext.concatenationScope,
+ codeGenerationResults: generateContext.codeGenerationResults,
+ initFragments,
+ cssExports
+ };
+
+ /**
+ * @param {Dependency} dependency the dependency
+ */
+ const handleDependency = dependency => {
+ const constructor = /** @type {new (...args: any[]) => Dependency} */ (
+ dependency.constructor
+ );
+ const template = generateContext.dependencyTemplates.get(constructor);
+ if (!template) {
+ throw new Error(
+ "No template for dependency: " + dependency.constructor.name
+ );
+ }
+
+ template.apply(dependency, source, templateContext);
+ };
+ module.dependencies.forEach(handleDependency);
+
+ if (generateContext.concatenationScope) {
+ const source = new ConcatSource();
+ const usedIdentifiers = new Set();
+ for (const [k, v] of cssExports) {
+ let identifier = Template.toIdentifier(k);
+ let i = 0;
+ while (usedIdentifiers.has(identifier)) {
+ identifier = Template.toIdentifier(k + i);
+ }
+ usedIdentifiers.add(identifier);
+ generateContext.concatenationScope.registerExport(k, identifier);
+ source.add(
+ `${
+ generateContext.runtimeTemplate.supportsConst ? "const" : "var"
+ } ${identifier} = ${JSON.stringify(v)};\n`
+ );
+ }
+ return source;
+ } else {
+ const otherUsed =
+ generateContext.moduleGraph
+ .getExportsInfo(module)
+ .otherExportsInfo.getUsed(generateContext.runtime) !==
+ UsageState.Unused;
+ if (otherUsed) {
+ generateContext.runtimeRequirements.add(
+ RuntimeGlobals.makeNamespaceObject
+ );
+ }
+ return new RawSource(
+ `${otherUsed ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${
+ module.moduleArgument
+ }.exports = {\n${Array.from(
+ cssExports,
+ ([k, v]) => `\t${JSON.stringify(k)}: ${JSON.stringify(v)}`
+ ).join(",\n")}\n}${otherUsed ? ")" : ""};`
+ );
+ }
+ }
+
+ /**
+ * @param {NormalModule} module fresh module
+ * @returns {Set<string>} available types (do not mutate)
+ */
+ getTypes(module) {
+ return TYPES;
+ }
+
+ /**
+ * @param {NormalModule} module the module
+ * @param {string=} type source type
+ * @returns {number} estimate size of the module
+ */
+ getSize(module, type) {
+ return 42;
+ }
+
+ /**
+ * @param {Hash} hash hash that will be modified
+ * @param {UpdateHashContext} updateHashContext context for updating hash
+ */
+ updateHash(hash, { module }) {}
+}
+
+module.exports = CssExportsGenerator;
diff --git a/node_modules/webpack/lib/css/CssGenerator.js b/node_modules/webpack/lib/css/CssGenerator.js
new file mode 100644
index 00000000..e18c70b0
--- /dev/null
+++ b/node_modules/webpack/lib/css/CssGenerator.js
@@ -0,0 +1,113 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Sergey Melyukov @smelukov
+*/
+
+"use strict";
+
+const { ReplaceSource } = require("webpack-sources");
+const Generator = require("../Generator");
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../util/Hash")} Hash */
+
+const TYPES = new Set(["css"]);
+
+class CssGenerator extends Generator {
+ constructor() {
+ super();
+ }
+
+ /**
+ * @param {NormalModule} module module for which the code should be generated
+ * @param {GenerateContext} generateContext context for generate
+ * @returns {Source} generated code
+ */
+ generate(module, generateContext) {
+ const originalSource = /** @type {Source} */ (module.originalSource());
+ const source = new ReplaceSource(originalSource);
+ /** @type {InitFragment[]} */
+ const initFragments = [];
+ const cssExports = new Map();
+
+ generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules);
+
+ const templateContext = {
+ runtimeTemplate: generateContext.runtimeTemplate,
+ dependencyTemplates: generateContext.dependencyTemplates,
+ moduleGraph: generateContext.moduleGraph,
+ chunkGraph: generateContext.chunkGraph,
+ module,
+ runtime: generateContext.runtime,
+ runtimeRequirements: generateContext.runtimeRequirements,
+ concatenationScope: generateContext.concatenationScope,
+ codeGenerationResults: generateContext.codeGenerationResults,
+ initFragments,
+ cssExports
+ };
+
+ /**
+ * @param {Dependency} dependency dependency
+ */
+ const handleDependency = dependency => {
+ const constructor = /** @type {new (...args: any[]) => Dependency} */ (
+ dependency.constructor
+ );
+ const template = generateContext.dependencyTemplates.get(constructor);
+ if (!template) {
+ throw new Error(
+ "No template for dependency: " + dependency.constructor.name
+ );
+ }
+
+ template.apply(dependency, source, templateContext);
+ };
+ module.dependencies.forEach(handleDependency);
+ if (module.presentationalDependencies !== undefined)
+ module.presentationalDependencies.forEach(handleDependency);
+
+ if (cssExports.size > 0) {
+ const data = generateContext.getData();
+ data.set("css-exports", cssExports);
+ }
+
+ return InitFragment.addToSource(source, initFragments, generateContext);
+ }
+
+ /**
+ * @param {NormalModule} module fresh module
+ * @returns {Set<string>} available types (do not mutate)
+ */
+ getTypes(module) {
+ return TYPES;
+ }
+
+ /**
+ * @param {NormalModule} module the module
+ * @param {string=} type source type
+ * @returns {number} estimate size of the module
+ */
+ getSize(module, type) {
+ const originalSource = module.originalSource();
+
+ if (!originalSource) {
+ return 0;
+ }
+
+ return originalSource.size();
+ }
+
+ /**
+ * @param {Hash} hash hash that will be modified
+ * @param {UpdateHashContext} updateHashContext context for updating hash
+ */
+ updateHash(hash, { module }) {}
+}
+
+module.exports = CssGenerator;
diff --git a/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js b/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js
new file mode 100644
index 00000000..a0b164f3
--- /dev/null
+++ b/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js
@@ -0,0 +1,473 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { SyncWaterfallHook } = require("tapable");
+const Compilation = require("../Compilation");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const compileBooleanMatcher = require("../util/compileBooleanMatcher");
+const { chunkHasCss } = require("./CssModulesPlugin");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation").RuntimeRequirementsContext} RuntimeRequirementsContext */
+
+/**
+ * @typedef {Object} JsonpCompilationPluginHooks
+ * @property {SyncWaterfallHook<[string, Chunk]>} createStylesheet
+ */
+
+/** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
+const compilationHooksMap = new WeakMap();
+
+class CssLoadingRuntimeModule extends RuntimeModule {
+ /**
+ * @param {Compilation} compilation the compilation
+ * @returns {JsonpCompilationPluginHooks} hooks
+ */
+ static getCompilationHooks(compilation) {
+ if (!(compilation instanceof Compilation)) {
+ throw new TypeError(
+ "The 'compilation' argument must be an instance of Compilation"
+ );
+ }
+ let hooks = compilationHooksMap.get(compilation);
+ if (hooks === undefined) {
+ hooks = {
+ createStylesheet: new SyncWaterfallHook(["source", "chunk"])
+ };
+ compilationHooksMap.set(compilation, hooks);
+ }
+ return hooks;
+ }
+
+ /**
+ * @param {Set<string>} runtimeRequirements runtime requirements
+ */
+ constructor(runtimeRequirements) {
+ super("css loading", 10);
+
+ this._runtimeRequirements = runtimeRequirements;
+ }
+
+ /**
+ * @returns {string | null} runtime code
+ */
+ generate() {
+ const { compilation, chunk, _runtimeRequirements } = this;
+ const {
+ chunkGraph,
+ runtimeTemplate,
+ outputOptions: {
+ crossOriginLoading,
+ uniqueName,
+ chunkLoadTimeout: loadTimeout
+ }
+ } = /** @type {Compilation} */ (compilation);
+ const fn = RuntimeGlobals.ensureChunkHandlers;
+ const conditionMap = chunkGraph.getChunkConditionMap(
+ /** @type {Chunk} */ (chunk),
+ /**
+ * @param {Chunk} chunk the chunk
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @returns {boolean} true, if the chunk has css
+ */
+ (chunk, chunkGraph) =>
+ !!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css")
+ );
+ const hasCssMatcher = compileBooleanMatcher(conditionMap);
+
+ const withLoading =
+ _runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) &&
+ hasCssMatcher !== false;
+ /** @type {boolean} */
+ const withHmr = _runtimeRequirements.has(
+ RuntimeGlobals.hmrDownloadUpdateHandlers
+ );
+ /** @type {Set<number | string | null>} */
+ const initialChunkIdsWithCss = new Set();
+ /** @type {Set<number | string | null>} */
+ const initialChunkIdsWithoutCss = new Set();
+ for (const c of /** @type {Chunk} */ (chunk).getAllInitialChunks()) {
+ (chunkHasCss(c, chunkGraph)
+ ? initialChunkIdsWithCss
+ : initialChunkIdsWithoutCss
+ ).add(c.id);
+ }
+
+ if (!withLoading && !withHmr && initialChunkIdsWithCss.size === 0) {
+ return null;
+ }
+
+ const { createStylesheet } = CssLoadingRuntimeModule.getCompilationHooks(
+ /** @type {Compilation} */ (compilation)
+ );
+
+ const stateExpression = withHmr
+ ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_css`
+ : undefined;
+
+ const code = Template.asString([
+ "link = document.createElement('link');",
+ uniqueName
+ ? 'link.setAttribute("data-webpack", uniqueName + ":" + key);'
+ : "",
+ "link.setAttribute(loadingAttribute, 1);",
+ 'link.rel = "stylesheet";',
+ "link.href = url;",
+ crossOriginLoading
+ ? crossOriginLoading === "use-credentials"
+ ? 'link.crossOrigin = "use-credentials";'
+ : Template.asString([
+ "if (link.href.indexOf(window.location.origin + '/') !== 0) {",
+ Template.indent(
+ `link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
+ ),
+ "}"
+ ])
+ : ""
+ ]);
+
+ /** @type {(str: string) => number} */
+ const cc = str => str.charCodeAt(0);
+ const name = uniqueName
+ ? runtimeTemplate.concatenation(
+ "--webpack-",
+ { expr: "uniqueName" },
+ "-",
+ { expr: "chunkId" }
+ )
+ : runtimeTemplate.concatenation("--webpack-", { expr: "chunkId" });
+
+ return Template.asString([
+ "// object to store loaded and loading chunks",
+ "// undefined = chunk not loaded, null = chunk preloaded/prefetched",
+ "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded",
+ `var installedChunks = ${
+ stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+ }{${Array.from(
+ initialChunkIdsWithoutCss,
+ id => `${JSON.stringify(id)}:0`
+ ).join(",")}};`,
+ "",
+ uniqueName
+ ? `var uniqueName = ${JSON.stringify(
+ runtimeTemplate.outputOptions.uniqueName
+ )};`
+ : "// data-webpack is not used as build has no uniqueName",
+ `var loadCssChunkData = ${runtimeTemplate.basicFunction(
+ "target, link, chunkId",
+ [
+ `var data, token = "", token2, exports = {}, exportsWithId = [], exportsWithDashes = [], ${
+ withHmr ? "moduleIds = [], " : ""
+ }name = ${name}, i = 0, cc = 1;`,
+ "try {",
+ Template.indent([
+ "if(!link) link = loadStylesheet(chunkId);",
+ // `link.sheet.rules` for legacy browsers
+ "var cssRules = link.sheet.cssRules || link.sheet.rules;",
+ "var j = cssRules.length - 1;",
+ "while(j > -1 && !data) {",
+ Template.indent([
+ "var style = cssRules[j--].style;",
+ "if(!style) continue;",
+ `data = style.getPropertyValue(name);`
+ ]),
+ "}"
+ ]),
+ "}catch(e){}",
+ "if(!data) {",
+ Template.indent([
+ "data = getComputedStyle(document.head).getPropertyValue(name);"
+ ]),
+ "}",
+ "if(!data) return [];",
+ "for(; cc; i++) {",
+ Template.indent([
+ "cc = data.charCodeAt(i);",
+ `if(cc == ${cc("(")}) { token2 = token; token = ""; }`,
+ `else if(cc == ${cc(
+ ")"
+ )}) { exports[token2.replace(/^_/, "")] = token.replace(/^_/, ""); token = ""; }`,
+ `else if(cc == ${cc("/")} || cc == ${cc(
+ "%"
+ )}) { token = token.replace(/^_/, ""); exports[token] = token; exportsWithId.push(token); if(cc == ${cc(
+ "%"
+ )}) exportsWithDashes.push(token); token = ""; }`,
+ `else if(!cc || cc == ${cc(
+ ","
+ )}) { token = token.replace(/^_/, ""); exportsWithId.forEach(${runtimeTemplate.expressionFunction(
+ `exports[x] = ${
+ uniqueName
+ ? runtimeTemplate.concatenation(
+ { expr: "uniqueName" },
+ "-",
+ { expr: "token" },
+ "-",
+ { expr: "exports[x]" }
+ )
+ : runtimeTemplate.concatenation({ expr: "token" }, "-", {
+ expr: "exports[x]"
+ })
+ }`,
+ "x"
+ )}); exportsWithDashes.forEach(${runtimeTemplate.expressionFunction(
+ `exports[x] = "--" + exports[x]`,
+ "x"
+ )}); ${
+ RuntimeGlobals.makeNamespaceObject
+ }(exports); target[token] = (${runtimeTemplate.basicFunction(
+ "exports, module",
+ `module.exports = exports;`
+ )}).bind(null, exports); ${
+ withHmr ? "moduleIds.push(token); " : ""
+ }token = ""; exports = {}; exportsWithId.length = 0; }`,
+ `else if(cc == ${cc("\\")}) { token += data[++i] }`,
+ `else { token += data[i]; }`
+ ]),
+ "}",
+ `${
+ withHmr ? `if(target == ${RuntimeGlobals.moduleFactories}) ` : ""
+ }installedChunks[chunkId] = 0;`,
+ withHmr ? "return moduleIds;" : ""
+ ]
+ )}`,
+ 'var loadingAttribute = "data-webpack-loading";',
+ `var loadStylesheet = ${runtimeTemplate.basicFunction(
+ "chunkId, url, done" + (withHmr ? ", hmr" : ""),
+ [
+ 'var link, needAttach, key = "chunk-" + chunkId;',
+ withHmr ? "if(!hmr) {" : "",
+ 'var links = document.getElementsByTagName("link");',
+ "for(var i = 0; i < links.length; i++) {",
+ Template.indent([
+ "var l = links[i];",
+ `if(l.rel == "stylesheet" && (${
+ withHmr
+ ? 'l.href.startsWith(url) || l.getAttribute("href").startsWith(url)'
+ : 'l.href == url || l.getAttribute("href") == url'
+ }${
+ uniqueName
+ ? ' || l.getAttribute("data-webpack") == uniqueName + ":" + key'
+ : ""
+ })) { link = l; break; }`
+ ]),
+ "}",
+ "if(!done) return link;",
+ withHmr ? "}" : "",
+ "if(!link) {",
+ Template.indent([
+ "needAttach = true;",
+ createStylesheet.call(code, /** @type {Chunk} */ (this.chunk))
+ ]),
+ "}",
+ `var onLinkComplete = ${runtimeTemplate.basicFunction(
+ "prev, event",
+ Template.asString([
+ "link.onerror = link.onload = null;",
+ "link.removeAttribute(loadingAttribute);",
+ "clearTimeout(timeout);",
+ 'if(event && event.type != "load") link.parentNode.removeChild(link)',
+ "done(event);",
+ "if(prev) return prev(event);"
+ ])
+ )};`,
+ "if(link.getAttribute(loadingAttribute)) {",
+ Template.indent([
+ `var timeout = setTimeout(onLinkComplete.bind(null, undefined, { type: 'timeout', target: link }), ${loadTimeout});`,
+ "link.onerror = onLinkComplete.bind(null, link.onerror);",
+ "link.onload = onLinkComplete.bind(null, link.onload);"
+ ]),
+ "} else onLinkComplete(undefined, { type: 'load', target: link });", // We assume any existing stylesheet is render blocking
+ withHmr ? "hmr ? document.head.insertBefore(link, hmr) :" : "",
+ "needAttach && document.head.appendChild(link);",
+ "return link;"
+ ]
+ )};`,
+ initialChunkIdsWithCss.size > 2
+ ? `${JSON.stringify(
+ Array.from(initialChunkIdsWithCss)
+ )}.forEach(loadCssChunkData.bind(null, ${
+ RuntimeGlobals.moduleFactories
+ }, 0));`
+ : initialChunkIdsWithCss.size > 0
+ ? `${Array.from(
+ initialChunkIdsWithCss,
+ id =>
+ `loadCssChunkData(${
+ RuntimeGlobals.moduleFactories
+ }, 0, ${JSON.stringify(id)});`
+ ).join("")}`
+ : "// no initial css",
+ "",
+ withLoading
+ ? Template.asString([
+ `${fn}.css = ${runtimeTemplate.basicFunction("chunkId, promises", [
+ "// css chunk loading",
+ `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
+ 'if(installedChunkData !== 0) { // 0 means "already installed".',
+ Template.indent([
+ "",
+ '// a Promise means "currently loading".',
+ "if(installedChunkData) {",
+ Template.indent(["promises.push(installedChunkData[2]);"]),
+ "} else {",
+ Template.indent([
+ hasCssMatcher === true
+ ? "if(true) { // all chunks have CSS"
+ : `if(${hasCssMatcher("chunkId")}) {`,
+ Template.indent([
+ "// setup Promise in chunk cache",
+ `var promise = new Promise(${runtimeTemplate.expressionFunction(
+ `installedChunkData = installedChunks[chunkId] = [resolve, reject]`,
+ "resolve, reject"
+ )});`,
+ "promises.push(installedChunkData[2] = promise);",
+ "",
+ "// start chunk loading",
+ `var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
+ "// create error before stack unwound to get useful stacktrace later",
+ "var error = new Error();",
+ `var loadingEnded = ${runtimeTemplate.basicFunction(
+ "event",
+ [
+ `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
+ Template.indent([
+ "installedChunkData = installedChunks[chunkId];",
+ "if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
+ "if(installedChunkData) {",
+ Template.indent([
+ 'if(event.type !== "load") {',
+ Template.indent([
+ "var errorType = event && event.type;",
+ "var realSrc = event && event.target && event.target.src;",
+ "error.message = 'Loading css chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
+ "error.name = 'ChunkLoadError';",
+ "error.type = errorType;",
+ "error.request = realSrc;",
+ "installedChunkData[1](error);"
+ ]),
+ "} else {",
+ Template.indent([
+ `loadCssChunkData(${RuntimeGlobals.moduleFactories}, link, chunkId);`,
+ "installedChunkData[0]();"
+ ]),
+ "}"
+ ]),
+ "}"
+ ]),
+ "}"
+ ]
+ )};`,
+ "var link = loadStylesheet(chunkId, url, loadingEnded);"
+ ]),
+ "} else installedChunks[chunkId] = 0;"
+ ]),
+ "}"
+ ]),
+ "}"
+ ])};`
+ ])
+ : "// no chunk loading",
+ "",
+ withHmr
+ ? Template.asString([
+ "var oldTags = [];",
+ "var newTags = [];",
+ `var applyHandler = ${runtimeTemplate.basicFunction("options", [
+ `return { dispose: ${runtimeTemplate.basicFunction(
+ "",
+ []
+ )}, apply: ${runtimeTemplate.basicFunction("", [
+ "var moduleIds = [];",
+ `newTags.forEach(${runtimeTemplate.expressionFunction(
+ "info[1].sheet.disabled = false",
+ "info"
+ )});`,
+ "while(oldTags.length) {",
+ Template.indent([
+ "var oldTag = oldTags.pop();",
+ "if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);"
+ ]),
+ "}",
+ "while(newTags.length) {",
+ Template.indent([
+ `var info = newTags.pop();`,
+ `var chunkModuleIds = loadCssChunkData(${RuntimeGlobals.moduleFactories}, info[1], info[0]);`,
+ `chunkModuleIds.forEach(${runtimeTemplate.expressionFunction(
+ "moduleIds.push(id)",
+ "id"
+ )});`
+ ]),
+ "}",
+ "return moduleIds;"
+ ])} };`
+ ])}`,
+ `var cssTextKey = ${runtimeTemplate.returningFunction(
+ `Array.from(link.sheet.cssRules, ${runtimeTemplate.returningFunction(
+ "r.cssText",
+ "r"
+ )}).join()`,
+ "link"
+ )}`,
+ `${
+ RuntimeGlobals.hmrDownloadUpdateHandlers
+ }.css = ${runtimeTemplate.basicFunction(
+ "chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList",
+ [
+ "applyHandlers.push(applyHandler);",
+ `chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
+ `var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
+ `var url = ${RuntimeGlobals.publicPath} + filename;`,
+ "var oldTag = loadStylesheet(chunkId, url);",
+ "if(!oldTag) return;",
+ `promises.push(new Promise(${runtimeTemplate.basicFunction(
+ "resolve, reject",
+ [
+ `var link = loadStylesheet(chunkId, url + (url.indexOf("?") < 0 ? "?" : "&") + "hmr=" + Date.now(), ${runtimeTemplate.basicFunction(
+ "event",
+ [
+ 'if(event.type !== "load") {',
+ Template.indent([
+ "var errorType = event && event.type;",
+ "var realSrc = event && event.target && event.target.src;",
+ "error.message = 'Loading css hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
+ "error.name = 'ChunkLoadError';",
+ "error.type = errorType;",
+ "error.request = realSrc;",
+ "reject(error);"
+ ]),
+ "} else {",
+ Template.indent([
+ "try { if(cssTextKey(oldTag) == cssTextKey(link)) { if(link.parentNode) link.parentNode.removeChild(link); return resolve(); } } catch(e) {}",
+ "var factories = {};",
+ "loadCssChunkData(factories, link, chunkId);",
+ `Object.keys(factories).forEach(${runtimeTemplate.expressionFunction(
+ "updatedModulesList.push(id)",
+ "id"
+ )})`,
+ "link.sheet.disabled = true;",
+ "oldTags.push(oldTag);",
+ "newTags.push([chunkId, link]);",
+ "resolve();"
+ ]),
+ "}"
+ ]
+ )}, oldTag);`
+ ]
+ )}));`
+ ])});`
+ ]
+ )}`
+ ])
+ : "// no hmr"
+ ]);
+ }
+}
+
+module.exports = CssLoadingRuntimeModule;
diff --git a/node_modules/webpack/lib/css/CssModulesPlugin.js b/node_modules/webpack/lib/css/CssModulesPlugin.js
new file mode 100644
index 00000000..103ea670
--- /dev/null
+++ b/node_modules/webpack/lib/css/CssModulesPlugin.js
@@ -0,0 +1,641 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { ConcatSource, PrefixSource } = require("webpack-sources");
+const CssModule = require("../CssModule");
+const HotUpdateChunk = require("../HotUpdateChunk");
+const {
+ CSS_MODULE_TYPE,
+ CSS_MODULE_TYPE_GLOBAL,
+ CSS_MODULE_TYPE_MODULE,
+ CSS_MODULE_TYPE_AUTO
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const SelfModuleFactory = require("../SelfModuleFactory");
+const WebpackError = require("../WebpackError");
+const CssExportDependency = require("../dependencies/CssExportDependency");
+const CssImportDependency = require("../dependencies/CssImportDependency");
+const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
+const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency");
+const CssUrlDependency = require("../dependencies/CssUrlDependency");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const { compareModulesByIdentifier } = require("../util/comparators");
+const createSchemaValidation = require("../util/create-schema-validation");
+const createHash = require("../util/createHash");
+const memoize = require("../util/memoize");
+const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
+const CssExportsGenerator = require("./CssExportsGenerator");
+const CssGenerator = require("./CssGenerator");
+const CssParser = require("./CssParser");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").CssExperimentOptions} CssExperimentOptions */
+/** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../util/memoize")} Memoize */
+
+const getCssLoadingRuntimeModule = memoize(() =>
+ require("./CssLoadingRuntimeModule")
+);
+
+/**
+ * @param {string} name name
+ * @returns {{oneOf: [{$ref: string}], definitions: *}} schema
+ */
+const getSchema = name => {
+ const { definitions } = require("../../schemas/WebpackOptions.json");
+ return {
+ definitions,
+ oneOf: [{ $ref: `#/definitions/${name}` }]
+ };
+};
+
+const validateGeneratorOptions = createSchemaValidation(
+ require("../../schemas/plugins/css/CssGeneratorOptions.check.js"),
+ () => getSchema("CssGeneratorOptions"),
+ {
+ name: "Css Modules Plugin",
+ baseDataPath: "parser"
+ }
+);
+const validateParserOptions = createSchemaValidation(
+ require("../../schemas/plugins/css/CssParserOptions.check.js"),
+ () => getSchema("CssParserOptions"),
+ {
+ name: "Css Modules Plugin",
+ baseDataPath: "parser"
+ }
+);
+
+/**
+ * @param {string} str string
+ * @param {boolean=} omitOptionalUnderscore if true, optional underscore is not added
+ * @returns {string} escaped string
+ */
+const escapeCss = (str, omitOptionalUnderscore) => {
+ const escaped = `${str}`.replace(
+ // cspell:word uffff
+ /[^a-zA-Z0-9_\u0081-\uffff-]/g,
+ s => `\\${s}`
+ );
+ return !omitOptionalUnderscore && /^(?!--)[0-9_-]/.test(escaped)
+ ? `_${escaped}`
+ : escaped;
+};
+
+const plugin = "CssModulesPlugin";
+
+class CssModulesPlugin {
+ /**
+ * @param {CssExperimentOptions} options options
+ */
+ constructor({ exportsOnly = false }) {
+ this._exportsOnly = exportsOnly;
+ }
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.compilation.tap(
+ plugin,
+ (compilation, { normalModuleFactory }) => {
+ const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
+ compilation.dependencyFactories.set(
+ CssUrlDependency,
+ normalModuleFactory
+ );
+ compilation.dependencyTemplates.set(
+ CssUrlDependency,
+ new CssUrlDependency.Template()
+ );
+ compilation.dependencyTemplates.set(
+ CssLocalIdentifierDependency,
+ new CssLocalIdentifierDependency.Template()
+ );
+ compilation.dependencyFactories.set(
+ CssSelfLocalIdentifierDependency,
+ selfFactory
+ );
+ compilation.dependencyTemplates.set(
+ CssSelfLocalIdentifierDependency,
+ new CssSelfLocalIdentifierDependency.Template()
+ );
+ compilation.dependencyTemplates.set(
+ CssExportDependency,
+ new CssExportDependency.Template()
+ );
+ compilation.dependencyFactories.set(
+ CssImportDependency,
+ normalModuleFactory
+ );
+ compilation.dependencyTemplates.set(
+ CssImportDependency,
+ new CssImportDependency.Template()
+ );
+ compilation.dependencyTemplates.set(
+ StaticExportsDependency,
+ new StaticExportsDependency.Template()
+ );
+ for (const type of [
+ CSS_MODULE_TYPE,
+ CSS_MODULE_TYPE_GLOBAL,
+ CSS_MODULE_TYPE_MODULE,
+ CSS_MODULE_TYPE_AUTO
+ ]) {
+ normalModuleFactory.hooks.createParser
+ .for(type)
+ .tap(plugin, parserOptions => {
+ validateParserOptions(parserOptions);
+
+ switch (type) {
+ case CSS_MODULE_TYPE:
+ case CSS_MODULE_TYPE_AUTO:
+ return new CssParser();
+ case CSS_MODULE_TYPE_GLOBAL:
+ return new CssParser({
+ allowModeSwitch: false
+ });
+ case CSS_MODULE_TYPE_MODULE:
+ return new CssParser({
+ defaultMode: "local"
+ });
+ }
+ });
+ normalModuleFactory.hooks.createGenerator
+ .for(type)
+ .tap(plugin, generatorOptions => {
+ validateGeneratorOptions(generatorOptions);
+ return this._exportsOnly
+ ? new CssExportsGenerator()
+ : new CssGenerator();
+ });
+ normalModuleFactory.hooks.createModuleClass
+ .for(type)
+ .tap(plugin, (createData, resolveData) => {
+ if (resolveData.dependencies.length > 0) {
+ // When CSS is imported from CSS there is only one dependency
+ const dependency = resolveData.dependencies[0];
+
+ if (dependency instanceof CssImportDependency) {
+ const parent =
+ /** @type {CssModule} */
+ (compilation.moduleGraph.getParentModule(dependency));
+
+ if (parent instanceof CssModule) {
+ /** @type {import("../CssModule").Inheritance | undefined} */
+ let inheritance;
+
+ if (
+ (parent.cssLayer !== null &&
+ parent.cssLayer !== undefined) ||
+ parent.supports ||
+ parent.media
+ ) {
+ if (!inheritance) {
+ inheritance = [];
+ }
+
+ inheritance.push([
+ parent.cssLayer,
+ parent.supports,
+ parent.media
+ ]);
+ }
+
+ if (parent.inheritance) {
+ if (!inheritance) {
+ inheritance = [];
+ }
+
+ inheritance.push(...parent.inheritance);
+ }
+
+ return new CssModule({
+ ...createData,
+ cssLayer: dependency.layer,
+ supports: dependency.supports,
+ media: dependency.media,
+ inheritance
+ });
+ }
+
+ return new CssModule({
+ ...createData,
+ cssLayer: dependency.layer,
+ supports: dependency.supports,
+ media: dependency.media
+ });
+ }
+ }
+
+ return new CssModule(createData);
+ });
+ }
+ const orderedCssModulesPerChunk = new WeakMap();
+ compilation.hooks.afterCodeGeneration.tap("CssModulesPlugin", () => {
+ const { chunkGraph } = compilation;
+ for (const chunk of compilation.chunks) {
+ if (CssModulesPlugin.chunkHasCss(chunk, chunkGraph)) {
+ orderedCssModulesPerChunk.set(
+ chunk,
+ this.getOrderedChunkCssModules(chunk, chunkGraph, compilation)
+ );
+ }
+ }
+ });
+ compilation.hooks.contentHash.tap("CssModulesPlugin", chunk => {
+ const {
+ chunkGraph,
+ outputOptions: {
+ hashSalt,
+ hashDigest,
+ hashDigestLength,
+ hashFunction
+ }
+ } = compilation;
+ const modules = orderedCssModulesPerChunk.get(chunk);
+ if (modules === undefined) return;
+ const hash = createHash(hashFunction);
+ if (hashSalt) hash.update(hashSalt);
+ for (const module of modules) {
+ hash.update(chunkGraph.getModuleHash(module, chunk.runtime));
+ }
+ const digest = /** @type {string} */ (hash.digest(hashDigest));
+ chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength);
+ });
+ compilation.hooks.renderManifest.tap(plugin, (result, options) => {
+ const { chunkGraph } = compilation;
+ const { hash, chunk, codeGenerationResults } = options;
+
+ if (chunk instanceof HotUpdateChunk) return result;
+
+ /** @type {CssModule[] | undefined} */
+ const modules = orderedCssModulesPerChunk.get(chunk);
+ if (modules !== undefined) {
+ result.push({
+ render: () =>
+ this.renderChunk({
+ chunk,
+ chunkGraph,
+ codeGenerationResults,
+ uniqueName: compilation.outputOptions.uniqueName,
+ modules
+ }),
+ filenameTemplate: CssModulesPlugin.getChunkFilenameTemplate(
+ chunk,
+ compilation.outputOptions
+ ),
+ pathOptions: {
+ hash,
+ runtime: chunk.runtime,
+ chunk,
+ contentHashType: "css"
+ },
+ identifier: `css${chunk.id}`,
+ hash: chunk.contentHash.css
+ });
+ }
+ return result;
+ });
+ const globalChunkLoading = compilation.outputOptions.chunkLoading;
+ /**
+ * @param {Chunk} chunk the chunk
+ * @returns {boolean} true, when enabled
+ */
+ const isEnabledForChunk = chunk => {
+ const options = chunk.getEntryOptions();
+ const chunkLoading =
+ options && options.chunkLoading !== undefined
+ ? options.chunkLoading
+ : globalChunkLoading;
+ return chunkLoading === "jsonp";
+ };
+ const onceForChunkSet = new WeakSet();
+ /**
+ * @param {Chunk} chunk chunk to check
+ * @param {Set<string>} set runtime requirements
+ */
+ const handler = (chunk, set) => {
+ if (onceForChunkSet.has(chunk)) return;
+ onceForChunkSet.add(chunk);
+ if (!isEnabledForChunk(chunk)) return;
+
+ set.add(RuntimeGlobals.publicPath);
+ set.add(RuntimeGlobals.getChunkCssFilename);
+ set.add(RuntimeGlobals.hasOwnProperty);
+ set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+ set.add(RuntimeGlobals.makeNamespaceObject);
+
+ const CssLoadingRuntimeModule = getCssLoadingRuntimeModule();
+ compilation.addRuntimeModule(chunk, new CssLoadingRuntimeModule(set));
+ };
+ compilation.hooks.runtimeRequirementInTree
+ .for(RuntimeGlobals.hasCssModules)
+ .tap(plugin, handler);
+ compilation.hooks.runtimeRequirementInTree
+ .for(RuntimeGlobals.ensureChunkHandlers)
+ .tap(plugin, handler);
+ compilation.hooks.runtimeRequirementInTree
+ .for(RuntimeGlobals.hmrDownloadUpdateHandlers)
+ .tap(plugin, handler);
+ }
+ );
+ }
+
+ /**
+ * @param {Chunk} chunk chunk
+ * @param {Iterable<Module>} modules unordered modules
+ * @param {Compilation} compilation compilation
+ * @returns {Module[]} ordered modules
+ */
+ getModulesInOrder(chunk, modules, compilation) {
+ if (!modules) return [];
+
+ /** @type {Module[]} */
+ const modulesList = [...modules];
+
+ // Get ordered list of modules per chunk group
+ // Lists are in reverse order to allow to use Array.pop()
+ const modulesByChunkGroup = Array.from(chunk.groupsIterable, chunkGroup => {
+ const sortedModules = modulesList
+ .map(module => {
+ return {
+ module,
+ index: chunkGroup.getModulePostOrderIndex(module)
+ };
+ })
+ .filter(item => item.index !== undefined)
+ .sort(
+ (a, b) =>
+ /** @type {number} */ (b.index) - /** @type {number} */ (a.index)
+ )
+ .map(item => item.module);
+
+ return { list: sortedModules, set: new Set(sortedModules) };
+ });
+
+ if (modulesByChunkGroup.length === 1)
+ return modulesByChunkGroup[0].list.reverse();
+
+ const compareModuleLists = ({ list: a }, { list: b }) => {
+ if (a.length === 0) {
+ return b.length === 0 ? 0 : 1;
+ } else {
+ if (b.length === 0) return -1;
+ return compareModulesByIdentifier(a[a.length - 1], b[b.length - 1]);
+ }
+ };
+
+ modulesByChunkGroup.sort(compareModuleLists);
+
+ /** @type {Module[]} */
+ const finalModules = [];
+
+ for (;;) {
+ const failedModules = new Set();
+ const list = modulesByChunkGroup[0].list;
+ if (list.length === 0) {
+ // done, everything empty
+ break;
+ }
+ /** @type {Module} */
+ let selectedModule = list[list.length - 1];
+ let hasFailed = undefined;
+ outer: for (;;) {
+ for (const { list, set } of modulesByChunkGroup) {
+ if (list.length === 0) continue;
+ const lastModule = list[list.length - 1];
+ if (lastModule === selectedModule) continue;
+ if (!set.has(selectedModule)) continue;
+ failedModules.add(selectedModule);
+ if (failedModules.has(lastModule)) {
+ // There is a conflict, try other alternatives
+ hasFailed = lastModule;
+ continue;
+ }
+ selectedModule = lastModule;
+ hasFailed = false;
+ continue outer; // restart
+ }
+ break;
+ }
+ if (hasFailed) {
+ // There is a not resolve-able conflict with the selectedModule
+ if (compilation) {
+ // TODO print better warning
+ compilation.warnings.push(
+ new WebpackError(
+ `chunk ${chunk.name || chunk.id}\nConflicting order between ${
+ /** @type {Module} */
+ (hasFailed).readableIdentifier(compilation.requestShortener)
+ } and ${selectedModule.readableIdentifier(
+ compilation.requestShortener
+ )}`
+ )
+ );
+ }
+ selectedModule = /** @type {Module} */ (hasFailed);
+ }
+ // Insert the selected module into the final modules list
+ finalModules.push(selectedModule);
+ // Remove the selected module from all lists
+ for (const { list, set } of modulesByChunkGroup) {
+ const lastModule = list[list.length - 1];
+ if (lastModule === selectedModule) list.pop();
+ else if (hasFailed && set.has(selectedModule)) {
+ const idx = list.indexOf(selectedModule);
+ if (idx >= 0) list.splice(idx, 1);
+ }
+ }
+ modulesByChunkGroup.sort(compareModuleLists);
+ }
+ return finalModules;
+ }
+
+ /**
+ * @param {Chunk} chunk chunk
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @param {Compilation} compilation compilation
+ * @returns {Module[]} ordered css modules
+ */
+ getOrderedChunkCssModules(chunk, chunkGraph, compilation) {
+ return [
+ ...this.getModulesInOrder(
+ chunk,
+ /** @type {Iterable<Module>} */
+ (
+ chunkGraph.getOrderedChunkModulesIterableBySourceType(
+ chunk,
+ "css-import",
+ compareModulesByIdentifier
+ )
+ ),
+ compilation
+ ),
+ ...this.getModulesInOrder(
+ chunk,
+ /** @type {Iterable<Module>} */
+ (
+ chunkGraph.getOrderedChunkModulesIterableBySourceType(
+ chunk,
+ "css",
+ compareModulesByIdentifier
+ )
+ ),
+ compilation
+ )
+ ];
+ }
+
+ /**
+ * @param {Object} options options
+ * @param {string | undefined} options.uniqueName unique name
+ * @param {Chunk} options.chunk chunk
+ * @param {ChunkGraph} options.chunkGraph chunk graph
+ * @param {CodeGenerationResults} options.codeGenerationResults code generation results
+ * @param {CssModule[]} options.modules ordered css modules
+ * @returns {Source} generated source
+ */
+ renderChunk({
+ uniqueName,
+ chunk,
+ chunkGraph,
+ codeGenerationResults,
+ modules
+ }) {
+ const source = new ConcatSource();
+ /** @type {string[]} */
+ const metaData = [];
+ for (const module of modules) {
+ try {
+ const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
+
+ let moduleSource =
+ /** @type {Source} */
+ (
+ codeGenResult.sources.get("css") ||
+ codeGenResult.sources.get("css-import")
+ );
+
+ let inheritance = [[module.cssLayer, module.supports, module.media]];
+
+ if (module.inheritance) {
+ inheritance.push(...module.inheritance);
+ }
+
+ for (let i = 0; i < inheritance.length; i++) {
+ const layer = inheritance[i][0];
+ const supports = inheritance[i][1];
+ const media = inheritance[i][2];
+
+ if (media) {
+ moduleSource = new ConcatSource(
+ `@media ${media} {\n`,
+ new PrefixSource("\t", moduleSource),
+ "}\n"
+ );
+ }
+
+ if (supports) {
+ moduleSource = new ConcatSource(
+ `@supports (${supports}) {\n`,
+ new PrefixSource("\t", moduleSource),
+ "}\n"
+ );
+ }
+
+ // Layer can be anonymous
+ if (layer !== undefined && layer !== null) {
+ moduleSource = new ConcatSource(
+ `@layer${layer ? ` ${layer}` : ""} {\n`,
+ new PrefixSource("\t", moduleSource),
+ "}\n"
+ );
+ }
+ }
+
+ if (moduleSource) {
+ source.add(moduleSource);
+ source.add("\n");
+ }
+ /** @type {Map<string, string> | undefined} */
+ const exports =
+ codeGenResult.data && codeGenResult.data.get("css-exports");
+ let moduleId = chunkGraph.getModuleId(module) + "";
+
+ // When `optimization.moduleIds` is `named` the module id is a path, so we need to normalize it between platforms
+ if (typeof moduleId === "string") {
+ moduleId = moduleId.replace(/\\/g, "/");
+ }
+
+ metaData.push(
+ `${
+ exports
+ ? Array.from(exports, ([n, v]) => {
+ const shortcutValue = `${
+ uniqueName ? uniqueName + "-" : ""
+ }${moduleId}-${n}`;
+ return v === shortcutValue
+ ? `${escapeCss(n)}/`
+ : v === "--" + shortcutValue
+ ? `${escapeCss(n)}%`
+ : `${escapeCss(n)}(${escapeCss(v)})`;
+ }).join("")
+ : ""
+ }${escapeCss(moduleId)}`
+ );
+ } catch (e) {
+ /** @type {Error} */
+ (e).message += `\nduring rendering of css ${module.identifier()}`;
+ throw e;
+ }
+ }
+ source.add(
+ `head{--webpack-${escapeCss(
+ (uniqueName ? uniqueName + "-" : "") + chunk.id,
+ true
+ )}:${metaData.join(",")};}`
+ );
+ return source;
+ }
+
+ /**
+ * @param {Chunk} chunk chunk
+ * @param {OutputOptions} outputOptions output options
+ * @returns {Chunk["cssFilenameTemplate"] | OutputOptions["cssFilename"] | OutputOptions["cssChunkFilename"]} used filename template
+ */
+ static getChunkFilenameTemplate(chunk, outputOptions) {
+ if (chunk.cssFilenameTemplate) {
+ return chunk.cssFilenameTemplate;
+ } else if (chunk.canBeInitial()) {
+ return outputOptions.cssFilename;
+ } else {
+ return outputOptions.cssChunkFilename;
+ }
+ }
+
+ /**
+ * @param {Chunk} chunk chunk
+ * @param {ChunkGraph} chunkGraph chunk graph
+ * @returns {boolean} true, when the chunk has css
+ */
+ static chunkHasCss(chunk, chunkGraph) {
+ return (
+ !!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css") ||
+ !!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css-import")
+ );
+ }
+}
+
+module.exports = CssModulesPlugin;
diff --git a/node_modules/webpack/lib/css/CssParser.js b/node_modules/webpack/lib/css/CssParser.js
new file mode 100644
index 00000000..98a937d9
--- /dev/null
+++ b/node_modules/webpack/lib/css/CssParser.js
@@ -0,0 +1,1033 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependencyWarning = require("../ModuleDependencyWarning");
+const { CSS_MODULE_TYPE_AUTO } = require("../ModuleTypeConstants");
+const Parser = require("../Parser");
+const WebpackError = require("../WebpackError");
+const ConstDependency = require("../dependencies/ConstDependency");
+const CssExportDependency = require("../dependencies/CssExportDependency");
+const CssImportDependency = require("../dependencies/CssImportDependency");
+const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
+const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency");
+const CssUrlDependency = require("../dependencies/CssUrlDependency");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const { parseResource } = require("../util/identifier");
+const walkCssTokens = require("./walkCssTokens");
+
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+/** @typedef {[number, number]} Range */
+
+const CC_LEFT_CURLY = "{".charCodeAt(0);
+const CC_RIGHT_CURLY = "}".charCodeAt(0);
+const CC_COLON = ":".charCodeAt(0);
+const CC_SLASH = "/".charCodeAt(0);
+const CC_SEMICOLON = ";".charCodeAt(0);
+
+// https://www.w3.org/TR/css-syntax-3/#newline
+// We don't have `preprocessing` stage, so we need specify all of them
+const STRING_MULTILINE = /\\[\n\r\f]/g;
+// https://www.w3.org/TR/css-syntax-3/#whitespace
+const TRIM_WHITE_SPACES = /(^[ \t\n\r\f]*|[ \t\n\r\f]*$)/g;
+const UNESCAPE = /\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g;
+const IMAGE_SET_FUNCTION = /^(-\w+-)?image-set$/i;
+const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
+const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
+ /^(-\w+-)?animation(-name)?$/i;
+const IS_MODULES = /\.module(s)?\.[^.]+$/i;
+
+/**
+ * @param {string} str url string
+ * @param {boolean} isString is url wrapped in quotes
+ * @returns {string} normalized url
+ */
+const normalizeUrl = (str, isString) => {
+ // Remove extra spaces and newlines:
+ // `url("im\
+ // g.png")`
+ if (isString) {
+ str = str.replace(STRING_MULTILINE, "");
+ }
+
+ str = str
+ // Remove unnecessary spaces from `url(" img.png ")`
+ .replace(TRIM_WHITE_SPACES, "")
+ // Unescape
+ .replace(UNESCAPE, match => {
+ if (match.length > 2) {
+ return String.fromCharCode(parseInt(match.slice(1).trim(), 16));
+ } else {
+ return match[1];
+ }
+ });
+
+ if (/^data:/i.test(str)) {
+ return str;
+ }
+
+ if (str.includes("%")) {
+ // Convert `url('%2E/img.png')` -> `url('./img.png')`
+ try {
+ str = decodeURIComponent(str);
+ } catch (error) {
+ // Ignore
+ }
+ }
+
+ return str;
+};
+
+class LocConverter {
+ /**
+ * @param {string} input input
+ */
+ constructor(input) {
+ this._input = input;
+ this.line = 1;
+ this.column = 0;
+ this.pos = 0;
+ }
+
+ /**
+ * @param {number} pos position
+ * @returns {LocConverter} location converter
+ */
+ get(pos) {
+ if (this.pos !== pos) {
+ if (this.pos < pos) {
+ const str = this._input.slice(this.pos, pos);
+ let i = str.lastIndexOf("\n");
+ if (i === -1) {
+ this.column += str.length;
+ } else {
+ this.column = str.length - i - 1;
+ this.line++;
+ while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1)
+ this.line++;
+ }
+ } else {
+ let i = this._input.lastIndexOf("\n", this.pos);
+ while (i >= pos) {
+ this.line--;
+ i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1;
+ }
+ this.column = pos - i;
+ }
+ this.pos = pos;
+ }
+ return this;
+ }
+}
+
+const CSS_MODE_TOP_LEVEL = 0;
+const CSS_MODE_IN_BLOCK = 1;
+const CSS_MODE_IN_AT_IMPORT = 2;
+const CSS_MODE_AT_IMPORT_INVALID = 3;
+const CSS_MODE_AT_NAMESPACE_INVALID = 4;
+
+class CssParser extends Parser {
+ constructor({ allowModeSwitch = true, defaultMode = "global" } = {}) {
+ super();
+ this.allowModeSwitch = allowModeSwitch;
+ this.defaultMode = defaultMode;
+ }
+
+ /**
+ * @param {ParserState} state parser state
+ * @param {string} message warning message
+ * @param {LocConverter} locConverter location converter
+ * @param {number} start start offset
+ * @param {number} end end offset
+ */
+ _emitWarning(state, message, locConverter, start, end) {
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(end);
+
+ state.current.addWarning(
+ new ModuleDependencyWarning(state.module, new WebpackError(message), {
+ start: { line: sl, column: sc },
+ end: { line: el, column: ec }
+ })
+ );
+ }
+
+ /**
+ * @param {string | Buffer | PreparsedAst} source the source to parse
+ * @param {ParserState} state the parser state
+ * @returns {ParserState} the parser state
+ */
+ parse(source, state) {
+ if (Buffer.isBuffer(source)) {
+ source = source.toString("utf-8");
+ } else if (typeof source === "object") {
+ throw new Error("webpackAst is unexpected for the CssParser");
+ }
+ if (source[0] === "\ufeff") {
+ source = source.slice(1);
+ }
+
+ const module = state.module;
+
+ /** @type {string | undefined} */
+ let oldDefaultMode;
+
+ if (
+ module.type === CSS_MODULE_TYPE_AUTO &&
+ IS_MODULES.test(
+ parseResource(module.matchResource || module.resource).path
+ )
+ ) {
+ oldDefaultMode = this.defaultMode;
+
+ this.defaultMode = "local";
+ }
+
+ const locConverter = new LocConverter(source);
+ /** @type {Set<string>}*/
+ const declaredCssVariables = new Set();
+ /** @type {number} */
+ let scope = CSS_MODE_TOP_LEVEL;
+ /** @type {number} */
+ let blockNestingLevel = 0;
+ /** @type {boolean} */
+ let allowImportAtRule = true;
+ /** @type {"local" | "global" | undefined} */
+ let modeData = undefined;
+ /** @type {[number, number] | undefined} */
+ let lastIdentifier = undefined;
+ /** @type [string, number, number][] */
+ let balanced = [];
+ /** @type {undefined | { start: number, url?: string, urlStart?: number, urlEnd?: number, layer?: string, layerStart?: number, layerEnd?: number, supports?: string, supportsStart?: number, supportsEnd?: number, inSupports?:boolean, media?: string }} */
+ let importData = undefined;
+ /** @type {boolean} */
+ let inAnimationProperty = false;
+ /** @type {boolean} */
+ let isNextRulePrelude = true;
+
+ /**
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {boolean} true, when next is nested syntax
+ */
+ const isNextNestedSyntax = (input, pos) => {
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+
+ if (input[pos] === "}") {
+ return false;
+ }
+
+ // According spec only identifier can be used as a property name
+ const isIdentifier = walkCssTokens.isIdentStartCodePoint(
+ input.charCodeAt(pos)
+ );
+
+ return !isIdentifier;
+ };
+ /**
+ * @returns {boolean} true, when in local scope
+ */
+ const isLocalMode = () =>
+ modeData === "local" ||
+ (this.defaultMode === "local" && modeData === undefined);
+ /**
+ * @param {string} chars characters
+ * @returns {(input: string, pos: number) => number} function to eat characters
+ */
+ const eatUntil = chars => {
+ const charCodes = Array.from({ length: chars.length }, (_, i) =>
+ chars.charCodeAt(i)
+ );
+ const arr = Array.from(
+ { length: charCodes.reduce((a, b) => Math.max(a, b), 0) + 1 },
+ () => false
+ );
+ charCodes.forEach(cc => (arr[cc] = true));
+ return (input, pos) => {
+ for (;;) {
+ const cc = input.charCodeAt(pos);
+ if (cc < arr.length && arr[cc]) {
+ return pos;
+ }
+ pos++;
+ if (pos === input.length) return pos;
+ }
+ };
+ };
+ /**
+ * @param {string} input input
+ * @param {number} pos start position
+ * @param {(input: string, pos: number) => number} eater eater
+ * @returns {[number,string]} new position and text
+ */
+ const eatText = (input, pos, eater) => {
+ let text = "";
+ for (;;) {
+ if (input.charCodeAt(pos) === CC_SLASH) {
+ const newPos = walkCssTokens.eatComments(input, pos);
+ if (pos !== newPos) {
+ pos = newPos;
+ if (pos === input.length) break;
+ } else {
+ text += "/";
+ pos++;
+ if (pos === input.length) break;
+ }
+ }
+ const newPos = eater(input, pos);
+ if (pos !== newPos) {
+ text += input.slice(pos, newPos);
+ pos = newPos;
+ } else {
+ break;
+ }
+ if (pos === input.length) break;
+ }
+ return [pos, text.trimEnd()];
+ };
+ const eatExportName = eatUntil(":};/");
+ const eatExportValue = eatUntil("};/");
+ /**
+ * @param {string} input input
+ * @param {number} pos start position
+ * @returns {number} position after parse
+ */
+ const parseExports = (input, pos) => {
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ const cc = input.charCodeAt(pos);
+ if (cc !== CC_LEFT_CURLY) {
+ this._emitWarning(
+ state,
+ `Unexpected '${input[pos]}' at ${pos} during parsing of ':export' (expected '{')`,
+ locConverter,
+ pos,
+ pos
+ );
+ return pos;
+ }
+ pos++;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ for (;;) {
+ if (input.charCodeAt(pos) === CC_RIGHT_CURLY) break;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ if (pos === input.length) return pos;
+ let start = pos;
+ let name;
+ [pos, name] = eatText(input, pos, eatExportName);
+ if (pos === input.length) return pos;
+ if (input.charCodeAt(pos) !== CC_COLON) {
+ this._emitWarning(
+ state,
+ `Unexpected '${input[pos]}' at ${pos} during parsing of export name in ':export' (expected ':')`,
+ locConverter,
+ start,
+ pos
+ );
+ return pos;
+ }
+ pos++;
+ if (pos === input.length) return pos;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ if (pos === input.length) return pos;
+ let value;
+ [pos, value] = eatText(input, pos, eatExportValue);
+ if (pos === input.length) return pos;
+ const cc = input.charCodeAt(pos);
+ if (cc === CC_SEMICOLON) {
+ pos++;
+ if (pos === input.length) return pos;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ if (pos === input.length) return pos;
+ } else if (cc !== CC_RIGHT_CURLY) {
+ this._emitWarning(
+ state,
+ `Unexpected '${input[pos]}' at ${pos} during parsing of export value in ':export' (expected ';' or '}')`,
+ locConverter,
+ start,
+ pos
+ );
+ return pos;
+ }
+ const dep = new CssExportDependency(name, value);
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(pos);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ }
+ pos++;
+ if (pos === input.length) return pos;
+ pos = walkCssTokens.eatWhiteLine(input, pos);
+ return pos;
+ };
+ const eatPropertyName = eatUntil(":{};");
+ /**
+ * @param {string} input input
+ * @param {number} pos name start position
+ * @param {number} end name end position
+ * @returns {number} position after handling
+ */
+ const processLocalDeclaration = (input, pos, end) => {
+ modeData = undefined;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ const propertyNameStart = pos;
+ const [propertyNameEnd, propertyName] = eatText(
+ input,
+ pos,
+ eatPropertyName
+ );
+ if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return end;
+ pos = propertyNameEnd + 1;
+ if (propertyName.startsWith("--")) {
+ // CSS Variable
+ const { line: sl, column: sc } = locConverter.get(propertyNameStart);
+ const { line: el, column: ec } = locConverter.get(propertyNameEnd);
+ const name = propertyName.slice(2);
+ const dep = new CssLocalIdentifierDependency(
+ name,
+ [propertyNameStart, propertyNameEnd],
+ "--"
+ );
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ declaredCssVariables.add(name);
+ } else if (
+ !propertyName.startsWith("--") &&
+ OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY.test(propertyName)
+ ) {
+ inAnimationProperty = true;
+ }
+ return pos;
+ };
+ /**
+ * @param {string} input input
+ */
+ const processDeclarationValueDone = input => {
+ if (inAnimationProperty && lastIdentifier) {
+ const { line: sl, column: sc } = locConverter.get(lastIdentifier[0]);
+ const { line: el, column: ec } = locConverter.get(lastIdentifier[1]);
+ const name = input.slice(lastIdentifier[0], lastIdentifier[1]);
+ const dep = new CssSelfLocalIdentifierDependency(name, lastIdentifier);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ lastIdentifier = undefined;
+ }
+ };
+ const eatKeyframes = eatUntil("{};/");
+ const eatNameInVar = eatUntil(",)};/");
+ walkCssTokens(source, {
+ isSelector: () => {
+ return isNextRulePrelude;
+ },
+ url: (input, start, end, contentStart, contentEnd) => {
+ let value = normalizeUrl(input.slice(contentStart, contentEnd), false);
+
+ switch (scope) {
+ case CSS_MODE_IN_AT_IMPORT: {
+ // Do not parse URLs in `supports(...)`
+ if (importData.inSupports) {
+ break;
+ }
+
+ if (importData.url) {
+ this._emitWarning(
+ state,
+ `Duplicate of 'url(...)' in '${input.slice(
+ importData.start,
+ end
+ )}'`,
+ locConverter,
+ start,
+ end
+ );
+
+ break;
+ }
+
+ importData.url = value;
+ importData.urlStart = start;
+ importData.urlEnd = end;
+ break;
+ }
+ // Do not parse URLs in import between rules
+ case CSS_MODE_AT_NAMESPACE_INVALID:
+ case CSS_MODE_AT_IMPORT_INVALID: {
+ break;
+ }
+ case CSS_MODE_IN_BLOCK: {
+ // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
+ if (value.length === 0) {
+ break;
+ }
+
+ const dep = new CssUrlDependency(value, [start, end], "url");
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(end);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ module.addCodeGenerationDependency(dep);
+ break;
+ }
+ }
+ return end;
+ },
+ string: (input, start, end) => {
+ switch (scope) {
+ case CSS_MODE_IN_AT_IMPORT: {
+ const insideURLFunction =
+ balanced[balanced.length - 1] &&
+ balanced[balanced.length - 1][0] === "url";
+
+ // Do not parse URLs in `supports(...)` and other strings if we already have a URL
+ if (
+ importData.inSupports ||
+ (!insideURLFunction && importData.url)
+ ) {
+ break;
+ }
+
+ if (insideURLFunction && importData.url) {
+ this._emitWarning(
+ state,
+ `Duplicate of 'url(...)' in '${input.slice(
+ importData.start,
+ end
+ )}'`,
+ locConverter,
+ start,
+ end
+ );
+
+ break;
+ }
+
+ importData.url = normalizeUrl(
+ input.slice(start + 1, end - 1),
+ true
+ );
+
+ if (!insideURLFunction) {
+ importData.urlStart = start;
+ importData.urlEnd = end;
+ }
+
+ break;
+ }
+ case CSS_MODE_IN_BLOCK: {
+ // TODO move escaped parsing to tokenizer
+ const last = balanced[balanced.length - 1];
+
+ if (
+ last &&
+ (last[0].replace(/\\/g, "").toLowerCase() === "url" ||
+ IMAGE_SET_FUNCTION.test(last[0].replace(/\\/g, "")))
+ ) {
+ let value = normalizeUrl(input.slice(start + 1, end - 1), true);
+
+ // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
+ if (value.length === 0) {
+ break;
+ }
+
+ const isUrl = last[0].replace(/\\/g, "").toLowerCase() === "url";
+ const dep = new CssUrlDependency(
+ value,
+ [start, end],
+ isUrl ? "string" : "url"
+ );
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(end);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ module.addCodeGenerationDependency(dep);
+ }
+ }
+ }
+ return end;
+ },
+ atKeyword: (input, start, end) => {
+ const name = input.slice(start, end).toLowerCase();
+ if (name === "@namespace") {
+ scope = CSS_MODE_AT_NAMESPACE_INVALID;
+ this._emitWarning(
+ state,
+ "'@namespace' is not supported in bundled CSS",
+ locConverter,
+ start,
+ end
+ );
+ return end;
+ } else if (name === "@import") {
+ if (!allowImportAtRule) {
+ scope = CSS_MODE_AT_IMPORT_INVALID;
+ this._emitWarning(
+ state,
+ "Any '@import' rules must precede all other rules",
+ locConverter,
+ start,
+ end
+ );
+ return end;
+ }
+
+ scope = CSS_MODE_IN_AT_IMPORT;
+ importData = { start };
+ } else if (
+ this.allowModeSwitch &&
+ OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name)
+ ) {
+ let pos = end;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ if (pos === input.length) return pos;
+ const [newPos, name] = eatText(input, pos, eatKeyframes);
+ if (newPos === input.length) return newPos;
+ if (input.charCodeAt(newPos) !== CC_LEFT_CURLY) {
+ this._emitWarning(
+ state,
+ `Unexpected '${input[newPos]}' at ${newPos} during parsing of @keyframes (expected '{')`,
+ locConverter,
+ start,
+ end
+ );
+
+ return newPos;
+ }
+ const { line: sl, column: sc } = locConverter.get(pos);
+ const { line: el, column: ec } = locConverter.get(newPos);
+ const dep = new CssLocalIdentifierDependency(name, [pos, newPos]);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ pos = newPos;
+ return pos + 1;
+ } else if (this.allowModeSwitch && name === "@property") {
+ let pos = end;
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
+ if (pos === input.length) return pos;
+ const propertyNameStart = pos;
+ const [propertyNameEnd, propertyName] = eatText(
+ input,
+ pos,
+ eatKeyframes
+ );
+ if (propertyNameEnd === input.length) return propertyNameEnd;
+ if (!propertyName.startsWith("--")) return propertyNameEnd;
+ if (input.charCodeAt(propertyNameEnd) !== CC_LEFT_CURLY) {
+ this._emitWarning(
+ state,
+ `Unexpected '${input[propertyNameEnd]}' at ${propertyNameEnd} during parsing of @property (expected '{')`,
+ locConverter,
+ start,
+ end
+ );
+
+ return propertyNameEnd;
+ }
+ const { line: sl, column: sc } = locConverter.get(pos);
+ const { line: el, column: ec } = locConverter.get(propertyNameEnd);
+ const name = propertyName.slice(2);
+ const dep = new CssLocalIdentifierDependency(
+ name,
+ [propertyNameStart, propertyNameEnd],
+ "--"
+ );
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ declaredCssVariables.add(name);
+ pos = propertyNameEnd;
+ return pos + 1;
+ } else if (
+ name === "@media" ||
+ name === "@supports" ||
+ name === "@layer" ||
+ name === "@container"
+ ) {
+ modeData = isLocalMode() ? "local" : "global";
+ isNextRulePrelude = true;
+ return end;
+ } else if (this.allowModeSwitch) {
+ modeData = "global";
+ isNextRulePrelude = false;
+ }
+ return end;
+ },
+ semicolon: (input, start, end) => {
+ switch (scope) {
+ case CSS_MODE_IN_AT_IMPORT: {
+ const { start } = importData;
+
+ if (importData.url === undefined) {
+ this._emitWarning(
+ state,
+ `Expected URL in '${input.slice(start, end)}'`,
+ locConverter,
+ start,
+ end
+ );
+ importData = undefined;
+ scope = CSS_MODE_TOP_LEVEL;
+ return end;
+ }
+ if (
+ importData.urlStart > importData.layerStart ||
+ importData.urlStart > importData.supportsStart
+ ) {
+ this._emitWarning(
+ state,
+ `An URL in '${input.slice(
+ start,
+ end
+ )}' should be before 'layer(...)' or 'supports(...)'`,
+ locConverter,
+ start,
+ end
+ );
+ importData = undefined;
+ scope = CSS_MODE_TOP_LEVEL;
+ return end;
+ }
+ if (importData.layerStart > importData.supportsStart) {
+ this._emitWarning(
+ state,
+ `The 'layer(...)' in '${input.slice(
+ start,
+ end
+ )}' should be before 'supports(...)'`,
+ locConverter,
+ start,
+ end
+ );
+ importData = undefined;
+ scope = CSS_MODE_TOP_LEVEL;
+ return end;
+ }
+
+ const semicolonPos = end;
+ end = walkCssTokens.eatWhiteLine(input, end + 1);
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(end);
+ const lastEnd =
+ importData.supportsEnd ||
+ importData.layerEnd ||
+ importData.urlEnd ||
+ start;
+ const pos = walkCssTokens.eatWhitespaceAndComments(input, lastEnd);
+ // Prevent to consider comments as a part of media query
+ if (pos !== semicolonPos - 1) {
+ importData.media = input.slice(lastEnd, semicolonPos - 1).trim();
+ }
+
+ const url = importData.url.trim();
+
+ if (url.length === 0) {
+ const dep = new ConstDependency("", [start, end]);
+ module.addPresentationalDependency(dep);
+ dep.setLoc(sl, sc, el, ec);
+ } else {
+ const dep = new CssImportDependency(
+ url,
+ [start, end],
+ importData.layer,
+ importData.supports,
+ importData.media && importData.media.length > 0
+ ? importData.media
+ : undefined
+ );
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ }
+
+ importData = undefined;
+ scope = CSS_MODE_TOP_LEVEL;
+
+ break;
+ }
+ case CSS_MODE_AT_IMPORT_INVALID:
+ case CSS_MODE_AT_NAMESPACE_INVALID: {
+ scope = CSS_MODE_TOP_LEVEL;
+
+ break;
+ }
+ case CSS_MODE_IN_BLOCK: {
+ if (this.allowModeSwitch) {
+ processDeclarationValueDone(input);
+ inAnimationProperty = false;
+ isNextRulePrelude = isNextNestedSyntax(input, end);
+ }
+ break;
+ }
+ }
+ return end;
+ },
+ leftCurlyBracket: (input, start, end) => {
+ switch (scope) {
+ case CSS_MODE_TOP_LEVEL: {
+ allowImportAtRule = false;
+ scope = CSS_MODE_IN_BLOCK;
+ blockNestingLevel = 1;
+
+ if (this.allowModeSwitch) {
+ isNextRulePrelude = isNextNestedSyntax(input, end);
+ }
+
+ break;
+ }
+ case CSS_MODE_IN_BLOCK: {
+ blockNestingLevel++;
+
+ if (this.allowModeSwitch) {
+ isNextRulePrelude = isNextNestedSyntax(input, end);
+ }
+ break;
+ }
+ }
+ return end;
+ },
+ rightCurlyBracket: (input, start, end) => {
+ switch (scope) {
+ case CSS_MODE_IN_BLOCK: {
+ if (isLocalMode()) {
+ processDeclarationValueDone(input);
+ inAnimationProperty = false;
+ }
+ if (--blockNestingLevel === 0) {
+ scope = CSS_MODE_TOP_LEVEL;
+
+ if (this.allowModeSwitch) {
+ isNextRulePrelude = true;
+ modeData = undefined;
+ }
+ } else if (this.allowModeSwitch) {
+ isNextRulePrelude = isNextNestedSyntax(input, end);
+ }
+ break;
+ }
+ }
+ return end;
+ },
+ identifier: (input, start, end) => {
+ switch (scope) {
+ case CSS_MODE_IN_BLOCK: {
+ if (isLocalMode()) {
+ // Handle only top level values and not inside functions
+ if (inAnimationProperty && balanced.length === 0) {
+ lastIdentifier = [start, end];
+ } else {
+ return processLocalDeclaration(input, start, end);
+ }
+ }
+ break;
+ }
+ case CSS_MODE_IN_AT_IMPORT: {
+ if (input.slice(start, end).toLowerCase() === "layer") {
+ importData.layer = "";
+ importData.layerStart = start;
+ importData.layerEnd = end;
+ }
+ break;
+ }
+ }
+ return end;
+ },
+ class: (input, start, end) => {
+ if (isLocalMode()) {
+ const name = input.slice(start + 1, end);
+ const dep = new CssLocalIdentifierDependency(name, [start + 1, end]);
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(end);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ }
+
+ return end;
+ },
+ id: (input, start, end) => {
+ if (isLocalMode()) {
+ const name = input.slice(start + 1, end);
+ const dep = new CssLocalIdentifierDependency(name, [start + 1, end]);
+ const { line: sl, column: sc } = locConverter.get(start);
+ const { line: el, column: ec } = locConverter.get(end);
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ }
+ return end;
+ },
+ function: (input, start, end) => {
+ let name = input.slice(start, end - 1);
+
+ balanced.push([name, start, end]);
+
+ if (
+ scope === CSS_MODE_IN_AT_IMPORT &&
+ name.toLowerCase() === "supports"
+ ) {
+ importData.inSupports = true;
+ }
+
+ if (isLocalMode()) {
+ name = name.toLowerCase();
+
+ // Don't rename animation name when we have `var()` function
+ if (inAnimationProperty && balanced.length === 1) {
+ lastIdentifier = undefined;
+ }
+
+ if (name === "var") {
+ let pos = walkCssTokens.eatWhitespaceAndComments(input, end);
+ if (pos === input.length) return pos;
+ const [newPos, name] = eatText(input, pos, eatNameInVar);
+ if (!name.startsWith("--")) return end;
+ const { line: sl, column: sc } = locConverter.get(pos);
+ const { line: el, column: ec } = locConverter.get(newPos);
+ const dep = new CssSelfLocalIdentifierDependency(
+ name.slice(2),
+ [pos, newPos],
+ "--",
+ declaredCssVariables
+ );
+ dep.setLoc(sl, sc, el, ec);
+ module.addDependency(dep);
+ return newPos;
+ }
+ }
+
+ return end;
+ },
+ leftParenthesis: (input, start, end) => {
+ balanced.push(["(", start, end]);
+
+ return end;
+ },
+ rightParenthesis: (input, start, end) => {
+ const last = balanced[balanced.length - 1];
+ const popped = balanced.pop();
+
+ if (
+ this.allowModeSwitch &&
+ popped &&
+ (popped[0] === ":local" || popped[0] === ":global")
+ ) {
+ modeData = balanced[balanced.length - 1]
+ ? /** @type {"local" | "global"} */
+ (balanced[balanced.length - 1][0])
+ : undefined;
+ const dep = new ConstDependency("", [start, end]);
+ module.addPresentationalDependency(dep);
+
+ return end;
+ }
+
+ switch (scope) {
+ case CSS_MODE_IN_AT_IMPORT: {
+ if (last && last[0] === "url" && !importData.inSupports) {
+ importData.urlStart = last[1];
+ importData.urlEnd = end;
+ } else if (
+ last &&
+ last[0].toLowerCase() === "layer" &&
+ !importData.inSupports
+ ) {
+ importData.layer = input.slice(last[2], end - 1).trim();
+ importData.layerStart = last[1];
+ importData.layerEnd = end;
+ } else if (last && last[0].toLowerCase() === "supports") {
+ importData.supports = input.slice(last[2], end - 1).trim();
+ importData.supportsStart = last[1];
+ importData.supportsEnd = end;
+ importData.inSupports = false;
+ }
+ break;
+ }
+ }
+
+ return end;
+ },
+ pseudoClass: (input, start, end) => {
+ if (this.allowModeSwitch) {
+ const name = input.slice(start, end).toLowerCase();
+
+ if (name === ":global") {
+ modeData = "global";
+ // Eat extra whitespace and comments
+ end = walkCssTokens.eatWhitespace(input, end);
+ const dep = new ConstDependency("", [start, end]);
+ module.addPresentationalDependency(dep);
+ return end;
+ } else if (name === ":local") {
+ modeData = "local";
+ // Eat extra whitespace and comments
+ end = walkCssTokens.eatWhitespace(input, end);
+ const dep = new ConstDependency("", [start, end]);
+ module.addPresentationalDependency(dep);
+ return end;
+ }
+
+ switch (scope) {
+ case CSS_MODE_TOP_LEVEL: {
+ if (name === ":export") {
+ const pos = parseExports(input, end);
+ const dep = new ConstDependency("", [start, pos]);
+ module.addPresentationalDependency(dep);
+ return pos;
+ }
+ break;
+ }
+ }
+ }
+
+ return end;
+ },
+ pseudoFunction: (input, start, end) => {
+ let name = input.slice(start, end - 1);
+
+ balanced.push([name, start, end]);
+
+ if (this.allowModeSwitch) {
+ name = name.toLowerCase();
+
+ if (name === ":global") {
+ modeData = "global";
+ const dep = new ConstDependency("", [start, end]);
+ module.addPresentationalDependency(dep);
+ } else if (name === ":local") {
+ modeData = "local";
+ const dep = new ConstDependency("", [start, end]);
+ module.addPresentationalDependency(dep);
+ }
+ }
+
+ return end;
+ },
+ comma: (input, start, end) => {
+ if (this.allowModeSwitch) {
+ // Reset stack for `:global .class :local .class-other` selector after
+ modeData = undefined;
+
+ switch (scope) {
+ case CSS_MODE_IN_BLOCK: {
+ if (isLocalMode()) {
+ processDeclarationValueDone(input);
+ }
+
+ break;
+ }
+ }
+ }
+ return end;
+ }
+ });
+
+ if (oldDefaultMode) {
+ this.defaultMode = oldDefaultMode;
+ }
+
+ module.buildInfo.strict = true;
+ module.buildMeta.exportsType = "namespace";
+ module.addDependency(new StaticExportsDependency([], true));
+ return state;
+ }
+}
+
+module.exports = CssParser;
diff --git a/node_modules/webpack/lib/css/walkCssTokens.js b/node_modules/webpack/lib/css/walkCssTokens.js
new file mode 100644
index 00000000..badc61aa
--- /dev/null
+++ b/node_modules/webpack/lib/css/walkCssTokens.js
@@ -0,0 +1,790 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/**
+ * @typedef {Object} CssTokenCallbacks
+ * @property {function(string, number): boolean=} isSelector
+ * @property {function(string, number, number, number, number): number=} url
+ * @property {function(string, number, number): number=} string
+ * @property {function(string, number, number): number=} leftParenthesis
+ * @property {function(string, number, number): number=} rightParenthesis
+ * @property {function(string, number, number): number=} pseudoFunction
+ * @property {function(string, number, number): number=} function
+ * @property {function(string, number, number): number=} pseudoClass
+ * @property {function(string, number, number): number=} atKeyword
+ * @property {function(string, number, number): number=} class
+ * @property {function(string, number, number): number=} identifier
+ * @property {function(string, number, number): number=} id
+ * @property {function(string, number, number): number=} leftCurlyBracket
+ * @property {function(string, number, number): number=} rightCurlyBracket
+ * @property {function(string, number, number): number=} semicolon
+ * @property {function(string, number, number): number=} comma
+ */
+
+/** @typedef {function(string, number, CssTokenCallbacks): number} CharHandler */
+
+// spec: https://drafts.csswg.org/css-syntax/
+
+const CC_LINE_FEED = "\n".charCodeAt(0);
+const CC_CARRIAGE_RETURN = "\r".charCodeAt(0);
+const CC_FORM_FEED = "\f".charCodeAt(0);
+
+const CC_TAB = "\t".charCodeAt(0);
+const CC_SPACE = " ".charCodeAt(0);
+
+const CC_SOLIDUS = "/".charCodeAt(0);
+const CC_REVERSE_SOLIDUS = "\\".charCodeAt(0);
+const CC_ASTERISK = "*".charCodeAt(0);
+
+const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
+const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
+const CC_LEFT_CURLY = "{".charCodeAt(0);
+const CC_RIGHT_CURLY = "}".charCodeAt(0);
+const CC_LEFT_SQUARE = "[".charCodeAt(0);
+const CC_RIGHT_SQUARE = "]".charCodeAt(0);
+
+const CC_QUOTATION_MARK = '"'.charCodeAt(0);
+const CC_APOSTROPHE = "'".charCodeAt(0);
+
+const CC_FULL_STOP = ".".charCodeAt(0);
+const CC_COLON = ":".charCodeAt(0);
+const CC_SEMICOLON = ";".charCodeAt(0);
+const CC_COMMA = ",".charCodeAt(0);
+const CC_PERCENTAGE = "%".charCodeAt(0);
+const CC_AT_SIGN = "@".charCodeAt(0);
+
+const CC_LOW_LINE = "_".charCodeAt(0);
+const CC_LOWER_A = "a".charCodeAt(0);
+const CC_LOWER_U = "u".charCodeAt(0);
+const CC_LOWER_E = "e".charCodeAt(0);
+const CC_LOWER_Z = "z".charCodeAt(0);
+const CC_UPPER_A = "A".charCodeAt(0);
+const CC_UPPER_E = "E".charCodeAt(0);
+const CC_UPPER_U = "U".charCodeAt(0);
+const CC_UPPER_Z = "Z".charCodeAt(0);
+const CC_0 = "0".charCodeAt(0);
+const CC_9 = "9".charCodeAt(0);
+
+const CC_NUMBER_SIGN = "#".charCodeAt(0);
+const CC_PLUS_SIGN = "+".charCodeAt(0);
+const CC_HYPHEN_MINUS = "-".charCodeAt(0);
+
+const CC_LESS_THAN_SIGN = "<".charCodeAt(0);
+const CC_GREATER_THAN_SIGN = ">".charCodeAt(0);
+
+/**
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a newline
+ */
+const _isNewLine = cc => {
+ return (
+ cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
+ );
+};
+
+/** @type {CharHandler} */
+const consumeSpace = (input, pos, callbacks) => {
+ /** @type {number} */
+ let cc;
+ do {
+ pos++;
+ cc = input.charCodeAt(pos);
+ } while (_isWhiteSpace(cc));
+ return pos;
+};
+
+/**
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a newline
+ */
+const _isNewline = cc => {
+ return (
+ cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
+ );
+};
+
+/**
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE)
+ */
+const _isSpace = cc => {
+ return cc === CC_TAB || cc === CC_SPACE;
+};
+
+/**
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a whitespace
+ */
+const _isWhiteSpace = cc => {
+ return _isNewline(cc) || _isSpace(cc);
+};
+
+/**
+ * ident-start code point
+ *
+ * A letter, a non-ASCII code point, or U+005F LOW LINE (_).
+ *
+ * @param {number} cc char code
+ * @returns {boolean} true, if cc is a start code point of an identifier
+ */
+const isIdentStartCodePoint = cc => {
+ return (
+ (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
+ (cc >= CC_UPPER_A && cc <= CC_UPPER_Z) ||
+ cc === CC_LOW_LINE ||
+ cc >= 0x80
+ );
+};
+
+/** @type {CharHandler} */
+const consumeDelimToken = (input, pos, callbacks) => {
+ return pos + 1;
+};
+
+/** @type {CharHandler} */
+const consumeComments = (input, pos, callbacks) => {
+ // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A
+ // ASTERISK (*), consume them and all following code points up to and including
+ // the first U+002A ASTERISK (*) followed by a U+002F SOLIDUS (/), or up to an
+ // EOF code point. Return to the start of this step.
+ //
+ // If the preceding paragraph ended by consuming an EOF code point, this is a parse error.
+ // But we are silent on errors.
+ if (
+ input.charCodeAt(pos) === CC_SOLIDUS &&
+ input.charCodeAt(pos + 1) === CC_ASTERISK
+ ) {
+ pos += 1;
+ while (pos < input.length) {
+ if (
+ input.charCodeAt(pos) === CC_ASTERISK &&
+ input.charCodeAt(pos + 1) === CC_SOLIDUS
+ ) {
+ pos += 2;
+ break;
+ }
+ pos++;
+ }
+ }
+ return pos;
+};
+
+/** @type {function(number): CharHandler} */
+const consumeString = quote_cc => (input, pos, callbacks) => {
+ const start = pos;
+ pos = _consumeString(input, pos, quote_cc);
+ if (callbacks.string !== undefined) {
+ pos = callbacks.string(input, start, pos);
+ }
+ return pos;
+};
+
+/**
+ * @param {string} input input
+ * @param {number} pos position
+ * @param {number} quote_cc quote char code
+ * @returns {number} new position
+ */
+const _consumeString = (input, pos, quote_cc) => {
+ pos++;
+ for (;;) {
+ if (pos === input.length) return pos;
+ const cc = input.charCodeAt(pos);
+ if (cc === quote_cc) return pos + 1;
+ if (_isNewLine(cc)) {
+ // bad string
+ return pos;
+ }
+ if (cc === CC_REVERSE_SOLIDUS) {
+ // we don't need to fully parse the escaped code point
+ // just skip over a potential new line
+ pos++;
+ if (pos === input.length) return pos;
+ pos++;
+ } else {
+ pos++;
+ }
+ }
+};
+
+/**
+ * @param {number} cc char code
+ * @returns {boolean} is identifier start code
+ */
+const _isIdentifierStartCode = cc => {
+ return (
+ cc === CC_LOW_LINE ||
+ (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
+ (cc >= CC_UPPER_A && cc <= CC_UPPER_Z) ||
+ cc > 0x80
+ );
+};
+
+/**
+ * @param {number} first first code point
+ * @param {number} second second code point
+ * @returns {boolean} true if two code points are a valid escape
+ */
+const _isTwoCodePointsAreValidEscape = (first, second) => {
+ if (first !== CC_REVERSE_SOLIDUS) return false;
+ if (_isNewLine(second)) return false;
+ return true;
+};
+
+/**
+ * @param {number} cc char code
+ * @returns {boolean} is digit
+ */
+const _isDigit = cc => {
+ return cc >= CC_0 && cc <= CC_9;
+};
+
+/**
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {boolean} true, if input at pos starts an identifier
+ */
+const _startsIdentifier = (input, pos) => {
+ const cc = input.charCodeAt(pos);
+ if (cc === CC_HYPHEN_MINUS) {
+ if (pos === input.length) return false;
+ const cc = input.charCodeAt(pos + 1);
+ if (cc === CC_HYPHEN_MINUS) return true;
+ if (cc === CC_REVERSE_SOLIDUS) {
+ const cc = input.charCodeAt(pos + 2);
+ return !_isNewLine(cc);
+ }
+ return _isIdentifierStartCode(cc);
+ }
+ if (cc === CC_REVERSE_SOLIDUS) {
+ const cc = input.charCodeAt(pos + 1);
+ return !_isNewLine(cc);
+ }
+ return _isIdentifierStartCode(cc);
+};
+
+/** @type {CharHandler} */
+const consumeNumberSign = (input, pos, callbacks) => {
+ const start = pos;
+ pos++;
+ if (pos === input.length) return pos;
+ if (callbacks.isSelector(input, pos) && _startsIdentifier(input, pos)) {
+ pos = _consumeIdentifier(input, pos, callbacks);
+ if (callbacks.id !== undefined) {
+ return callbacks.id(input, start, pos);
+ }
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeMinus = (input, pos, callbacks) => {
+ const start = pos;
+ pos++;
+ if (pos === input.length) return pos;
+ const cc = input.charCodeAt(pos);
+ // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
+ if (cc === CC_FULL_STOP || _isDigit(cc)) {
+ return consumeNumericToken(input, pos, callbacks);
+ } else if (cc === CC_HYPHEN_MINUS) {
+ pos++;
+ if (pos === input.length) return pos;
+ const cc = input.charCodeAt(pos);
+ if (cc === CC_GREATER_THAN_SIGN) {
+ return pos + 1;
+ } else {
+ pos = _consumeIdentifier(input, pos, callbacks);
+ if (callbacks.identifier !== undefined) {
+ return callbacks.identifier(input, start, pos);
+ }
+ }
+ } else if (cc === CC_REVERSE_SOLIDUS) {
+ if (pos + 1 === input.length) return pos;
+ const cc = input.charCodeAt(pos + 1);
+ if (_isNewLine(cc)) return pos;
+ pos = _consumeIdentifier(input, pos, callbacks);
+ if (callbacks.identifier !== undefined) {
+ return callbacks.identifier(input, start, pos);
+ }
+ } else if (_isIdentifierStartCode(cc)) {
+ pos = consumeOtherIdentifier(input, pos - 1, callbacks);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeDot = (input, pos, callbacks) => {
+ const start = pos;
+ pos++;
+ if (pos === input.length) return pos;
+ const cc = input.charCodeAt(pos);
+ if (_isDigit(cc)) return consumeNumericToken(input, pos - 2, callbacks);
+ if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
+ return pos;
+ pos = _consumeIdentifier(input, pos, callbacks);
+ if (callbacks.class !== undefined) return callbacks.class(input, start, pos);
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeNumericToken = (input, pos, callbacks) => {
+ pos = _consumeNumber(input, pos, callbacks);
+ if (pos === input.length) return pos;
+ if (_startsIdentifier(input, pos))
+ return _consumeIdentifier(input, pos, callbacks);
+ const cc = input.charCodeAt(pos);
+ if (cc === CC_PERCENTAGE) return pos + 1;
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeOtherIdentifier = (input, pos, callbacks) => {
+ const start = pos;
+ pos = _consumeIdentifier(input, pos, callbacks);
+ if (pos !== input.length && input.charCodeAt(pos) === CC_LEFT_PARENTHESIS) {
+ pos++;
+ if (callbacks.function !== undefined) {
+ return callbacks.function(input, start, pos);
+ }
+ } else {
+ if (callbacks.identifier !== undefined) {
+ return callbacks.identifier(input, start, pos);
+ }
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumePotentialUrl = (input, pos, callbacks) => {
+ const start = pos;
+ pos = _consumeIdentifier(input, pos, callbacks);
+ const nextPos = pos + 1;
+ if (
+ pos === start + 3 &&
+ input.slice(start, nextPos).toLowerCase() === "url("
+ ) {
+ pos++;
+ let cc = input.charCodeAt(pos);
+ while (_isWhiteSpace(cc)) {
+ pos++;
+ if (pos === input.length) return pos;
+ cc = input.charCodeAt(pos);
+ }
+ if (cc === CC_QUOTATION_MARK || cc === CC_APOSTROPHE) {
+ if (callbacks.function !== undefined) {
+ return callbacks.function(input, start, nextPos);
+ }
+ return nextPos;
+ } else {
+ const contentStart = pos;
+ /** @type {number} */
+ let contentEnd;
+ for (;;) {
+ if (cc === CC_REVERSE_SOLIDUS) {
+ pos++;
+ if (pos === input.length) return pos;
+ pos++;
+ } else if (_isWhiteSpace(cc)) {
+ contentEnd = pos;
+ do {
+ pos++;
+ if (pos === input.length) return pos;
+ cc = input.charCodeAt(pos);
+ } while (_isWhiteSpace(cc));
+ if (cc !== CC_RIGHT_PARENTHESIS) return pos;
+ pos++;
+ if (callbacks.url !== undefined) {
+ return callbacks.url(input, start, pos, contentStart, contentEnd);
+ }
+ return pos;
+ } else if (cc === CC_RIGHT_PARENTHESIS) {
+ contentEnd = pos;
+ pos++;
+ if (callbacks.url !== undefined) {
+ return callbacks.url(input, start, pos, contentStart, contentEnd);
+ }
+ return pos;
+ } else if (cc === CC_LEFT_PARENTHESIS) {
+ return pos;
+ } else {
+ pos++;
+ }
+ if (pos === input.length) return pos;
+ cc = input.charCodeAt(pos);
+ }
+ }
+ } else {
+ if (callbacks.identifier !== undefined) {
+ return callbacks.identifier(input, start, pos);
+ }
+ return pos;
+ }
+};
+
+/** @type {CharHandler} */
+const consumePotentialPseudo = (input, pos, callbacks) => {
+ const start = pos;
+ pos++;
+ if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
+ return pos;
+ pos = _consumeIdentifier(input, pos, callbacks);
+ let cc = input.charCodeAt(pos);
+ if (cc === CC_LEFT_PARENTHESIS) {
+ pos++;
+ if (callbacks.pseudoFunction !== undefined) {
+ return callbacks.pseudoFunction(input, start, pos);
+ }
+ return pos;
+ }
+ if (callbacks.pseudoClass !== undefined) {
+ return callbacks.pseudoClass(input, start, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLeftParenthesis = (input, pos, callbacks) => {
+ pos++;
+ if (callbacks.leftParenthesis !== undefined) {
+ return callbacks.leftParenthesis(input, pos - 1, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeRightParenthesis = (input, pos, callbacks) => {
+ pos++;
+ if (callbacks.rightParenthesis !== undefined) {
+ return callbacks.rightParenthesis(input, pos - 1, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLeftCurlyBracket = (input, pos, callbacks) => {
+ pos++;
+ if (callbacks.leftCurlyBracket !== undefined) {
+ return callbacks.leftCurlyBracket(input, pos - 1, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeRightCurlyBracket = (input, pos, callbacks) => {
+ pos++;
+ if (callbacks.rightCurlyBracket !== undefined) {
+ return callbacks.rightCurlyBracket(input, pos - 1, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeSemicolon = (input, pos, callbacks) => {
+ pos++;
+ if (callbacks.semicolon !== undefined) {
+ return callbacks.semicolon(input, pos - 1, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeComma = (input, pos, callbacks) => {
+ pos++;
+ if (callbacks.comma !== undefined) {
+ return callbacks.comma(input, pos - 1, pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const _consumeIdentifier = (input, pos) => {
+ for (;;) {
+ const cc = input.charCodeAt(pos);
+ if (cc === CC_REVERSE_SOLIDUS) {
+ pos++;
+ if (pos === input.length) return pos;
+ pos++;
+ } else if (
+ _isIdentifierStartCode(cc) ||
+ _isDigit(cc) ||
+ cc === CC_HYPHEN_MINUS
+ ) {
+ pos++;
+ } else {
+ return pos;
+ }
+ }
+};
+
+/** @type {CharHandler} */
+const _consumeNumber = (input, pos) => {
+ pos++;
+ if (pos === input.length) return pos;
+ let cc = input.charCodeAt(pos);
+ while (_isDigit(cc)) {
+ pos++;
+ if (pos === input.length) return pos;
+ cc = input.charCodeAt(pos);
+ }
+ if (cc === CC_FULL_STOP && pos + 1 !== input.length) {
+ const next = input.charCodeAt(pos + 1);
+ if (_isDigit(next)) {
+ pos += 2;
+ cc = input.charCodeAt(pos);
+ while (_isDigit(cc)) {
+ pos++;
+ if (pos === input.length) return pos;
+ cc = input.charCodeAt(pos);
+ }
+ }
+ }
+ if (cc === CC_LOWER_E || cc === CC_UPPER_E) {
+ if (pos + 1 !== input.length) {
+ const next = input.charCodeAt(pos + 2);
+ if (_isDigit(next)) {
+ pos += 2;
+ } else if (
+ (next === CC_HYPHEN_MINUS || next === CC_PLUS_SIGN) &&
+ pos + 2 !== input.length
+ ) {
+ const next = input.charCodeAt(pos + 2);
+ if (_isDigit(next)) {
+ pos += 3;
+ } else {
+ return pos;
+ }
+ } else {
+ return pos;
+ }
+ }
+ } else {
+ return pos;
+ }
+ cc = input.charCodeAt(pos);
+ while (_isDigit(cc)) {
+ pos++;
+ if (pos === input.length) return pos;
+ cc = input.charCodeAt(pos);
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeLessThan = (input, pos, callbacks) => {
+ if (input.slice(pos + 1, pos + 4) === "!--") return pos + 4;
+ return pos + 1;
+};
+
+/** @type {CharHandler} */
+const consumeAt = (input, pos, callbacks) => {
+ const start = pos;
+ pos++;
+ if (pos === input.length) return pos;
+ if (_startsIdentifier(input, pos)) {
+ pos = _consumeIdentifier(input, pos, callbacks);
+ if (callbacks.atKeyword !== undefined) {
+ pos = callbacks.atKeyword(input, start, pos);
+ }
+ }
+ return pos;
+};
+
+/** @type {CharHandler} */
+const consumeReverseSolidus = (input, pos, callbacks) => {
+ const start = pos;
+ pos++;
+ if (pos === input.length) return pos;
+ // If the input stream starts with a valid escape, reconsume the current input code point, consume an ident-like token, and return it.
+ if (
+ _isTwoCodePointsAreValidEscape(
+ input.charCodeAt(start),
+ input.charCodeAt(pos)
+ )
+ ) {
+ return consumeOtherIdentifier(input, pos - 1, callbacks);
+ }
+ // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
+ return pos;
+};
+
+const CHAR_MAP = Array.from({ length: 0x80 }, (_, cc) => {
+ // https://drafts.csswg.org/css-syntax/#consume-token
+ switch (cc) {
+ // whitespace
+ case CC_LINE_FEED:
+ case CC_CARRIAGE_RETURN:
+ case CC_FORM_FEED:
+ case CC_TAB:
+ case CC_SPACE:
+ return consumeSpace;
+ // U+0022 QUOTATION MARK (")
+ case CC_QUOTATION_MARK:
+ return consumeString(cc);
+ // U+0023 NUMBER SIGN (#)
+ case CC_NUMBER_SIGN:
+ return consumeNumberSign;
+ // U+0027 APOSTROPHE (')
+ case CC_APOSTROPHE:
+ return consumeString(cc);
+ // U+0028 LEFT PARENTHESIS (()
+ case CC_LEFT_PARENTHESIS:
+ return consumeLeftParenthesis;
+ // U+0029 RIGHT PARENTHESIS ())
+ case CC_RIGHT_PARENTHESIS:
+ return consumeRightParenthesis;
+ // U+002B PLUS SIGN (+)
+ case CC_PLUS_SIGN:
+ return consumeNumericToken;
+ // U+002C COMMA (,)
+ case CC_COMMA:
+ return consumeComma;
+ // U+002D HYPHEN-MINUS (-)
+ case CC_HYPHEN_MINUS:
+ return consumeMinus;
+ // U+002E FULL STOP (.)
+ case CC_FULL_STOP:
+ return consumeDot;
+ // U+003A COLON (:)
+ case CC_COLON:
+ return consumePotentialPseudo;
+ // U+003B SEMICOLON (;)
+ case CC_SEMICOLON:
+ return consumeSemicolon;
+ // U+003C LESS-THAN SIGN (<)
+ case CC_LESS_THAN_SIGN:
+ return consumeLessThan;
+ // U+0040 COMMERCIAL AT (@)
+ case CC_AT_SIGN:
+ return consumeAt;
+ // U+005B LEFT SQUARE BRACKET ([)
+ case CC_LEFT_SQUARE:
+ return consumeDelimToken;
+ // U+005C REVERSE SOLIDUS (\)
+ case CC_REVERSE_SOLIDUS:
+ return consumeReverseSolidus;
+ // U+005D RIGHT SQUARE BRACKET (])
+ case CC_RIGHT_SQUARE:
+ return consumeDelimToken;
+ // U+007B LEFT CURLY BRACKET ({)
+ case CC_LEFT_CURLY:
+ return consumeLeftCurlyBracket;
+ // U+007D RIGHT CURLY BRACKET (})
+ case CC_RIGHT_CURLY:
+ return consumeRightCurlyBracket;
+ // Optimization
+ case CC_LOWER_U:
+ case CC_UPPER_U:
+ return consumePotentialUrl;
+ default:
+ // digit
+ if (_isDigit(cc)) return consumeNumericToken;
+ // ident-start code point
+ if (isIdentStartCodePoint(cc)) {
+ return consumeOtherIdentifier;
+ }
+ // EOF, but we don't have it
+ // anything else
+ return consumeDelimToken;
+ }
+});
+
+/**
+ * @param {string} input input css
+ * @param {CssTokenCallbacks} callbacks callbacks
+ * @returns {void}
+ */
+module.exports = (input, callbacks) => {
+ // This section describes how to consume a token from a stream of code points. It will return a single token of any type.
+ let pos = 0;
+ while (pos < input.length) {
+ // Consume comments.
+ pos = consumeComments(input, pos, callbacks);
+
+ const cc = input.charCodeAt(pos);
+
+ // Consume the next input code point.
+ if (cc < 0x80) {
+ pos = CHAR_MAP[cc](input, pos, callbacks);
+ } else {
+ pos++;
+ }
+ }
+};
+
+module.exports.isIdentStartCodePoint = isIdentStartCodePoint;
+
+/**
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after comments
+ */
+module.exports.eatComments = (input, pos) => {
+ for (;;) {
+ let originalPos = pos;
+ pos = consumeComments(input, pos, {});
+ if (originalPos === pos) {
+ break;
+ }
+ }
+
+ return pos;
+};
+
+/**
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after whitespace
+ */
+module.exports.eatWhitespace = (input, pos) => {
+ while (_isWhiteSpace(input.charCodeAt(pos))) {
+ pos++;
+ }
+
+ return pos;
+};
+
+/**
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after whitespace and comments
+ */
+module.exports.eatWhitespaceAndComments = (input, pos) => {
+ for (;;) {
+ let originalPos = pos;
+ pos = consumeComments(input, pos, {});
+ while (_isWhiteSpace(input.charCodeAt(pos))) {
+ pos++;
+ }
+ if (originalPos === pos) {
+ break;
+ }
+ }
+
+ return pos;
+};
+
+/**
+ * @param {string} input input
+ * @param {number} pos position
+ * @returns {number} position after whitespace
+ */
+module.exports.eatWhiteLine = (input, pos) => {
+ for (;;) {
+ const cc = input.charCodeAt(pos);
+ if (_isSpace(cc)) {
+ pos++;
+ continue;
+ }
+ if (_isNewLine(cc)) pos++;
+ // For `\r\n`
+ if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos + 1) === CC_LINE_FEED)
+ pos++;
+ break;
+ }
+
+ return pos;
+};