diff --git a/CHANGELOG.md b/CHANGELOG.md
index be14a565c..a6885b1e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,48 @@
# Changelog
+# v1.6.5
+
+## New
+
+- [x] Added fine-grained minification parameters:
+ - [x] RenderOptions#minifyValues: minify CSS values such as numbers and dimension tokens
+ - [x] ParseOptions#minifyAST: minify the AST.
+
+## Improvement
+
+```css
+ .footer{
+ grid-row:4;
+ grid-column:1;
+ grid-column-end:2;
+ }
+```
+
+is now computed as
+
+```css
+.footer {
+ grid-area: 4/1/auto/2
+}
+```
+
+## Fixes
+
+- [x] fix a98-rgb, hwb color color space handling in color-mix()
+- [x] fix percentage handling in relative rgb color
+
+```css
+ .c {
+color: rgb(from rgb(20% 40% 60% / 80%) r g b / calc(alpha / 2));
+```
+is now computed as
+
+```css
+.c {
+ color: #3696
+}
+```
+
# v1.6.4
## New
diff --git a/README.md b/README.md
index 640f02dd4..25f767c47 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,49 @@ A sample result:
On the [complete benchmark suite](https://tbela99.github.io/css-parser/benchmark/index.html), css-parser generated a total output size of 2,158,698 bytes, compared to 2,494,113 bytes for Lightning CSS and larger outputs for all other tested minifiers.
While some tools prioritize raw execution speed, css-parser focuses on maximizing compression while preserving stylesheet semantics, resulting in consistently smaller production bundles.
+## Minification performance vs execution speed
+
+`css-parser` is designed for maximum minification performance, but the optimal configuration depends on what matters most for your workload.
+
+The parser provides settings that let you choose the balance between minification performance and execution speed:
+
+- Minification performance: prioritize the quality and efficiency of the minification process, allowing the parser to perform additional work when generating the minimized output.
+
+- Execution speed: minimize the amount of work performed during parsing and minification to achieve the fastest possible execution time.
+
+However, the available settings allow you to shift the balance toward execution speed when minimizing runtime is more important than performing every available minification optimization.
+
+The example below demonstrates a balanced configuration that improves execution speed by disabling advanced minification features.
+
+```ts
+
+import {transformSync} from "@tbela99/css-parser";
+
+const css = `...`;
+
+const result = transformSync({
+ input: css,
+ minify: false,
+ beautify: false,
+ removeEmpty: true,
+ removeComments: true,
+ convertColor: true,
+ minifyValues: true,
+ });
+
+console.debug(result.code);
+console.debug(result.stats);
+```
+
+Performance vs execution speed comparison
+
+
+| File: tailwind.css | Speed optimization | Minification optimization |
+| --------------------- | ------------------ | ------------------------- |
+| Size: 2,380,419 bytes | 1,890,728 bytes | 1,633,188 bytes |
+| Time | 205.91 ms | 471.89 ms |
+| Size reduction | -20.6% | -31.4% |
+
## Playground
Try it [online](https://tbela99.github.io/css-parser/playground/)
@@ -196,3 +239,64 @@ Try it [online](https://tbela99.github.io/css-parser/playground/)
## Performance
- [x] Bundle file referenced by the @import statement.
+
+# Architecture
+
+```mermaid
+flowchart TD
+ %% --- Transform ---
+ Input(["CSS input"])
+
+
+ %% The Grouped Container
+ subgraph Group10["Transform step"]
+
+ transform["transform()/transformSync()"]
+
+
+ %% The Grouped Container
+ subgraph Group1 ["Parse step"]
+
+ %% --- Parse step ---
+ parse["parse()/parseSync()"]
+ tokenize(["tokenize()"])
+ parseNode(["parse and validate token stream"])
+ visitors(["visitors"])
+ minify(["minify AST"])
+ cssModules(["generate CSS module"])
+ parseResult["Parse result"]
+ end
+
+ %% The Grouped Container
+ subgraph Group2 ["Render step"]
+
+ %% --- Render step ---
+ renderAst(["Render AST"])
+ sourcemap([Sourcemap generation])
+
+ end
+
+ %% --- Result step ---
+ transformResult["Transform result"]
+ end
+
+ %% --- Routing step ---
+ Input --> transform
+ transform --> parse
+ parse --> tokenize
+ tokenize --> parseNode
+ parseNode -- "Visitors set?" --> visitors
+ visitors -- "Minify AST?" --> minify
+ minify -- "CSS module?" --> cssModules
+ visitors -- "CSS module?" --> cssModules
+ cssModules --> parseResult
+ parseNode -- "CSS module?" --> cssModules
+ parseNode -- "Minify AST?" --> minify
+ parseNode --> parseResult
+ visitors --> parseResult
+ minify --> parseResult
+ parseResult --> renderAst
+ renderAst -- "Sourcemap?" --> sourcemap
+ renderAst --> transformResult
+ sourcemap --> transformResult
+```
\ No newline at end of file
diff --git a/benchmark/package.json b/benchmark/package.json
index 5d81be43d..4e75aa7c0 100644
--- a/benchmark/package.json
+++ b/benchmark/package.json
@@ -10,8 +10,8 @@
"all": "npm run sizes && npm run bench; npm run report"
},
"dependencies": {
- "@tbela99/css-parser": "^1.6.3",
- "@tbela99/css-parser2": "github:tbela99/css-parser#04832c9",
+ "@tbela99/css-parser": "^1.6.5",
+ "@tbela99/css-parser2": "github:tbela99/css-parser#b74aa264",
"clean-css": "^5.3.3",
"css-tree": "^3.2.1",
"cssnano": "^9.0.5",
@@ -21,4 +21,4 @@
"postcss": "^8.5.28",
"vitest": "^5.0.1"
}
-}
\ No newline at end of file
+}
diff --git a/benchmark/src/generate-report.js b/benchmark/src/generate-report.js
index 8effbf060..422cd9a8b 100644
--- a/benchmark/src/generate-report.js
+++ b/benchmark/src/generate-report.js
@@ -72,7 +72,7 @@ for (const m of minifiers) {
totalRow += `\n`;
const headerCells = minifiers
- .map((m) => `
${m.url != null ? `${m.label}` : m.label} | `)
+ .map((m) => `${m.url != null ? `${m.label}` : m.label} | `)
.join("\n");
const html = `
diff --git a/benchmark/src/minifiers.js b/benchmark/src/minifiers.js
index 57ee284ed..a8d829865 100644
--- a/benchmark/src/minifiers.js
+++ b/benchmark/src/minifiers.js
@@ -10,9 +10,9 @@ import cssnano from "cssnano";
import * as csso from "csso";
import * as csstree from "css-tree";
import * as esbuild from "esbuild";
-import { transform as lightningTransform } from "lightningcss";
-import { transform as tbelaTransform } from "@tbela99/css-parser";
-import {transformSync as tbelaDevTransform} from "@tbela99/css-parser2";
+import { transform } from "lightningcss";
+import { transformSync as tbelaTransform } from "@tbela99/css-parser";
+import { transformSync as tbelaDevTransform } from "@tbela99/css-parser2";
function pkgVersion(name, pathToPkgJson) {
const { version, repository } = JSON.parse(
@@ -39,16 +39,14 @@ function pkgVersion(name, pathToPkgJson) {
const githubShorthand = url.match(/^github:([^/]+\/[^/]+)$/);
if (githubShorthand) {
url = `https://github.com/${githubShorthand[1]}`;
- }
-
- else {
+ } else {
url = url
.replace(/^git\+/, "")
.replace(/^git@github\.com:/, "https://github.com/")
.replace(/^ssh:\/\/git@github\.com\//, "https://github.com/")
.replace(/\.git$/, "");
}
-
+
if (!url.match(/[a-zA-Z]+:/)) {
url = "https://github.com/" + url;
}
@@ -99,15 +97,15 @@ export const minifiers = [
minify: (css) => csso.minify(css).css,
},
// infinite loop bug
- // {
- // id: "css-tree",
- // url: versions["css-tree"].url,
- // label: `css-tree - ${versions["css-tree"].version}`,
- // // css-tree has no dedicated minifier API; parse+generate already
- // // drops whitespace/comments, which is how the official benchmark
- // // treats it too (no property-level optimization, just compact output).
- // minify: (css) => csstree.generate(csstree.parse(css)),
- // },
+ {
+ id: "css-tree",
+ url: versions["css-tree"].url,
+ label: `css-tree - ${versions["css-tree"].version}`,
+ // css-tree has no dedicated minifier API; parse+generate already
+ // drops whitespace/comments, which is how the official benchmark
+ // treats it too (no property-level optimization, just compact output).
+ minify: (css) => csstree.generate(csstree.parse(css)),
+ },
{
id: "esbuild",
url: versions.esbuild.url,
@@ -118,19 +116,28 @@ export const minifiers = [
id: "lightningcss",
url: versions.lightningcss.url,
label: `lightningcss - ${versions.lightningcss.version}`,
- minify: (css) =>
- lightningTransform({ filename: "style.css", code: Buffer.from(css), minify: true }).code.toString(),
+ minify: (css) => transform({ filename: "style.css", code: Buffer.from(css), minify: true }).code.toString(),
},
{
id: "css-parser",
url: versions["css-parser"].url,
- label: `@tbela99/css-parser - ${versions["css-parser"].version}`,
- minify: async (css) => (await tbelaTransform(css, { minify: true })).code,
+ label: `@tbela99/css-parser (speed) - ${versions["css-parser"].version}`,
+ title: `settings: { minify: false, beautify: false, removeEmpty: true, removeComments: true, convertColor: true }`,
+ minify: async (css) =>
+ tbelaTransform({
+ input: css,
+ minify: false,
+ beautify: false,
+ removeEmpty: true,
+ removeComments: true,
+ convertColor: true,
+ // minifyValues: true,
+ }).code,
},
{
id: "css-parser-dev",
url: versions["css-parser-dev"].url,
- label: `@tbela99/css-parser-dev - ${versions["css-parser-dev"].version}`,
- minify: async (css) => (await tbelaDevTransform(css, { minify: true })).code,
+ label: `@tbela99/css-parser-dev (default) - ${versions["css-parser-dev"].version}`,
+ minify: async (css) => tbelaDevTransform({ input: css }).code,
},
];
diff --git a/dist/index-umd-web.js b/dist/index-umd-web.js
index c42387449..e8505ba55 100644
--- a/dist/index-umd-web.js
+++ b/dist/index-umd-web.js
@@ -6429,6 +6429,11 @@
* Color range definitions
*/
const colorRange = {
+ rgb: {
+ r: [0, 255],
+ g: [0, 255],
+ b: [0, 255],
+ },
lab: {
l: [0, 100],
a: [-125, 125],
@@ -6898,13 +6903,6 @@
}
function getColorComponents(token) {
- // if (token.typ === EnumToken.IdenTokenType) {
- // if (isColor(token)) {
- // parseColor(token);
- // } else {
- // return null;
- // }
- // }
if (token.kin == exports.ColorType.HEX || token.kin == exports.ColorType.LIT) {
if (equalsIgnoreCase("currentcolor", token.val)) {
return null;
@@ -6928,25 +6926,12 @@
].includes(child.typ)) {
continue;
}
- // if (child.typ === EnumToken.IdenTokenType && isColor(child)) {
- // parseColor(child);
- // }
if (child.typ === exports.EnumToken.FunctionTokenType ||
child.typ === exports.EnumToken.WildCardFunctionTokenType ||
child.typ === exports.EnumToken.MathFunctionTokenType) {
if ("var" == child.val.toLowerCase()) {
return null;
}
- // else {
- // for (const { value } of walkValues((child as FunctionToken).chi)) {
- // if (
- // value.typ == EnumToken.WildCardFunctionTokenDefType &&
- // "var" === (value as FunctionToken).val.toLowerCase()
- // ) {
- // return null;
- // }
- // }
- // }
}
if (child.typ == exports.EnumToken.ColorTokenType && equalsIgnoreCase("currentcolor", child.val)) {
return null;
@@ -8242,7 +8227,10 @@
if (value == null) {
return null;
}
- return hexToken(value.reduce((acc, curr) => acc + srgb2rgb(curr + Number.EPSILON).toString(16).padStart(2, "0"), "#"));
+ return hexToken(value.reduce((acc, curr) => acc +
+ srgb2rgb(curr + Number.EPSILON)
+ .toString(16)
+ .padStart(2, "0"), "#"));
}
function oklab2HexToken(token) {
let value = oklab2srgbvalues(token);
@@ -9091,7 +9079,7 @@
// convert an array of linear-light a98-rgb in the range 0.0-1.0
// to gamma corrected form
// negative values are also now accepted
- return [r, b, g]
+ return [r, g, b]
.map(function (val) {
let sign = val < 0 ? -1 : 1;
let abs = Math.abs(val);
@@ -9227,6 +9215,9 @@
if (values == null) {
return null;
}
+ if (colorSpace == "hwb") {
+ colorSpace = "srgb";
+ }
switch (colorSpace) {
case "srgb":
break;
@@ -9256,17 +9247,17 @@
values = srgb2xyz_d65(values[0], values[1], values[2], values[3]);
values = XYZ_D65_to_D50(values[0], values[1], values[2], values[3]);
break;
- case "rgb":
- for (let j = 0; j < values.length; j++) {
- values[j] = j == 3 ? values[j] : srgb2rgb(values[j]);
- }
- break;
+ // case "rgb":
+ // for (let j = 0; j < values.length; j++) {
+ // values[j] = j == 3 ? values[j] : srgb2rgb(values[j]);
+ // }
+ // break;
case "hsl":
values = srgb2hslvalues(values[0], values[1], values[2], values[3]);
break;
- case "hwb":
- values = srgb2hwb(values[0], values[1], values[2], values[3]);
- break;
+ // case "hwb":
+ // values = srgb2hwb(values[0], values[1], values[2], values[3]);
+ // break;
case "lab":
values = srgb2labvalues(values[0], values[1], values[2], values[3]);
break;
@@ -9465,14 +9456,14 @@
kin: exports.ColorType.COLOR,
cal: "col",
};
- case "rgb":
+ // case "rgb":
case "hsl":
- case "hwb":
+ // case "hwb":
case "lab":
case "lch":
case "oklab":
case "oklch":
- if (colorSpace == "hsl" || colorSpace == "hwb") {
+ if (colorSpace == "hsl") {
// @ts-ignore
if (values[2] < 0) {
// @ts-ignore
@@ -9502,7 +9493,7 @@
}),
kin: exports.ColorType[colorSpace.toUpperCase().replaceAll("-", "_")],
};
- if (colorSpace == "hsl" || colorSpace == "hwb") {
+ if (colorSpace == "hsl") {
// @ts-ignore
result.chi[0] = { typ: exports.EnumToken.AngleTokenType, val: result.chi[0].val * 360 };
// @ts-ignore
@@ -10097,6 +10088,7 @@
[LOCSRCID]: nodes[0][LOCSRCID],
[LOCSTA]: nodes[0][LOCSTA],
[LOCEND]: nodes[0][LOCEND],
+ [PARENT]: nodes[0][PARENT],
},
];
}
@@ -10119,6 +10111,7 @@
[LOCSRCID]: nodes[i][LOCSRCID],
[LOCSTA]: nodes[i][LOCSTA],
[LOCEND]: nodes[i + 1][LOCEND],
+ [PARENT]: nodes[i + 1][PARENT],
};
}
else {
@@ -10128,6 +10121,7 @@
[LOCSRCID]: nodes[i + 1][LOCSRCID],
[LOCSTA]: nodes[i + 1][LOCSTA],
[LOCEND]: nodes[i + 1][LOCEND],
+ [PARENT]: nodes[i + 1][PARENT],
}, exports.EnumToken.Mul);
}
i++;
@@ -10148,12 +10142,14 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
}, {
...token,
val: -token.val,
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
return acc;
}
@@ -10164,6 +10160,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
}
acc.push(token);
@@ -10185,6 +10182,7 @@
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: r?.[LOCEND] ?? l[LOCEND],
+ [PARENT]: l[PARENT],
};
if (!isScalarToken(l) || !isScalarToken(r) || (l.typ == r.typ && "unit" in l && "unit" in r && l.unit != r.unit)) {
return defaultReturn;
@@ -10257,6 +10255,7 @@
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: l[LOCEND],
+ [PARENT]: l[PARENT],
},
r: {
typ: exports.EnumToken.NumberTokenType,
@@ -10264,6 +10263,7 @@
[LOCSRCID]: r[LOCSRCID],
[LOCSTA]: r[LOCSTA],
[LOCEND]: r[LOCEND],
+ [PARENT]: r[PARENT],
},
};
}
@@ -10276,6 +10276,7 @@
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: l[LOCEND],
+ [PARENT]: l[PARENT],
},
r: {
typ: exports.EnumToken.NumberTokenType,
@@ -10283,6 +10284,7 @@
[LOCSRCID]: r[LOCSRCID],
[LOCSTA]: r[LOCSTA],
[LOCEND]: r[LOCEND],
+ [PARENT]: r[PARENT],
},
};
}
@@ -10309,6 +10311,7 @@
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: r?.[LOCEND] ?? l[LOCEND],
+ [PARENT]: l[PARENT],
};
if (token.typ == exports.EnumToken.IdenTokenType) {
// @ts-ignore
@@ -10489,6 +10492,7 @@
[LOCSRCID]: value[0][LOCSRCID],
[LOCSTA]: value[0][LOCSTA],
[LOCEND]: value[0][LOCEND],
+ [PARENT]: value[0][PARENT],
}
: {
typ: token.val == "sign" ? exports.EnumToken.NumberTokenType : value[0].typ,
@@ -10496,6 +10500,7 @@
[LOCSRCID]: value[0][LOCSRCID],
[LOCSTA]: value[0][LOCSTA],
[LOCEND]: value[0][LOCEND],
+ [PARENT]: value[0][PARENT],
},
];
}
@@ -10518,6 +10523,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10591,6 +10597,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10605,6 +10612,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10615,6 +10623,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10654,6 +10663,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10696,6 +10706,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10723,6 +10734,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
for (const child of inlineExpression$1(token.r)) {
result.push(child);
@@ -10802,6 +10814,7 @@
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
};
// @ts-ignore
delete token.val;
@@ -10843,6 +10856,7 @@
[LOCSRCID]: tokens[i - 1][LOCSRCID],
[LOCSTA]: tokens[i - 1][LOCSTA],
[LOCEND]: tokens[i + 1][LOCEND],
+ [PARENT]: tokens[i + 1][PARENT],
});
i--;
}
@@ -10888,20 +10902,20 @@
continue;
}
if (component.typ == exports.EnumToken.IdenTokenType) {
- val = component.val.toLowerCase();
+ val = component.val;
if (
// @ts-expect-error
typeof Math[val.toUpperCase()] !== "number" &&
- val != "in" &&
- val != "hue" &&
- val != "from" &&
- val != "alpha" &&
- val != "none" &&
- val != "shorter" &&
- val != "longer" &&
- val != "increasing" &&
- val != "decreasing" &&
- !colorsFunc.includes(val) &&
+ !equalsIgnoreCase(val, "in") &&
+ !equalsIgnoreCase(val, "hue") &&
+ !equalsIgnoreCase(val, "from") &&
+ !equalsIgnoreCase(val, "alpha") &&
+ !equalsIgnoreCase(val, "none") &&
+ !equalsIgnoreCase(val, "shorter") &&
+ !equalsIgnoreCase(val, "longer") &&
+ !equalsIgnoreCase(val, "increasing") &&
+ !equalsIgnoreCase(val, "decreasing") &&
+ !colorsFunc.some((t) => equalsIgnoreCase(t, val)) &&
!colorFuncColorSpace.includes(val) &&
!validKeys.includes(val)) {
return null;
@@ -12805,7 +12819,8 @@
for (let i = index; i < syntaxes.length; i++) {
if (syntaxes[i].typ == ValidationTokenEnum.Whitespace ||
syntaxes[i].isOptional ||
- syntaxes[i].isRepeatable) {
+ syntaxes[i].isRepeatable ||
+ syntaxes[i].match?.min?.val === 0) {
continue;
}
return {
@@ -14510,7 +14525,6 @@
}
let components = getColorComponents(color);
if (alpha.typ === exports.EnumToken.MathFunctionTokenType) {
- const originalAlpha = cloneNode(alpha, true);
for (const { value } of walkValues(alpha.chi, alpha)) {
if (value.typ === exports.EnumToken.IdenTokenType) {
if (equalsIgnoreCase(value.val, "alpha")) {
@@ -14522,22 +14536,22 @@
});
// continue;
}
- else if (equalsIgnoreCase(value.val, "none")) {
- Object.assign(value, {
- typ: exports.EnumToken.NumberTokenType,
- val: 0,
- });
- }
+ // else if (equalsIgnoreCase((value as IdentToken).val, "none")) {
+ // Object.assign(value, {
+ // typ: EnumToken.NumberTokenType,
+ // val: 0,
+ // });
+ // }
}
}
const result = evaluate([alpha]);
if (result.length == 1) {
alpha = result[0];
}
- else {
- // @ts-expect-error
- alpha = originalAlpha;
- }
+ // else {
+ // // @ts-expect-error
+ // alpha = originalAlpha;
+ // }
}
// console.error({ alpha });
if (alpha.typ !== exports.EnumToken.IdenTokenType &&
@@ -14563,17 +14577,17 @@
return null;
}
if (alpha?.typ === exports.EnumToken.IdenTokenType) {
- if (equalsIgnoreCase(alpha.val, "alpha")) {
- alpha = components[3] ?? {
- typ: exports.EnumToken.NumberTokenType,
- val: 1,
- };
- }
- else if (equalsIgnoreCase(alpha.val, "node")) {
- alpha = {
+ // if (equalsIgnoreCase((alpha as IdentToken).val, "alpha")) {
+ // alpha = components[3] ?? {
+ // typ: EnumToken.NumberTokenType,
+ // val: 1,
+ // };
+ // } else
+ if (equalsIgnoreCase(alpha.val, "none")) {
+ Object.assign(alpha, {
typ: exports.EnumToken.NumberTokenType,
val: 0,
- };
+ });
}
}
return makeColor(color.kin, components, alpha);
@@ -15294,12 +15308,12 @@
// '\\'
const REVERSE_SOLIDUS = 0x5c;
const flexUnits = ["fr"];
- const frequencyUnits = ["hz", "khz"];
+ const frequencyUnits = ["Hz", "kHz"];
const timeUnits = ["ms", "s"];
const angleUnits = ["rad", "turn", "deg", "grad"];
const resolutionUnits = ["dpi", "dpcm", "dppx", "x"];
const dimensionUnits = [
- "q",
+ "Q",
"cap",
"ch",
"cm",
@@ -16983,7 +16997,7 @@
}
class ComputePrefixFeature {
get ordering() {
- return 2;
+ return 0;
}
get processMode() {
return exports.FeatureWalkMode.Pre;
@@ -17427,10 +17441,10 @@
class InlineCssVariablesFeature {
accept = new Set([exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType]);
get ordering() {
- return 0;
+ return 2;
}
get processMode() {
- return exports.FeatureWalkMode.Pre;
+ return exports.FeatureWalkMode.Post;
}
static register(options) {
if (options.inlineCssVariables) {
@@ -19680,8 +19694,8 @@
const propertiesConfig = getConfig();
class PropertyMap {
- config;
declarations;
+ config;
requiredCount;
pattern;
constructor(config) {
@@ -19695,7 +19709,7 @@
}
add(declaration) {
if (declaration.nam == this.config.shorthand) {
- this.declarations = new Map();
+ this.declarations.clear();
this.declarations.set(declaration.nam, declaration);
this.matchTypes(declaration);
}
@@ -19711,23 +19725,17 @@
if (this.declarations.has(this.config.shorthand)) {
const tokens = {};
const values = [];
- // @ts-ignore
- this.declarations
- .get(this.config.shorthand)
- // @ts-ignore
- .val.slice()
- .reduce((acc, curr) => {
+ const val = [[]];
+ for (const curr of this.declarations.get(this.config.shorthand).val) { // @ts-ignore
// @ts-ignore
if (separator != null && separator.typ == curr.typ && separator.val == curr.val) {
- acc.push([]);
- return acc;
+ val.push([]);
+ continue;
}
// @ts-ignore
- acc.at(-1).push(curr);
- return acc;
- }, [[]])
- // @ts-ignore
- .reduce((acc, list, current) => {
+ val.at(-1).push(curr);
+ }
+ for (let current = 0; current < val.length; current++) {
values.push(...this.pattern.reduce((acc, property) => {
// let current: number = 0;
const props = this.config.properties[property];
@@ -19742,9 +19750,7 @@
// @ts-ignore
acc[i][PROPERTYNAME] == property ||
matchType(acc[i], props)) {
- if ("prefix" in props &&
- props.previous != null &&
- !(props.previous in tokens)) {
+ if ("prefix" in props && props.previous != null && !(props.previous in tokens)) {
return acc;
}
if (!(property in tokens)) {
@@ -19809,9 +19815,8 @@
}
}
return acc;
- }, list));
- return values;
- }, []);
+ }, val[current]));
+ }
if (values.length == 0) {
this.declarations = Object.entries(tokens).reduce((acc, curr) => {
acc.set(curr[0], {
@@ -19871,17 +19876,40 @@
}
if (hasMapping) {
const mapped = {};
- for (const key of declarations.keys()) {
- const value = declarations.get(key);
+ let key;
+ for (const value of declarations.values()) {
+ key = value.nam;
if (value instanceof PropertyMap) {
for (const [k, v] of value.declarations) {
- mapped[k] = v;
+ if (k == value.config.shorthand) {
+ for (const [key, val] of Object.entries(value.config.properties)) {
+ mapped[key] = cloneNode(v);
+ for (let i = 0; i < v.val.length; i++) {
+ // @ts-ignore
+ if (key == v.val[i][PROPERTYNAME]) {
+ if (mapped[key].val.length > 0) {
+ mapped[key].val.push({
+ typ: exports.EnumToken.WhitespaceTokenType,
+ });
+ }
+ mapped[key].val.push(v.val[i]);
+ }
+ }
+ if (mapped[key].val.length == 0) {
+ mapped[key].val.push(...parseString(value.config.properties[key].default[0]));
+ }
+ }
+ }
+ else {
+ mapped[k] = v;
+ }
}
}
else {
mapped[key] = value;
}
}
+ // console.error(mapped);
if (patterns.length === Object.keys(mapped).length) {
declarations = new Map();
for (const key of patterns) {
@@ -20337,8 +20365,6 @@
}
return acc;
}, []);
- // console.error({hasMapping, shorthand: this.config.shorthand, requiredCount, isShorthand,
- // declarations: declarations.values(), values});
if (this.config.mapping != null) {
const val = values.reduce((acc, curr) => acc +
renderValue(curr, {
@@ -20375,6 +20401,7 @@
}
}
const iterators = [];
+ // @ts-ignore
return {
// @ts-ignore
next() {
@@ -20627,6 +20654,9 @@
}
const config = getConfig();
+ /**
+ * Represents a list of property declarations, compute shorthand and remove duplicate declarations.
+ */
class PropertyList {
options = { removeDuplicateDeclarations: true, computeShorthand: true };
declarations;
@@ -20701,28 +20731,35 @@
// @ts-ignore
shorthand = config.property[propertyName];
}
- // console.error({shortHandType, propertyName, config: config.map[propertyName], map: config.map[shorthand].properties[propertyName]});
// @ts-ignore
if (shortHandType == "map") {
let owner = this;
+ const mapName =
// @ts-ignore
- const mapName = config.map[propertyName]?.map ?? config.map[shorthand]?.properties?.[propertyName]?.map;
+ config.map[propertyName]?.map ?? config.map[shorthand]?.properties?.[propertyName]?.map;
if (typeof mapName === "string") {
if (!this.declarations.has(mapName)) {
// @ts-ignore
this.declarations.set(mapName, new PropertyMap(config.map[mapName]));
}
owner = this.declarations.get(mapName);
- // console.error({mapName});
}
- // @ts-ignore
- if (!owner.declarations.has(shorthand)) {
+ else if (!this.declarations.has(shorthand)) {
// @ts-ignore
- owner.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ }
+ if (owner == this) {
+ // @ts-ignore
+ owner.declarations.get(shorthand).add(declaration);
+ }
+ else {
+ if (!owner.declarations.has(shorthand)) {
+ // @ts-ignore
+ owner.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ }
+ // @ts-ignore
+ owner.declarations.get(shorthand).add(declaration);
}
- // console.error({propertyName,mapName, owned: owner == this});
- // @ts-ignore
- owner.declarations.get(shorthand).add(declaration);
}
// @ts-ignore
else if (shortHandType == "set") {
@@ -20809,7 +20846,7 @@
[Symbol.iterator]() {
let iterator = this.declarations.values();
const iterators = [];
- // console.error(this);
+ // @ts-ignore
return {
next() {
let value = iterator.next();
@@ -20840,7 +20877,7 @@
exports.EnumToken.KeyframesRuleNodeType,
]);
get ordering() {
- return 10;
+ return 5;
}
get processMode() {
return exports.FeatureWalkMode.Post;
@@ -20859,7 +20896,6 @@
const j = ast.chi.length;
let k = 0;
let l;
- // let properties: PropertyList = new PropertyList(options);
const rules = [];
const declarations = [];
// @ts-ignore
@@ -20880,7 +20916,6 @@
if (node.typ == exports.EnumToken.DeclarationNodeType) {
for (let m = k; m <= l; m++) {
declarations.push(ast.chi[m]);
- // properties.add(ast.chi![m]);
}
}
else {
@@ -20890,7 +20925,6 @@
}
k = l;
}
- // console.error([...new PropertyList(options).add(declarations)]);
if (declarations.length > 0) {
ast.chi.length = 0;
// @ts-expect-error
@@ -21001,7 +21035,7 @@
class ComputeCalcExpressionFeature {
accept = new Set([exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType]);
get ordering() {
- return 1;
+ return 3;
}
get processMode() {
return exports.FeatureWalkMode.Post;
@@ -21026,8 +21060,20 @@
continue;
}
if (value.typ == exports.EnumToken.BinaryExpressionTokenType) {
- // @ts-ignore
- replaceNodeOrValue(parent, value, evaluate([value]));
+ const result = evaluate([value]);
+ try {
+ // @ts-ignore
+ replaceNodeOrValue(parent, value, result);
+ }
+ catch (e) {
+ // @ts-ignore
+ if (Array.isArray(parent.chi)) {
+ // @ts-ignore
+ parent.chi.length = 0;
+ // @ts-ignore
+ parent.chi.push(...result);
+ }
+ }
continue;
}
if (value != null && tokensfuncSet.has(value.typ)) {
@@ -21045,7 +21091,7 @@
? value.val
: value.chi;
const values = evaluate(cp);
- // fix a + -b to a - b
+ // fix a + -b into a - b
for (const { value, parent: p } of walkValues(values)) {
if (value.typ === exports.EnumToken.BinaryExpressionTokenType) {
if (value.op === exports.EnumToken.Add &&
@@ -22311,7 +22357,7 @@
exports.EnumToken.KeyframesRuleNodeType,
]);
get ordering() {
- return 3;
+ return 4;
}
get processMode() {
return exports.FeatureWalkMode.Post;
@@ -22714,7 +22760,7 @@
class ExpandIfFeature {
accept = new Set([exports.EnumToken.DeclarationNodeType]);
get ordering() {
- return 4;
+ return 1;
}
get processMode() {
return exports.FeatureWalkMode.Pre;
@@ -23516,7 +23562,8 @@
previous = node;
nodeIndex = i;
}
- if (recursive && node != null && "chi" in node) {
+ // @ts-ignore
+ if (recursive && node != null && node.chi != null) {
if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType ||
!node.chi.some((n) => n.typ == exports.EnumToken.DeclarationNodeType)) {
if (!(node.typ == exports.EnumToken.AtRuleNodeType && node.nam != "font-face")) {
@@ -25349,6 +25396,7 @@
removeEmpty: false,
removeComments: false,
}),
+ minifyValues: true,
sourcemap: false,
convertColor: true,
expandNestingRules: false,
@@ -25588,7 +25636,7 @@
const indentSub = indents[level + 1];
switch (data.typ) {
case exports.EnumToken.DeclarationNodeType:
- return `${data.nam}:${options.indent}${(options.minify
+ return `${data.nam}:${options.indent}${(options.minifyValues
? filterValues(data.val)
: data.val).reduce(reducer, "")}`;
case exports.EnumToken.CommentNodeType:
@@ -25643,7 +25691,7 @@
: node.val;
}
else if (node.typ == exports.EnumToken.DeclarationNodeType) {
- str = `${node.nam}:${options.indent}${(options.minify
+ str = `${node.nam}:${options.indent}${(options.minifyValues
? filterValues(node.val)
: node.val)
.reduce(reducer, "")
@@ -25711,9 +25759,10 @@
function renderValue(token, options = {}, cache = Object.create(null), reducer, errors) {
if (token.typ === exports.EnumToken.WhenElseFunctionTokenType &&
equalsIgnoreCase(token.val, "supports")) {
- options = { ...options, minify: false, convertColor: false };
+ options = { ...options, minifyValues: false, minify: false, convertColor: false };
reducer = null;
}
+ options.minifyValues ??= options.minify;
if (reducer == null) {
reducer = function (acc, curr) {
if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
@@ -25870,7 +25919,7 @@
")");
}
case exports.EnumToken.UrlFunctionTokenType:
- if (options.minify && token.typ === exports.EnumToken.UrlFunctionTokenType) {
+ if (options.minifyValues && token.typ === exports.EnumToken.UrlFunctionTokenType) {
if (token.chi[0]?.typ === exports.EnumToken.BadUrlTokenType) {
return "url()";
}
@@ -25891,7 +25940,7 @@
case exports.EnumToken.FunctionTokenType:
case exports.EnumToken.MathFunctionTokenType:
case exports.EnumToken.ImageFunctionTokenType:
- if (options.minify && token.typ === exports.EnumToken.ImageFunctionTokenType) {
+ if (options.minifyValues && token.typ === exports.EnumToken.ImageFunctionTokenType) {
const slice = token.chi.slice();
switch (token.val) {
case "linear-gradient":
@@ -26377,37 +26426,7 @@
renderValue(curr, token.typ == exports.EnumToken.FunctionTokenType ? { minify: false } : options, cache, reducer), "") +
")");
}
- return (
- /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/ (token.val ?? "") +
- "(" +
- token.chi.reduce(reducer, "") +
- ")");
- // case EnumToken.MatchExpressionTokenType:
- // return (
- // renderValue((token as MatchExpressionToken).l as Token, options, cache, reducer, errors) +
- // renderValue((token as MatchExpressionToken).op, options, cache, reducer, errors) +
- // renderValue((token as MatchExpressionToken).r, options, cache, reducer, errors) +
- // ((token as MatchExpressionToken).attr ? " " + (token as MatchExpressionToken).attr : "")
- // );
- // case EnumToken.NameSpaceAttributeTokenType:
- // return (
- // ((token as NameSpaceAttributeToken).l == null
- // ? ""
- // : renderValue((token as NameSpaceAttributeToken).l as Token, options, cache, reducer, errors)) +
- // "|" +
- // renderValue((token as NameSpaceAttributeToken).r, options, cache, reducer, errors)
- // );
- // case EnumToken.ComposesSelectorNodeType:
- // return (
- // (token as ComposesSelectorToken).l.reduce(
- // (acc: string, curr: Token) => acc + renderValue(curr, options, cache),
- // "",
- // ) +
- // ((token as ComposesSelectorToken).r == null
- // ? ""
- // : " from " +
- // renderValue((token as ComposesSelectorToken).r as Token, options, cache, reducer, errors))
- // );
+ return (token.val ?? "") + "(" + token.chi.reduce(reducer, "") + ")";
case exports.EnumToken.BlockStartTokenType:
return "{";
case exports.EnumToken.BlockEndTokenType:
@@ -26556,7 +26575,11 @@
const perc = token.val.typ == exports.EnumToken.FractionTokenType
? renderValue(token.val, options, cache)
: minifyNumber(token.val);
- return options.minify && perc == "0" ? "0" : perc.includes("/") ? perc.replace("/", uni + "/") : perc + uni;
+ return options.minifyValues && perc == "0"
+ ? "0"
+ : perc.includes("/")
+ ? perc.replace("/", uni + "/")
+ : perc + uni;
case exports.EnumToken.NumberTokenType:
return token.val.typ == exports.EnumToken.FractionTokenType
? renderValue(token.val, options, cache)
@@ -26621,7 +26644,7 @@
case exports.EnumToken.DeclarationNodeType:
return (token.nam +
":" +
- (options.minify ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderValue(curr, options, cache), ""));
+ (options.minifyValues ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderValue(curr, options, cache), ""));
case exports.EnumToken.MediaQueryUnaryFeatureTokenType:
return (renderValue(token.l, options, cache, reducer) +
" " +
@@ -26695,6 +26718,7 @@
}
const SymbolsMapTokens = Object.create(null);
+ const SymbolsMapTokensLower = Object.create(null);
// Regex for escape sequence decoding - compile once, reuse many times
const ESCAPE_SEQUENCE_REGEX = /\\((\n|\r|\f|\v|\u2028|\u2029|([0-9a-fA-F]{1,6})) ?)/gms;
function decodeEscapeSequences(value) {
@@ -26723,7 +26747,9 @@
}
function assignTokenMap(entries, tokenType, suffix = "", lowercase = false) {
for (const entry of entries) {
- SymbolsMapTokens[(lowercase ? entry.toLowerCase() : entry) + suffix] = tokenType;
+ const key = (lowercase ? entry.toLowerCase() : entry) + suffix;
+ SymbolsMapTokens[key] = tokenType;
+ SymbolsMapTokensLower[key.toLowerCase()] = tokenType;
}
}
SymbolsMapTokens[""] = exports.EnumToken.DelimTokenType;
@@ -26823,20 +26849,24 @@
})(TokenMap || (TokenMap = {}));
function getSymbolHint(parseInfo, start, end) {
const len = end - start;
- const keysLength = SymbolsMapTokensKeys.length;
- // Early exit for impossible lengths
- if (len < 0)
+ if (len <= 0)
return null;
+ const value = parseInfo.stream.slice(start, end);
+ // Direct lookup handles the hottest punctuation and keyword cases without
+ // scanning the entire symbol table on every token.
+ const match = SymbolsMapTokens[value] ?? SymbolsMapTokensLower[value.toLowerCase()];
+ if (match != null) {
+ return match;
+ }
+ const keysLength = SymbolsMapTokensKeys.length;
for (let i = 0; i < keysLength; i++) {
const key = SymbolsMapTokensKeys[i];
if (key.length !== len)
continue;
- // Match character by character
let match = true;
for (let j = 0; j < len; j++) {
let ca = key.charCodeAt(j);
- let cb = parseInfo.stream.charCodeAt(start + j);
- // Normalize A-Z to a-z
+ let cb = value.charCodeAt(j);
if (ca >= 65 && ca <= 90)
ca += 32;
if (cb >= 65 && cb <= 90)
@@ -26854,32 +26884,29 @@
}
function searchArray(array, parseInfo, start, end) {
const len = end - start;
- // Early exit for impossible lengths
- if (len < 0)
+ if (len <= 0)
return null;
- // Use a simple linear search optimized with length pre-filtering
- let i = array.length;
- while (i--) {
- if (array[i].length !== len)
+ let match;
+ let item;
+ for (let i = 0; i < array.length; i++) {
+ item = array[i];
+ if (item.length !== len)
continue;
- // Match character by character
- let match = true;
- const arrayItem = array[i];
+ match = true;
for (let j = 0; j < len; j++) {
- let ca = arrayItem.charCodeAt(j);
- let cb = parseInfo.stream.charCodeAt(start + j);
- // Normalize A-Z to a-z
+ let ca = parseInfo.stream.charCodeAt(start + j);
+ let cb = item.charCodeAt(j);
if (ca >= 65 && ca <= 90)
ca += 32;
if (cb >= 65 && cb <= 90)
cb += 32;
- if (ca != cb) {
+ if (ca !== cb) {
match = false;
break;
}
}
if (match) {
- return arrayItem;
+ return item;
}
}
return null;
@@ -27817,23 +27844,6 @@
}
return true;
}
- /**
- *
- * @param parseInfo
- * @returns
- */
- // isPseudo(parseInfo: ParseInfo): boolean {
- // let position: number = parseInfo.currentPosition - parseInfo.offset;
- // let endPosition: number = parseInfo.currentPosition - parseInfo.offset;
- // return (parseInfo.stream.charAt(position) == ":" &&
- // parseInfo.stream.charAt(endPosition - 1) == "(" &&
- // (parseInfo.stream.charAt(position + 1) == ":"
- // ? this.isIdentToken(parseInfo, 2, -1)
- // : this.isIdentToken(parseInfo, 1, -1))) ||
- // parseInfo.stream.charAt(position + 1) == ":"
- // ? this.isIdentToken(parseInfo, 2)
- // : this.isIdentToken(parseInfo, 1);
- // }
/**
*
* @param parseInfo
@@ -27964,28 +27974,28 @@
// EOF
switch (charCode) {
case 61 /* TokenMap.EQUALS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.DelimTokenType);
// '+' or '-'
case 43 /* TokenMap.PLUS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
charCode = parseInfo.stream.charCodeAt(parseInfo.currentPosition - parseInfo.offset);
- if (isDigit(charCode)) {
- tokensCount = this.consumeNumericToken(parseInfo);
- if (tokensCount > 0) {
- this.advance(parseInfo, tokensCount);
- return this.makeToken(parseInfo, this.hint ?? exports.EnumToken.NumberTokenType, {
- slice: this.slice,
- sign: "+",
- });
- }
- }
+ // if (isDigit(charCode)) {
+ // tokensCount = this.consumeNumericToken(parseInfo);
+ // if (tokensCount > 0) {
+ // this.advance(parseInfo, tokensCount);
+ // return this.makeToken(parseInfo, this.hint ?? EnumToken.NumberTokenType, {
+ // slice: this.slice,
+ // sign: "+",
+ // });
+ // }
+ // }
return this.makeToken(parseInfo, exports.EnumToken.Plus);
case 45 /* TokenMap.MINUS */:
if (parseInfo.position == parseInfo.currentPosition) {
@@ -27995,15 +28005,17 @@
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.Sub);
}
- if (charCode == 45 /* TokenMap.MINUS */ &&
- (nextCharCode == 45 /* TokenMap.MINUS */ || isIdentStart(nextCharCode))) {
- this.advance(parseInfo);
- tokensCount = this.consumeIdentToken(parseInfo);
- if (tokensCount > 0) {
- this.advance(parseInfo, tokensCount);
- return this.makeToken(parseInfo, exports.EnumToken.IdenTokenType);
- }
- }
+ // if (
+ // charCode == TokenMap.MINUS &&
+ // (nextCharCode == TokenMap.MINUS || isIdentStart(nextCharCode))
+ // ) {
+ // this.advance(parseInfo);
+ // tokensCount = this.consumeIdentToken(parseInfo);
+ // if (tokensCount > 0) {
+ // this.advance(parseInfo, tokensCount);
+ // return this.makeToken(parseInfo, EnumToken.IdenTokenType);
+ // }
+ // }
}
this.advance(parseInfo);
break;
@@ -28056,28 +28068,28 @@
return this.makeToken(parseInfo, exports.EnumToken.EndParensTokenType);
// '['
case 91 /* TokenMap.LEFT_BRACKETS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.AttrStartTokenType);
// ']'
case 93 /* TokenMap.RIGHT_BRACKETS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.AttrEndTokenType);
case 59 /* TokenMap.SEMICOLON */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.SemiColonTokenType);
case 58 /* TokenMap.COLON */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
if (this.peekCharCode(parseInfo) == 58 /* TokenMap.COLON */) {
this.advance(parseInfo);
@@ -28109,15 +28121,15 @@
}
return this.makeToken(parseInfo, exports.EnumToken.WhitespaceTokenType);
case 44 /* TokenMap.COMMA */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.CommaTokenType);
case 36 /* TokenMap.DOLLAR */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "$=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.EndMatchTokenType);
@@ -28125,9 +28137,9 @@
this.advance(parseInfo);
break;
case 126 /* TokenMap.TILDA */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "~=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.IncludeMatchTokenType);
@@ -28136,9 +28148,9 @@
return this.makeToken(parseInfo, exports.EnumToken.Tilda);
// case '^':
case 94 /* TokenMap.CARET */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "^=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.StartMatchTokenType);
@@ -28146,9 +28158,9 @@
this.advance(parseInfo);
break;
case 42 /* TokenMap.STAR */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "*=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.ContainMatchTokenType);
@@ -28162,9 +28174,9 @@
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.NestingSelectorTokenType);
case 124 /* TokenMap.PIPE */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
// '||'
if (this.match(parseInfo, "||")) {
this.advance(parseInfo, 2);
@@ -28187,9 +28199,9 @@
this.advance(parseInfo);
break;
case 47 /* TokenMap.SLASH */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (!this.match(parseInfo, "/*")) {
this.advance(parseInfo);
return this.makeToken(parseInfo, getSymbolHint(parseInfo, parseInfo.position - parseInfo.offset, parseInfo.currentPosition - parseInfo.offset));
@@ -28208,9 +28220,9 @@
}
break;
case 62 /* TokenMap.GREATERTHAN */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, ">=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.GteTokenType);
@@ -28249,20 +28261,11 @@
this.advance(parseInfo);
break;
case 92 /* TokenMap.REVERSE_SOLIDUS */:
- // if (!yieldEOFToken && parseInfo.stream.length == parseInfo.currentPosition - parseInfo.offset + 1) {
- // break;
- // }
this.advance(parseInfo);
// EOF
- if (!this.peek(parseInfo)) {
- // if (!yieldEOFToken) {
- // break;
- // }
- // end of stream ignore \\
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
- break;
+ // end of stream ignore \\
+ if (!this.peek(parseInfo) && parseInfo.position < parseInfo.currentPosition) {
+ return this.makeToken(parseInfo);
}
this.advance(parseInfo);
break;
@@ -28275,9 +28278,9 @@
case 46 /* TokenMap.DOT */:
const codepoint = parseInfo.stream.charCodeAt(parseInfo.currentPosition - parseInfo.offset + 1);
if (isIdentStart(codepoint) || codepoint == 45 /* TokenMap.MINUS */) {
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
let tokensCount = this.consumeIdentToken(parseInfo);
if (tokensCount > 0) {
@@ -28285,27 +28288,22 @@
return this.makeToken(parseInfo, exports.EnumToken.ClassSelectorTokenType);
}
}
- if (!isDigit(codepoint) && parseInfo.position !== parseInfo.currentPosition) {
- this.makeToken(parseInfo);
- this.advance(parseInfo, 2);
- return this;
- }
+ // if (!isDigit(codepoint) && parseInfo.position !== parseInfo.currentPosition) {
+ // this.makeToken(parseInfo);
+ // this.advance(parseInfo, 2);
+ // return this;
+ // }
this.advance(parseInfo);
break;
default:
this.advance(parseInfo);
break;
}
- // if (!yieldEOFToken && endPosition <= parseInfo.currentPosition - parseInfo.offset + 1) {
- // break;
- // }
}
- // if (yieldEOFToken) {
if (parseInfo.position < parseInfo.currentPosition) {
return this.makeToken(parseInfo);
}
return this.makeToken(parseInfo, exports.EnumToken.EOFTokenType);
- // }
}
/**
* tokenize readable stream
@@ -31079,6 +31077,7 @@
if (options.expandNestingRules) {
options.nestingRules = false;
}
+ options.minifyAST ??= options.minify;
const startTime = performance.now();
const errors = [];
const stack = [];
@@ -31458,7 +31457,7 @@
}
}
}
- if (options.minify) {
+ if (options.minifyAST) {
if (ast.chi.length > 0) {
let passes = options.pass ?? 1;
while (passes--) {
@@ -31998,6 +31997,7 @@
lenient: true,
...options,
};
+ options.minifyAST ??= options.minify;
if (typeof options.validation !== "boolean") {
options.validation = !!options.validation;
}
@@ -32452,7 +32452,7 @@
}
}
}
- if (options.minify) {
+ if (options.minifyAST) {
if (ast.chi.length > 0) {
let passes = options.pass ?? 1;
while (passes--) {
@@ -34842,6 +34842,7 @@
});
}
+ exports.PropertyList = PropertyList;
exports.SourceMap = SourceMap;
exports.cloneNode = cloneNode;
exports.convertColor = convertColor;
diff --git a/dist/index.cjs b/dist/index.cjs
index c9475aa67..1c95d5ec5 100644
--- a/dist/index.cjs
+++ b/dist/index.cjs
@@ -6432,6 +6432,11 @@ const anglePrecision = 3;
* Color range definitions
*/
const colorRange = {
+ rgb: {
+ r: [0, 255],
+ g: [0, 255],
+ b: [0, 255],
+ },
lab: {
l: [0, 100],
a: [-125, 125],
@@ -6901,13 +6906,6 @@ function equalsIgnoreCase(a, b) {
}
function getColorComponents(token) {
- // if (token.typ === EnumToken.IdenTokenType) {
- // if (isColor(token)) {
- // parseColor(token);
- // } else {
- // return null;
- // }
- // }
if (token.kin == exports.ColorType.HEX || token.kin == exports.ColorType.LIT) {
if (equalsIgnoreCase("currentcolor", token.val)) {
return null;
@@ -6931,25 +6929,12 @@ function getColorComponents(token) {
].includes(child.typ)) {
continue;
}
- // if (child.typ === EnumToken.IdenTokenType && isColor(child)) {
- // parseColor(child);
- // }
if (child.typ === exports.EnumToken.FunctionTokenType ||
child.typ === exports.EnumToken.WildCardFunctionTokenType ||
child.typ === exports.EnumToken.MathFunctionTokenType) {
if ("var" == child.val.toLowerCase()) {
return null;
}
- // else {
- // for (const { value } of walkValues((child as FunctionToken).chi)) {
- // if (
- // value.typ == EnumToken.WildCardFunctionTokenDefType &&
- // "var" === (value as FunctionToken).val.toLowerCase()
- // ) {
- // return null;
- // }
- // }
- // }
}
if (child.typ == exports.EnumToken.ColorTokenType && equalsIgnoreCase("currentcolor", child.val)) {
return null;
@@ -8245,7 +8230,10 @@ function color2HexToken(token) {
if (value == null) {
return null;
}
- return hexToken(value.reduce((acc, curr) => acc + srgb2rgb(curr + Number.EPSILON).toString(16).padStart(2, "0"), "#"));
+ return hexToken(value.reduce((acc, curr) => acc +
+ srgb2rgb(curr + Number.EPSILON)
+ .toString(16)
+ .padStart(2, "0"), "#"));
}
function oklab2HexToken(token) {
let value = oklab2srgbvalues(token);
@@ -9094,7 +9082,7 @@ function la98rgb2a98rgb(r, g, b, a = null) {
// convert an array of linear-light a98-rgb in the range 0.0-1.0
// to gamma corrected form
// negative values are also now accepted
- return [r, b, g]
+ return [r, g, b]
.map(function (val) {
let sign = val < 0 ? -1 : 1;
let abs = Math.abs(val);
@@ -9230,6 +9218,9 @@ function colorMix(...args) {
if (values == null) {
return null;
}
+ if (colorSpace == "hwb") {
+ colorSpace = "srgb";
+ }
switch (colorSpace) {
case "srgb":
break;
@@ -9259,17 +9250,17 @@ function colorMix(...args) {
values = srgb2xyz_d65(values[0], values[1], values[2], values[3]);
values = XYZ_D65_to_D50(values[0], values[1], values[2], values[3]);
break;
- case "rgb":
- for (let j = 0; j < values.length; j++) {
- values[j] = j == 3 ? values[j] : srgb2rgb(values[j]);
- }
- break;
+ // case "rgb":
+ // for (let j = 0; j < values.length; j++) {
+ // values[j] = j == 3 ? values[j] : srgb2rgb(values[j]);
+ // }
+ // break;
case "hsl":
values = srgb2hslvalues(values[0], values[1], values[2], values[3]);
break;
- case "hwb":
- values = srgb2hwb(values[0], values[1], values[2], values[3]);
- break;
+ // case "hwb":
+ // values = srgb2hwb(values[0], values[1], values[2], values[3]);
+ // break;
case "lab":
values = srgb2labvalues(values[0], values[1], values[2], values[3]);
break;
@@ -9468,14 +9459,14 @@ function colorMix(...args) {
kin: exports.ColorType.COLOR,
cal: "col",
};
- case "rgb":
+ // case "rgb":
case "hsl":
- case "hwb":
+ // case "hwb":
case "lab":
case "lch":
case "oklab":
case "oklch":
- if (colorSpace == "hsl" || colorSpace == "hwb") {
+ if (colorSpace == "hsl") {
// @ts-ignore
if (values[2] < 0) {
// @ts-ignore
@@ -9505,7 +9496,7 @@ function colorMix(...args) {
}),
kin: exports.ColorType[colorSpace.toUpperCase().replaceAll("-", "_")],
};
- if (colorSpace == "hsl" || colorSpace == "hwb") {
+ if (colorSpace == "hsl") {
// @ts-ignore
result.chi[0] = { typ: exports.EnumToken.AngleTokenType, val: result.chi[0].val * 360 };
// @ts-ignore
@@ -10100,6 +10091,7 @@ function evaluate(tokens) {
[LOCSRCID]: nodes[0][LOCSRCID],
[LOCSTA]: nodes[0][LOCSTA],
[LOCEND]: nodes[0][LOCEND],
+ [PARENT]: nodes[0][PARENT],
},
];
}
@@ -10122,6 +10114,7 @@ function evaluate(tokens) {
[LOCSRCID]: nodes[i][LOCSRCID],
[LOCSTA]: nodes[i][LOCSTA],
[LOCEND]: nodes[i + 1][LOCEND],
+ [PARENT]: nodes[i + 1][PARENT],
};
}
else {
@@ -10131,6 +10124,7 @@ function evaluate(tokens) {
[LOCSRCID]: nodes[i + 1][LOCSRCID],
[LOCSTA]: nodes[i + 1][LOCSTA],
[LOCEND]: nodes[i + 1][LOCEND],
+ [PARENT]: nodes[i + 1][PARENT],
}, exports.EnumToken.Mul);
}
i++;
@@ -10151,12 +10145,14 @@ function evaluate(tokens) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
}, {
...token,
val: -token.val,
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
return acc;
}
@@ -10167,6 +10163,7 @@ function evaluate(tokens) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
}
acc.push(token);
@@ -10188,6 +10185,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: r?.[LOCEND] ?? l[LOCEND],
+ [PARENT]: l[PARENT],
};
if (!isScalarToken(l) || !isScalarToken(r) || (l.typ == r.typ && "unit" in l && "unit" in r && l.unit != r.unit)) {
return defaultReturn;
@@ -10260,6 +10258,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: l[LOCEND],
+ [PARENT]: l[PARENT],
},
r: {
typ: exports.EnumToken.NumberTokenType,
@@ -10267,6 +10266,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: r[LOCSRCID],
[LOCSTA]: r[LOCSTA],
[LOCEND]: r[LOCEND],
+ [PARENT]: r[PARENT],
},
};
}
@@ -10279,6 +10279,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: l[LOCEND],
+ [PARENT]: l[PARENT],
},
r: {
typ: exports.EnumToken.NumberTokenType,
@@ -10286,6 +10287,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: r[LOCSRCID],
[LOCSTA]: r[LOCSTA],
[LOCEND]: r[LOCEND],
+ [PARENT]: r[PARENT],
},
};
}
@@ -10312,6 +10314,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: r?.[LOCEND] ?? l[LOCEND],
+ [PARENT]: l[PARENT],
};
if (token.typ == exports.EnumToken.IdenTokenType) {
// @ts-ignore
@@ -10492,6 +10495,7 @@ function evaluateFunc(token) {
[LOCSRCID]: value[0][LOCSRCID],
[LOCSTA]: value[0][LOCSTA],
[LOCEND]: value[0][LOCEND],
+ [PARENT]: value[0][PARENT],
}
: {
typ: token.val == "sign" ? exports.EnumToken.NumberTokenType : value[0].typ,
@@ -10499,6 +10503,7 @@ function evaluateFunc(token) {
[LOCSRCID]: value[0][LOCSRCID],
[LOCSTA]: value[0][LOCSTA],
[LOCEND]: value[0][LOCEND],
+ [PARENT]: value[0][PARENT],
},
];
}
@@ -10521,6 +10526,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10594,6 +10600,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10608,6 +10615,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10618,6 +10626,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10657,6 +10666,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10699,6 +10709,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -10726,6 +10737,7 @@ function inlineExpression$1(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
for (const child of inlineExpression$1(token.r)) {
result.push(child);
@@ -10805,6 +10817,7 @@ function factorToken(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
};
// @ts-ignore
delete token.val;
@@ -10846,6 +10859,7 @@ function factor(tokens, ops) {
[LOCSRCID]: tokens[i - 1][LOCSRCID],
[LOCSTA]: tokens[i - 1][LOCSTA],
[LOCEND]: tokens[i + 1][LOCEND],
+ [PARENT]: tokens[i + 1][PARENT],
});
i--;
}
@@ -10891,20 +10905,20 @@ function parseRelativeColorComponents(relativeKeys, original, rExp, gExp, bExp,
continue;
}
if (component.typ == exports.EnumToken.IdenTokenType) {
- val = component.val.toLowerCase();
+ val = component.val;
if (
// @ts-expect-error
typeof Math[val.toUpperCase()] !== "number" &&
- val != "in" &&
- val != "hue" &&
- val != "from" &&
- val != "alpha" &&
- val != "none" &&
- val != "shorter" &&
- val != "longer" &&
- val != "increasing" &&
- val != "decreasing" &&
- !colorsFunc.includes(val) &&
+ !equalsIgnoreCase(val, "in") &&
+ !equalsIgnoreCase(val, "hue") &&
+ !equalsIgnoreCase(val, "from") &&
+ !equalsIgnoreCase(val, "alpha") &&
+ !equalsIgnoreCase(val, "none") &&
+ !equalsIgnoreCase(val, "shorter") &&
+ !equalsIgnoreCase(val, "longer") &&
+ !equalsIgnoreCase(val, "increasing") &&
+ !equalsIgnoreCase(val, "decreasing") &&
+ !colorsFunc.some((t) => equalsIgnoreCase(t, val)) &&
!colorFuncColorSpace.includes(val) &&
!validKeys.includes(val)) {
return null;
@@ -12808,7 +12822,8 @@ function matchAllSyntaxes(syntaxes, context, options) {
for (let i = index; i < syntaxes.length; i++) {
if (syntaxes[i].typ == ValidationTokenEnum.Whitespace ||
syntaxes[i].isOptional ||
- syntaxes[i].isRepeatable) {
+ syntaxes[i].isRepeatable ||
+ syntaxes[i].match?.min?.val === 0) {
continue;
}
return {
@@ -14513,7 +14528,6 @@ function alpha(color, alpha) {
}
let components = getColorComponents(color);
if (alpha.typ === exports.EnumToken.MathFunctionTokenType) {
- const originalAlpha = cloneNode(alpha, true);
for (const { value } of walkValues(alpha.chi, alpha)) {
if (value.typ === exports.EnumToken.IdenTokenType) {
if (equalsIgnoreCase(value.val, "alpha")) {
@@ -14525,22 +14539,22 @@ function alpha(color, alpha) {
});
// continue;
}
- else if (equalsIgnoreCase(value.val, "none")) {
- Object.assign(value, {
- typ: exports.EnumToken.NumberTokenType,
- val: 0,
- });
- }
+ // else if (equalsIgnoreCase((value as IdentToken).val, "none")) {
+ // Object.assign(value, {
+ // typ: EnumToken.NumberTokenType,
+ // val: 0,
+ // });
+ // }
}
}
const result = evaluate([alpha]);
if (result.length == 1) {
alpha = result[0];
}
- else {
- // @ts-expect-error
- alpha = originalAlpha;
- }
+ // else {
+ // // @ts-expect-error
+ // alpha = originalAlpha;
+ // }
}
// console.error({ alpha });
if (alpha.typ !== exports.EnumToken.IdenTokenType &&
@@ -14566,17 +14580,17 @@ function alpha(color, alpha) {
return null;
}
if (alpha?.typ === exports.EnumToken.IdenTokenType) {
- if (equalsIgnoreCase(alpha.val, "alpha")) {
- alpha = components[3] ?? {
- typ: exports.EnumToken.NumberTokenType,
- val: 1,
- };
- }
- else if (equalsIgnoreCase(alpha.val, "node")) {
- alpha = {
+ // if (equalsIgnoreCase((alpha as IdentToken).val, "alpha")) {
+ // alpha = components[3] ?? {
+ // typ: EnumToken.NumberTokenType,
+ // val: 1,
+ // };
+ // } else
+ if (equalsIgnoreCase(alpha.val, "none")) {
+ Object.assign(alpha, {
typ: exports.EnumToken.NumberTokenType,
val: 0,
- };
+ });
}
}
return makeColor(color.kin, components, alpha);
@@ -15297,12 +15311,12 @@ function getColorSpace(color) {
// '\\'
const REVERSE_SOLIDUS = 0x5c;
const flexUnits = ["fr"];
-const frequencyUnits = ["hz", "khz"];
+const frequencyUnits = ["Hz", "kHz"];
const timeUnits = ["ms", "s"];
const angleUnits = ["rad", "turn", "deg", "grad"];
const resolutionUnits = ["dpi", "dpcm", "dppx", "x"];
const dimensionUnits = [
- "q",
+ "Q",
"cap",
"ch",
"cm",
@@ -16986,7 +17000,7 @@ function replaceAstNodes(tokens, root) {
}
class ComputePrefixFeature {
get ordering() {
- return 2;
+ return 0;
}
get processMode() {
return exports.FeatureWalkMode.Pre;
@@ -17430,10 +17444,10 @@ function replace(node, variableScope) {
class InlineCssVariablesFeature {
accept = new Set([exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType]);
get ordering() {
- return 0;
+ return 2;
}
get processMode() {
- return exports.FeatureWalkMode.Pre;
+ return exports.FeatureWalkMode.Post;
}
static register(options) {
if (options.inlineCssVariables) {
@@ -19683,8 +19697,8 @@ function matchType(val, properties) {
const propertiesConfig = getConfig();
class PropertyMap {
- config;
declarations;
+ config;
requiredCount;
pattern;
constructor(config) {
@@ -19698,7 +19712,7 @@ class PropertyMap {
}
add(declaration) {
if (declaration.nam == this.config.shorthand) {
- this.declarations = new Map();
+ this.declarations.clear();
this.declarations.set(declaration.nam, declaration);
this.matchTypes(declaration);
}
@@ -19714,23 +19728,17 @@ class PropertyMap {
if (this.declarations.has(this.config.shorthand)) {
const tokens = {};
const values = [];
- // @ts-ignore
- this.declarations
- .get(this.config.shorthand)
- // @ts-ignore
- .val.slice()
- .reduce((acc, curr) => {
+ const val = [[]];
+ for (const curr of this.declarations.get(this.config.shorthand).val) { // @ts-ignore
// @ts-ignore
if (separator != null && separator.typ == curr.typ && separator.val == curr.val) {
- acc.push([]);
- return acc;
+ val.push([]);
+ continue;
}
// @ts-ignore
- acc.at(-1).push(curr);
- return acc;
- }, [[]])
- // @ts-ignore
- .reduce((acc, list, current) => {
+ val.at(-1).push(curr);
+ }
+ for (let current = 0; current < val.length; current++) {
values.push(...this.pattern.reduce((acc, property) => {
// let current: number = 0;
const props = this.config.properties[property];
@@ -19745,9 +19753,7 @@ class PropertyMap {
// @ts-ignore
acc[i][PROPERTYNAME] == property ||
matchType(acc[i], props)) {
- if ("prefix" in props &&
- props.previous != null &&
- !(props.previous in tokens)) {
+ if ("prefix" in props && props.previous != null && !(props.previous in tokens)) {
return acc;
}
if (!(property in tokens)) {
@@ -19812,9 +19818,8 @@ class PropertyMap {
}
}
return acc;
- }, list));
- return values;
- }, []);
+ }, val[current]));
+ }
if (values.length == 0) {
this.declarations = Object.entries(tokens).reduce((acc, curr) => {
acc.set(curr[0], {
@@ -19874,17 +19879,40 @@ class PropertyMap {
}
if (hasMapping) {
const mapped = {};
- for (const key of declarations.keys()) {
- const value = declarations.get(key);
+ let key;
+ for (const value of declarations.values()) {
+ key = value.nam;
if (value instanceof PropertyMap) {
for (const [k, v] of value.declarations) {
- mapped[k] = v;
+ if (k == value.config.shorthand) {
+ for (const [key, val] of Object.entries(value.config.properties)) {
+ mapped[key] = cloneNode(v);
+ for (let i = 0; i < v.val.length; i++) {
+ // @ts-ignore
+ if (key == v.val[i][PROPERTYNAME]) {
+ if (mapped[key].val.length > 0) {
+ mapped[key].val.push({
+ typ: exports.EnumToken.WhitespaceTokenType,
+ });
+ }
+ mapped[key].val.push(v.val[i]);
+ }
+ }
+ if (mapped[key].val.length == 0) {
+ mapped[key].val.push(...parseString(value.config.properties[key].default[0]));
+ }
+ }
+ }
+ else {
+ mapped[k] = v;
+ }
}
}
else {
mapped[key] = value;
}
}
+ // console.error(mapped);
if (patterns.length === Object.keys(mapped).length) {
declarations = new Map();
for (const key of patterns) {
@@ -20340,8 +20368,6 @@ class PropertyMap {
}
return acc;
}, []);
- // console.error({hasMapping, shorthand: this.config.shorthand, requiredCount, isShorthand,
- // declarations: declarations.values(), values});
if (this.config.mapping != null) {
const val = values.reduce((acc, curr) => acc +
renderValue(curr, {
@@ -20378,6 +20404,7 @@ class PropertyMap {
}
}
const iterators = [];
+ // @ts-ignore
return {
// @ts-ignore
next() {
@@ -20630,6 +20657,9 @@ function syncHash(input, length = 6, algo) {
}
const config = getConfig();
+/**
+ * Represents a list of property declarations, compute shorthand and remove duplicate declarations.
+ */
class PropertyList {
options = { removeDuplicateDeclarations: true, computeShorthand: true };
declarations;
@@ -20704,28 +20734,35 @@ class PropertyList {
// @ts-ignore
shorthand = config.property[propertyName];
}
- // console.error({shortHandType, propertyName, config: config.map[propertyName], map: config.map[shorthand].properties[propertyName]});
// @ts-ignore
if (shortHandType == "map") {
let owner = this;
+ const mapName =
// @ts-ignore
- const mapName = config.map[propertyName]?.map ?? config.map[shorthand]?.properties?.[propertyName]?.map;
+ config.map[propertyName]?.map ?? config.map[shorthand]?.properties?.[propertyName]?.map;
if (typeof mapName === "string") {
if (!this.declarations.has(mapName)) {
// @ts-ignore
this.declarations.set(mapName, new PropertyMap(config.map[mapName]));
}
owner = this.declarations.get(mapName);
- // console.error({mapName});
}
- // @ts-ignore
- if (!owner.declarations.has(shorthand)) {
+ else if (!this.declarations.has(shorthand)) {
// @ts-ignore
- owner.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ }
+ if (owner == this) {
+ // @ts-ignore
+ owner.declarations.get(shorthand).add(declaration);
+ }
+ else {
+ if (!owner.declarations.has(shorthand)) {
+ // @ts-ignore
+ owner.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ }
+ // @ts-ignore
+ owner.declarations.get(shorthand).add(declaration);
}
- // console.error({propertyName,mapName, owned: owner == this});
- // @ts-ignore
- owner.declarations.get(shorthand).add(declaration);
}
// @ts-ignore
else if (shortHandType == "set") {
@@ -20812,7 +20849,7 @@ class PropertyList {
[Symbol.iterator]() {
let iterator = this.declarations.values();
const iterators = [];
- // console.error(this);
+ // @ts-ignore
return {
next() {
let value = iterator.next();
@@ -20843,7 +20880,7 @@ class ComputeShorthandFeature {
exports.EnumToken.KeyframesRuleNodeType,
]);
get ordering() {
- return 10;
+ return 5;
}
get processMode() {
return exports.FeatureWalkMode.Post;
@@ -20862,7 +20899,6 @@ class ComputeShorthandFeature {
const j = ast.chi.length;
let k = 0;
let l;
- // let properties: PropertyList = new PropertyList(options);
const rules = [];
const declarations = [];
// @ts-ignore
@@ -20883,7 +20919,6 @@ class ComputeShorthandFeature {
if (node.typ == exports.EnumToken.DeclarationNodeType) {
for (let m = k; m <= l; m++) {
declarations.push(ast.chi[m]);
- // properties.add(ast.chi![m]);
}
}
else {
@@ -20893,7 +20928,6 @@ class ComputeShorthandFeature {
}
k = l;
}
- // console.error([...new PropertyList(options).add(declarations)]);
if (declarations.length > 0) {
ast.chi.length = 0;
// @ts-expect-error
@@ -21004,7 +21038,7 @@ function trimWhiteSpaceTokens(tokens) {
class ComputeCalcExpressionFeature {
accept = new Set([exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType]);
get ordering() {
- return 1;
+ return 3;
}
get processMode() {
return exports.FeatureWalkMode.Post;
@@ -21029,8 +21063,20 @@ class ComputeCalcExpressionFeature {
continue;
}
if (value.typ == exports.EnumToken.BinaryExpressionTokenType) {
- // @ts-ignore
- replaceNodeOrValue(parent, value, evaluate([value]));
+ const result = evaluate([value]);
+ try {
+ // @ts-ignore
+ replaceNodeOrValue(parent, value, result);
+ }
+ catch (e) {
+ // @ts-ignore
+ if (Array.isArray(parent.chi)) {
+ // @ts-ignore
+ parent.chi.length = 0;
+ // @ts-ignore
+ parent.chi.push(...result);
+ }
+ }
continue;
}
if (value != null && tokensfuncSet.has(value.typ)) {
@@ -21048,7 +21094,7 @@ class ComputeCalcExpressionFeature {
? value.val
: value.chi;
const values = evaluate(cp);
- // fix a + -b to a - b
+ // fix a + -b into a - b
for (const { value, parent: p } of walkValues(values)) {
if (value.typ === exports.EnumToken.BinaryExpressionTokenType) {
if (value.op === exports.EnumToken.Add &&
@@ -22314,7 +22360,7 @@ class TransformCssFeature {
exports.EnumToken.KeyframesRuleNodeType,
]);
get ordering() {
- return 3;
+ return 4;
}
get processMode() {
return exports.FeatureWalkMode.Post;
@@ -22717,7 +22763,7 @@ function processNode(declarationNode, cache) {
class ExpandIfFeature {
accept = new Set([exports.EnumToken.DeclarationNodeType]);
get ordering() {
- return 4;
+ return 1;
}
get processMode() {
return exports.FeatureWalkMode.Pre;
@@ -23519,7 +23565,8 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
previous = node;
nodeIndex = i;
}
- if (recursive && node != null && "chi" in node) {
+ // @ts-ignore
+ if (recursive && node != null && node.chi != null) {
if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType ||
!node.chi.some((n) => n.typ == exports.EnumToken.DeclarationNodeType)) {
if (!(node.typ == exports.EnumToken.AtRuleNodeType && node.nam != "font-face")) {
@@ -25352,6 +25399,7 @@ function doRender(data, options = {}, mapping) {
removeEmpty: false,
removeComments: false,
}),
+ minifyValues: true,
sourcemap: false,
convertColor: true,
expandNestingRules: false,
@@ -25591,7 +25639,7 @@ function renderAstNode(data, options, sourcemaps, sourceLocation, linesMap, erro
const indentSub = indents[level + 1];
switch (data.typ) {
case exports.EnumToken.DeclarationNodeType:
- return `${data.nam}:${options.indent}${(options.minify
+ return `${data.nam}:${options.indent}${(options.minifyValues
? filterValues(data.val)
: data.val).reduce(reducer, "")}`;
case exports.EnumToken.CommentNodeType:
@@ -25646,7 +25694,7 @@ function renderAstNode(data, options, sourcemaps, sourceLocation, linesMap, erro
: node.val;
}
else if (node.typ == exports.EnumToken.DeclarationNodeType) {
- str = `${node.nam}:${options.indent}${(options.minify
+ str = `${node.nam}:${options.indent}${(options.minifyValues
? filterValues(node.val)
: node.val)
.reduce(reducer, "")
@@ -25714,9 +25762,10 @@ function renderAstNode(data, options, sourcemaps, sourceLocation, linesMap, erro
function renderValue(token, options = {}, cache = Object.create(null), reducer, errors) {
if (token.typ === exports.EnumToken.WhenElseFunctionTokenType &&
equalsIgnoreCase(token.val, "supports")) {
- options = { ...options, minify: false, convertColor: false };
+ options = { ...options, minifyValues: false, minify: false, convertColor: false };
reducer = null;
}
+ options.minifyValues ??= options.minify;
if (reducer == null) {
reducer = function (acc, curr) {
if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
@@ -25873,7 +25922,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
")");
}
case exports.EnumToken.UrlFunctionTokenType:
- if (options.minify && token.typ === exports.EnumToken.UrlFunctionTokenType) {
+ if (options.minifyValues && token.typ === exports.EnumToken.UrlFunctionTokenType) {
if (token.chi[0]?.typ === exports.EnumToken.BadUrlTokenType) {
return "url()";
}
@@ -25894,7 +25943,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
case exports.EnumToken.FunctionTokenType:
case exports.EnumToken.MathFunctionTokenType:
case exports.EnumToken.ImageFunctionTokenType:
- if (options.minify && token.typ === exports.EnumToken.ImageFunctionTokenType) {
+ if (options.minifyValues && token.typ === exports.EnumToken.ImageFunctionTokenType) {
const slice = token.chi.slice();
switch (token.val) {
case "linear-gradient":
@@ -26380,37 +26429,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
renderValue(curr, token.typ == exports.EnumToken.FunctionTokenType ? { minify: false } : options, cache, reducer), "") +
")");
}
- return (
- /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/ (token.val ?? "") +
- "(" +
- token.chi.reduce(reducer, "") +
- ")");
- // case EnumToken.MatchExpressionTokenType:
- // return (
- // renderValue((token as MatchExpressionToken).l as Token, options, cache, reducer, errors) +
- // renderValue((token as MatchExpressionToken).op, options, cache, reducer, errors) +
- // renderValue((token as MatchExpressionToken).r, options, cache, reducer, errors) +
- // ((token as MatchExpressionToken).attr ? " " + (token as MatchExpressionToken).attr : "")
- // );
- // case EnumToken.NameSpaceAttributeTokenType:
- // return (
- // ((token as NameSpaceAttributeToken).l == null
- // ? ""
- // : renderValue((token as NameSpaceAttributeToken).l as Token, options, cache, reducer, errors)) +
- // "|" +
- // renderValue((token as NameSpaceAttributeToken).r, options, cache, reducer, errors)
- // );
- // case EnumToken.ComposesSelectorNodeType:
- // return (
- // (token as ComposesSelectorToken).l.reduce(
- // (acc: string, curr: Token) => acc + renderValue(curr, options, cache),
- // "",
- // ) +
- // ((token as ComposesSelectorToken).r == null
- // ? ""
- // : " from " +
- // renderValue((token as ComposesSelectorToken).r as Token, options, cache, reducer, errors))
- // );
+ return (token.val ?? "") + "(" + token.chi.reduce(reducer, "") + ")";
case exports.EnumToken.BlockStartTokenType:
return "{";
case exports.EnumToken.BlockEndTokenType:
@@ -26559,7 +26578,11 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
const perc = token.val.typ == exports.EnumToken.FractionTokenType
? renderValue(token.val, options, cache)
: minifyNumber(token.val);
- return options.minify && perc == "0" ? "0" : perc.includes("/") ? perc.replace("/", uni + "/") : perc + uni;
+ return options.minifyValues && perc == "0"
+ ? "0"
+ : perc.includes("/")
+ ? perc.replace("/", uni + "/")
+ : perc + uni;
case exports.EnumToken.NumberTokenType:
return token.val.typ == exports.EnumToken.FractionTokenType
? renderValue(token.val, options, cache)
@@ -26624,7 +26647,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
case exports.EnumToken.DeclarationNodeType:
return (token.nam +
":" +
- (options.minify ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderValue(curr, options, cache), ""));
+ (options.minifyValues ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderValue(curr, options, cache), ""));
case exports.EnumToken.MediaQueryUnaryFeatureTokenType:
return (renderValue(token.l, options, cache, reducer) +
" " +
@@ -26698,6 +26721,7 @@ function filterValues(values) {
}
const SymbolsMapTokens = Object.create(null);
+const SymbolsMapTokensLower = Object.create(null);
// Regex for escape sequence decoding - compile once, reuse many times
const ESCAPE_SEQUENCE_REGEX = /\\((\n|\r|\f|\v|\u2028|\u2029|([0-9a-fA-F]{1,6})) ?)/gms;
function decodeEscapeSequences(value) {
@@ -26726,7 +26750,9 @@ function decodeEscapeSequences(value) {
}
function assignTokenMap(entries, tokenType, suffix = "", lowercase = false) {
for (const entry of entries) {
- SymbolsMapTokens[(lowercase ? entry.toLowerCase() : entry) + suffix] = tokenType;
+ const key = (lowercase ? entry.toLowerCase() : entry) + suffix;
+ SymbolsMapTokens[key] = tokenType;
+ SymbolsMapTokensLower[key.toLowerCase()] = tokenType;
}
}
SymbolsMapTokens[""] = exports.EnumToken.DelimTokenType;
@@ -26826,20 +26852,24 @@ var TokenMap;
})(TokenMap || (TokenMap = {}));
function getSymbolHint(parseInfo, start, end) {
const len = end - start;
- const keysLength = SymbolsMapTokensKeys.length;
- // Early exit for impossible lengths
- if (len < 0)
+ if (len <= 0)
return null;
+ const value = parseInfo.stream.slice(start, end);
+ // Direct lookup handles the hottest punctuation and keyword cases without
+ // scanning the entire symbol table on every token.
+ const match = SymbolsMapTokens[value] ?? SymbolsMapTokensLower[value.toLowerCase()];
+ if (match != null) {
+ return match;
+ }
+ const keysLength = SymbolsMapTokensKeys.length;
for (let i = 0; i < keysLength; i++) {
const key = SymbolsMapTokensKeys[i];
if (key.length !== len)
continue;
- // Match character by character
let match = true;
for (let j = 0; j < len; j++) {
let ca = key.charCodeAt(j);
- let cb = parseInfo.stream.charCodeAt(start + j);
- // Normalize A-Z to a-z
+ let cb = value.charCodeAt(j);
if (ca >= 65 && ca <= 90)
ca += 32;
if (cb >= 65 && cb <= 90)
@@ -26857,32 +26887,29 @@ function getSymbolHint(parseInfo, start, end) {
}
function searchArray(array, parseInfo, start, end) {
const len = end - start;
- // Early exit for impossible lengths
- if (len < 0)
+ if (len <= 0)
return null;
- // Use a simple linear search optimized with length pre-filtering
- let i = array.length;
- while (i--) {
- if (array[i].length !== len)
+ let match;
+ let item;
+ for (let i = 0; i < array.length; i++) {
+ item = array[i];
+ if (item.length !== len)
continue;
- // Match character by character
- let match = true;
- const arrayItem = array[i];
+ match = true;
for (let j = 0; j < len; j++) {
- let ca = arrayItem.charCodeAt(j);
- let cb = parseInfo.stream.charCodeAt(start + j);
- // Normalize A-Z to a-z
+ let ca = parseInfo.stream.charCodeAt(start + j);
+ let cb = item.charCodeAt(j);
if (ca >= 65 && ca <= 90)
ca += 32;
if (cb >= 65 && cb <= 90)
cb += 32;
- if (ca != cb) {
+ if (ca !== cb) {
match = false;
break;
}
}
if (match) {
- return arrayItem;
+ return item;
}
}
return null;
@@ -27820,23 +27847,6 @@ class Tokenizer {
}
return true;
}
- /**
- *
- * @param parseInfo
- * @returns
- */
- // isPseudo(parseInfo: ParseInfo): boolean {
- // let position: number = parseInfo.currentPosition - parseInfo.offset;
- // let endPosition: number = parseInfo.currentPosition - parseInfo.offset;
- // return (parseInfo.stream.charAt(position) == ":" &&
- // parseInfo.stream.charAt(endPosition - 1) == "(" &&
- // (parseInfo.stream.charAt(position + 1) == ":"
- // ? this.isIdentToken(parseInfo, 2, -1)
- // : this.isIdentToken(parseInfo, 1, -1))) ||
- // parseInfo.stream.charAt(position + 1) == ":"
- // ? this.isIdentToken(parseInfo, 2)
- // : this.isIdentToken(parseInfo, 1);
- // }
/**
*
* @param parseInfo
@@ -27967,28 +27977,28 @@ class Tokenizer {
// EOF
switch (charCode) {
case 61 /* TokenMap.EQUALS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.DelimTokenType);
// '+' or '-'
case 43 /* TokenMap.PLUS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
charCode = parseInfo.stream.charCodeAt(parseInfo.currentPosition - parseInfo.offset);
- if (isDigit(charCode)) {
- tokensCount = this.consumeNumericToken(parseInfo);
- if (tokensCount > 0) {
- this.advance(parseInfo, tokensCount);
- return this.makeToken(parseInfo, this.hint ?? exports.EnumToken.NumberTokenType, {
- slice: this.slice,
- sign: "+",
- });
- }
- }
+ // if (isDigit(charCode)) {
+ // tokensCount = this.consumeNumericToken(parseInfo);
+ // if (tokensCount > 0) {
+ // this.advance(parseInfo, tokensCount);
+ // return this.makeToken(parseInfo, this.hint ?? EnumToken.NumberTokenType, {
+ // slice: this.slice,
+ // sign: "+",
+ // });
+ // }
+ // }
return this.makeToken(parseInfo, exports.EnumToken.Plus);
case 45 /* TokenMap.MINUS */:
if (parseInfo.position == parseInfo.currentPosition) {
@@ -27998,15 +28008,17 @@ class Tokenizer {
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.Sub);
}
- if (charCode == 45 /* TokenMap.MINUS */ &&
- (nextCharCode == 45 /* TokenMap.MINUS */ || isIdentStart(nextCharCode))) {
- this.advance(parseInfo);
- tokensCount = this.consumeIdentToken(parseInfo);
- if (tokensCount > 0) {
- this.advance(parseInfo, tokensCount);
- return this.makeToken(parseInfo, exports.EnumToken.IdenTokenType);
- }
- }
+ // if (
+ // charCode == TokenMap.MINUS &&
+ // (nextCharCode == TokenMap.MINUS || isIdentStart(nextCharCode))
+ // ) {
+ // this.advance(parseInfo);
+ // tokensCount = this.consumeIdentToken(parseInfo);
+ // if (tokensCount > 0) {
+ // this.advance(parseInfo, tokensCount);
+ // return this.makeToken(parseInfo, EnumToken.IdenTokenType);
+ // }
+ // }
}
this.advance(parseInfo);
break;
@@ -28059,28 +28071,28 @@ class Tokenizer {
return this.makeToken(parseInfo, exports.EnumToken.EndParensTokenType);
// '['
case 91 /* TokenMap.LEFT_BRACKETS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.AttrStartTokenType);
// ']'
case 93 /* TokenMap.RIGHT_BRACKETS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.AttrEndTokenType);
case 59 /* TokenMap.SEMICOLON */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.SemiColonTokenType);
case 58 /* TokenMap.COLON */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
if (this.peekCharCode(parseInfo) == 58 /* TokenMap.COLON */) {
this.advance(parseInfo);
@@ -28112,15 +28124,15 @@ class Tokenizer {
}
return this.makeToken(parseInfo, exports.EnumToken.WhitespaceTokenType);
case 44 /* TokenMap.COMMA */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.CommaTokenType);
case 36 /* TokenMap.DOLLAR */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "$=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.EndMatchTokenType);
@@ -28128,9 +28140,9 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 126 /* TokenMap.TILDA */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "~=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.IncludeMatchTokenType);
@@ -28139,9 +28151,9 @@ class Tokenizer {
return this.makeToken(parseInfo, exports.EnumToken.Tilda);
// case '^':
case 94 /* TokenMap.CARET */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "^=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.StartMatchTokenType);
@@ -28149,9 +28161,9 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 42 /* TokenMap.STAR */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "*=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.ContainMatchTokenType);
@@ -28165,9 +28177,9 @@ class Tokenizer {
this.advance(parseInfo);
return this.makeToken(parseInfo, exports.EnumToken.NestingSelectorTokenType);
case 124 /* TokenMap.PIPE */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
// '||'
if (this.match(parseInfo, "||")) {
this.advance(parseInfo, 2);
@@ -28190,9 +28202,9 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 47 /* TokenMap.SLASH */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (!this.match(parseInfo, "/*")) {
this.advance(parseInfo);
return this.makeToken(parseInfo, getSymbolHint(parseInfo, parseInfo.position - parseInfo.offset, parseInfo.currentPosition - parseInfo.offset));
@@ -28211,9 +28223,9 @@ class Tokenizer {
}
break;
case 62 /* TokenMap.GREATERTHAN */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, ">=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, exports.EnumToken.GteTokenType);
@@ -28252,20 +28264,11 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 92 /* TokenMap.REVERSE_SOLIDUS */:
- // if (!yieldEOFToken && parseInfo.stream.length == parseInfo.currentPosition - parseInfo.offset + 1) {
- // break;
- // }
this.advance(parseInfo);
// EOF
- if (!this.peek(parseInfo)) {
- // if (!yieldEOFToken) {
- // break;
- // }
- // end of stream ignore \\
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
- break;
+ // end of stream ignore \\
+ if (!this.peek(parseInfo) && parseInfo.position < parseInfo.currentPosition) {
+ return this.makeToken(parseInfo);
}
this.advance(parseInfo);
break;
@@ -28278,9 +28281,9 @@ class Tokenizer {
case 46 /* TokenMap.DOT */:
const codepoint = parseInfo.stream.charCodeAt(parseInfo.currentPosition - parseInfo.offset + 1);
if (isIdentStart(codepoint) || codepoint == 45 /* TokenMap.MINUS */) {
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
let tokensCount = this.consumeIdentToken(parseInfo);
if (tokensCount > 0) {
@@ -28288,27 +28291,22 @@ class Tokenizer {
return this.makeToken(parseInfo, exports.EnumToken.ClassSelectorTokenType);
}
}
- if (!isDigit(codepoint) && parseInfo.position !== parseInfo.currentPosition) {
- this.makeToken(parseInfo);
- this.advance(parseInfo, 2);
- return this;
- }
+ // if (!isDigit(codepoint) && parseInfo.position !== parseInfo.currentPosition) {
+ // this.makeToken(parseInfo);
+ // this.advance(parseInfo, 2);
+ // return this;
+ // }
this.advance(parseInfo);
break;
default:
this.advance(parseInfo);
break;
}
- // if (!yieldEOFToken && endPosition <= parseInfo.currentPosition - parseInfo.offset + 1) {
- // break;
- // }
}
- // if (yieldEOFToken) {
if (parseInfo.position < parseInfo.currentPosition) {
return this.makeToken(parseInfo);
}
return this.makeToken(parseInfo, exports.EnumToken.EOFTokenType);
- // }
}
/**
* tokenize readable stream
@@ -31082,6 +31080,7 @@ function doParseSync(tokenizer, options = {}) {
if (options.expandNestingRules) {
options.nestingRules = false;
}
+ options.minifyAST ??= options.minify;
const startTime = performance.now();
const errors = [];
const stack = [];
@@ -31461,7 +31460,7 @@ function doParseSync(tokenizer, options = {}) {
}
}
}
- if (options.minify) {
+ if (options.minifyAST) {
if (ast.chi.length > 0) {
let passes = options.pass ?? 1;
while (passes--) {
@@ -32001,6 +32000,7 @@ async function doParse(iter, options = {}) {
lenient: true,
...options,
};
+ options.minifyAST ??= options.minify;
if (typeof options.validation !== "boolean") {
options.validation = !!options.validation;
}
@@ -32455,7 +32455,7 @@ async function doParse(iter, options = {}) {
}
}
}
- if (options.minify) {
+ if (options.minifyAST) {
if (ast.chi.length > 0) {
let passes = options.pass ?? 1;
while (passes--) {
diff --git a/dist/index.d.ts b/dist/index.d.ts
index 096b023d7..5c17e370e 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -5217,6 +5217,12 @@ interface MinifyOptions {
* Enable minification
*/
minify?: boolean;
+
+ /**
+ * enable ast minification
+ */
+ minifyAST?: boolean;
+
/**
* Parse color tokens
*/
@@ -5294,7 +5300,8 @@ export declare type LoadResult =
| Promise>
| ReadableStream
| string
- | Promise | object;
+ | Promise
+ | object;
/**
* CSS module parser options
@@ -5792,9 +5799,15 @@ export declare interface RenderOptions {
src?: string;
/**
- * Minify css values.
+ * strip comments and whitespace.
*/
minify?: boolean;
+
+ /**
+ * Minify values
+ */
+ minifyValues?: boolean;
+
/**
* Pretty print css
*
diff --git a/dist/lib/ast/features/calc.js b/dist/lib/ast/features/calc.js
index 9ac0aa9c5..67a32fefd 100644
--- a/dist/lib/ast/features/calc.js
+++ b/dist/lib/ast/features/calc.js
@@ -8,7 +8,7 @@ import { replaceNodeOrValue } from '../../parser/utils/token.js';
class ComputeCalcExpressionFeature {
accept = new Set([EnumToken.RuleNodeType, EnumToken.AtRuleNodeType]);
get ordering() {
- return 1;
+ return 3;
}
get processMode() {
return FeatureWalkMode.Post;
@@ -33,8 +33,20 @@ class ComputeCalcExpressionFeature {
continue;
}
if (value.typ == EnumToken.BinaryExpressionTokenType) {
- // @ts-ignore
- replaceNodeOrValue(parent, value, evaluate([value]));
+ const result = evaluate([value]);
+ try {
+ // @ts-ignore
+ replaceNodeOrValue(parent, value, result);
+ }
+ catch (e) {
+ // @ts-ignore
+ if (Array.isArray(parent.chi)) {
+ // @ts-ignore
+ parent.chi.length = 0;
+ // @ts-ignore
+ parent.chi.push(...result);
+ }
+ }
continue;
}
if (value != null && tokensfuncSet.has(value.typ)) {
@@ -52,7 +64,7 @@ class ComputeCalcExpressionFeature {
? value.val
: value.chi;
const values = evaluate(cp);
- // fix a + -b to a - b
+ // fix a + -b into a - b
for (const { value, parent: p } of walkValues(values)) {
if (value.typ === EnumToken.BinaryExpressionTokenType) {
if (value.op === EnumToken.Add &&
diff --git a/dist/lib/ast/features/if.js b/dist/lib/ast/features/if.js
index cbf4cb516..0acfa25c5 100644
--- a/dist/lib/ast/features/if.js
+++ b/dist/lib/ast/features/if.js
@@ -174,7 +174,7 @@ function processNode(declarationNode, cache) {
class ExpandIfFeature {
accept = new Set([EnumToken.DeclarationNodeType]);
get ordering() {
- return 4;
+ return 1;
}
get processMode() {
return FeatureWalkMode.Pre;
diff --git a/dist/lib/ast/features/inlinecssvariables.js b/dist/lib/ast/features/inlinecssvariables.js
index 0c7716bea..9dc33e0ce 100644
--- a/dist/lib/ast/features/inlinecssvariables.js
+++ b/dist/lib/ast/features/inlinecssvariables.js
@@ -57,10 +57,10 @@ function replace(node, variableScope) {
class InlineCssVariablesFeature {
accept = new Set([EnumToken.RuleNodeType, EnumToken.AtRuleNodeType]);
get ordering() {
- return 0;
+ return 2;
}
get processMode() {
- return FeatureWalkMode.Pre;
+ return FeatureWalkMode.Post;
}
static register(options) {
if (options.inlineCssVariables) {
diff --git a/dist/lib/ast/features/prefix.js b/dist/lib/ast/features/prefix.js
index fa2aa3c71..5b551497f 100644
--- a/dist/lib/ast/features/prefix.js
+++ b/dist/lib/ast/features/prefix.js
@@ -109,7 +109,7 @@ function replaceAstNodes(tokens, root) {
}
class ComputePrefixFeature {
get ordering() {
- return 2;
+ return 0;
}
get processMode() {
return FeatureWalkMode.Pre;
diff --git a/dist/lib/ast/features/shorthand.js b/dist/lib/ast/features/shorthand.js
index 149ed4e87..684f0e747 100644
--- a/dist/lib/ast/features/shorthand.js
+++ b/dist/lib/ast/features/shorthand.js
@@ -9,7 +9,7 @@ class ComputeShorthandFeature {
EnumToken.KeyframesRuleNodeType,
]);
get ordering() {
- return 10;
+ return 5;
}
get processMode() {
return FeatureWalkMode.Post;
@@ -28,7 +28,6 @@ class ComputeShorthandFeature {
const j = ast.chi.length;
let k = 0;
let l;
- // let properties: PropertyList = new PropertyList(options);
const rules = [];
const declarations = [];
// @ts-ignore
@@ -49,7 +48,6 @@ class ComputeShorthandFeature {
if (node.typ == EnumToken.DeclarationNodeType) {
for (let m = k; m <= l; m++) {
declarations.push(ast.chi[m]);
- // properties.add(ast.chi![m]);
}
}
else {
@@ -59,7 +57,6 @@ class ComputeShorthandFeature {
}
k = l;
}
- // console.error([...new PropertyList(options).add(declarations)]);
if (declarations.length > 0) {
ast.chi.length = 0;
// @ts-expect-error
diff --git a/dist/lib/ast/features/transform.js b/dist/lib/ast/features/transform.js
index 2f59e3910..97503a60b 100644
--- a/dist/lib/ast/features/transform.js
+++ b/dist/lib/ast/features/transform.js
@@ -12,7 +12,7 @@ class TransformCssFeature {
EnumToken.KeyframesRuleNodeType,
]);
get ordering() {
- return 3;
+ return 4;
}
get processMode() {
return FeatureWalkMode.Post;
diff --git a/dist/lib/ast/math/expression.js b/dist/lib/ast/math/expression.js
index 1a372b279..5a04f657e 100644
--- a/dist/lib/ast/math/expression.js
+++ b/dist/lib/ast/math/expression.js
@@ -1,5 +1,5 @@
import { equalsIgnoreCase } from '../../parser/utils/text.js';
-import { mathFuncs, LOCEND, LOCSTA, LOCSRCID } from '../../syntax/constants.js';
+import { mathFuncs, PARENT, LOCEND, LOCSTA, LOCSRCID } from '../../syntax/constants.js';
import { EnumToken } from '../types.js';
import { rem, compute } from './math.js';
@@ -64,6 +64,7 @@ function evaluate(tokens) {
[LOCSRCID]: nodes[0][LOCSRCID],
[LOCSTA]: nodes[0][LOCSTA],
[LOCEND]: nodes[0][LOCEND],
+ [PARENT]: nodes[0][PARENT],
},
];
}
@@ -86,6 +87,7 @@ function evaluate(tokens) {
[LOCSRCID]: nodes[i][LOCSRCID],
[LOCSTA]: nodes[i][LOCSTA],
[LOCEND]: nodes[i + 1][LOCEND],
+ [PARENT]: nodes[i + 1][PARENT],
};
}
else {
@@ -95,6 +97,7 @@ function evaluate(tokens) {
[LOCSRCID]: nodes[i + 1][LOCSRCID],
[LOCSTA]: nodes[i + 1][LOCSTA],
[LOCEND]: nodes[i + 1][LOCEND],
+ [PARENT]: nodes[i + 1][PARENT],
}, EnumToken.Mul);
}
i++;
@@ -115,12 +118,14 @@ function evaluate(tokens) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
}, {
...token,
val: -token.val,
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
return acc;
}
@@ -131,6 +136,7 @@ function evaluate(tokens) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
}
acc.push(token);
@@ -152,6 +158,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: r?.[LOCEND] ?? l[LOCEND],
+ [PARENT]: l[PARENT],
};
if (!isScalarToken(l) || !isScalarToken(r) || (l.typ == r.typ && "unit" in l && "unit" in r && l.unit != r.unit)) {
return defaultReturn;
@@ -224,6 +231,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: l[LOCEND],
+ [PARENT]: l[PARENT],
},
r: {
typ: EnumToken.NumberTokenType,
@@ -231,6 +239,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: r[LOCSRCID],
[LOCSTA]: r[LOCSTA],
[LOCEND]: r[LOCEND],
+ [PARENT]: r[PARENT],
},
};
}
@@ -243,6 +252,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: l[LOCEND],
+ [PARENT]: l[PARENT],
},
r: {
typ: EnumToken.NumberTokenType,
@@ -250,6 +260,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: r[LOCSRCID],
[LOCSTA]: r[LOCSTA],
[LOCEND]: r[LOCEND],
+ [PARENT]: r[PARENT],
},
};
}
@@ -276,6 +287,7 @@ function doEvaluate(l, r, op) {
[LOCSRCID]: l[LOCSRCID],
[LOCSTA]: l[LOCSTA],
[LOCEND]: r?.[LOCEND] ?? l[LOCEND],
+ [PARENT]: l[PARENT],
};
if (token.typ == EnumToken.IdenTokenType) {
// @ts-ignore
@@ -456,6 +468,7 @@ function evaluateFunc(token) {
[LOCSRCID]: value[0][LOCSRCID],
[LOCSTA]: value[0][LOCSTA],
[LOCEND]: value[0][LOCEND],
+ [PARENT]: value[0][PARENT],
}
: {
typ: token.val == "sign" ? EnumToken.NumberTokenType : value[0].typ,
@@ -463,6 +476,7 @@ function evaluateFunc(token) {
[LOCSRCID]: value[0][LOCSRCID],
[LOCSTA]: value[0][LOCSTA],
[LOCEND]: value[0][LOCEND],
+ [PARENT]: value[0][PARENT],
},
];
}
@@ -485,6 +499,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -558,6 +573,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -572,6 +588,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -582,6 +599,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -621,6 +639,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -663,6 +682,7 @@ function evaluateFunc(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
},
];
}
@@ -690,6 +710,7 @@ function inlineExpression(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
});
for (const child of inlineExpression(token.r)) {
result.push(child);
@@ -769,6 +790,7 @@ function factorToken(token) {
[LOCSRCID]: token[LOCSRCID],
[LOCSTA]: token[LOCSTA],
[LOCEND]: token[LOCEND],
+ [PARENT]: token[PARENT],
};
// @ts-ignore
delete token.val;
@@ -810,6 +832,7 @@ function factor(tokens, ops) {
[LOCSRCID]: tokens[i - 1][LOCSRCID],
[LOCSTA]: tokens[i - 1][LOCSTA],
[LOCEND]: tokens[i + 1][LOCEND],
+ [PARENT]: tokens[i + 1][PARENT],
});
i--;
}
diff --git a/dist/lib/ast/minify.js b/dist/lib/ast/minify.js
index 54a57e2d7..6817fbf1d 100644
--- a/dist/lib/ast/minify.js
+++ b/dist/lib/ast/minify.js
@@ -787,7 +787,8 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
previous = node;
nodeIndex = i;
}
- if (recursive && node != null && "chi" in node) {
+ // @ts-ignore
+ if (recursive && node != null && node.chi != null) {
if (node.typ == EnumToken.KeyframesAtRuleNodeType ||
!node.chi.some((n) => n.typ == EnumToken.DeclarationNodeType)) {
if (!(node.typ == EnumToken.AtRuleNodeType && node.nam != "font-face")) {
diff --git a/dist/lib/parser/declaration/list.js b/dist/lib/parser/declaration/list.js
index 40b326e84..205c01f68 100644
--- a/dist/lib/parser/declaration/list.js
+++ b/dist/lib/parser/declaration/list.js
@@ -10,6 +10,9 @@ import { objectHash } from '../utils/hash.js';
import { equalsIgnoreCase } from '../utils/text.js';
const config = getConfig();
+/**
+ * Represents a list of property declarations, compute shorthand and remove duplicate declarations.
+ */
class PropertyList {
options = { removeDuplicateDeclarations: true, computeShorthand: true };
declarations;
@@ -84,28 +87,35 @@ class PropertyList {
// @ts-ignore
shorthand = config.property[propertyName];
}
- // console.error({shortHandType, propertyName, config: config.map[propertyName], map: config.map[shorthand].properties[propertyName]});
// @ts-ignore
if (shortHandType == "map") {
let owner = this;
+ const mapName =
// @ts-ignore
- const mapName = config.map[propertyName]?.map ?? config.map[shorthand]?.properties?.[propertyName]?.map;
+ config.map[propertyName]?.map ?? config.map[shorthand]?.properties?.[propertyName]?.map;
if (typeof mapName === "string") {
if (!this.declarations.has(mapName)) {
// @ts-ignore
this.declarations.set(mapName, new PropertyMap(config.map[mapName]));
}
owner = this.declarations.get(mapName);
- // console.error({mapName});
}
- // @ts-ignore
- if (!owner.declarations.has(shorthand)) {
+ else if (!this.declarations.has(shorthand)) {
// @ts-ignore
- owner.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ }
+ if (owner == this) {
+ // @ts-ignore
+ owner.declarations.get(shorthand).add(declaration);
+ }
+ else {
+ if (!owner.declarations.has(shorthand)) {
+ // @ts-ignore
+ owner.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
+ }
+ // @ts-ignore
+ owner.declarations.get(shorthand).add(declaration);
}
- // console.error({propertyName,mapName, owned: owner == this});
- // @ts-ignore
- owner.declarations.get(shorthand).add(declaration);
}
// @ts-ignore
else if (shortHandType == "set") {
@@ -192,7 +202,7 @@ class PropertyList {
[Symbol.iterator]() {
let iterator = this.declarations.values();
const iterators = [];
- // console.error(this);
+ // @ts-ignore
return {
next() {
let value = iterator.next();
diff --git a/dist/lib/parser/declaration/map.js b/dist/lib/parser/declaration/map.js
index 30978bc29..91749665c 100644
--- a/dist/lib/parser/declaration/map.js
+++ b/dist/lib/parser/declaration/map.js
@@ -10,8 +10,8 @@ import { cloneNode } from '../../ast/clone.js';
const propertiesConfig = getConfig();
class PropertyMap {
- config;
declarations;
+ config;
requiredCount;
pattern;
constructor(config) {
@@ -25,7 +25,7 @@ class PropertyMap {
}
add(declaration) {
if (declaration.nam == this.config.shorthand) {
- this.declarations = new Map();
+ this.declarations.clear();
this.declarations.set(declaration.nam, declaration);
this.matchTypes(declaration);
}
@@ -41,23 +41,17 @@ class PropertyMap {
if (this.declarations.has(this.config.shorthand)) {
const tokens = {};
const values = [];
- // @ts-ignore
- this.declarations
- .get(this.config.shorthand)
- // @ts-ignore
- .val.slice()
- .reduce((acc, curr) => {
+ const val = [[]];
+ for (const curr of this.declarations.get(this.config.shorthand).val) { // @ts-ignore
// @ts-ignore
if (separator != null && separator.typ == curr.typ && separator.val == curr.val) {
- acc.push([]);
- return acc;
+ val.push([]);
+ continue;
}
// @ts-ignore
- acc.at(-1).push(curr);
- return acc;
- }, [[]])
- // @ts-ignore
- .reduce((acc, list, current) => {
+ val.at(-1).push(curr);
+ }
+ for (let current = 0; current < val.length; current++) {
values.push(...this.pattern.reduce((acc, property) => {
// let current: number = 0;
const props = this.config.properties[property];
@@ -72,9 +66,7 @@ class PropertyMap {
// @ts-ignore
acc[i][PROPERTYNAME] == property ||
matchType(acc[i], props)) {
- if ("prefix" in props &&
- props.previous != null &&
- !(props.previous in tokens)) {
+ if ("prefix" in props && props.previous != null && !(props.previous in tokens)) {
return acc;
}
if (!(property in tokens)) {
@@ -139,9 +131,8 @@ class PropertyMap {
}
}
return acc;
- }, list));
- return values;
- }, []);
+ }, val[current]));
+ }
if (values.length == 0) {
this.declarations = Object.entries(tokens).reduce((acc, curr) => {
acc.set(curr[0], {
@@ -201,17 +192,40 @@ class PropertyMap {
}
if (hasMapping) {
const mapped = {};
- for (const key of declarations.keys()) {
- const value = declarations.get(key);
+ let key;
+ for (const value of declarations.values()) {
+ key = value.nam;
if (value instanceof PropertyMap) {
for (const [k, v] of value.declarations) {
- mapped[k] = v;
+ if (k == value.config.shorthand) {
+ for (const [key, val] of Object.entries(value.config.properties)) {
+ mapped[key] = cloneNode(v);
+ for (let i = 0; i < v.val.length; i++) {
+ // @ts-ignore
+ if (key == v.val[i][PROPERTYNAME]) {
+ if (mapped[key].val.length > 0) {
+ mapped[key].val.push({
+ typ: EnumToken.WhitespaceTokenType,
+ });
+ }
+ mapped[key].val.push(v.val[i]);
+ }
+ }
+ if (mapped[key].val.length == 0) {
+ mapped[key].val.push(...parseString(value.config.properties[key].default[0]));
+ }
+ }
+ }
+ else {
+ mapped[k] = v;
+ }
}
}
else {
mapped[key] = value;
}
}
+ // console.error(mapped);
if (patterns.length === Object.keys(mapped).length) {
declarations = new Map();
for (const key of patterns) {
@@ -667,8 +681,6 @@ class PropertyMap {
}
return acc;
}, []);
- // console.error({hasMapping, shorthand: this.config.shorthand, requiredCount, isShorthand,
- // declarations: declarations.values(), values});
if (this.config.mapping != null) {
const val = values.reduce((acc, curr) => acc +
renderValue(curr, {
@@ -705,6 +717,7 @@ class PropertyMap {
}
}
const iterators = [];
+ // @ts-ignore
return {
// @ts-ignore
next() {
diff --git a/dist/lib/parser/parse.js b/dist/lib/parser/parse.js
index ab1e48152..d4ed48bb7 100644
--- a/dist/lib/parser/parse.js
+++ b/dist/lib/parser/parse.js
@@ -475,6 +475,7 @@ function doParseSync(tokenizer, options = {}) {
if (options.expandNestingRules) {
options.nestingRules = false;
}
+ options.minifyAST ??= options.minify;
const startTime = performance.now();
const errors = [];
const stack = [];
@@ -854,7 +855,7 @@ function doParseSync(tokenizer, options = {}) {
}
}
}
- if (options.minify) {
+ if (options.minifyAST) {
if (ast.chi.length > 0) {
let passes = options.pass ?? 1;
while (passes--) {
@@ -1394,6 +1395,7 @@ async function doParse(iter, options = {}) {
lenient: true,
...options,
};
+ options.minifyAST ??= options.minify;
if (typeof options.validation !== "boolean") {
options.validation = !!options.validation;
}
@@ -1848,7 +1850,7 @@ async function doParse(iter, options = {}) {
}
}
}
- if (options.minify) {
+ if (options.minifyAST) {
if (ast.chi.length > 0) {
let passes = options.pass ?? 1;
while (passes--) {
diff --git a/dist/lib/parser/tokenize.js b/dist/lib/parser/tokenize.js
index 3f0a70ba8..3abc35c43 100644
--- a/dist/lib/parser/tokenize.js
+++ b/dist/lib/parser/tokenize.js
@@ -4,6 +4,7 @@ import { isWhiteSpace, isNewLine, isDigit, isLetter, isIdentStart, isIdentCodepo
import { SourceFile } from './source.js';
const SymbolsMapTokens = Object.create(null);
+const SymbolsMapTokensLower = Object.create(null);
// Regex for escape sequence decoding - compile once, reuse many times
const ESCAPE_SEQUENCE_REGEX = /\\((\n|\r|\f|\v|\u2028|\u2029|([0-9a-fA-F]{1,6})) ?)/gms;
function decodeEscapeSequences(value) {
@@ -32,7 +33,9 @@ function decodeEscapeSequences(value) {
}
function assignTokenMap(entries, tokenType, suffix = "", lowercase = false) {
for (const entry of entries) {
- SymbolsMapTokens[(lowercase ? entry.toLowerCase() : entry) + suffix] = tokenType;
+ const key = (lowercase ? entry.toLowerCase() : entry) + suffix;
+ SymbolsMapTokens[key] = tokenType;
+ SymbolsMapTokensLower[key.toLowerCase()] = tokenType;
}
}
SymbolsMapTokens[""] = EnumToken.DelimTokenType;
@@ -132,20 +135,24 @@ var TokenMap;
})(TokenMap || (TokenMap = {}));
function getSymbolHint(parseInfo, start, end) {
const len = end - start;
- const keysLength = SymbolsMapTokensKeys.length;
- // Early exit for impossible lengths
- if (len < 0)
+ if (len <= 0)
return null;
+ const value = parseInfo.stream.slice(start, end);
+ // Direct lookup handles the hottest punctuation and keyword cases without
+ // scanning the entire symbol table on every token.
+ const match = SymbolsMapTokens[value] ?? SymbolsMapTokensLower[value.toLowerCase()];
+ if (match != null) {
+ return match;
+ }
+ const keysLength = SymbolsMapTokensKeys.length;
for (let i = 0; i < keysLength; i++) {
const key = SymbolsMapTokensKeys[i];
if (key.length !== len)
continue;
- // Match character by character
let match = true;
for (let j = 0; j < len; j++) {
let ca = key.charCodeAt(j);
- let cb = parseInfo.stream.charCodeAt(start + j);
- // Normalize A-Z to a-z
+ let cb = value.charCodeAt(j);
if (ca >= 65 && ca <= 90)
ca += 32;
if (cb >= 65 && cb <= 90)
@@ -163,32 +170,29 @@ function getSymbolHint(parseInfo, start, end) {
}
function searchArray(array, parseInfo, start, end) {
const len = end - start;
- // Early exit for impossible lengths
- if (len < 0)
+ if (len <= 0)
return null;
- // Use a simple linear search optimized with length pre-filtering
- let i = array.length;
- while (i--) {
- if (array[i].length !== len)
+ let match;
+ let item;
+ for (let i = 0; i < array.length; i++) {
+ item = array[i];
+ if (item.length !== len)
continue;
- // Match character by character
- let match = true;
- const arrayItem = array[i];
+ match = true;
for (let j = 0; j < len; j++) {
- let ca = arrayItem.charCodeAt(j);
- let cb = parseInfo.stream.charCodeAt(start + j);
- // Normalize A-Z to a-z
+ let ca = parseInfo.stream.charCodeAt(start + j);
+ let cb = item.charCodeAt(j);
if (ca >= 65 && ca <= 90)
ca += 32;
if (cb >= 65 && cb <= 90)
cb += 32;
- if (ca != cb) {
+ if (ca !== cb) {
match = false;
break;
}
}
if (match) {
- return arrayItem;
+ return item;
}
}
return null;
@@ -1126,23 +1130,6 @@ class Tokenizer {
}
return true;
}
- /**
- *
- * @param parseInfo
- * @returns
- */
- // isPseudo(parseInfo: ParseInfo): boolean {
- // let position: number = parseInfo.currentPosition - parseInfo.offset;
- // let endPosition: number = parseInfo.currentPosition - parseInfo.offset;
- // return (parseInfo.stream.charAt(position) == ":" &&
- // parseInfo.stream.charAt(endPosition - 1) == "(" &&
- // (parseInfo.stream.charAt(position + 1) == ":"
- // ? this.isIdentToken(parseInfo, 2, -1)
- // : this.isIdentToken(parseInfo, 1, -1))) ||
- // parseInfo.stream.charAt(position + 1) == ":"
- // ? this.isIdentToken(parseInfo, 2)
- // : this.isIdentToken(parseInfo, 1);
- // }
/**
*
* @param parseInfo
@@ -1273,28 +1260,28 @@ class Tokenizer {
// EOF
switch (charCode) {
case 61 /* TokenMap.EQUALS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.DelimTokenType);
// '+' or '-'
case 43 /* TokenMap.PLUS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
charCode = parseInfo.stream.charCodeAt(parseInfo.currentPosition - parseInfo.offset);
- if (isDigit(charCode)) {
- tokensCount = this.consumeNumericToken(parseInfo);
- if (tokensCount > 0) {
- this.advance(parseInfo, tokensCount);
- return this.makeToken(parseInfo, this.hint ?? EnumToken.NumberTokenType, {
- slice: this.slice,
- sign: "+",
- });
- }
- }
+ // if (isDigit(charCode)) {
+ // tokensCount = this.consumeNumericToken(parseInfo);
+ // if (tokensCount > 0) {
+ // this.advance(parseInfo, tokensCount);
+ // return this.makeToken(parseInfo, this.hint ?? EnumToken.NumberTokenType, {
+ // slice: this.slice,
+ // sign: "+",
+ // });
+ // }
+ // }
return this.makeToken(parseInfo, EnumToken.Plus);
case 45 /* TokenMap.MINUS */:
if (parseInfo.position == parseInfo.currentPosition) {
@@ -1304,15 +1291,17 @@ class Tokenizer {
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.Sub);
}
- if (charCode == 45 /* TokenMap.MINUS */ &&
- (nextCharCode == 45 /* TokenMap.MINUS */ || isIdentStart(nextCharCode))) {
- this.advance(parseInfo);
- tokensCount = this.consumeIdentToken(parseInfo);
- if (tokensCount > 0) {
- this.advance(parseInfo, tokensCount);
- return this.makeToken(parseInfo, EnumToken.IdenTokenType);
- }
- }
+ // if (
+ // charCode == TokenMap.MINUS &&
+ // (nextCharCode == TokenMap.MINUS || isIdentStart(nextCharCode))
+ // ) {
+ // this.advance(parseInfo);
+ // tokensCount = this.consumeIdentToken(parseInfo);
+ // if (tokensCount > 0) {
+ // this.advance(parseInfo, tokensCount);
+ // return this.makeToken(parseInfo, EnumToken.IdenTokenType);
+ // }
+ // }
}
this.advance(parseInfo);
break;
@@ -1365,28 +1354,28 @@ class Tokenizer {
return this.makeToken(parseInfo, EnumToken.EndParensTokenType);
// '['
case 91 /* TokenMap.LEFT_BRACKETS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.AttrStartTokenType);
// ']'
case 93 /* TokenMap.RIGHT_BRACKETS */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.AttrEndTokenType);
case 59 /* TokenMap.SEMICOLON */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.SemiColonTokenType);
case 58 /* TokenMap.COLON */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
if (this.peekCharCode(parseInfo) == 58 /* TokenMap.COLON */) {
this.advance(parseInfo);
@@ -1418,15 +1407,15 @@ class Tokenizer {
}
return this.makeToken(parseInfo, EnumToken.WhitespaceTokenType);
case 44 /* TokenMap.COMMA */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.CommaTokenType);
case 36 /* TokenMap.DOLLAR */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "$=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, EnumToken.EndMatchTokenType);
@@ -1434,9 +1423,9 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 126 /* TokenMap.TILDA */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "~=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, EnumToken.IncludeMatchTokenType);
@@ -1445,9 +1434,9 @@ class Tokenizer {
return this.makeToken(parseInfo, EnumToken.Tilda);
// case '^':
case 94 /* TokenMap.CARET */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "^=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, EnumToken.StartMatchTokenType);
@@ -1455,9 +1444,9 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 42 /* TokenMap.STAR */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, "*=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, EnumToken.ContainMatchTokenType);
@@ -1471,9 +1460,9 @@ class Tokenizer {
this.advance(parseInfo);
return this.makeToken(parseInfo, EnumToken.NestingSelectorTokenType);
case 124 /* TokenMap.PIPE */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
// '||'
if (this.match(parseInfo, "||")) {
this.advance(parseInfo, 2);
@@ -1496,9 +1485,9 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 47 /* TokenMap.SLASH */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (!this.match(parseInfo, "/*")) {
this.advance(parseInfo);
return this.makeToken(parseInfo, getSymbolHint(parseInfo, parseInfo.position - parseInfo.offset, parseInfo.currentPosition - parseInfo.offset));
@@ -1517,9 +1506,9 @@ class Tokenizer {
}
break;
case 62 /* TokenMap.GREATERTHAN */:
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
if (this.match(parseInfo, ">=")) {
this.advance(parseInfo, 2);
return this.makeToken(parseInfo, EnumToken.GteTokenType);
@@ -1558,20 +1547,11 @@ class Tokenizer {
this.advance(parseInfo);
break;
case 92 /* TokenMap.REVERSE_SOLIDUS */:
- // if (!yieldEOFToken && parseInfo.stream.length == parseInfo.currentPosition - parseInfo.offset + 1) {
- // break;
- // }
this.advance(parseInfo);
// EOF
- if (!this.peek(parseInfo)) {
- // if (!yieldEOFToken) {
- // break;
- // }
- // end of stream ignore \\
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
- break;
+ // end of stream ignore \\
+ if (!this.peek(parseInfo) && parseInfo.position < parseInfo.currentPosition) {
+ return this.makeToken(parseInfo);
}
this.advance(parseInfo);
break;
@@ -1584,9 +1564,9 @@ class Tokenizer {
case 46 /* TokenMap.DOT */:
const codepoint = parseInfo.stream.charCodeAt(parseInfo.currentPosition - parseInfo.offset + 1);
if (isIdentStart(codepoint) || codepoint == 45 /* TokenMap.MINUS */) {
- if (parseInfo.position < parseInfo.currentPosition) {
- return this.makeToken(parseInfo);
- }
+ // if (parseInfo.position < parseInfo.currentPosition) {
+ // return this.makeToken(parseInfo);
+ // }
this.advance(parseInfo);
let tokensCount = this.consumeIdentToken(parseInfo);
if (tokensCount > 0) {
@@ -1594,27 +1574,22 @@ class Tokenizer {
return this.makeToken(parseInfo, EnumToken.ClassSelectorTokenType);
}
}
- if (!isDigit(codepoint) && parseInfo.position !== parseInfo.currentPosition) {
- this.makeToken(parseInfo);
- this.advance(parseInfo, 2);
- return this;
- }
+ // if (!isDigit(codepoint) && parseInfo.position !== parseInfo.currentPosition) {
+ // this.makeToken(parseInfo);
+ // this.advance(parseInfo, 2);
+ // return this;
+ // }
this.advance(parseInfo);
break;
default:
this.advance(parseInfo);
break;
}
- // if (!yieldEOFToken && endPosition <= parseInfo.currentPosition - parseInfo.offset + 1) {
- // break;
- // }
}
- // if (yieldEOFToken) {
if (parseInfo.position < parseInfo.currentPosition) {
return this.makeToken(parseInfo);
}
return this.makeToken(parseInfo, EnumToken.EOFTokenType);
- // }
}
/**
* tokenize readable stream
diff --git a/dist/lib/printer/render.js b/dist/lib/printer/render.js
index cfa4dc5a5..75c27a5e7 100644
--- a/dist/lib/printer/render.js
+++ b/dist/lib/printer/render.js
@@ -42,6 +42,7 @@ function doRender(data, options = {}, mapping) {
removeEmpty: false,
removeComments: false,
}),
+ minifyValues: true,
sourcemap: false,
convertColor: true,
expandNestingRules: false,
@@ -281,7 +282,7 @@ function renderAstNode(data, options, sourcemaps, sourceLocation, linesMap, erro
const indentSub = indents[level + 1];
switch (data.typ) {
case EnumToken.DeclarationNodeType:
- return `${data.nam}:${options.indent}${(options.minify
+ return `${data.nam}:${options.indent}${(options.minifyValues
? filterValues(data.val)
: data.val).reduce(reducer, "")}`;
case EnumToken.CommentNodeType:
@@ -336,7 +337,7 @@ function renderAstNode(data, options, sourcemaps, sourceLocation, linesMap, erro
: node.val;
}
else if (node.typ == EnumToken.DeclarationNodeType) {
- str = `${node.nam}:${options.indent}${(options.minify
+ str = `${node.nam}:${options.indent}${(options.minifyValues
? filterValues(node.val)
: node.val)
.reduce(reducer, "")
@@ -404,9 +405,10 @@ function renderAstNode(data, options, sourcemaps, sourceLocation, linesMap, erro
function renderValue(token, options = {}, cache = Object.create(null), reducer, errors) {
if (token.typ === EnumToken.WhenElseFunctionTokenType &&
equalsIgnoreCase(token.val, "supports")) {
- options = { ...options, minify: false, convertColor: false };
+ options = { ...options, minifyValues: false, minify: false, convertColor: false };
reducer = null;
}
+ options.minifyValues ??= options.minify;
if (reducer == null) {
reducer = function (acc, curr) {
if (curr.typ == EnumToken.CommentTokenType && options.removeComments) {
@@ -563,7 +565,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
")");
}
case EnumToken.UrlFunctionTokenType:
- if (options.minify && token.typ === EnumToken.UrlFunctionTokenType) {
+ if (options.minifyValues && token.typ === EnumToken.UrlFunctionTokenType) {
if (token.chi[0]?.typ === EnumToken.BadUrlTokenType) {
return "url()";
}
@@ -584,7 +586,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
case EnumToken.FunctionTokenType:
case EnumToken.MathFunctionTokenType:
case EnumToken.ImageFunctionTokenType:
- if (options.minify && token.typ === EnumToken.ImageFunctionTokenType) {
+ if (options.minifyValues && token.typ === EnumToken.ImageFunctionTokenType) {
const slice = token.chi.slice();
switch (token.val) {
case "linear-gradient":
@@ -1070,37 +1072,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
renderValue(curr, token.typ == EnumToken.FunctionTokenType ? { minify: false } : options, cache, reducer), "") +
")");
}
- return (
- /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/ (token.val ?? "") +
- "(" +
- token.chi.reduce(reducer, "") +
- ")");
- // case EnumToken.MatchExpressionTokenType:
- // return (
- // renderValue((token as MatchExpressionToken).l as Token, options, cache, reducer, errors) +
- // renderValue((token as MatchExpressionToken).op, options, cache, reducer, errors) +
- // renderValue((token as MatchExpressionToken).r, options, cache, reducer, errors) +
- // ((token as MatchExpressionToken).attr ? " " + (token as MatchExpressionToken).attr : "")
- // );
- // case EnumToken.NameSpaceAttributeTokenType:
- // return (
- // ((token as NameSpaceAttributeToken).l == null
- // ? ""
- // : renderValue((token as NameSpaceAttributeToken).l as Token, options, cache, reducer, errors)) +
- // "|" +
- // renderValue((token as NameSpaceAttributeToken).r, options, cache, reducer, errors)
- // );
- // case EnumToken.ComposesSelectorNodeType:
- // return (
- // (token as ComposesSelectorToken).l.reduce(
- // (acc: string, curr: Token) => acc + renderValue(curr, options, cache),
- // "",
- // ) +
- // ((token as ComposesSelectorToken).r == null
- // ? ""
- // : " from " +
- // renderValue((token as ComposesSelectorToken).r as Token, options, cache, reducer, errors))
- // );
+ return (token.val ?? "") + "(" + token.chi.reduce(reducer, "") + ")";
case EnumToken.BlockStartTokenType:
return "{";
case EnumToken.BlockEndTokenType:
@@ -1249,7 +1221,11 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
const perc = token.val.typ == EnumToken.FractionTokenType
? renderValue(token.val, options, cache)
: minifyNumber(token.val);
- return options.minify && perc == "0" ? "0" : perc.includes("/") ? perc.replace("/", uni + "/") : perc + uni;
+ return options.minifyValues && perc == "0"
+ ? "0"
+ : perc.includes("/")
+ ? perc.replace("/", uni + "/")
+ : perc + uni;
case EnumToken.NumberTokenType:
return token.val.typ == EnumToken.FractionTokenType
? renderValue(token.val, options, cache)
@@ -1314,7 +1290,7 @@ function renderValue(token, options = {}, cache = Object.create(null), reducer,
case EnumToken.DeclarationNodeType:
return (token.nam +
":" +
- (options.minify ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderValue(curr, options, cache), ""));
+ (options.minifyValues ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderValue(curr, options, cache), ""));
case EnumToken.MediaQueryUnaryFeatureTokenType:
return (renderValue(token.l, options, cache, reducer) +
" " +
diff --git a/dist/lib/syntax/color/a98rgb.js b/dist/lib/syntax/color/a98rgb.js
index 87fd4de9d..1b5ada0af 100644
--- a/dist/lib/syntax/color/a98rgb.js
+++ b/dist/lib/syntax/color/a98rgb.js
@@ -37,7 +37,7 @@ function la98rgb2a98rgb(r, g, b, a = null) {
// convert an array of linear-light a98-rgb in the range 0.0-1.0
// to gamma corrected form
// negative values are also now accepted
- return [r, b, g]
+ return [r, g, b]
.map(function (val) {
let sign = val < 0 ? -1 : 1;
let abs = Math.abs(val);
diff --git a/dist/lib/syntax/color/alpha.js b/dist/lib/syntax/color/alpha.js
index 1f667d317..d85237b70 100644
--- a/dist/lib/syntax/color/alpha.js
+++ b/dist/lib/syntax/color/alpha.js
@@ -24,7 +24,6 @@ function alpha(color, alpha) {
}
let components = getColorComponents(color);
if (alpha.typ === EnumToken.MathFunctionTokenType) {
- const originalAlpha = cloneNode(alpha, true);
for (const { value } of walkValues(alpha.chi, alpha)) {
if (value.typ === EnumToken.IdenTokenType) {
if (equalsIgnoreCase(value.val, "alpha")) {
@@ -36,22 +35,22 @@ function alpha(color, alpha) {
});
// continue;
}
- else if (equalsIgnoreCase(value.val, "none")) {
- Object.assign(value, {
- typ: EnumToken.NumberTokenType,
- val: 0,
- });
- }
+ // else if (equalsIgnoreCase((value as IdentToken).val, "none")) {
+ // Object.assign(value, {
+ // typ: EnumToken.NumberTokenType,
+ // val: 0,
+ // });
+ // }
}
}
const result = evaluate([alpha]);
if (result.length == 1) {
alpha = result[0];
}
- else {
- // @ts-expect-error
- alpha = originalAlpha;
- }
+ // else {
+ // // @ts-expect-error
+ // alpha = originalAlpha;
+ // }
}
// console.error({ alpha });
if (alpha.typ !== EnumToken.IdenTokenType &&
@@ -77,17 +76,17 @@ function alpha(color, alpha) {
return null;
}
if (alpha?.typ === EnumToken.IdenTokenType) {
- if (equalsIgnoreCase(alpha.val, "alpha")) {
- alpha = components[3] ?? {
- typ: EnumToken.NumberTokenType,
- val: 1,
- };
- }
- else if (equalsIgnoreCase(alpha.val, "node")) {
- alpha = {
+ // if (equalsIgnoreCase((alpha as IdentToken).val, "alpha")) {
+ // alpha = components[3] ?? {
+ // typ: EnumToken.NumberTokenType,
+ // val: 1,
+ // };
+ // } else
+ if (equalsIgnoreCase(alpha.val, "none")) {
+ Object.assign(alpha, {
typ: EnumToken.NumberTokenType,
val: 0,
- };
+ });
}
}
return makeColor(color.kin, components, alpha);
diff --git a/dist/lib/syntax/color/color-mix.js b/dist/lib/syntax/color/color-mix.js
index 2478e5fcc..24febd95f 100644
--- a/dist/lib/syntax/color/color-mix.js
+++ b/dist/lib/syntax/color/color-mix.js
@@ -2,9 +2,7 @@ import { EnumToken, ColorType } from '../../ast/types.js';
import { minmax, getNumber } from './color.js';
import { srgbvalues, srgb2lsrgbvalues } from './srgb.js';
import { srgb2lch, xyz2lchvalues } from './lch.js';
-import { srgb2rgb } from './rgb.js';
import { srgb2hslvalues } from './hsl.js';
-import { srgb2hwb } from './hwb.js';
import { srgb2labvalues } from './lab.js';
import { srgb2lp3values, srgb2p3values } from './p3.js';
import { getColorComponents } from './utils/components.js';
@@ -121,6 +119,9 @@ function colorMix(...args) {
if (values == null) {
return null;
}
+ if (colorSpace == "hwb") {
+ colorSpace = "srgb";
+ }
switch (colorSpace) {
case "srgb":
break;
@@ -150,17 +151,17 @@ function colorMix(...args) {
values = srgb2xyz_d65(values[0], values[1], values[2], values[3]);
values = XYZ_D65_to_D50(values[0], values[1], values[2], values[3]);
break;
- case "rgb":
- for (let j = 0; j < values.length; j++) {
- values[j] = j == 3 ? values[j] : srgb2rgb(values[j]);
- }
- break;
+ // case "rgb":
+ // for (let j = 0; j < values.length; j++) {
+ // values[j] = j == 3 ? values[j] : srgb2rgb(values[j]);
+ // }
+ // break;
case "hsl":
values = srgb2hslvalues(values[0], values[1], values[2], values[3]);
break;
- case "hwb":
- values = srgb2hwb(values[0], values[1], values[2], values[3]);
- break;
+ // case "hwb":
+ // values = srgb2hwb(values[0], values[1], values[2], values[3]);
+ // break;
case "lab":
values = srgb2labvalues(values[0], values[1], values[2], values[3]);
break;
@@ -359,14 +360,14 @@ function colorMix(...args) {
kin: ColorType.COLOR,
cal: "col",
};
- case "rgb":
+ // case "rgb":
case "hsl":
- case "hwb":
+ // case "hwb":
case "lab":
case "lch":
case "oklab":
case "oklch":
- if (colorSpace == "hsl" || colorSpace == "hwb") {
+ if (colorSpace == "hsl") {
// @ts-ignore
if (values[2] < 0) {
// @ts-ignore
@@ -396,7 +397,7 @@ function colorMix(...args) {
}),
kin: ColorType[colorSpace.toUpperCase().replaceAll("-", "_")],
};
- if (colorSpace == "hsl" || colorSpace == "hwb") {
+ if (colorSpace == "hsl") {
// @ts-ignore
result.chi[0] = { typ: EnumToken.AngleTokenType, val: result.chi[0].val * 360 };
// @ts-ignore
diff --git a/dist/lib/syntax/color/hex.js b/dist/lib/syntax/color/hex.js
index c21026b67..6fdc2bc42 100644
--- a/dist/lib/syntax/color/hex.js
+++ b/dist/lib/syntax/color/hex.js
@@ -70,7 +70,10 @@ function color2HexToken(token) {
if (value == null) {
return null;
}
- return hexToken(value.reduce((acc, curr) => acc + srgb2rgb(curr + Number.EPSILON).toString(16).padStart(2, "0"), "#"));
+ return hexToken(value.reduce((acc, curr) => acc +
+ srgb2rgb(curr + Number.EPSILON)
+ .toString(16)
+ .padStart(2, "0"), "#"));
}
function oklab2HexToken(token) {
let value = oklab2srgbvalues(token);
diff --git a/dist/lib/syntax/color/relative-color.js b/dist/lib/syntax/color/relative-color.js
index 68e56a13d..b5b915146 100644
--- a/dist/lib/syntax/color/relative-color.js
+++ b/dist/lib/syntax/color/relative-color.js
@@ -44,20 +44,20 @@ function parseRelativeColorComponents(relativeKeys, original, rExp, gExp, bExp,
continue;
}
if (component.typ == EnumToken.IdenTokenType) {
- val = component.val.toLowerCase();
+ val = component.val;
if (
// @ts-expect-error
typeof Math[val.toUpperCase()] !== "number" &&
- val != "in" &&
- val != "hue" &&
- val != "from" &&
- val != "alpha" &&
- val != "none" &&
- val != "shorter" &&
- val != "longer" &&
- val != "increasing" &&
- val != "decreasing" &&
- !colorsFunc.includes(val) &&
+ !equalsIgnoreCase(val, "in") &&
+ !equalsIgnoreCase(val, "hue") &&
+ !equalsIgnoreCase(val, "from") &&
+ !equalsIgnoreCase(val, "alpha") &&
+ !equalsIgnoreCase(val, "none") &&
+ !equalsIgnoreCase(val, "shorter") &&
+ !equalsIgnoreCase(val, "longer") &&
+ !equalsIgnoreCase(val, "increasing") &&
+ !equalsIgnoreCase(val, "decreasing") &&
+ !colorsFunc.some((t) => equalsIgnoreCase(t, val)) &&
!colorFuncColorSpace.includes(val) &&
!validKeys.includes(val)) {
return null;
diff --git a/dist/lib/syntax/color/utils/components.js b/dist/lib/syntax/color/utils/components.js
index 559d04785..2cd077053 100644
--- a/dist/lib/syntax/color/utils/components.js
+++ b/dist/lib/syntax/color/utils/components.js
@@ -4,13 +4,6 @@ import { expandHexValue } from '../hex.js';
import { equalsIgnoreCase } from '../../../parser/utils/text.js';
function getColorComponents(token) {
- // if (token.typ === EnumToken.IdenTokenType) {
- // if (isColor(token)) {
- // parseColor(token);
- // } else {
- // return null;
- // }
- // }
if (token.kin == ColorType.HEX || token.kin == ColorType.LIT) {
if (equalsIgnoreCase("currentcolor", token.val)) {
return null;
@@ -34,25 +27,12 @@ function getColorComponents(token) {
].includes(child.typ)) {
continue;
}
- // if (child.typ === EnumToken.IdenTokenType && isColor(child)) {
- // parseColor(child);
- // }
if (child.typ === EnumToken.FunctionTokenType ||
child.typ === EnumToken.WildCardFunctionTokenType ||
child.typ === EnumToken.MathFunctionTokenType) {
if ("var" == child.val.toLowerCase()) {
return null;
}
- // else {
- // for (const { value } of walkValues((child as FunctionToken).chi)) {
- // if (
- // value.typ == EnumToken.WildCardFunctionTokenDefType &&
- // "var" === (value as FunctionToken).val.toLowerCase()
- // ) {
- // return null;
- // }
- // }
- // }
}
if (child.typ == EnumToken.ColorTokenType && equalsIgnoreCase("currentcolor", child.val)) {
return null;
diff --git a/dist/lib/syntax/constants.js b/dist/lib/syntax/constants.js
index 3297b2c0d..e92ac312b 100644
--- a/dist/lib/syntax/constants.js
+++ b/dist/lib/syntax/constants.js
@@ -67,6 +67,11 @@ const anglePrecision = 3;
* Color range definitions
*/
const colorRange = {
+ rgb: {
+ r: [0, 255],
+ g: [0, 255],
+ b: [0, 255],
+ },
lab: {
l: [0, 100],
a: [-125, 125],
diff --git a/dist/lib/syntax/syntax.js b/dist/lib/syntax/syntax.js
index e44ba17e3..4690cf7ce 100644
--- a/dist/lib/syntax/syntax.js
+++ b/dist/lib/syntax/syntax.js
@@ -16,12 +16,12 @@ import { getSyntaxConfig } from '../validation/config.js';
// '\\'
const REVERSE_SOLIDUS = 0x5c;
const flexUnits = ["fr"];
-const frequencyUnits = ["hz", "khz"];
+const frequencyUnits = ["Hz", "kHz"];
const timeUnits = ["ms", "s"];
const angleUnits = ["rad", "turn", "deg", "grad"];
const resolutionUnits = ["dpi", "dpcm", "dppx", "x"];
const dimensionUnits = [
- "q",
+ "Q",
"cap",
"ch",
"cm",
diff --git a/dist/lib/validation/match.js b/dist/lib/validation/match.js
index f865e4bf9..3ee9a31e4 100644
--- a/dist/lib/validation/match.js
+++ b/dist/lib/validation/match.js
@@ -643,7 +643,8 @@ function matchAllSyntaxes(syntaxes, context, options) {
for (let i = index; i < syntaxes.length; i++) {
if (syntaxes[i].typ == ValidationTokenEnum.Whitespace ||
syntaxes[i].isOptional ||
- syntaxes[i].isRepeatable) {
+ syntaxes[i].isRepeatable ||
+ syntaxes[i].match?.min?.val === 0) {
continue;
}
return {
diff --git a/dist/web.js b/dist/web.js
index f7e55bf76..e3e3363d2 100644
--- a/dist/web.js
+++ b/dist/web.js
@@ -17,6 +17,7 @@ export { isOkLabClose, okLabDistance } from './lib/syntax/color/utils/distance.j
export { find, findAll, findByValue, findLast } from './lib/ast/find.js';
export { cloneNode } from './lib/ast/clone.js';
export { replaceNodeOrValue } from './lib/parser/utils/token.js';
+export { PropertyList } from './lib/parser/declaration/list.js';
export { SourceMap } from './lib/printer/sourcemap/sourcemap.js';
export { FeatureWalkMode } from './lib/ast/features/type.js';
export { getNodeProperty, setNodeProperty } from './lib/ast/node.js';
diff --git a/files/architecture.md b/files/architecture.md
new file mode 100644
index 000000000..4ea848bcd
--- /dev/null
+++ b/files/architecture.md
@@ -0,0 +1,69 @@
+---
+title: Architecture
+group: Documents
+category: Guides
+---
+
+# CSS parser architecture
+
+```mermaid
+flowchart TD
+ %% --- Transform ---
+ Input(["CSS input"])
+
+
+ %% The Grouped Container
+ subgraph Group10["Transform step"]
+
+ transform["transform()/transformSync()"]
+
+
+ %% The Grouped Container
+ subgraph Group1 ["Parse step"]
+
+ %% --- Parse step ---
+ parse["parse()/parseSync()"]
+ tokenize(["tokenize()"])
+ parseNode(["parse and validate token stream"])
+ visitors(["visitors"])
+ minify(["minify AST"])
+ cssModules(["generate CSS module"])
+ parseResult["Parse result"]
+ end
+
+ %% The Grouped Container
+ subgraph Group2 ["Render step"]
+
+ %% --- Render step ---
+ renderAst(["Render AST"])
+ sourcemap([Sourcemap generation])
+
+ end
+
+ %% --- Result step ---
+ transformResult["Transform result"]
+ end
+
+ %% --- Routing step ---
+ Input --> transform
+ transform --> parse
+ parse --> tokenize
+ tokenize --> parseNode
+ parseNode -- "Visitors set?" --> visitors
+ visitors -- "Minify AST?" --> minify
+ minify -- "CSS module?" --> cssModules
+ visitors -- "CSS module?" --> cssModules
+ cssModules --> parseResult
+ parseNode -- "CSS module?" --> cssModules
+ parseNode -- "Minify AST?" --> minify
+ parseNode --> parseResult
+ visitors --> parseResult
+ minify --> parseResult
+ parseResult --> renderAst
+ renderAst -- "Sourcemap?" --> sourcemap
+ renderAst --> transformResult
+ sourcemap --> transformResult
+```
+------
+[← Usage](./usage.md) | [Validation →](./Guide.Validation.html)
+
diff --git a/files/assets/typedoc-custom.css b/files/assets/typedoc-custom.css
index 2cb11e7ad..6c2a8a9ab 100644
--- a/files/assets/typedoc-custom.css
+++ b/files/assets/typedoc-custom.css
@@ -74,26 +74,54 @@ html[data-theme="dark"] {
}
}
}
+
+ table {
+ border-collapse: collapse;
+ margin-bottom: 15px;
+
+ tr {
+ border-bottom: 1px solid #f0f0f0;
+
+ th {
+ font-weight: 400;
+ }
+
+ th,
+ td {
+ padding-bottom: 5px;
+ padding-top: 5px;
+ text-align: left;
+ }
+ }
+
+ thead th {
+ text-align: left;
+ }
+
+ tbody {
+ tr {
+ &:hover {
+ background-color: var(--transparent-blue) !important;
+ color: var(--blue-dark) !important;
+ }
+ }
+ td {
+ text-align: left;
+ }
+ }
+ }
}
}
}
-#main-function-differences ~ table tbody tr {
- &:hover {
- background-color: var(--transparent-blue) !important;
- color: var(--blue-dark) !important;
- }
+#css-parser-architecture ~ .mermaid-block .mermaid {
+ min-height: 1745px;
- td {
- &:first-child {
- text-align: left;
- }
-
- text-align: center;
+ svg {
+ min-height: 1740px;
}
}
-
.tsd-kind-icon {
- width: 16px;
-}
\ No newline at end of file
+ width: 16px;
+}
diff --git a/files/getting-started.md b/files/getting-started.md
index 564ff7e4f..df6ac0b1e 100644
--- a/files/getting-started.md
+++ b/files/getting-started.md
@@ -62,7 +62,7 @@ It can be imported as an umd module.
```html
+
+