@tbela99/css-parser
Advanced tools
Comparing version
@@ -94,2 +94,3 @@ declare enum EnumToken { | ||
PseudoPageTokenType = 91, | ||
PseudoElementTokenType = 92, | ||
Time = 25, | ||
@@ -133,3 +134,3 @@ Iden = 7, | ||
*/ | ||
declare function minify(ast: AstNode, options?: ParserOptions | MinifyOptions, recursive?: boolean, errors?: ErrorDescription[], nestingContent?: boolean, context?: { | ||
declare function minify(ast: AstNode, options?: ParserOptions | MinifyFeatureOptions, recursive?: boolean, errors?: ErrorDescription[], nestingContent?: boolean, context?: { | ||
[key: string]: any; | ||
@@ -522,2 +523,8 @@ }): AstNode; | ||
export declare interface PseudoElementToken extends BaseToken { | ||
typ: EnumToken.PseudoElementTokenType; | ||
val: string; | ||
} | ||
export declare interface PseudoPageToken extends BaseToken { | ||
@@ -818,2 +825,3 @@ | ||
| PseudoPageToken | ||
| PseudoElementToken | ||
| PseudoClassFunctionToken | ||
@@ -1042,11 +1050,20 @@ | DelimToken | ||
export declare interface ParserOptions extends ValidationOptions, PropertyListOptions { | ||
interface MinifyOptions { | ||
minify?: boolean; | ||
nestingRules?: boolean; | ||
expandNestingRules?: boolean; | ||
removeDuplicateDeclarations?: boolean; | ||
computeShorthand?: boolean; | ||
computeCalcExpression?: boolean; | ||
inlineCssVariables?: boolean; | ||
removeEmpty?: boolean; | ||
pass?: number; | ||
} | ||
export declare interface ParserOptions extends MinifyOptions, ValidationOptions, PropertyListOptions { | ||
src?: string; | ||
sourcemap?: boolean; | ||
nestingRules?: boolean; | ||
expandNestingRules?: boolean; | ||
removeCharset?: boolean; | ||
removeEmpty?: boolean; | ||
resolveUrls?: boolean; | ||
@@ -1056,7 +1073,3 @@ resolveImport?: boolean; | ||
parseColor?: boolean; | ||
removeDuplicateDeclarations?: boolean; | ||
computeShorthand?: boolean; | ||
removePrefix?: boolean; | ||
inlineCssVariables?: boolean; | ||
computeCalcExpression?: boolean; | ||
load?: (url: string, currentUrl: string) => Promise<string>; | ||
@@ -1073,3 +1086,3 @@ dirname?: (path: string) => string; | ||
export declare interface MinifyOptions extends ParserOptions { | ||
export declare interface MinifyFeatureOptions extends ParserOptions { | ||
@@ -1083,3 +1096,3 @@ features: MinifyFeature[]; | ||
register(options: MinifyOptions | ParserOptions): void; | ||
register(options: MinifyFeatureOptions | ParserOptions): void; | ||
@@ -1094,3 +1107,3 @@ // run(ast: AstRule | AstAtRule, options: ParserOptions = {}, parent: AstRule | AstAtRule | AstRuleStyleSheet, context: { [key: string]: any }): void; | ||
ordering: number; | ||
register: (options: MinifyOptions | ParserOptions) => void; | ||
register: (options: MinifyFeatureOptions | ParserOptions) => void; | ||
run: (ast: AstRule | AstAtRule, options: ParserOptions, parent: AstRule | AstAtRule | AstRuleStyleSheet, context: { | ||
@@ -1097,0 +1110,0 @@ [key: string]: any |
@@ -72,3 +72,10 @@ import { splitRule, combinators } from './minify.js'; | ||
else { | ||
selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' ')); | ||
// selRule = splitRule(selRule.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.join(''), '')); | ||
const arSelf = splitRule(ast.sel).filter((r) => r.every((t) => t != ':before' && t != ':after' && !t.startsWith('::'))).reduce((acc, curr) => acc.concat([curr.join('')]), []).join(','); | ||
if (arSelf.length == 0) { | ||
ast.chi.splice(i--, 1); | ||
continue; | ||
} | ||
// | ||
selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(arSelf) : arr.unshift(arSelf, ' ')); | ||
rule.sel = selRule.reduce((acc, curr) => { | ||
@@ -84,4 +91,10 @@ acc.push(curr.join('')); | ||
let withoutCompound = []; | ||
const rules = splitRule(ast.sel); | ||
// pseudo elements cannot be used with '&' | ||
// https://www.w3.org/TR/css-nesting-1/#example-7145ff1e | ||
const rules = splitRule(ast.sel).filter((r) => r.every((t) => t != ':before' && t != ':after' && !t.startsWith('::'))); | ||
const parentSelector = !node.sel.includes('&'); | ||
if (rules.length == 0) { | ||
ast.chi.splice(i--, 1); | ||
continue; | ||
} | ||
for (const sel of (rule.raw ?? splitRule(rule.sel))) { | ||
@@ -88,0 +101,0 @@ const s = sel.join(''); |
@@ -230,3 +230,3 @@ import { parseString } from '../parser/parse.js'; | ||
// @ts-ignore | ||
let sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule; | ||
let sel = wrap ? node.optimized.optimized.join('') + `:is(${rule})` : rule; | ||
if (rule.includes('&')) { | ||
@@ -233,0 +233,0 @@ // @ts-ignore |
@@ -104,2 +104,3 @@ var ValidationLevel; | ||
EnumToken[EnumToken["PseudoPageTokenType"] = 91] = "PseudoPageTokenType"; | ||
EnumToken[EnumToken["PseudoElementTokenType"] = 92] = "PseudoElementTokenType"; | ||
/* aliases */ | ||
@@ -106,0 +107,0 @@ EnumToken[EnumToken["Time"] = 25] = "Time"; |
@@ -1,2 +0,2 @@ | ||
import { webkitPseudoAliasMap, isIdentStart, isIdent, mathFuncs, isColor, isHexColor, isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isHash, mediaTypes } from '../syntax/syntax.js'; | ||
import { webkitPseudoAliasMap, isIdentStart, isIdent, mathFuncs, isColor, isHexColor, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isHash, mediaTypes } from '../syntax/syntax.js'; | ||
import './utils/config.js'; | ||
@@ -49,2 +49,3 @@ import { EnumToken, funcLike, ValidationLevel } from '../ast/types.js'; | ||
minify: true, | ||
pass: 1, | ||
parseColor: true, | ||
@@ -169,3 +170,3 @@ nestingRules: false, | ||
if (context != null && context.typ == EnumToken.InvalidRuleTokenType) { | ||
const index = context.chi.findIndex(node => node == context); | ||
const index = context.chi.findIndex((node) => node == context); | ||
if (index > -1) { | ||
@@ -230,3 +231,6 @@ context.chi.splice(index, 1); | ||
if (ast.chi.length > 0) { | ||
minify(ast, options, true, errors, false); | ||
let passes = options.pass ?? 1; | ||
while (passes--) { | ||
minify(ast, options, true, errors, false); | ||
} | ||
} | ||
@@ -332,4 +336,9 @@ } | ||
if (type != EnumToken.AtRuleNodeType) { | ||
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } }); | ||
return null; | ||
// @ts-ignore | ||
if (!(type == EnumToken.InvalidAtRuleTokenType && | ||
// @ts-ignore | ||
['charset', 'layer', 'import'].includes(context.chi[i].nam))) { | ||
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } }); | ||
return null; | ||
} | ||
} | ||
@@ -369,3 +378,3 @@ // @ts-ignore | ||
tokens.shift(); | ||
if (tokens[1].typ == EnumToken.UrlTokenTokenType) { | ||
if (tokens[0]?.typ == EnumToken.UrlTokenTokenType) { | ||
// @ts-ignore | ||
@@ -376,2 +385,10 @@ tokens[0].typ = EnumToken.StringTokenType; | ||
} | ||
// @ts-ignore | ||
while (tokens[1]?.typ == EnumToken.WhitespaceTokenType || tokens[1]?.typ == EnumToken.CommentTokenType) { | ||
tokens.splice(1, 1); | ||
} | ||
// @ts-ignore | ||
if (tokens[1]?.typ == EnumToken.EndParensTokenType) { | ||
tokens.splice(1, 1); | ||
} | ||
} | ||
@@ -460,7 +477,7 @@ } | ||
nam: renderToken(atRule, { removeComments: true }), | ||
tokens: t, | ||
// tokens: t, | ||
val: raw.join('') | ||
}; | ||
Object.defineProperties(node, { | ||
tokens: { ...definedPropertySettings, enumerable: true, value: tokens.slice() }, | ||
tokens: { ...definedPropertySettings, enumerable: false, value: tokens.slice() }, | ||
raw: { ...definedPropertySettings, value: raw } | ||
@@ -590,3 +607,3 @@ }); | ||
...definedPropertySettings, | ||
enumerable: true, | ||
enumerable: false, | ||
value: tokens.slice() | ||
@@ -692,3 +709,3 @@ }); | ||
// | ||
// console.error({valid}); | ||
// // console.error({valid}); | ||
// | ||
@@ -1065,6 +1082,12 @@ // if (valid.valid == ValidationLevel.Drop) { | ||
} | ||
: { | ||
typ: EnumToken.PseudoClassTokenType, | ||
: ( | ||
// https://www.w3.org/TR/selectors-4/#single-colon-pseudos | ||
val.startsWith('::') || pseudoElements.includes(val) ? { | ||
typ: EnumToken.PseudoElementTokenType, | ||
val | ||
}; | ||
} : | ||
{ | ||
typ: EnumToken.PseudoClassTokenType, | ||
val | ||
}); | ||
} | ||
@@ -1246,3 +1269,3 @@ if (isAtKeyword(val)) { | ||
} | ||
Object.assign(t, { | ||
const attr = Object.assign(t, { | ||
typ: inAttr == 0 ? EnumToken.AttrTokenType : EnumToken.InvalidAttrTokenType, | ||
@@ -1252,16 +1275,16 @@ chi: tokens.splice(i + 1, k - i) | ||
// @ts-ignore | ||
if (t.chi.at(-1).typ == EnumToken.AttrEndTokenType) { | ||
if (attr.chi.at(-1).typ == EnumToken.AttrEndTokenType) { | ||
// @ts-ignore | ||
t.chi.pop(); | ||
attr.chi.pop(); | ||
} | ||
// @ts-ignore | ||
if (t.chi.length > 1) { | ||
if (attr.chi.length > 1) { | ||
/*(<AttrToken>t).chi =*/ | ||
// @ts-ignore | ||
parseTokens(t.chi, t.typ); | ||
parseTokens(attr.chi, t.typ); | ||
} | ||
let m = t.chi.length; | ||
let m = attr.chi.length; | ||
let val; | ||
for (m = 0; m < t.chi.length; m++) { | ||
val = t.chi[m]; | ||
for (m = 0; m < attr.chi.length; m++) { | ||
val = attr.chi[m]; | ||
if (val.typ == EnumToken.StringTokenType) { | ||
@@ -1276,4 +1299,4 @@ const slice = val.val.slice(1, -1); | ||
let lower = m; | ||
while (++upper < t.chi.length) { | ||
if (t.chi[upper].typ == EnumToken.CommentTokenType) { | ||
while (++upper < attr.chi.length) { | ||
if (attr.chi[upper].typ == EnumToken.CommentTokenType) { | ||
continue; | ||
@@ -1284,3 +1307,3 @@ } | ||
while (lower-- > 0) { | ||
if (t.chi[lower].typ == EnumToken.CommentTokenType) { | ||
if (attr.chi[lower].typ == EnumToken.CommentTokenType) { | ||
continue; | ||
@@ -1291,10 +1314,10 @@ } | ||
// @ts-ignore | ||
t.chi[m] = { | ||
attr.chi[m] = { | ||
typ: EnumToken.NameSpaceAttributeTokenType, | ||
l: t.chi[lower], | ||
r: t.chi[upper] | ||
l: attr.chi[lower], | ||
r: attr.chi[upper] | ||
}; | ||
t.chi.splice(upper, 1); | ||
attr.chi.splice(upper, 1); | ||
if (lower >= 0) { | ||
t.chi.splice(lower, 1); | ||
attr.chi.splice(lower, 1); | ||
m--; | ||
@@ -1305,7 +1328,7 @@ } | ||
EnumToken.DashMatchTokenType, EnumToken.StartMatchTokenType, EnumToken.ContainMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DelimTokenType | ||
].includes(t.chi[m].typ)) { | ||
].includes(attr.chi[m].typ)) { | ||
let upper = m; | ||
let lower = m; | ||
while (++upper < t.chi.length) { | ||
if (t.chi[upper].typ == EnumToken.CommentTokenType) { | ||
while (++upper < attr.chi.length) { | ||
if (attr.chi[upper].typ == EnumToken.CommentTokenType) { | ||
continue; | ||
@@ -1316,3 +1339,3 @@ } | ||
while (lower-- > 0) { | ||
if (t.chi[lower].typ == EnumToken.CommentTokenType) { | ||
if (attr.chi[lower].typ == EnumToken.CommentTokenType) { | ||
continue; | ||
@@ -1322,3 +1345,3 @@ } | ||
} | ||
val = t.chi[lower]; | ||
val = attr.chi[lower]; | ||
if (val.typ == EnumToken.StringTokenType) { | ||
@@ -1330,3 +1353,3 @@ const slice = val.val.slice(1, -1); | ||
} | ||
val = t.chi[upper]; | ||
val = attr.chi[upper]; | ||
if (val.typ == EnumToken.StringTokenType) { | ||
@@ -1451,3 +1474,5 @@ const slice = val.val.slice(1, -1); | ||
t.kin = t.val; | ||
// @ts-ignore | ||
if (t.chi[0].typ == EnumToken.IdenTokenType) { | ||
// @ts-ignore | ||
if (t.chi[0].val == 'from') { | ||
@@ -1462,6 +1487,7 @@ // @ts-ignore | ||
} | ||
else if (t.val == 'color') { | ||
// @ts-ignore | ||
t.cal = 'col'; | ||
// t.chi = t.chi.filter((t: Token) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.PercentageTokenType].includes(t.typ)); | ||
else { // @ts-ignore | ||
if (t.val == 'color') { | ||
// @ts-ignore | ||
t.cal = 'col'; | ||
} | ||
} | ||
@@ -1500,3 +1526,3 @@ } | ||
// | ||
const count = t.chi.filter(t => t.typ != EnumToken.CommentTokenType).length; | ||
const count = t.chi.filter((t) => t.typ != EnumToken.CommentTokenType).length; | ||
if (count == 1 || | ||
@@ -1503,0 +1529,0 @@ (i == 0 && |
@@ -18,5 +18,5 @@ import { EnumToken } from '../../ast/types.js'; | ||
import { rec20202srgb, srgb2rec2020values } from './rec2020.js'; | ||
import { xyzd502srgb, srgb2xyz } from './xyz.js'; | ||
import { srgb2xyz } from './xyz.js'; | ||
import { p32srgbvalues, srgb2p3values } from './p3.js'; | ||
import { XYZ_D65_to_D50 } from './xyzd50.js'; | ||
import { xyzd502srgb, XYZ_D65_to_D50 } from './xyzd50.js'; | ||
import '../sourcemap/lib/encode.js'; | ||
@@ -23,0 +23,0 @@ import '../../parser/utils/config.js'; |
import { e, k, D50 } from './utils/constants.js'; | ||
import { getComponents } from './utils/components.js'; | ||
import { srgb2xyz, xyzd502srgb } from './xyz.js'; | ||
import { srgb2xyz } from './xyz.js'; | ||
import { oklch2srgb, hwb2srgb, hsl2srgb, rgb2srgb, hex2srgb } from './srgb.js'; | ||
@@ -12,2 +12,3 @@ import { getLCHComponents } from './lch.js'; | ||
import '../../parser/parse.js'; | ||
import { xyzd502srgb } from './xyzd50.js'; | ||
import '../sourcemap/lib/encode.js'; | ||
@@ -14,0 +15,0 @@ import '../../parser/utils/config.js'; |
@@ -1,3 +0,3 @@ | ||
import { srgb2xyz, xyzd502srgb } from './xyz.js'; | ||
import { XYZ_D65_to_D50 } from './xyzd50.js'; | ||
import { srgb2xyz } from './xyz.js'; | ||
import { XYZ_D65_to_D50, xyzd502srgb } from './xyzd50.js'; | ||
@@ -4,0 +4,0 @@ function prophotorgb2srgbvalues(r, g, b, a = null) { |
@@ -1,3 +0,3 @@ | ||
import { srgb2xyz, xyzd502srgb } from './xyz.js'; | ||
import { XYZ_D65_to_D50 } from './xyzd50.js'; | ||
import { srgb2xyz } from './xyz.js'; | ||
import { XYZ_D65_to_D50, xyzd502srgb } from './xyzd50.js'; | ||
@@ -4,0 +4,0 @@ function prophotorgb2srgbvalues(r, g, b, a = null) { |
@@ -7,22 +7,6 @@ import { multiplyMatrices } from './utils/matrix.js'; | ||
import '../../parser/parse.js'; | ||
import { srgb2lsrgbvalues, lsrgb2srgbvalues } from './srgb.js'; | ||
import { srgb2lsrgbvalues } from './srgb.js'; | ||
import '../sourcemap/lib/encode.js'; | ||
import '../../parser/utils/config.js'; | ||
function xyzd502srgb(x, y, z) { | ||
// @ts-ignore | ||
return lsrgb2srgbvalues( | ||
/* r: */ | ||
x * 3.1341359569958707 - | ||
y * 1.6173863321612538 - | ||
0.4906619460083532 * z, | ||
/* g: */ | ||
x * -0.978795502912089 + | ||
y * 1.916254567259524 + | ||
0.03344273116131949 * z, | ||
/* b: */ | ||
x * 0.07195537988411677 - | ||
y * 0.2289768264158322 + | ||
1.405386058324125 * z); | ||
} | ||
function XYZ_to_lin_sRGB(x, y, z) { | ||
@@ -67,2 +51,2 @@ // convert XYZ to linear-light sRGB | ||
export { XYZ_D50_to_D65, XYZ_to_lin_sRGB, srgb2xyz, xyzd502srgb }; | ||
export { XYZ_D50_to_D65, XYZ_to_lin_sRGB, srgb2xyz }; |
@@ -0,1 +1,2 @@ | ||
import { lsrgb2srgbvalues } from './srgb.js'; | ||
import { multiplyMatrices } from './utils/matrix.js'; | ||
@@ -13,2 +14,4 @@ import './utils/constants.js'; | ||
/* | ||
*/ | ||
function xyzd502lch(x, y, z, alpha) { | ||
@@ -18,3 +21,2 @@ // @ts-ignore | ||
// L in range [0,100]. For use in CSS, add a percent | ||
// @ts-ignore | ||
return lab2lchvalues(l, a, b, alpha); | ||
@@ -36,3 +38,19 @@ } | ||
} | ||
function xyzd502srgb(x, y, z) { | ||
// @ts-ignore | ||
return lsrgb2srgbvalues( | ||
/* r: */ | ||
x * 3.1341359569958707 - | ||
y * 1.6173863321612538 - | ||
0.4906619460083532 * z, | ||
/* g: */ | ||
x * -0.978795502912089 + | ||
y * 1.916254567259524 + | ||
0.03344273116131949 * z, | ||
/* b: */ | ||
x * 0.07195537988411677 - | ||
y * 0.2289768264158322 + | ||
1.405386058324125 * z); | ||
} | ||
export { XYZ_D65_to_D50, xyzd502lch }; | ||
export { XYZ_D65_to_D50, xyzd502lch, xyzd502srgb }; |
@@ -12,3 +12,3 @@ import { getAngle, color2srgbvalues, clamp } from './color/color.js'; | ||
import { SourceMap } from './sourcemap/sourcemap.js'; | ||
import { isColor, mathFuncs, isNewLine } from '../syntax/syntax.js'; | ||
import { isColor, pseudoElements, mathFuncs, isNewLine } from '../syntax/syntax.js'; | ||
@@ -593,4 +593,5 @@ const colorsFunc = ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk', 'color-mix', 'color', 'oklab', 'lab', 'oklch', 'lch', 'light-dark']; | ||
case EnumToken.PseudoClassTokenType: | ||
case EnumToken.PseudoElementTokenType: | ||
// https://www.w3.org/TR/selectors-4/#single-colon-pseudos | ||
if (token.typ == EnumToken.PseudoClassTokenType && ['::before', '::after', '::first-line', '::first-letter'].includes(token.val)) { | ||
if (token.typ == EnumToken.PseudoElementTokenType && pseudoElements.includes(token.val.slice(1))) { | ||
return token.val.slice(1); | ||
@@ -597,0 +598,0 @@ } |
import { encode } from './lib/encode.js'; | ||
class SourceMap { | ||
lastLocation = null; | ||
#version = 3; | ||
@@ -8,3 +9,2 @@ #sources = []; | ||
#line = -1; | ||
lastLocation = null; | ||
add(source, original) { | ||
@@ -11,0 +11,0 @@ if (original.src !== '') { |
@@ -28,2 +28,3 @@ import { colorsFunc } from '../renderer/render.js'; | ||
const mathFuncs = ['calc', 'clamp', 'min', 'max', 'round', 'mod', 'rem', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2', 'pow', 'sqrt', 'hypot', 'log', 'exp', 'abs', 'sign']; | ||
const pseudoElements = [':before', ':after', ':first-line', ':first-letter']; | ||
const webkitPseudoAliasMap = { | ||
@@ -815,2 +816,2 @@ '-webkit-autofill': 'autofill', | ||
export { colorFontTech, fontFeaturesTech, fontFormat, isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, mathFuncs, mediaTypes, mozExtensions, parseDimension, webkitExtensions, webkitPseudoAliasMap }; | ||
export { colorFontTech, fontFeaturesTech, fontFormat, isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, mathFuncs, mediaTypes, mozExtensions, parseDimension, pseudoElements, webkitExtensions, webkitPseudoAliasMap }; |
@@ -9,2 +9,3 @@ import { ValidationLevel, EnumToken } from '../../ast/types.js'; | ||
import { consumeWhitespace } from '../utils/whitespace.js'; | ||
import { splitTokenList } from '../utils/list.js'; | ||
import { validateURL } from '../syntaxes/url.js'; | ||
@@ -38,67 +39,46 @@ | ||
} | ||
if (tokens[0].typ == EnumToken.CommaTokenType) { | ||
for (const t of splitTokenList(tokens)) { | ||
if (t.length != 1) { | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: t[0] ?? atRule, | ||
syntax: '@document', | ||
error: 'unexpected token', | ||
tokens | ||
}; | ||
} | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@document', | ||
error: 'unexpected token', | ||
tokens | ||
}; | ||
} | ||
while (tokens.length > 0) { | ||
if (tokens[0].typ == EnumToken.CommentTokenType) { | ||
tokens.shift(); | ||
consumeWhitespace(tokens); | ||
if ((t[0].typ != EnumToken.FunctionTokenType && t[0].typ != EnumToken.UrlFunctionTokenType) || !['url', 'url-prefix', 'domain', 'media-document', 'regexp'].some((f) => f.localeCompare(t[0].val, undefined, { sensitivity: 'base' }) == 0)) { | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: t[0] ?? atRule, | ||
syntax: '@document', | ||
error: 'expecting any of url-prefix(), domain(), media-document(), regexp() but found ' + t[0].val, | ||
tokens | ||
}; | ||
} | ||
result = validateURL(tokens[0]); | ||
if (result.valid == ValidationLevel.Valid) { | ||
tokens.shift(); | ||
consumeWhitespace(tokens); | ||
if (t[0].typ == EnumToken.UrlFunctionTokenType) { | ||
result = validateURL(t[0]); | ||
if (result.valid == ValidationLevel.Drop) { | ||
return result; | ||
} | ||
continue; | ||
} | ||
if (tokens[0].typ == EnumToken.FunctionTokenType) { | ||
if (!['url-prefix', 'domain', 'media-document', 'regexp'].some((t) => t.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) == 0)) { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@document', | ||
error: 'unexpected token', | ||
tokens | ||
}; | ||
} | ||
const children = tokens[0].chi.slice(); | ||
consumeWhitespace(children); | ||
if (children.length == 0) { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@document', | ||
error: 'expecting string argument', | ||
tokens | ||
}; | ||
} | ||
if (children[0].typ == EnumToken.StringTokenType) { | ||
children.shift(); | ||
consumeWhitespace(children); | ||
} | ||
if (children.length > 0) { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: children[0], | ||
syntax: '@document', | ||
error: 'unexpected token', | ||
tokens | ||
}; | ||
} | ||
tokens.shift(); | ||
consumeWhitespace(tokens); | ||
const children = t[0].chi.slice(); | ||
consumeWhitespace(children); | ||
if (children.length != 1 || (children[0].typ != EnumToken.StringTokenType && children[0].typ != EnumToken.UrlTokenTokenType)) { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@document', | ||
error: 'expecting string argument', | ||
tokens | ||
}; | ||
} | ||
tokens.shift(); | ||
consumeWhitespace(tokens); | ||
} | ||
@@ -105,0 +85,0 @@ // @ts-ignore |
@@ -8,3 +8,2 @@ import { ValidationLevel, EnumToken } from '../../ast/types.js'; | ||
import '../../parser/utils/config.js'; | ||
import { validateAtRuleSupports } from './supports.js'; | ||
import { validateAtRuleMediaQueryList } from './media.js'; | ||
@@ -17,2 +16,3 @@ import { consumeWhitespace } from '../utils/whitespace.js'; | ||
import '../config.js'; | ||
import { validateAtRuleSupportsConditions } from './supports.js'; | ||
@@ -87,2 +87,5 @@ function validateAtRuleImport(atRule, options, root) { | ||
} | ||
tokens.shift(); | ||
// @ts-ignore | ||
consumeWhitespace(tokens); | ||
} | ||
@@ -123,68 +126,67 @@ else { | ||
// @ts-ignore | ||
if ('layer'.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) != 0) { | ||
if ('layer'.localeCompare(tokens[0].val, undefined, { sensitivity: 'base' }) == 0) { | ||
const result = validateLayerName(tokens[0].chi); | ||
if (result.valid == ValidationLevel.Drop) { | ||
return result; | ||
} | ||
tokens.shift(); | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@' + atRule.nam, | ||
error: 'expecting layer()', | ||
tokens | ||
}; | ||
consumeWhitespace(tokens); | ||
} | ||
// @ts-ignore | ||
const result = validateLayerName(tokens[0].chi); | ||
if (result.valid == ValidationLevel.Drop) { | ||
return result; | ||
} | ||
tokens.shift(); | ||
// @ts-ignore | ||
if (!consumeWhitespace(tokens)) { | ||
if ('supports'.localeCompare(tokens[0]?.val, undefined, { sensitivity: 'base' }) == 0) { | ||
const result = validateAtRuleSupportsConditions(atRule, tokens[0].chi); | ||
if (result.valid == ValidationLevel.Drop) { | ||
return result; | ||
} | ||
tokens.shift(); | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@' + atRule.nam, | ||
error: 'expecting whitespace', | ||
tokens | ||
}; | ||
consumeWhitespace(tokens); | ||
} | ||
} | ||
} | ||
// if (tokens.length > 0) { | ||
// | ||
// // @ts-ignore | ||
// if (tokens[0].typ == EnumToken.AtRuleTokenType) { | ||
// | ||
// if ((tokens[0] as AstAtRule).nam != 'supports') { | ||
// | ||
// // @ts-ignore | ||
// return { | ||
// valid: ValidationLevel.Drop, | ||
// matches: [], | ||
// node: tokens[0], | ||
// syntax: '@' + atRule.nam, | ||
// error: 'expecting @supports or media query list', | ||
// tokens | ||
// } | ||
// } | ||
// | ||
// // @ts-ignore | ||
// const result: ValidationSyntaxResult = validateAtRuleSupports(tokens[0] as AstAtRule, options, atRule); | ||
// | ||
// if (result.valid == ValidationLevel.Drop) { | ||
// | ||
// return result; | ||
// } | ||
// | ||
// tokens.shift(); | ||
// | ||
// // @ts-ignore | ||
// if (!consumeWhitespace(tokens)) { | ||
// | ||
// // @ts-ignore | ||
// return { | ||
// valid: ValidationLevel.Drop, | ||
// matches: [], | ||
// node: tokens[0], | ||
// syntax: '@' + atRule.nam, | ||
// error: 'expecting whitespace', | ||
// tokens | ||
// } | ||
// } | ||
// } | ||
// } | ||
if (tokens.length > 0) { | ||
// @ts-ignore | ||
if (tokens[0].typ == EnumToken.AtRuleTokenType) { | ||
if (tokens[0].nam != 'supports') { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@' + atRule.nam, | ||
error: 'expecting @supports or media query list', | ||
tokens | ||
}; | ||
} | ||
// @ts-ignore | ||
const result = validateAtRuleSupports(tokens[0]); | ||
if (result.valid == ValidationLevel.Drop) { | ||
return result; | ||
} | ||
tokens.shift(); | ||
// @ts-ignore | ||
if (!consumeWhitespace(tokens)) { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: [], | ||
node: tokens[0], | ||
syntax: '@' + atRule.nam, | ||
error: 'expecting whitespace', | ||
tokens | ||
}; | ||
} | ||
} | ||
} | ||
if (tokens.length > 0) { | ||
return validateAtRuleMediaQueryList(tokens, atRule); | ||
@@ -191,0 +193,0 @@ } |
@@ -228,3 +228,3 @@ import { ValidationLevel, EnumToken } from '../../ast/types.js'; | ||
} | ||
if (token.typ != EnumToken.ParensTokenType && !(['when', 'else'].includes(atRule.nam) && token.typ == EnumToken.FunctionTokenType && ['media', 'supports'].includes(token.val))) { | ||
if (token.typ != EnumToken.ParensTokenType && !(['when', 'else', 'import'].includes(atRule.nam) && token.typ == EnumToken.FunctionTokenType && ['media', 'supports', 'selector'].includes(token.val))) { | ||
return false; | ||
@@ -245,2 +245,3 @@ } | ||
} | ||
console.error(chi[0].parent); | ||
return false; | ||
@@ -247,0 +248,0 @@ } |
import { ValidationLevel, EnumToken } from '../../ast/types.js'; | ||
import '../../ast/minify.js'; | ||
import '../../ast/walk.js'; | ||
import '../../parser/parse.js'; | ||
import { parseSelector } from '../../parser/parse.js'; | ||
import { colorFontTech, fontFeaturesTech, fontFormat } from '../../syntax/syntax.js'; | ||
@@ -11,4 +11,3 @@ import '../../parser/utils/config.js'; | ||
import { splitTokenList } from '../utils/list.js'; | ||
import { validateSyntax } from '../syntax.js'; | ||
import { getParsedSyntax } from '../config.js'; | ||
import { validateComplexSelector } from '../syntaxes/complex-selector.js'; | ||
@@ -57,2 +56,3 @@ function validateAtRuleSupports(atRule, options, root) { | ||
function validateAtRuleSupportsConditions(atRule, tokenList) { | ||
let result = null; | ||
for (const tokens of splitTokenList(tokenList)) { | ||
@@ -71,7 +71,6 @@ if (tokens.length == 0) { | ||
let previousToken = null; | ||
let result = null; | ||
while (tokens.length > 0) { | ||
result = validateSupportCondition(atRule, tokens[0]); | ||
// supports-condition | ||
if (result == null || result.valid == ValidationLevel.Valid) { | ||
if (result.valid == ValidationLevel.Valid) { | ||
previousToken = tokens[0]; | ||
@@ -82,3 +81,3 @@ tokens.shift(); | ||
result = validateSupportFeature(tokens[0]); | ||
if (result == null || result.valid == ValidationLevel.Valid) { | ||
if ( /*result == null || */result.valid == ValidationLevel.Valid) { | ||
previousToken = tokens[0]; | ||
@@ -88,3 +87,28 @@ tokens.shift(); | ||
else { | ||
return result; | ||
if (tokens[0].typ == EnumToken.ParensTokenType) { | ||
result = validateAtRuleSupportsConditions(atRule, tokens[0].chi); | ||
if ( /* result == null || */result.valid == ValidationLevel.Valid) { | ||
previousToken = tokens[0]; | ||
tokens.shift(); | ||
// continue; | ||
} | ||
else { | ||
return result; | ||
} | ||
} | ||
else { | ||
return result; | ||
} | ||
// if (result!= null && result.valid == ValidationLevel.Drop) { | ||
// | ||
// return { | ||
// valid: ValidationLevel.Drop, | ||
// matches: [], | ||
// node: tokens[0] ?? atRule, | ||
// syntax: '@' + atRule.nam, | ||
// // @ts-ignore | ||
// error: result.error as string ?? 'unexpected token', | ||
// tokens: [] | ||
// }; | ||
// } | ||
} | ||
@@ -144,3 +168,10 @@ } | ||
} | ||
return null; | ||
return { | ||
valid: ValidationLevel.Valid, | ||
matches: [], | ||
node: atRule, | ||
syntax: '@' + atRule.nam, | ||
error: '', | ||
tokens: [] | ||
}; | ||
} | ||
@@ -212,3 +243,3 @@ function validateSupportCondition(atRule, token) { | ||
if (token.val.localeCompare('selector', undefined, { sensitivity: 'base' }) == 0) { | ||
return validateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, 'complex-selector'), token.chi); | ||
return validateComplexSelector(parseSelector(token.chi)); | ||
} | ||
@@ -215,0 +246,0 @@ if (token.val.localeCompare('font-tech', undefined, { sensitivity: 'base' }) == 0) { |
@@ -8,3 +8,3 @@ import { EnumToken, ValidationLevel } from '../ast/types.js'; | ||
import '../parser/utils/config.js'; | ||
import { getParsedSyntax, getSyntaxConfig } from './config.js'; | ||
import { getSyntaxConfig, getParsedSyntax } from './config.js'; | ||
import { validateSyntax } from './syntax.js'; | ||
@@ -27,3 +27,2 @@ | ||
const syntax = getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, '@' + root.nam)?.[0]; | ||
// console.error({syntax}); | ||
if (syntax != null) { | ||
@@ -57,3 +56,3 @@ if (!('chi' in syntax)) { | ||
syntax: `<${declaration.nam}>`, | ||
error: ` declaration <${declaration.nam}> is not allowed in <@${root.nam}>` | ||
error: `declaration <${declaration.nam}> is not allowed in <@${root.nam}>` | ||
}; | ||
@@ -95,9 +94,2 @@ } | ||
} | ||
// return { | ||
// | ||
// valid: ValidationLevel.Valid, | ||
// node: declaration, | ||
// syntax: null, | ||
// error: '' | ||
// } | ||
return validateSyntax(getParsedSyntax("declarations" /* ValidationSyntaxGroupEnum.Declarations */, name), declaration.val); | ||
@@ -104,0 +96,0 @@ } |
@@ -952,96 +952,2 @@ import { ValidationTokenEnum } from './types.js'; | ||
} | ||
function renderSyntax(token, parent) { | ||
let glue; | ||
switch (token.typ) { | ||
case ValidationTokenEnum.Root: | ||
return token.chi.reduce((acc, curr) => acc + renderSyntax(curr), ''); | ||
case ValidationTokenEnum.Whitespace: | ||
return ' '; | ||
case ValidationTokenEnum.ValidationFunctionDefinition: | ||
return '<' + token.val + '()>'; | ||
case ValidationTokenEnum.HashMark: | ||
return '#'; | ||
case ValidationTokenEnum.Pipe: | ||
return '|'; | ||
case ValidationTokenEnum.Column: | ||
return '||'; | ||
case ValidationTokenEnum.PipeToken: | ||
return token.chi.reduce((acc, curr) => acc + (acc.trim().length > 0 ? '|' : '') + curr.reduce((acc, curr) => acc + renderSyntax(curr), ''), ''); | ||
case ValidationTokenEnum.ColumnToken: | ||
case ValidationTokenEnum.AmpersandToken: | ||
glue = token.typ == ValidationTokenEnum.ColumnToken ? '||' : '&&'; | ||
return token.l.reduce((acc, curr) => acc + renderSyntax(curr), '') + | ||
glue + | ||
token.r.reduce((acc, curr) => acc + renderSyntax(curr), ''); | ||
case ValidationTokenEnum.Function: | ||
case ValidationTokenEnum.PseudoClassFunctionToken: | ||
case ValidationTokenEnum.Parens: | ||
return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '') + ')' + renderAttributes(token); | ||
case ValidationTokenEnum.Comma: | ||
return ','; | ||
case ValidationTokenEnum.Keyword: | ||
return token.val + renderAttributes(token); | ||
case ValidationTokenEnum.OpenBracket: | ||
return '['; | ||
case ValidationTokenEnum.Ampersand: | ||
return '&&'; | ||
case ValidationTokenEnum.QuestionMark: | ||
return '?'; | ||
case ValidationTokenEnum.Separator: | ||
return '/'; | ||
case ValidationTokenEnum.Bracket: | ||
return '[' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']' + renderAttributes(token); | ||
case ValidationTokenEnum.PropertyType: | ||
return '<' + token.val + '>' + renderAttributes(token); | ||
case ValidationTokenEnum.DeclarationType: | ||
return "<'" + token.val + "'>" + renderAttributes(token); | ||
case ValidationTokenEnum.Number: | ||
case ValidationTokenEnum.PseudoClassToken: | ||
case ValidationTokenEnum.StringToken: | ||
return token.val + ''; | ||
case ValidationTokenEnum.SemiColon: | ||
return ';'; | ||
case ValidationTokenEnum.AtRule: | ||
return '@' + token.val; | ||
case ValidationTokenEnum.AtRuleDefinition: | ||
return '@' + token.val + | ||
(token.prelude == null ? '' : ' ' + token.prelude.reduce((acc, curr) => acc + renderSyntax(curr), '')) + | ||
(token.chi == null ? '' : ' {\n' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '')).slice(1, -1) + '\n}'; | ||
case ValidationTokenEnum.Block: | ||
return '{' + token.chi.reduce((acc, t) => acc + renderSyntax(t), '') + '}'; | ||
case ValidationTokenEnum.DeclarationDefinitionToken: | ||
return token.nam + ': ' + renderSyntax(token.val); | ||
case ValidationTokenEnum.ColumnArrayToken: | ||
return token.chi.reduce((acc, curr) => acc + (acc.trim().length > 0 ? '||' : '') + renderSyntax(curr), ''); | ||
default: | ||
throw new Error('Unhandled token: ' + JSON.stringify({ token })); | ||
} | ||
} | ||
function renderAttributes(token) { | ||
let result = ''; | ||
if (token.isList) { | ||
result += '#'; | ||
} | ||
if (token.isOptional) { | ||
result += '?'; | ||
} | ||
if (token.isRepeatableGroup) { | ||
result += '!'; | ||
} | ||
if (token.isRepeatable) { | ||
result += '*'; | ||
} | ||
if (token.atLeastOnce) { | ||
result += '+'; | ||
} | ||
if (token.occurence != null) { | ||
if (token.occurence.max == 0 || token.occurence.max == token.occurence.min || Number.isNaN(token.occurence.max)) { | ||
result += '{' + token.occurence.min + '}'; | ||
} | ||
else { | ||
result += '{' + token.occurence.min + ',' + token.occurence.max + '}'; | ||
} | ||
} | ||
return result; | ||
} | ||
function minify(ast) { | ||
@@ -1147,2 +1053,2 @@ if (Array.isArray(ast)) { | ||
export { WalkValidationTokenEnum, WalkValidationTokenKeyTypeEnum, parseSyntax, renderSyntax, walkValidationToken }; | ||
export { WalkValidationTokenEnum, WalkValidationTokenKeyTypeEnum, parseSyntax, walkValidationToken }; |
@@ -1,2 +0,1 @@ | ||
const specialValues = ['inherit', 'initial', 'unset', 'revert', 'revert-layer']; | ||
var ValidationTokenEnum; | ||
@@ -55,2 +54,2 @@ (function (ValidationTokenEnum) { | ||
export { ValidationSyntaxGroupEnum, ValidationTokenEnum, specialValues }; | ||
export { ValidationSyntaxGroupEnum, ValidationTokenEnum }; |
@@ -9,4 +9,3 @@ import { ValidationTokenEnum, specialValues } from './parser/types.js'; | ||
import '../parser/utils/config.js'; | ||
import '../renderer/color/utils/constants.js'; | ||
import '../renderer/sourcemap/lib/encode.js'; | ||
import { renderToken } from '../renderer/render.js'; | ||
import { getSyntaxConfig, getParsedSyntax } from './config.js'; | ||
@@ -37,5 +36,5 @@ import { validateSelector } from './selector.js'; | ||
console.error(JSON.stringify({ | ||
syntax: syntaxes.reduce((acc, curr) => acc + renderSyntax(curr), ''), | ||
syntaxes, | ||
tokens, | ||
syntax: syntaxes?.reduce?.((acc, curr) => acc + renderSyntax(curr), ''), | ||
// syntaxes, | ||
tokens: tokens.reduce((acc, curr) => acc + renderToken(curr), ''), | ||
s: new Error('bar').stack | ||
@@ -1396,2 +1395,37 @@ }, null, 1)); | ||
break; | ||
case ValidationTokenEnum.ColumnArrayToken: | ||
{ | ||
matches = []; | ||
queue = []; | ||
const children = syntax.chi; | ||
let child; | ||
while (child = children.shift()) { | ||
result = validateSyntax([child], tokens, root, options, context); | ||
if (result.valid == ValidationLevel.Valid) { | ||
matches.push(child); | ||
consumeToken(tokens); | ||
token = tokens[0]; | ||
if (queue.length > 0) { | ||
children.unshift(...queue); | ||
queue = []; | ||
} | ||
if (token == null) { | ||
break; | ||
} | ||
} | ||
else { | ||
queue.push(child); | ||
} | ||
} | ||
valid = matches.length > 0; | ||
result = { | ||
valid: valid ? ValidationLevel.Valid : ValidationLevel.Drop, | ||
matches: valid ? [token] : [], | ||
node: valid ? null : token, | ||
syntax, | ||
error: valid ? '' : 'expecting token', | ||
tokens | ||
}; | ||
} | ||
break; | ||
case ValidationTokenEnum.ColumnToken: | ||
@@ -1398,0 +1432,0 @@ children = [...syntax.l.slice(), ...syntax.r.slice()]; |
@@ -83,4 +83,4 @@ import { ValidationLevel, EnumToken } from '../../ast/types.js'; | ||
} | ||
while (tokens.length > 0 && tokens[0].typ == EnumToken.PseudoClassTokenType) { | ||
const isPseudoElement = tokens[0].val.startsWith('::'); | ||
while (tokens.length > 0 && (tokens[0].typ == EnumToken.PseudoElementTokenType || tokens[0].typ == EnumToken.PseudoClassTokenType)) { | ||
const isPseudoElement = tokens[0].typ == EnumToken.PseudoElementTokenType; | ||
if ( | ||
@@ -87,0 +87,0 @@ // https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions#pseudo-elements |
@@ -18,3 +18,3 @@ import { EnumToken, ValidationLevel } from '../../ast/types.js'; | ||
return acc; | ||
}, [[]]).slice(1); | ||
}, [[]]); | ||
for (let i = 0; i < slice.length; i++) { | ||
@@ -32,15 +32,4 @@ if (slice[i].length == 0) { | ||
} | ||
if (slice[i][0].typ != EnumToken.IdenTokenType) { | ||
// @ts-ignore | ||
return { | ||
valid: ValidationLevel.Drop, | ||
matches: tokens, | ||
node: slice[i][0], | ||
syntax: 'ident', | ||
error: 'expecting ident', | ||
tokens | ||
}; | ||
} | ||
for (let j = 1; j < slice[i].length; j++) { | ||
if (slice[i][j].typ != EnumToken.ClassSelectorTokenType) { | ||
for (let j = 0; j < slice[i].length; j++) { | ||
if (slice[i][j].typ != EnumToken.IdenTokenType && slice[i][j].typ != EnumToken.ClassSelectorTokenType) { | ||
// @ts-ignore | ||
@@ -51,4 +40,4 @@ return { | ||
node: slice[i][j], | ||
syntax: 'layer-name', | ||
error: 'expecting class selector', | ||
syntax: '<layer-name>', | ||
error: 'expecting ident or class selector', | ||
tokens | ||
@@ -55,0 +44,0 @@ }; |
{ | ||
"name": "@tbela99/css-parser", | ||
"description": "CSS parser for node and the browser", | ||
"version": "v0.9.0", | ||
"version": "v0.9.1", | ||
"exports": { | ||
".": "./dist/node/index.js", | ||
"./node": "./dist/node/index.js", | ||
"./umd": "./dist/index-umd-web.js", | ||
@@ -20,4 +21,4 @@ "./web": "./dist/web/index.js", | ||
"test:node": "mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"", | ||
"test:cov": "c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"", | ||
"test:web-cov": "web-test-runner \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=. --coverage", | ||
"test:cov": "c8 -x dist/lib/validation/syntax.js -x 'dist/lib/validation/parser/*.js' --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"", | ||
"test:web-cov": "web-test-runner -x dist/lib/validation/syntax.js,dist/lib/validation/parser \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=. --coverage", | ||
"profile": "node --enable-source-maps --inspect-brk test/inspect.js", | ||
@@ -24,0 +25,0 @@ "syntax-update": "esno tools/validation.ts", |
[](https://tbela99.github.io/css-parser/playground/) [](https://www.npmjs.com/package/@tbela99/css-parser) [](https://jsr.io/@tbela99/css-parser) [](https://github.com/tbela99/css-parser/actions) [](https://www.npmjs.com/package/@tbela99/css-parser) | ||
)](https://jsr.io/@tbela99/css-parser) [](https://github.com/tbela99/css-parser/actions) [](https://www.npmjs.com/package/@tbela99/css-parser) [](https://www.npmjs.com/package/@tbela99/css-parser) | ||
@@ -68,3 +68,3 @@ # css-parser | ||
import {transform} from 'npm:@tbela99/css-parser'; | ||
import {transform} from '@tbela99/css-parser'; | ||
@@ -100,3 +100,3 @@ // ... | ||
import {transform} from 'https://esm.sh/@tbela99/css-parser@0.4.0/web'; | ||
import {transform} from 'https://esm.sh/@tbela99/css-parser@0.9.0/web'; | ||
@@ -159,2 +159,3 @@ | ||
- minify: boolean, optional. default to _true_. optimize ast. | ||
- pass: number, optional. minification pass. default to 1 | ||
- nestingRules: boolean, optional. automatically generated nested rules. | ||
@@ -706,3 +707,5 @@ - expandNestingRules: boolean, optional. convert nesting rules into separate rules. will automatically set nestingRules | ||
- [x] reduce calc() | ||
- [x] evaluate math functions calc(), clamp(), min(), max(), round(), mod(), rem(), sin(), cos(), tan(), asin(), | ||
acos(), atan(), atan2(), pow(), sqrt(), hypot(), log(), exp(), abs(), sign() | ||
- [x] multi-pass minification | ||
- [x] inline css variables | ||
@@ -823,3 +826,3 @@ - [x] merge identical rules | ||
import {AstDeclaration, LengthToken, ParserOptions} from "../src/@types"; | ||
import {EnumToken, EnumToken} from "../src/lib"; | ||
import {EnumToken} from "../src/lib"; | ||
import {transform} from "../src/node"; | ||
@@ -826,0 +829,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
1029
0.29%2150353
-5.49%59647
-4.66%