UNPKG

@tbela99/css-parser

Version:

CSS parser, minifier and validator for node and the browser

487 lines (484 loc) 13.2 kB
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 };