@tbela99/css-parser
Version:
CSS parser, minifier and validator for node and the browser
487 lines (484 loc) • 13.2 kB
JavaScript
import { EnumToken } from '../ast/types.js';
import config from '../validation/config.json.js';
const LOC = Symbol.for("loc");
const RAW = Symbol.for("raw");
const STATE = Symbol.for("state");
const ROOT = Symbol.for("root");
const ERRORS = Symbol.for("errors");
const TOKENS = Symbol.for("tokens");
const PARENT = Symbol.for("parent");
const OPTIMIZED = Symbol.for("optimized");
const PROPERTYNAME = Symbol.for("propertyName");
const regMatchLinearGradient = /^-((webkit)|o|moz)(-repeating)?-linear-gradient$/i;
const regMatchRadialGradient = /^-((webkit)|o|moz)(-repeating)?-radial-gradient$/i;
const mFLT = new Set([EnumToken.LtTokenType, EnumToken.LteTokenType]);
const mFGT = new Set([EnumToken.GtTokenType, EnumToken.GteTokenType]);
const tokensMap = new Map([
[EnumToken.Star, EnumToken.Mul],
[EnumToken.Plus, EnumToken.Add],
]);
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
const tokensfuncDefMap = new Map([
[EnumToken.FunctionTokenDefType, EnumToken.FunctionTokenType],
[EnumToken.ColorFunctionTokenDefType, EnumToken.ColorTokenType],
[EnumToken.UrlFunctionTokenDefType, EnumToken.UrlFunctionTokenType],
[EnumToken.MathFunctionTokenDefType, EnumToken.MathFunctionTokenType],
[EnumToken.ImageFunctionTokenDefType, EnumToken.ImageFunctionTokenType],
[EnumToken.TimingFunctionTokenDefType, EnumToken.TimingFunctionTokenType],
[EnumToken.CustomFunctionTokenDefType, EnumToken.CustomFunctionTokenType],
[EnumToken.WildCardFunctionTokenDefType, EnumToken.WildCardFunctionTokenType],
[EnumToken.TimelineFunctionTokenDefType, EnumToken.TimelineFunctionTokenType],
[EnumToken.GridTemplateFuncTokenDefType, EnumToken.GridTemplateFuncTokenType],
[EnumToken.SupportsFunctionTokenDefType, EnumToken.SupportsFunctionTokenType],
[EnumToken.WhenElseFunctionTokenDefType, EnumToken.WhenElseFunctionTokenType],
[EnumToken.ContainerFunctionTokenDefType, EnumToken.ContainerFunctionTokenType],
[EnumToken.PseudoClassFunctionTokenDefType, EnumToken.PseudoClassFuncTokenType],
[EnumToken.TransformFunctionTokenDefType, EnumToken.TransformFunctionTokenType],
[EnumToken.GeneralEnclosedFunctionTokenDefType, EnumToken.GeneralEnclosedFunctionTokenType],
]);
const tokensfuncSet = new Set(tokensfuncDefMap.values());
/**
* Epsilon
*/
const epsilon = 1e-5;
/**
* Color distance precision
*/
const colorDistancePrecision = epsilon;
/**
* Color precision
*/
const colorPrecision = 6;
/**
* Angle precision
*/
const anglePrecision = 0.001;
/**
* Color range definitions
*/
const colorRange = {
lab: {
l: [0, 100],
a: [-125, 125],
b: [-125, 125],
},
lch: {
l: [0, 100],
c: [0, 150],
h: [0, 360],
},
oklab: {
l: [0, 1],
a: [-0.4, 0.4],
b: [-0.4, 0.4],
},
oklch: {
l: [0, 1],
a: [0, 0.4],
b: [0, 0.4],
},
};
// https://www.w3.org/TR/css-values-4/#math-function
const pseudoElements = [
":before",
":after",
":first-line",
":first-letter",
"::before",
"::after",
"::first-line",
"::first-letter",
];
const wildCardFuncs = ["var", "env", "if"];
const mathFuncs = [
"minmax",
"repeat",
"fit-content",
"calc",
"clamp",
"min",
"max",
"round",
"mod",
"rem",
"sin",
"cos",
"tan",
"asin",
"acos",
"atan",
"atan2",
"pow",
"sqrt",
"hypot",
"log",
"exp",
"abs",
"sign",
"anchor",
];
// export const fontFormat: string[] = ['collection', 'embedded-opentype', 'opentype', 'svg', 'truetype', 'woff', 'woff2'];
// export const colorFontTech: string[] = ['color-colrv0', 'color-colrv1', 'color-svg', 'color-sbix', 'color-cbdt'];
// export const fontFeaturesTech: string[] = ['features-opentype', 'features-aat', 'features-graphite', 'incremental-patch', 'incremental-range', 'incremental-auto', 'variations', 'palettes'];
// https://drafts.csswg.org/mediaqueries/#media-types
const mediaTypes = [
"all",
"print",
"screen",
/* deprecated */
"aural",
"braille",
"embossed",
"handheld",
"projection",
"tty",
"tv",
"speech",
];
const pageMarginBoxType = new Set([
"top-left-corner",
"top-left",
"top-center",
"top-right",
"top-right-corner",
"bottom-left-corner",
"bottom-left",
"bottom-center",
"bottom-right",
"bottom-right-corner",
"left-top",
"left-middle",
"left-bottom",
"right-top",
"right-middle",
"right-bottom",
]);
const urlFunc = ["url"];
const timelineFunc = ["view", "scroll"];
const gridTemplateFunc = ["minmax", "fit-content", "repeat"];
// export const generalEnclosedFunc: string[] = [];
const supportFunc = ["selector", "font-tech", "font-format", "at-rule", "named-feature"];
const whenElseFunc = ["media", "supports"];
const containerFunc = ["style", "scroll-state"];
const timingFunc = [
"ease",
"ease-in",
"ease-out",
"ease-in-out",
"linear",
"step-start",
"step-end",
"steps",
"cubic-bezier",
];
const colorsFunc = [
"rgb",
"rgba",
"hsl",
"hsla",
"hwb",
"device-cmyk",
"color-mix",
"color",
"oklab",
"lab",
"oklch",
"lch",
"light-dark",
"contrast-color",
"alpha",
];
const imageFunc = [
"linear-gradient",
"radial-gradient",
"repeating-linear-gradient",
"repeating-radial-gradient",
"repeating-conic-gradient",
"conic-gradient",
"image",
"image-set",
"element",
"cross-fade",
"paint",
"-o-linear-gradient",
"-moz-linear-gradient",
"-webkit-linear-gradient",
"-webkit-repeating-linear-gradient",
"-webkit-gradient",
"-webkit-radial-gradient",
"-webkit-repeating-radial-gradient",
];
const transformFunctions = [
"translate",
"scale",
"rotate",
"skew",
"perspective",
"translateX",
"translateY",
"translateZ",
"scaleX",
"scaleY",
"scaleZ",
"rotateX",
"rotateY",
"rotateZ",
"skewX",
"skewY",
"rotate3d",
"translate3d",
"scale3d",
"matrix",
"matrix3d",
];
const funcLike = [
EnumToken.ParensTokenType,
EnumToken.FunctionTokenType,
EnumToken.UrlFunctionTokenType,
EnumToken.StartParensTokenType,
EnumToken.ImageFunctionTokenType,
EnumToken.TimingFunctionTokenType,
EnumToken.TimingFunctionTokenType,
EnumToken.PseudoClassFuncTokenType,
EnumToken.GridTemplateFuncTokenType,
];
const colorFuncColorSpace = [
"srgb",
"srgb-linear",
"display-p3",
"display-p3-linear",
"prophoto-rgb",
"a98-rgb",
"rec2020",
"lab",
"oklab",
"xyz",
"xyz-d65",
"xyz-d50",
];
const D50 = [0.3457 / 0.3585, 1.0, (1.0 - 0.3457 - 0.3585) / 0.3585];
const k = Math.pow(29, 3) / Math.pow(3, 3);
const e = Math.pow(6, 3) / Math.pow(29, 3);
const nonStandardColors = new Set(config.syntaxes["-non-standard-color"].syntax.split(/[\s|]+/g).map((m) => m.toLowerCase()));
// color module v4
const systemColors = new Set([
"ActiveText",
"ButtonBorder",
"ButtonFace",
"ButtonText",
"Canvas",
"CanvasText",
"Field",
"FieldText",
"GrayText",
"Highlight",
"HighlightText",
"LinkText",
"Mark",
"MarkText",
"VisitedText",
"-webkit-focus-ring-color",
].map((m) => m.toLowerCase()));
// deprecated
const deprecatedSystemColors = new Set([
"ActiveBorder",
"ActiveCaption",
"AppWorkspace",
"Background",
"ButtonFace",
"ButtonHighlight",
"ButtonShadow",
"ButtonText",
"CaptionText",
"GrayText",
"Highlight",
"HighlightText",
"InactiveBorder",
"InactiveCaption",
"InactiveCaptionText",
"InfoBackground",
"InfoText",
"Menu",
"MenuText",
"Scrollbar",
"ThreeDDarkShadow",
"ThreeDFace",
"ThreeDHighlight",
"ThreeDLightShadow",
"ThreeDShadow",
"Window",
"WindowFrame",
"WindowText",
].map((t) => t.toLowerCase()));
// name to color
const COLORS_NAMES = Object.seal({
aliceblue: "#f0f8ff",
antiquewhite: "#faebd7",
aqua: "#00ffff",
aquamarine: "#7fffd4",
azure: "#f0ffff",
beige: "#f5f5dc",
bisque: "#ffe4c4",
black: "#000000",
blanchedalmond: "#ffebcd",
blue: "#0000ff",
blueviolet: "#8a2be2",
brown: "#a52a2a",
burlywood: "#deb887",
cadetblue: "#5f9ea0",
chartreuse: "#7fff00",
chocolate: "#d2691e",
coral: "#ff7f50",
cornflowerblue: "#6495ed",
cornsilk: "#fff8dc",
crimson: "#dc143c",
cyan: "#00ffff",
darkblue: "#00008b",
darkcyan: "#008b8b",
darkgoldenrod: "#b8860b",
darkgray: "#a9a9a9",
darkgrey: "#a9a9a9",
darkgreen: "#006400",
darkkhaki: "#bdb76b",
darkmagenta: "#8b008b",
darkolivegreen: "#556b2f",
darkorange: "#ff8c00",
darkorchid: "#9932cc",
darkred: "#8b0000",
darksalmon: "#e9967a",
darkseagreen: "#8fbc8f",
darkslateblue: "#483d8b",
darkslategray: "#2f4f4f",
darkslategrey: "#2f4f4f",
darkturquoise: "#00ced1",
darkviolet: "#9400d3",
deeppink: "#ff1493",
deepskyblue: "#00bfff",
dimgray: "#696969",
dimgrey: "#696969",
dodgerblue: "#1e90ff",
firebrick: "#b22222",
floralwhite: "#fffaf0",
forestgreen: "#228b22",
fuchsia: "#ff00ff",
gainsboro: "#dcdcdc",
ghostwhite: "#f8f8ff",
gold: "#ffd700",
goldenrod: "#daa520",
gray: "#808080",
grey: "#808080",
green: "#008000",
greenyellow: "#adff2f",
honeydew: "#f0fff0",
hotpink: "#ff69b4",
indianred: "#cd5c5c",
indigo: "#4b0082",
ivory: "#fffff0",
khaki: "#f0e68c",
lavender: "#e6e6fa",
lavenderblush: "#fff0f5",
lawngreen: "#7cfc00",
lemonchiffon: "#fffacd",
lightblue: "#add8e6",
lightcoral: "#f08080",
lightcyan: "#e0ffff",
lightgoldenrodyellow: "#fafad2",
lightgray: "#d3d3d3",
lightgrey: "#d3d3d3",
lightgreen: "#90ee90",
lightpink: "#ffb6c1",
lightsalmon: "#ffa07a",
lightseagreen: "#20b2aa",
lightskyblue: "#87cefa",
lightslategray: "#778899",
lightslategrey: "#778899",
lightsteelblue: "#b0c4de",
lightyellow: "#ffffe0",
lime: "#00ff00",
limegreen: "#32cd32",
linen: "#faf0e6",
magenta: "#ff00ff",
maroon: "#800000",
mediumaquamarine: "#66cdaa",
mediumblue: "#0000cd",
mediumorchid: "#ba55d3",
mediumpurple: "#9370d8",
mediumseagreen: "#3cb371",
mediumslateblue: "#7b68ee",
mediumspringgreen: "#00fa9a",
mediumturquoise: "#48d1cc",
mediumvioletred: "#c71585",
midnightblue: "#191970",
mintcream: "#f5fffa",
mistyrose: "#ffe4e1",
moccasin: "#ffe4b5",
navajowhite: "#ffdead",
navy: "#000080",
oldlace: "#fdf5e6",
olive: "#808000",
olivedrab: "#6b8e23",
orange: "#ffa500",
orangered: "#ff4500",
orchid: "#da70d6",
palegoldenrod: "#eee8aa",
palegreen: "#98fb98",
paleturquoise: "#afeeee",
palevioletred: "#d87093",
papayawhip: "#ffefd5",
peachpuff: "#ffdab9",
peru: "#cd853f",
pink: "#ffc0cb",
plum: "#dda0dd",
powderblue: "#b0e0e6",
purple: "#800080",
red: "#ff0000",
rosybrown: "#bc8f8f",
royalblue: "#4169e1",
saddlebrown: "#8b4513",
salmon: "#fa8072",
sandybrown: "#f4a460",
seagreen: "#2e8b57",
seashell: "#fff5ee",
sienna: "#a0522d",
silver: "#c0c0c0",
skyblue: "#87ceeb",
slateblue: "#6a5acd",
slategray: "#708090",
slategrey: "#708090",
snow: "#fffafa",
springgreen: "#00ff7f",
steelblue: "#4682b4",
tan: "#d2b48c",
teal: "#008080",
thistle: "#d8bfd8",
tomato: "#ff6347",
turquoise: "#40e0d0",
violet: "#ee82ee",
wheat: "#f5deb3",
white: "#ffffff",
whitesmoke: "#f5f5f5",
yellow: "#ffff00",
yellowgreen: "#9acd32",
rebeccapurple: "#663399",
transparent: "#00000000",
});
// color to name
const NAMES_COLORS = Object.seal(Object.entries(COLORS_NAMES).reduce((acc, [key, value]) => {
acc[value] = key;
return acc;
}, Object.create(null)));
const trimTokenSpace = new Set([
EnumToken.Add,
EnumToken.Mul,
EnumToken.Div,
EnumToken.Sub,
EnumToken.ColonTokenType,
EnumToken.CommaTokenType,
EnumToken.SemiColonTokenType,
EnumToken.DashedIdenTokenType,
EnumToken.DeclarationNodeType,
EnumToken.SupportsQueryConditionTokenType,
EnumToken.SupportsQueryUnaryConditionTokenType,
]);
const combinators = ["+", ">", "~", "||", "|"];
export { COLORS_NAMES, D50, ERRORS, LOC, NAMES_COLORS, OPTIMIZED, PARENT, PROPERTYNAME, RAW, ROOT, STATE, TOKENS, anglePrecision, colorDistancePrecision, colorFuncColorSpace, colorPrecision, colorRange, colorsFunc, combinators, containerFunc, deprecatedSystemColors, e, epsilon, funcLike, gridTemplateFunc, imageFunc, k, mFGT, mFLT, mathFuncs, mediaTypes, nonStandardColors, pageMarginBoxType, pseudoElements, regMatchLinearGradient, regMatchRadialGradient, supportFunc, systemColors, timelineFunc, timingFunc, tokensMap, tokensfuncDefMap, tokensfuncSet, transformFunctions, trimTokenSpace, urlFunc, urlTokenMatcher, whenElseFunc, wildCardFuncs };