Socket
Socket
Sign inDemoInstall

void-css

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

void-css - npm Package Compare versions

Comparing version 1.0.15 to 1.0.16

tests/keyframes/keyframes.test.css

4

index.ts

@@ -1,4 +0,1 @@

import { compileScope } from "./src/compiler/lexer";

@@ -8,3 +5,2 @@ import { Config, VoidCSSConfiguration } from "./src/config";

function VoidCSS(config?: VoidCSSConfiguration) {

@@ -11,0 +7,0 @@ const configInstance = new Config(config ?? {});

{
"name": "void-css",
"version": "1.0.15",
"version": "1.0.16",
"description": "",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -16,2 +16,3 @@

});
}
}

@@ -7,2 +7,3 @@

/**

@@ -9,0 +10,0 @@ * Wrap css arithmetic operations in calc

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_1 = __importDefault(require("crypto"));
const newLine = `\n`;

@@ -53,3 +49,3 @@ function compile(ctx) {

if (!compress)
shift = shift.substr(0, shift.length - shiftBy.length);
shift = shift.slice(0, shift.length - shiftBy.length);
css += `${shift}}${compress ? "" : newLine}`;

@@ -72,3 +68,3 @@ }

// TODO: cache
hash: normalizeBase64(crypto_1.default.createHash("sha1").update(css).digest("base64")),
//hash: normalizeBase64(crypto.createHash("sha1").update(css).digest("base64")),
});

@@ -80,2 +76,4 @@ }

}
if (ctx.keyframes.length)
css += createKeyframesScope(ctx, ctx.keyframes);
return {

@@ -87,2 +85,47 @@ classes: tree.classes,

}
function createKeyframesScope(ctx, tokens) {
const compress = ctx.config.compressed;
let css = "";
const shiftBy = compress ? "" : ctx.config.indentationStyle;
for (const [i, token] of tokens.entries()) {
const name = token.renamed || token.name;
if (["atSymbol", "keyframes", "keyframesWhiteSpace"].includes(name)) {
css += `${token.match}`;
}
else if (["keyframesName"].includes(name)) {
css += `${token.match}${compress ? "" : " "}{${compress ? "" : newLine}`;
}
else if (["keyframesSelector"].includes(name)) {
if (tokens[i - 1].domain !== "selector")
css += shiftBy;
css += `${token.match.trim()}`;
}
else if (["keyframesSeparator"].includes(name)) {
css += `,${compress ? "" : " "}`;
}
else if (["keyframesBlock"].includes(name)) {
css += `${compress ? "" : " "}{${compress ? "" : newLine}`;
}
else if (["keyframesBlockPropertyName"].includes(name)) {
css += `${shiftBy + shiftBy}${token.match}:${compress ? "" : " "}`;
}
else if (["keyframesPropertyValue"].includes(name)) {
const semiColon = compress && tokens[i + 1]?.match.toString() === "}" ? "" : ";";
css += `${token.match.trim()}${semiColon}${compress ? "" : newLine}`;
}
else if (["keyframesBlockEnd"].includes(name)) {
const match = token.match.trim();
if (/}/.test(match)) {
css += `${shiftBy}}${compress ? "" : newLine}`;
}
}
else if (["keyframesScopeEnd"].includes(name)) {
const match = token.match.trim();
if (/}/.test(match)) {
css += `}${compress ? "" : newLine}`;
}
}
}
return css;
}
/** This removes non css friendly characters from base64 string */

@@ -89,0 +132,0 @@ function normalizeBase64(input) {

@@ -17,2 +17,3 @@ import Context, { Token } from "../context";

const newLine = `\n`;

@@ -39,3 +40,3 @@

dependencies: string[];
hash: string;
//hash: string;
exportedClasses: {

@@ -84,3 +85,3 @@ newClassName: string;

if (!compress)
shift = shift.substr(0, shift.length - shiftBy.length);
shift = shift.slice(0, shift.length - shiftBy.length);
css += `${shift}}${compress ? "" : newLine}`;

@@ -103,3 +104,3 @@ }

// TODO: cache
hash: normalizeBase64(crypto.createHash("sha1").update(css).digest("base64")),
//hash: normalizeBase64(crypto.createHash("sha1").update(css).digest("base64")),
});

@@ -111,2 +112,6 @@ } else {

if (ctx.keyframes.length)
css += createKeyframesScope(ctx, ctx.keyframes);
return {

@@ -119,2 +124,45 @@ classes: tree.classes,

function createKeyframesScope(ctx: Context, tokens: Token[]) {
const compress = ctx.config.compressed;
let css: string = "";
const shiftBy = compress ? "" : ctx.config.indentationStyle;
for (const [i, token] of tokens.entries()) {
const name = token.renamed || token.name;
if (["atSymbol", "keyframes", "keyframesWhiteSpace"].includes(name)) {
css += `${token.match}`;
} else if (["keyframesName"].includes(name)) {
css += `${token.match}${compress ? "" : " "}{${compress ? "" : newLine}`;
} else if (["keyframesSelector"].includes(name)) {
if (tokens[i - 1].domain !== "selector")
css += shiftBy;
css += `${token.match.trim()}`;
} else if (["keyframesSeparator"].includes(name)) {
css += `,${compress ? "" : " "}`;
} else if (["keyframesBlock"].includes(name)) {
css += `${compress ? "" : " "}{${compress ? "" : newLine}`;
} else if (["keyframesBlockPropertyName"].includes(name)) {
css += `${shiftBy + shiftBy}${token.match}:${compress ? "" : " "}`;
} else if (["keyframesPropertyValue"].includes(name)) {
const semiColon = compress && tokens[i + 1]?.match.toString() === "}" ? "" : ";";
css += `${token.match.trim()}${semiColon}${compress ? "" : newLine}`;
} else if (["keyframesBlockEnd"].includes(name)) {
const match = token.match.trim();
if (/}/.test(match)) {
css += `${shiftBy}}${compress ? "" : newLine}`
}
} else if (["keyframesScopeEnd"].includes(name)) {
const match = token.match.trim();
if (/}/.test(match)) {
css += `}${compress ? "" : newLine}`
}
}
}
return css;
}
/** This removes non css friendly characters from base64 string */

@@ -121,0 +169,0 @@ function normalizeBase64(input: string) {

@@ -19,2 +19,16 @@ "use strict";

const globalTokens = [tokens_1.inlineComment, tokens_1.blockComment];
/**
* Void CSS lexer — Tokenizes given Void CSS input and then, if valid, compiles it,
* otherwise throws syntax error.
*
* Recursive and declarative design. Each case on the main switch statement represents the next step
* after the given (current token). Each self call of the lex function represents what the lexer should
* expect after the current token. Using attributes which live on the function recursively (as an argument),
* the lexer can call itself with possibly conditional expectations using helper functions such as `_if`.
*
* @param ctx Compile context
* @param token Current token (unless beginning)
* @param attributes Makes the lexer aware of its state
* @returns compiled Void CSS. see `compile` function
*/
function lex(ctx, token, attributes) {

@@ -36,2 +50,4 @@ const { lastToken, index, css: preTokenizedCSS } = ctx;

const enclosures = attributes?.enclosures || [];
const notOperatorDepth = attributes?.notOperatorDepth ?? 0;
/** The depth refers to the css rule or "scope" nesting level */
const depth = (attributes?.depth ?? 0) + (() => {

@@ -59,8 +75,9 @@ // The only way to descend a depth is to close it with the `}` token `styleScopeEnd`

/^\s*(?:~|>|\+|\|\|)/.test(section) ?
"Selectors cannot begin with a selector combinator ('~', '>', '+', '||'). Did you forget to add left side selector combinator operand?" :
"Root level selectors cannot begin with a selector combinator ('~', '>', '+', '||'). Did you forget to add left side selector combinator operand?" :
"Instead found invalid or missing selector.";
return lex(ctx, expect(slice, ...globals, tokens_1.atSymbol, tokens_1.whiteSpace, ...enclosures, ..._if(enclosures.length === 0, [tokens_1.rootSelector]), ..._if(depth > 0, [tokens_1.currentSelector]), tokens_1.classNameInitiator, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.wildcard, tokens_1.notOperator), {
return lex(ctx, expect(slice, ...globals, tokens_1.atSymbol, tokens_1.whiteSpace, ...enclosures, ..._if(enclosures.length === 0, [tokens_1.rootSelector]), ..._if(depth > 0, [tokens_1.currentSelector]), tokens_1.attributeSelectorInitiator, tokens_1.classNameInitiator, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.wildcard, tokens_1.notOperator), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [css selector]. " + hint, start, end),
enclosures,
depth,
notOperatorDepth,
});

@@ -72,15 +89,137 @@ case "notOperator":

depth,
notOperatorDepth,
});
case "notOperatorParenthesis":
return lex(ctx, expect(slice, ...globals, tokens_1.notOperatorParenthesis), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [selector].", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
return lex(ctx, expect(slice, ...globals, ..._if(enclosures.length === 0, [tokens_1.rootSelector]), ..._if(depth > 0, [tokens_1.currentSelector]), tokens_1.notOperator, tokens_1.attributeSelectorInitiator, tokens_1.classNameInitiator, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.wildcard), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [selector].", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth: notOperatorDepth + 1,
});
case "notOperatorParenthesisEndWhiteSpace":
case "notOperatorParenthesisEnd":
const newDepth = notOperatorDepth - (resolvedType === "notOperatorParenthesisEnd" ? 1 : 0);
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "notOperatorParenthesisEndWhiteSpace"), ..._if(enclosures.length === 0, [tokens_1.rootSelector]), ..._if(depth > 0, [tokens_1.currentSelector]), ..._if(newDepth > 0, [tokens_1.notOperatorParenthesisEnd]), tokens_1.colon, tokens_1.selectorSeparator, tokens_1.styleScope, tokens_1.attributeSelectorInitiator, tokens_1.classNameInitiator, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.wildcard), {
onError: (0, errors_1.createErrorContext)(newDepth === 0 ?
"Unexpected token. Expected: [selector]." :
"Unexpected token. Expected: ')' or [selector].", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth: newDepth,
});
case "atSymbol":
return lex(ctx, expect(slice, ...globals, tokens_1.nestedAtRuleName), {
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)(tokens_1.keyframes), tokens_1.nestedAtRuleName), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: 'color-profile', 'counter-style', 'document', 'font-face', 'font-feature-values', 'keyframes', 'media', 'page', 'property' or 'supports'. It's possible that this list is outdated, if so please make an issue on the repository.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframes":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.selectorChild, "keyframesWhiteSpace"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [whitespace].", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesWhiteSpace":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.selectorName, "keyframesName"), tokens_1.keyframesSpecialNames)), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [keyframes name].", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesSpecialNames":
case "keyframesNameWhiteSpace":
case "keyframesName":
if (resolvedType === "keyframesName" && ["None", "initial"].includes(token.match.toString())) {
return lex(ctx, expect(slice, ...globals), {
onError: (0, errors_1.createErrorContext)(`Invalid keyframes name. A keyframes name cannot be '${token.match}' as per "CSS Animations Level 2" w3c specification. You can wrap '${token.match}' in double quotes ('"') like this: '"${token.match}"' to still use this name.`, Math.max(ctx.index - token.match.toString().length, 0), ctx.index),
enclosures,
depth,
notOperatorDepth,
});
}
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.selectorChild, "keyframesNameWhiteSpace"), (0, tokens_1.renameToken)(tokens_1.styleScope, "keyframesScope"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: '{'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesScopeWhitespace":
case "keyframesScope":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesScopeWhitespace"), tokens_1.keyframesSelector, (0, tokens_1.renameToken)(tokens_1.styleScopeEnd, "keyframesScopeEnd"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [percentage selector], 'to', 'from' or '}'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesBlockEndWhitespace":
case "keyframesBlockEnd":
return lex(ctx, expect(slice, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesBlockEndWhitespace"), tokens_1.keyframesSelector, (0, tokens_1.renameToken)(tokens_1.styleScopeEnd, "keyframesScopeEnd"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [keyframes selector] or '}'.", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesScopeEnd":
return lex(ctx, expect(slice, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesScopeEnd"), tokens_1.currentSelector, tokens_1.propertyName, tokens_1.attributeSelectorClose, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.classNameInitiator, tokens_1.atSymbol, tokens_1.whiteSpaceOrNothing)), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [css].", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesSelector":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesSelector"), (0, tokens_1.renameToken)(tokens_1.selectorSeparator, "keyframesSeparator"), (0, tokens_1.renameToken)(tokens_1.styleScope, "keyframesBlock"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ',' or '{'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesSeparator":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesSeparator"), tokens_1.keyframesSelector)), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [percentage selector], 'to' or 'from'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesBlockWhitespace":
case "keyframesBlock":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesBlockWhitespace"), (0, tokens_1.renameToken)(tokens_1.propertyName, "keyframesBlockPropertyName"), (0, tokens_1.renameToken)(tokens_1.styleScopeEnd, "keyframesScopeEnd"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [property name] or '}'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesBlockPropertyName":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesBlockPropertyName"), (0, tokens_1.renameToken)(tokens_1.propertyColon, "keyframesPropertyColon"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ':'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesPropertyColon":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesPropertyColon"), ...(0, tokens_1.renameTokens)([tokens_1.propertyValueWithSemiColon, tokens_1.propertyValueWithoutSemiColon], "keyframesPropertyValue"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [property value]. Did you forget ';'?", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "keyframesPropertyValue": {
const hasSemiColon = false; // todo: fix
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesPropertyValue"), (0, tokens_1.renameToken)(tokens_1.valueSemiColon, "keyframesValueSemiColon"), (0, tokens_1.renameToken)(tokens_1.styleScopeEnd, "keyframesBlockEnd"))), {
onError: (0, errors_1.createErrorContext)(hasSemiColon ?
"Unexpected token. Expected: '}'." :
"Unexpected token. Expected: ';' or '}'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
}
case "keyframesValueSemiColon":
return lex(ctx, expect(slice, ...globals, ...(0, tokens_1.kf)((0, tokens_1.renameToken)(tokens_1.whiteSpace, "keyframesValueSemiColon"), (0, tokens_1.renameToken)(tokens_1.propertyName, "keyframesBlockPropertyName"), (0, tokens_1.renameToken)(tokens_1.styleScopeEnd, "keyframesBlockEnd"))), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [property name] or '}'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "nestedAtRuleName":

@@ -91,2 +230,3 @@ return lex(ctx, expect(slice, ...globals, tokens_1.nestedAtRule), {

depth,
notOperatorDepth,
});

@@ -98,14 +238,17 @@ case "nestedAtRule":

depth,
notOperatorDepth,
});
case "idInitiator":
return lex(ctx, expect(slice, ...globals, tokens_1.selectorName), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ID name", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ID name.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "currentSelector":
return lex(ctx, expect(slice, ...globals, tokens_1.selectorChild, tokens_1.classNameInitiator, tokens_1.colon, tokens_1.selectorName, tokens_1.selectorCombinator, tokens_1.selectorSeparator, tokens_1.styleScope), {
return lex(ctx, expect(slice, ...globals, tokens_1.notOperator, tokens_1.selectorChild, tokens_1.classNameInitiator, tokens_1.colon, tokens_1.selectorName, tokens_1.selectorCombinator, tokens_1.selectorSeparator, tokens_1.styleScope), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ' ', '>', '+', '||', '.', ':', '::', '[...]', ',' or '{' directly proceeding current selector ('&').", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});

@@ -117,2 +260,3 @@ case "attributeSelectorInitiator":

depth,
notOperatorDepth,
});

@@ -124,2 +268,3 @@ case "attributeSelectorName":

depth,
notOperatorDepth,
});

@@ -131,2 +276,3 @@ case "attributeSelectorModifier":

depth,
notOperatorDepth,
});

@@ -138,2 +284,3 @@ case "attributeSelectorSingleQuoteInitiator":

depth,
notOperatorDepth,
});

@@ -145,2 +292,3 @@ case "attributeSelectorDoubleQuoteInitiator":

depth,
notOperatorDepth,
});

@@ -150,11 +298,15 @@ case "attributeSelectorDoubleQuoteBody":

return lex(ctx, expect(slice, ...globals, tokens_1.attributeSelectorClose), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [selector operand]", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: 'i]', 'I]', 's]', 'S]', or ']'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});
case "attributeSelectorClose":
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "attributeSelectorClose"), tokens_1.classNameInitiator, tokens_1.colon, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.selectorSeparator, tokens_1.attributeSelectorInitiator, tokens_1.styleScope), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: 'i]', 'I]', 's]', 'S]', or ']'.", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "attributeSelectorClose"), ..._if(notOperatorDepth > 0, [tokens_1.notOperatorParenthesisEnd]), tokens_1.notOperator, tokens_1.selectorCombinator, tokens_1.wildcard, tokens_1.classNameInitiator, tokens_1.colon, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.selectorSeparator, tokens_1.attributeSelectorInitiator, tokens_1.styleScope), {
onError: (0, errors_1.createErrorContext)(notOperatorDepth === 0 ?
"Unexpected token. Expected: [css selector] or '{'" :
"Unexpected token. Expected: ')', [css selector] or '{'", ctx.index, ctx.index + (0, errors_1.resolveSelectorNameNotFound)(slice)),
enclosures,
depth,
notOperatorDepth,
});

@@ -166,2 +318,3 @@ case "classNameInitiator":

depth,
notOperatorDepth,
});

@@ -173,14 +326,19 @@ case "exportClassName":

depth,
notOperatorDepth,
});
case "wildcard":
return lex(ctx, expect(slice, ...globals, tokens_1.styleScope, tokens_1.colon, tokens_1.selectorChild, tokens_1.selectorSeparator, tokens_1.selectorCombinator), {
return lex(ctx, expect(slice, ...globals, tokens_1.notOperator, tokens_1.styleScope, tokens_1.colon, tokens_1.selectorChild, tokens_1.selectorSeparator, tokens_1.selectorCombinator), {
onError: (0, errors_1.createErrorContext)("Unexpected token directly proceeding universal selector (*). Expected: '{' or [css selector]. ", ctx.index, ctx.index + (/\s/.exec(slice)?.index || 1)),
enclosures,
depth,
notOperatorDepth,
});
case "combinator":
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "combinator"), tokens_1.selectorName, tokens_1.idInitiator, tokens_1.attributeSelectorInitiator, tokens_1.classNameInitiator, tokens_1.wildcard), {
onError: (0, errors_1.createErrorContext)("Unexpected token proceeding selector combinator. Expected: [css selector]. Combinators ('~', '>', '+', '||') cannot directly follow previous combinator. Did you forgot a [css selector] after a selector combinator?", ctx.index, ctx.index + (/\s/.exec(slice)?.index || 1)),
const previousIsCombinator = ctx.strippedTokens?.[ctx.strippedTokens.length - 2]?.name === "combinator";
const combinatorHint = previousIsCombinator ? "Combinators ('~', '>', '+', '||') cannot directly follow previous combinator. " : "";
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "combinator"), tokens_1.notOperator, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.attributeSelectorInitiator, tokens_1.classNameInitiator, tokens_1.wildcard), {
onError: (0, errors_1.createErrorContext)(`Unexpected token proceeding selector combinator. Expected: [combinator operand]. ${combinatorHint}Did you forgot a [combinator operand] after the selector combinator?`, ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});

@@ -192,15 +350,26 @@ case "rootSelector":

depth,
notOperatorDepth,
});
case "className":
case "selectorName":
return lex(ctx, expect(slice, ...globals, tokens_1.attributeSelectorInitiator, tokens_1.colon, tokens_1.styleScope, tokens_1.selectorChild, tokens_1.selectorSeparator, tokens_1.classNameInitiator, tokens_1.selectorCombinator), {
onError: (0, errors_1.createErrorContext)("Unexpected token in selector. Expected: '{' or [css selector].", ctx.index, ctx.index + (/\s/.exec(slice)?.index || 1)),
return lex(ctx, expect(slice, ...globals, tokens_1.notOperator, ..._if(notOperatorDepth > 0, [tokens_1.notOperatorParenthesisEnd]), tokens_1.attributeSelectorInitiator, tokens_1.colon, tokens_1.styleScope, tokens_1.selectorChild, tokens_1.selectorSeparator, tokens_1.classNameInitiator, tokens_1.selectorCombinator), {
onError: (0, errors_1.createErrorContext)("Unexpected token in selector. Expected: '{' or [css selector].", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});
case "selectorSeparator":
if (notOperatorDepth !== 0) {
return lex(ctx, expect(slice, ...globals), {
onError: (0, errors_1.createErrorContext)(`Unexpected selector separator ','. Selector branching is not valid inside ':not(...)' and ':has(...)' operators. Did you forget '${")".repeat(Math.max(1, notOperatorDepth))}'?`, Math.max(0, ctx.index - 1), ctx.index),
enclosures,
depth,
notOperatorDepth,
});
}
return lex(ctx, expect(slice, ...globals, ..._if(enclosures.length === 0, [tokens_1.rootSelector]), tokens_1.currentSelector, tokens_1.classNameInitiator, tokens_1.selectorName, tokens_1.idInitiator), {
onError: (0, errors_1.createErrorContext)("Unexpected token following selector separator (,). Expected: [css selector].", ctx.index, ctx.index + 1),
onError: (0, errors_1.createErrorContext)("Unexpected token following selector separator (','). Expected: [css selector].", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});

@@ -212,5 +381,14 @@ case "selectorChild":

depth,
notOperatorDepth,
});
case "styleScopeWhiteSpace":
case "styleScope":
if (notOperatorDepth !== 0) {
return lex(ctx, expect(slice, ...globals), {
onError: (0, errors_1.createErrorContext)("Unexpected token in style scope. Expected: ')'. Did you forget to end your ':not(...)' or ':has(...)' operator?", Math.max(0, ctx.index - 1), ctx.index),
enclosures,
depth,
notOperatorDepth,
});
}
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "styleScopeWhiteSpace"), tokens_1.atSymbol, tokens_1.styleScopeEnd, tokens_1.propertyName, tokens_1.selectorName, tokens_1.attributeSelectorClose, tokens_1.wildcard, tokens_1.idInitiator, tokens_1.classNameInitiator, tokens_1.currentSelector), {

@@ -220,2 +398,3 @@ onError: (0, errors_1.createErrorContext)("Unexpected token in style scope. Expected: '}', [css selector] or [css property].", ctx.index, ctx.index + 1),

depth,
notOperatorDepth,
});

@@ -226,5 +405,6 @@ case "styleScopeEnd":

expect(slice, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "styleScopeEnd"), ..._if(depth > 0, [tokens_1.styleScopeEnd]), tokens_1.currentSelector, tokens_1.propertyName, tokens_1.attributeSelectorClose, tokens_1.selectorName, tokens_1.idInitiator, tokens_1.classNameInitiator, tokens_1.atSymbol, tokens_1.whiteSpaceOrNothing), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Undefined behaviour." + (depth), ctx.index, ctx.index + 1),
onError: (0, errors_1.createErrorContext)("Unexpected token. Undefined behavior." + (depth), ctx.index, ctx.index + 1),
enclosures: enclosures.slice(1),
depth,
notOperatorDepth,
});

@@ -236,8 +416,10 @@ case "colon":

depth,
notOperatorDepth,
});
case "propertyName":
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "propertyName"), tokens_1.propertyColon), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: property name.", ctx.index, ctx.index + 1),
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [property name].", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});

@@ -247,17 +429,20 @@ case "propertyColon":

return lex(ctx, expect(slice, ...globals, tokens_1.propertyValueWithSemiColon, tokens_1.propertyValueWithoutSemiColon), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ';' or '}'.", errorStartEstimate, errorStartEstimate),
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: [property value].", errorStartEstimate, errorStartEstimate),
enclosures,
depth,
notOperatorDepth,
});
case "propertyValue":
return lex(ctx, expect(slice, ...globals, tokens_1.styleScopeEnd, tokens_1.valueSemiColon), {
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: property value.", ctx.index, ctx.index + 1),
onError: (0, errors_1.createErrorContext)("Unexpected token. Expected: ';' or '}'.", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});
case "valueSemiColon":
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "valueSemiColon"), tokens_1.currentSelector, tokens_1.valueSemiColon, tokens_1.propertyName, tokens_1.styleScopeEnd, tokens_1.classNameInitiator, tokens_1.idInitiator, tokens_1.selectorName), {
return lex(ctx, expect(slice, ...globals, (0, tokens_1.renameToken)(tokens_1.whiteSpace, "valueSemiColon"), tokens_1.atKeyframes, tokens_1.selectorCombinator, tokens_1.currentSelector, tokens_1.notOperator, tokens_1.valueSemiColon, tokens_1.propertyName, tokens_1.styleScopeEnd, tokens_1.classNameInitiator, tokens_1.idInitiator, tokens_1.selectorName), {
onError: (0, errors_1.createErrorContext)("Unexpected token in style scope. Expected: '}'.", ctx.index, ctx.index + 1),
enclosures,
depth,
notOperatorDepth,
});

@@ -264,0 +449,0 @@ default:

@@ -1,2 +0,2 @@

import { whiteSpace, Match, currentSelector, classNameInitiator, selectorName, idInitiator, wildcard, selectorChild, selectorCombinator, selectorSeparator, styleScope, renameToken, attributeSelectorCloseWithoutOperator, attributeSelectorModifier, attributeSelectorSingleQuoteInitiator, attributeSelectorDoubleQuoteInitiator, attributeSelectorSingleQuoteBody, attributeSelectorDoubleQuoteBody, attributeSelectorClose, attributeSelectorInitiator, styleScopeEnd, propertyName, valueSemiColon, propertyColon, propertyValueWithSemiColon, propertyValueWithoutSemiColon, TokenMatcher, inlineComment, renameTokens, blockComment, atSymbol, nestedAtRuleName, nestedAtRule, endStyleSheet, whiteSpaceOrNothing, exportClassName, colon, pseudoSelector, rootSelector, notOperatorParenthesis, notOperator } from "../tokens";
import { whiteSpace, Match, currentSelector, classNameInitiator, selectorName, idInitiator, wildcard, selectorChild, selectorCombinator, selectorSeparator, styleScope, renameToken, attributeSelectorCloseWithoutOperator, attributeSelectorModifier, attributeSelectorSingleQuoteInitiator, attributeSelectorDoubleQuoteInitiator, attributeSelectorSingleQuoteBody, attributeSelectorDoubleQuoteBody, attributeSelectorClose, attributeSelectorInitiator, styleScopeEnd, propertyName, valueSemiColon, propertyColon, propertyValueWithSemiColon, propertyValueWithoutSemiColon, TokenMatcher, inlineComment, renameTokens, blockComment, atSymbol, nestedAtRuleName, nestedAtRule, endStyleSheet, whiteSpaceOrNothing, exportClassName, colon, pseudoSelector, rootSelector, notOperatorParenthesis, notOperator, notOperatorParenthesisEnd, keyframes, requiredWhiteSpace, keyframesSpecialNames, keyframesSelector, kf, atKeyframes } from "../tokens";
import { Config } from "../config";

@@ -21,6 +21,29 @@ import Context from "../context";

/**
* Void CSS lexer — Tokenizes given Void CSS input and then, if valid, compiles it,
* otherwise throws syntax error.
*
* Recursive and declarative design. Each case on the main switch statement represents the next step
* after the given (current token). Each self call of the lex function represents what the lexer should
* expect after the current token. Using attributes which live on the function recursively (as an argument),
* the lexer can call itself with possibly conditional expectations using helper functions such as `_if`.
*
* @param ctx Compile context
* @param token Current token (unless beginning)
* @param attributes Makes the lexer aware of its state
* @returns compiled Void CSS. see `compile` function
*/
function lex(ctx: Context, token: Match | undefined, attributes?: {
onError: ReturnType<typeof createErrorContext>;
/** Requires enclosures to resolve such as a rule which resolve with '}' */
enclosures: TokenMatcher[];
/** The current css rule or "scope" depth (levels nested) */
depth: number;
/** The depth of the :not() syntax. Required since you can nest them */
notOperatorDepth: number;
}): ReturnType<typeof compile> | undefined {

@@ -41,2 +64,5 @@ const { lastToken, index, css: preTokenizedCSS } = ctx;

const notOperatorDepth = attributes?.notOperatorDepth ?? 0;
/** The depth refers to the css rule or "scope" nesting level */
const depth = (attributes?.depth ?? 0) + (() => {

@@ -66,7 +92,7 @@ // The only way to descend a depth is to close it with the `}` token `styleScopeEnd`

/^\s*(?:~|>|\+|\|\|)/.test(section) ?
"Selectors cannot begin with a selector combinator ('~', '>', '+', '||'). Did you forget to add left side selector combinator operand?" :
"Root level selectors cannot begin with a selector combinator ('~', '>', '+', '||'). Did you forget to add left side selector combinator operand?" :
"Instead found invalid or missing selector.";
return lex(
ctx,
expect(slice, ...globals, atSymbol, whiteSpace, ...enclosures, ..._if(enclosures.length === 0, [rootSelector]), ..._if(depth > 0, [currentSelector]), classNameInitiator, selectorName, idInitiator, wildcard, notOperator),
expect(slice, ...globals, atSymbol, whiteSpace, ...enclosures, ..._if(enclosures.length === 0, [rootSelector]), ..._if(depth > 0, [currentSelector]), attributeSelectorInitiator, classNameInitiator, selectorName, idInitiator, wildcard, notOperator),
{

@@ -80,2 +106,3 @@ onError: createErrorContext(

depth,
notOperatorDepth,
},

@@ -95,2 +122,3 @@ );

depth,
notOperatorDepth,
},

@@ -101,3 +129,3 @@ );

ctx,
expect(slice, ...globals, notOperatorParenthesis),
expect(slice, ...globals, ..._if(enclosures.length === 0, [rootSelector]), ..._if(depth > 0, [currentSelector]), notOperator, attributeSelectorInitiator, classNameInitiator, selectorName, idInitiator, wildcard),
{

@@ -107,12 +135,32 @@ onError: createErrorContext(

ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
ctx.index + 1,
),
enclosures,
depth,
notOperatorDepth: notOperatorDepth + 1,
},
);
case "notOperatorParenthesisEndWhiteSpace":
case "notOperatorParenthesisEnd":
const newDepth = notOperatorDepth - (resolvedType === "notOperatorParenthesisEnd" ? 1 : 0);
return lex(
ctx,
expect(slice, ...globals, renameToken(whiteSpace, "notOperatorParenthesisEndWhiteSpace"), ..._if(enclosures.length === 0, [rootSelector]), ..._if(depth > 0, [currentSelector]), ..._if(newDepth > 0, [notOperatorParenthesisEnd]), colon, selectorSeparator, styleScope, attributeSelectorInitiator, classNameInitiator, selectorName, idInitiator, wildcard),
{
onError: createErrorContext(
newDepth === 0 ?
"Unexpected token. Expected: [selector]." :
"Unexpected token. Expected: ')' or [selector].",
ctx.index,
ctx.index + 1,
),
enclosures,
depth,
notOperatorDepth: newDepth,
},
);
case "atSymbol":
return lex(
ctx,
expect(slice, ...globals, nestedAtRuleName),
expect(slice, ...globals, ...kf(keyframes), nestedAtRuleName),
{

@@ -126,4 +174,225 @@ onError: createErrorContext(

depth,
notOperatorDepth,
},
);
case "keyframes":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(selectorChild, "keyframesWhiteSpace"))),
{
onError: createErrorContext(
"Unexpected token. Expected: [whitespace].",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesWhiteSpace":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(selectorName, "keyframesName"), keyframesSpecialNames)),
{
onError: createErrorContext(
"Unexpected token. Expected: [keyframes name].",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesSpecialNames":
case "keyframesNameWhiteSpace":
case "keyframesName":
if (resolvedType === "keyframesName" && ["None", "initial"].includes(token.match.toString())) {
return lex(
ctx,
expect(slice, ...globals),
{
onError: createErrorContext(
`Invalid keyframes name. A keyframes name cannot be '${token.match}' as per "CSS Animations Level 2" w3c specification. You can wrap '${token.match}' in double quotes ('"') like this: '"${token.match}"' to still use this name.`,
Math.max(ctx.index - token.match.toString().length, 0),
ctx.index,
),
enclosures,
depth,
notOperatorDepth,
},
);
}
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(selectorChild, "keyframesNameWhiteSpace"), renameToken(styleScope, "keyframesScope"))),
{
onError: createErrorContext(
"Unexpected token. Expected: '{'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesScopeWhitespace":
case "keyframesScope":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesScopeWhitespace"), keyframesSelector, renameToken(styleScopeEnd, "keyframesScopeEnd"))),
{
onError: createErrorContext(
"Unexpected token. Expected: [percentage selector], 'to', 'from' or '}'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesBlockEndWhitespace":
case "keyframesBlockEnd":
return lex(
ctx,
expect(slice, ...kf(renameToken(whiteSpace, "keyframesBlockEndWhitespace"), keyframesSelector, renameToken(styleScopeEnd, "keyframesScopeEnd"))),
{
onError: createErrorContext(
"Unexpected token. Expected: [keyframes selector] or '}'.",
ctx.index,
ctx.index + 1,
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesScopeEnd":
return lex(
ctx,
expect(slice, ...kf(renameToken(whiteSpace, "keyframesScopeEnd"), currentSelector, propertyName, attributeSelectorClose, selectorName, idInitiator, classNameInitiator, atSymbol, whiteSpaceOrNothing)),
{
onError: createErrorContext(
"Unexpected token. Expected: [css].",
ctx.index,
ctx.index + 1,
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesSelector":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesSelector"), renameToken(selectorSeparator, "keyframesSeparator"), renameToken(styleScope, "keyframesBlock"))),
{
onError: createErrorContext(
"Unexpected token. Expected: ',' or '{'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesSeparator":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesSeparator"), keyframesSelector)),
{
onError: createErrorContext(
"Unexpected token. Expected: [percentage selector], 'to' or 'from'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesBlockWhitespace":
case "keyframesBlock":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesBlockWhitespace"), renameToken(propertyName, "keyframesBlockPropertyName"), renameToken(styleScopeEnd, "keyframesScopeEnd"))),
{
onError: createErrorContext(
"Unexpected token. Expected: [property name] or '}'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesBlockPropertyName":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesBlockPropertyName"), renameToken(propertyColon, "keyframesPropertyColon"))),
{
onError: createErrorContext(
"Unexpected token. Expected: ':'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesPropertyColon":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesPropertyColon"), ...renameTokens([propertyValueWithSemiColon, propertyValueWithoutSemiColon], "keyframesPropertyValue"))),
{
onError: createErrorContext(
"Unexpected token. Expected: [property value]. Did you forget ';'?",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "keyframesPropertyValue": {
const hasSemiColon = false; // todo: fix
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesPropertyValue"), renameToken(valueSemiColon, "keyframesValueSemiColon"), renameToken(styleScopeEnd, "keyframesBlockEnd"))),
{
onError: createErrorContext(
hasSemiColon ?
"Unexpected token. Expected: '}'." :
"Unexpected token. Expected: ';' or '}'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
}
case "keyframesValueSemiColon":
return lex(
ctx,
expect(slice, ...globals, ...kf(renameToken(whiteSpace, "keyframesValueSemiColon"), renameToken(propertyName, "keyframesBlockPropertyName"), renameToken(styleScopeEnd, "keyframesBlockEnd"))),
{
onError: createErrorContext(
"Unexpected token. Expected: [property name] or '}'.",
ctx.index,
ctx.index + resolveSelectorNameNotFound(slice),
),
enclosures,
depth,
notOperatorDepth,
},
);
case "nestedAtRuleName":

@@ -141,2 +410,3 @@ return lex(

depth,
notOperatorDepth,
},

@@ -156,2 +426,3 @@ );

depth,
notOperatorDepth,
},

@@ -165,3 +436,3 @@ );

onError: createErrorContext(
"Unexpected token. Expected: ID name",
"Unexpected token. Expected: ID name.",
ctx.index,

@@ -172,2 +443,3 @@ ctx.index + resolveSelectorNameNotFound(slice),

depth,
notOperatorDepth,
},

@@ -178,3 +450,3 @@ );

ctx,
expect(slice, ...globals, selectorChild, classNameInitiator, colon, selectorName, selectorCombinator, selectorSeparator, styleScope),
expect(slice, ...globals, notOperator, selectorChild, classNameInitiator, colon, selectorName, selectorCombinator, selectorSeparator, styleScope),
{

@@ -188,2 +460,3 @@ onError: createErrorContext(

depth,
notOperatorDepth,
},

@@ -203,2 +476,3 @@ );

depth,
notOperatorDepth,
},

@@ -218,2 +492,3 @@ );

depth,
notOperatorDepth,
},

@@ -233,2 +508,3 @@ );

depth,
notOperatorDepth,
},

@@ -248,2 +524,3 @@ );

depth,
notOperatorDepth,
},

@@ -263,2 +540,3 @@ );

depth,
notOperatorDepth,
},

@@ -273,3 +551,3 @@ );

onError: createErrorContext(
"Unexpected token. Expected: [selector operand]",
"Unexpected token. Expected: 'i]', 'I]', 's]', 'S]', or ']'.",
ctx.index,

@@ -280,2 +558,3 @@ ctx.index + resolveSelectorNameNotFound(slice),

depth,
notOperatorDepth,
},

@@ -286,6 +565,8 @@ );

ctx,
expect(slice, ...globals, renameToken(whiteSpace, "attributeSelectorClose"), classNameInitiator, colon, selectorName, idInitiator, selectorSeparator, attributeSelectorInitiator, styleScope),
expect(slice, ...globals, renameToken(whiteSpace, "attributeSelectorClose"), ..._if(notOperatorDepth > 0, [notOperatorParenthesisEnd]), notOperator, selectorCombinator, wildcard, classNameInitiator, colon, selectorName, idInitiator, selectorSeparator, attributeSelectorInitiator, styleScope),
{
onError: createErrorContext(
"Unexpected token. Expected: 'i]', 'I]', 's]', 'S]', or ']'.",
notOperatorDepth === 0 ?
"Unexpected token. Expected: [css selector] or '{'" :
"Unexpected token. Expected: ')', [css selector] or '{'",
ctx.index,

@@ -296,2 +577,3 @@ ctx.index + resolveSelectorNameNotFound(slice),

depth,
notOperatorDepth,
},

@@ -311,2 +593,3 @@ );

depth,
notOperatorDepth,
},

@@ -326,2 +609,3 @@ );

depth,
notOperatorDepth,
},

@@ -332,3 +616,3 @@ );

ctx,
expect(slice, ...globals, styleScope, colon, selectorChild, selectorSeparator, selectorCombinator),
expect(slice, ...globals, notOperator, styleScope, colon, selectorChild, selectorSeparator, selectorCombinator),
{

@@ -342,16 +626,21 @@ onError: createErrorContext(

depth,
notOperatorDepth,
},
);
case "combinator":
const previousIsCombinator = ctx.strippedTokens?.[ctx.strippedTokens.length - 2]?.name === "combinator";
const combinatorHint = previousIsCombinator ? "Combinators ('~', '>', '+', '||') cannot directly follow previous combinator. " : "";
return lex(
ctx,
expect(slice, ...globals, renameToken(whiteSpace, "combinator"), selectorName, idInitiator, attributeSelectorInitiator, classNameInitiator, wildcard),
expect(slice, ...globals, renameToken(whiteSpace, "combinator"), notOperator, selectorName, idInitiator, attributeSelectorInitiator, classNameInitiator, wildcard),
{
onError: createErrorContext(
"Unexpected token proceeding selector combinator. Expected: [css selector]. Combinators ('~', '>', '+', '||') cannot directly follow previous combinator. Did you forgot a [css selector] after a selector combinator?",
`Unexpected token proceeding selector combinator. Expected: [combinator operand]. ${combinatorHint}Did you forgot a [combinator operand] after the selector combinator?`,
ctx.index,
ctx.index + (/\s/.exec(slice)?.index || 1),
ctx.index + 1,
),
enclosures,
depth,
notOperatorDepth,
},

@@ -371,2 +660,3 @@ );

depth,
notOperatorDepth,
},

@@ -378,3 +668,3 @@ );

ctx,
expect(slice, ...globals, attributeSelectorInitiator, colon, styleScope, selectorChild, selectorSeparator, classNameInitiator, selectorCombinator),
expect(slice, ...globals, notOperator, ..._if(notOperatorDepth > 0, [notOperatorParenthesisEnd]), attributeSelectorInitiator, colon, styleScope, selectorChild, selectorSeparator, classNameInitiator, selectorCombinator),
{

@@ -384,9 +674,26 @@ onError: createErrorContext(

ctx.index,
ctx.index + (/\s/.exec(slice)?.index || 1),
ctx.index + 1,
),
enclosures,
depth,
notOperatorDepth,
},
);
case "selectorSeparator":
if (notOperatorDepth !== 0) {
return lex(
ctx,
expect(slice, ...globals),
{
onError: createErrorContext(
`Unexpected selector separator ','. Selector branching is not valid inside ':not(...)' and ':has(...)' operators. Did you forget '${")".repeat(Math.max(1, notOperatorDepth))}'?`,
Math.max(0, ctx.index - 1),
ctx.index,
),
enclosures,
depth,
notOperatorDepth,
},
);
}
return lex(

@@ -397,3 +704,3 @@ ctx,

onError: createErrorContext(
"Unexpected token following selector separator (,). Expected: [css selector].",
"Unexpected token following selector separator (','). Expected: [css selector].",
ctx.index,

@@ -404,2 +711,3 @@ ctx.index + 1,

depth,
notOperatorDepth,
},

@@ -419,5 +727,22 @@ );

depth,
notOperatorDepth,
});
case "styleScopeWhiteSpace":
case "styleScope":
if (notOperatorDepth !== 0) {
return lex(
ctx,
expect(slice, ...globals),
{
onError: createErrorContext(
"Unexpected token in style scope. Expected: ')'. Did you forget to end your ':not(...)' or ':has(...)' operator?",
Math.max(0, ctx.index - 1),
ctx.index,
),
enclosures,
depth,
notOperatorDepth,
},
);
}
return lex(

@@ -434,2 +759,3 @@ ctx,

depth,
notOperatorDepth,
},

@@ -444,3 +770,3 @@ );

onError: createErrorContext(
"Unexpected token. Undefined behaviour." + (depth),
"Unexpected token. Undefined behavior." + (depth),
ctx.index,

@@ -451,2 +777,3 @@ ctx.index + 1,

depth,
notOperatorDepth,
},

@@ -464,2 +791,3 @@ );

depth,
notOperatorDepth,
},

@@ -471,3 +799,3 @@ );

onError: createErrorContext(
"Unexpected token. Expected: property name.",
"Unexpected token. Expected: [property name].",
ctx.index,

@@ -478,2 +806,3 @@ ctx.index + 1,

depth,
notOperatorDepth,
},

@@ -488,3 +817,3 @@ );

onError: createErrorContext(
"Unexpected token. Expected: ';' or '}'.",
"Unexpected token. Expected: [property value].",
errorStartEstimate,

@@ -495,2 +824,3 @@ errorStartEstimate,

depth,
notOperatorDepth,
},

@@ -503,3 +833,3 @@ );

onError: createErrorContext(
"Unexpected token. Expected: property value.",
"Unexpected token. Expected: ';' or '}'.",
ctx.index,

@@ -510,2 +840,3 @@ ctx.index + 1,

depth,
notOperatorDepth,
},

@@ -516,3 +847,3 @@ );

ctx,
expect(slice, ...globals, renameToken(whiteSpace, "valueSemiColon"), currentSelector, valueSemiColon, propertyName, styleScopeEnd, classNameInitiator, idInitiator, selectorName),
expect(slice, ...globals, renameToken(whiteSpace, "valueSemiColon"), atKeyframes, selectorCombinator, currentSelector, notOperator, valueSemiColon, propertyName, styleScopeEnd, classNameInitiator, idInitiator, selectorName),
{

@@ -526,2 +857,3 @@ onError: createErrorContext(

depth,
notOperatorDepth,
},

@@ -528,0 +860,0 @@ );

@@ -21,2 +21,3 @@ "use strict";

_extensions = [];
_keyframes = [];
_config;

@@ -38,2 +39,5 @@ classesCache = new Map();

}
get keyframes() {
return this._keyframes;
}
get strippedTokens() {

@@ -70,5 +74,10 @@ return this._strippedTokens;

void (this._index += match.length ?? 0);
if (token.attributes?.includes("keyframes") && token.domain !== "void") {
void this._tokens.push(formalizeMatch(this._index, match, token, depth));
this._keyframes.push(formalizeMatch(this._index, match, token, depth));
return this;
}
void this._tokens.push(formalizeMatch(this._index, match, token, depth));
if (token.domain !== "void")
return (this._strippedTokens.push(formalizeMatch(this._index, match, token, depth)), this);
return (void this._strippedTokens.push(formalizeMatch(this._index, match, token, depth)), this);
return this;

@@ -75,0 +84,0 @@ }

@@ -26,2 +26,3 @@ import { Match } from "./tokens";

private _extensions: Extension[] = [];
private _keyframes: Token[] = [];
private readonly _config!: Config;

@@ -44,2 +45,5 @@ public readonly classesCache = new Map<string, string>();

}
get keyframes() {
return this._keyframes;
}
get strippedTokens() {

@@ -76,9 +80,17 @@ return this._strippedTokens;

const match = token?.match?.[0];
if (typeof match !== "string") return this;
void (this._index += match.length ?? 0);
if (token.attributes?.includes("keyframes") && token.domain !== "void") {
void this._tokens.push(formalizeMatch(this._index, match, token, depth));
this._keyframes.push(formalizeMatch(this._index, match, token, depth));
return this;
}
void this._tokens.push(formalizeMatch(this._index, match, token, depth));
if (token.domain !== "void") return (
this._strippedTokens.push(formalizeMatch(this._index, match, token, depth)), this
void this._strippedTokens.push(formalizeMatch(this._index, match, token, depth)), this
);
return this;

@@ -85,0 +97,0 @@ }

@@ -9,7 +9,12 @@ "use strict";

function createCompilationError(ctx, error) {
return `\n${highlightFormattedArea(ctx.css, error)}
return `\n${highlightFormattedArea(ctx.css.replace(/\t/g, " "), error)}
${chalk_1.default.yellow(`${chalk_1.default.white(chalk_1.default.bgRed("Error during Void CSS compilation:"))} ${error.message.replace(/'(.*?)'/g, (_, g) => {
${chalk_1.default.yellow(`${chalk_1.default.white(chalk_1.default.bgRed("Error during Void CSS compilation:"))} ${error.message
.replace(/\[([^\]]+)\]/g, (_, g) => {
return chalk_1.default.grey(`[`) + chalk_1.default.bold(chalk_1.default.cyan(g)) + chalk_1.default.grey(`]`);
})
.replace(/'(.*?)'/g, (_, g) => {
return chalk_1.default.grey(`‘`) + chalk_1.default.bold(chalk_1.default.cyan(g)) + chalk_1.default.grey(`’`);
}).replace(/(^.*?\.)/g, chalk_1.default.red("$1"))}`)}`;
})
.replace(/(^.*?\.)/g, chalk_1.default.red("$1"))}`)}`;
}

@@ -22,5 +27,5 @@ exports.createCompilationError = createCompilationError;

function resolveEndOfPropertyValue(slice) {
const property = slice.substr(0, /[a-zA-Z-]+:/.exec(slice)?.index ?? slice.length);
const property = slice.slice(0, /[a-zA-Z-]+:/.exec(slice)?.index ?? slice.length);
const newLines = property.match(/\n/g);
const lastNewLine = (newLines?.reduce(t => t + (property.substr(t).match(/\n/)?.index ?? 0) + 1, 0) ?? 1) - 1;
const lastNewLine = (newLines?.reduce(t => t + (property.slice(t).match(/\n/)?.index ?? 0) + 1, 0) ?? 1) - 1;
return lastNewLine || (slice.match(/\:\s*[a-zA-Z0-9_-]+/)?.length ?? 0);

@@ -45,3 +50,3 @@ }

function highlightFormattedArea(rawFile, { start, end }) {
const file = rawFile.slice(0, start) + interpolationStartId + rawFile.slice(start, end - start) + (start === end ? "" : interpolationEndId) + rawFile.slice(end);
const file = rawFile.slice(0, start) + interpolationStartId + rawFile.slice(start, end - start) + rawFile.slice(start);
const n = 2;

@@ -62,5 +67,5 @@ const affectedLines = {

}
const numbering = `${" ".repeat(Math.max((highestNumber + "").length - (i + affectedLines.start + "").length, 0))}${i + affectedLines.start - 1 + initial}| `;
const numbering = `${" ".repeat(Math.max((highestNumber + "").length - (i + affectedLines.start + "").length, 0))}${i + affectedLines.start - 1 + initial} | `;
const match = interpolRegex.exec(line);
const composedLine = `${numbering}${line}`;
const composedLine = ` ${numbering}${line}`;
if (!match)

@@ -73,4 +78,4 @@ return composedLine;

return [
numbering + newLine,
new Array(numbering.length + match.index + 1).fill("").join(" ") + chalk_1.default.red("~".repeat(repeatTilde)),
`${chalk_1.default.red(">") + chalk_1.default.reset()} ${numbering}${newLine}`,
new Array(numbering.length + match.index + 3).fill("").join(" ") + chalk_1.default.red("^") + chalk_1.default.red("~".repeat(repeatTilde - 1)),
];

@@ -77,0 +82,0 @@ })

@@ -5,7 +5,12 @@ import Context from "../context";

export function createCompilationError(ctx: Context, error: ReturnType<typeof createErrorContext>) {
return `\n${highlightFormattedArea(ctx.css, error)}
return `\n${highlightFormattedArea(ctx.css.replace(/\t/g, " "), error)}
${chalk.yellow(`${chalk.white(chalk.bgRed("Error during Void CSS compilation:"))} ${error.message.replace(/'(.*?)'/g, (_, g) => {
return chalk.grey(`‘`) + chalk.bold(chalk.cyan(g)) + chalk.grey(`’`);
}).replace(/(^.*?\.)/g, chalk.red("$1"))}`)}`;
${chalk.yellow(`${chalk.white(chalk.bgRed("Error during Void CSS compilation:"))} ${error.message
.replace(/\[([^\]]+)\]/g, (_, g) => {
return chalk.grey(`[`) + chalk.bold(chalk.cyan(g)) + chalk.grey(`]`);
})
.replace(/'(.*?)'/g, (_, g) => {
return chalk.grey(`‘`) + chalk.bold(chalk.cyan(g)) + chalk.grey(`’`);
})
.replace(/(^.*?\.)/g, chalk.red("$1"))}`)}`;
}

@@ -18,5 +23,5 @@

export function resolveEndOfPropertyValue(slice: string): number {
const property = slice.substr(0, /[a-zA-Z-]+:/.exec(slice)?.index ?? slice.length);
const property = slice.slice(0, /[a-zA-Z-]+:/.exec(slice)?.index ?? slice.length);
const newLines = property.match(/\n/g);
const lastNewLine = (newLines?.reduce<number>(t => t + (property.substr(t).match(/\n/)?.index ?? 0) + 1, 0) ?? 1) - 1;
const lastNewLine = (newLines?.reduce<number>(t => t + (property.slice(t).match(/\n/)?.index ?? 0) + 1, 0) ?? 1) - 1;
return lastNewLine || (slice.match(/\:\s*[a-zA-Z0-9_-]+/)?.length ?? 0);

@@ -41,3 +46,3 @@ }

function highlightFormattedArea(rawFile: string, { start, end }: ReturnType<typeof createErrorContext>) {
const file = rawFile.slice(0, start) + interpolationStartId + rawFile.slice(start, end - start) + (start === end ? "" : interpolationEndId) + rawFile.slice(end);
const file = rawFile.slice(0, start) + interpolationStartId + rawFile.slice(start, end - start) + rawFile.slice(start);
const n = 2;

@@ -48,2 +53,3 @@ const affectedLines = {

}
const lines = file.split(/\n/);

@@ -60,5 +66,5 @@ const interpolRegex = new RegExp(`${interpolationStartId}|${interpolationEndId}`, "g");

}
const numbering = `${" ".repeat(Math.max((highestNumber + "").length - (i + affectedLines.start + "").length, 0))}${i + affectedLines.start - 1 + initial}| `;
const numbering = `${" ".repeat(Math.max((highestNumber + "").length - (i + affectedLines.start + "").length, 0))}${i + affectedLines.start - 1 + initial} | `;
const match = interpolRegex.exec(line);
const composedLine = `${numbering}${line}`;
const composedLine = ` ${numbering}${line}`;
if (!match) return composedLine;

@@ -69,9 +75,9 @@ const newLine = line.replace(interpolRegex, start === end ? " " : "");

return [
numbering + newLine,
new Array(numbering.length + match.index + 1).fill("").join(" ") + chalk.red("~".repeat(repeatTilde)),
`${chalk.red(">") + chalk.reset()} ${numbering}${newLine}`,
new Array(numbering.length + match.index + 3).fill("").join(" ") + chalk.red("^") + chalk.red("~".repeat(repeatTilde - 1)),
];
})
.flat(2);
return finalLines/* .filter(line => !/^\d*\|*\s*$/.test(line)) */.join("\n");
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.currentSelector = exports.wildcard = exports.selectorCombinator = exports.attributeSelectorCloseWithoutOperator = exports.attributeSelectorClose = exports.attributeSelectorDoubleQuoteBody = exports.attributeSelectorDoubleQuoteInitiator = exports.attributeSelectorSingleQuoteBody = exports.attributeSelectorSingleQuoteInitiator = exports.attributeSelectorModifier = exports.attributeSelectorInitiator = exports.valueSemiColon = exports.propertyValueWithoutSemiColon = exports.propertyValueWithSemiColon = exports.propertyColon = exports.propertyName = exports.styleScopeEnd = exports.styleScope = exports.selectorName = exports.selectorChild = exports.selectorSeparator = exports.idInitiator = exports.exportClassName = exports.classNameInitiator = exports.whiteSpaceOrNothing = exports.pseudoSelector = exports.colon = exports.whiteSpace = exports.blockComment = exports.inlineComment = exports.rootSelector = exports.endStyleSheet = exports.nestedAtRule = exports.nestedAtRuleName = exports.atSymbol = exports.notOperatorParenthesis = exports.notOperator = exports.serializePropertyValues = exports.renameTokens = exports.renameToken = void 0;
exports.currentSelector = exports.wildcard = exports.selectorCombinator = exports.attributeSelectorCloseWithoutOperator = exports.attributeSelectorClose = exports.attributeSelectorDoubleQuoteBody = exports.attributeSelectorDoubleQuoteInitiator = exports.attributeSelectorSingleQuoteBody = exports.attributeSelectorSingleQuoteInitiator = exports.attributeSelectorModifier = exports.attributeSelectorInitiator = exports.valueSemiColon = exports.propertyValueWithoutSemiColon = exports.propertyValueWithSemiColon = exports.propertyColon = exports.propertyName = exports.styleScopeEnd = exports.requiredWhiteSpace = exports.styleScope = exports.selectorName = exports.selectorChild = exports.selectorSeparator = exports.idInitiator = exports.exportClassName = exports.classNameInitiator = exports.whiteSpaceOrNothing = exports.pseudoSelector = exports.colon = exports.whiteSpace = exports.blockComment = exports.inlineComment = exports.rootSelector = exports.endStyleSheet = exports.nestedAtRule = exports.nestedAtRuleName = exports.keyframesSelector = exports.keyframesSpecialNames = exports.atKeyframes = exports.keyframes = exports.atSymbol = exports.notOperatorParenthesisEnd = exports.notOperatorParenthesis = exports.notOperator = exports.ifOperator = exports.serializePropertyValues = exports.kf = exports.renameTokens = exports.renameToken = void 0;
/**

@@ -37,2 +37,26 @@ * Renames a token. Useful for borrowing logic while preserving the current grammar branch.

exports.renameTokens = renameTokens;
/**
* Utility to borrow logic while still restricting syntax for the special keyframes case;
* where for example, nested DOM (non-keyframe) selectors are not allowed.
* @param token old token
* @param type new name
* @returns new token with keyframes attribute
*/
function kf(...tokens) {
return attributeAdder("keyframes", tokens);
}
exports.kf = kf;
function attributeAdder(attribute, tokens) {
return tokens.map(token => {
return (input) => {
const match = token(input);
if (!match)
return undefined;
return {
...match,
attributes: [...new Set(["keyframes", ...(match.attributes ?? [])])],
};
};
});
}
function serializePropertyValues(match) {

@@ -46,2 +70,11 @@ if (!match)

exports.serializePropertyValues = serializePropertyValues;
function ifOperator(input) {
return {
type: "ifOperator",
domain: "flow",
attributes: [],
match: input.match(/^@if/),
};
}
exports.ifOperator = ifOperator;
function notOperator(input) {

@@ -65,2 +98,11 @@ return {

exports.notOperatorParenthesis = notOperatorParenthesis;
function notOperatorParenthesisEnd(input) {
return {
type: "notOperatorParenthesisEnd",
domain: "selector",
attributes: [],
match: input.match(/^\)/),
};
}
exports.notOperatorParenthesisEnd = notOperatorParenthesisEnd;
function atSymbol(input) {

@@ -70,3 +112,3 @@ return {

domain: "selector",
attributes: ["atRule"],
attributes: ["keyframes"],
match: input.match(/^@/),

@@ -76,3 +118,40 @@ };

exports.atSymbol = atSymbol;
// this intentionally does not include @import, @charset and @namespace
function keyframes(input) {
return {
type: "keyframes",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^keyframes/i),
};
}
exports.keyframes = keyframes;
function atKeyframes(input) {
return {
type: "keyframes",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^@keyframes/i),
};
}
exports.atKeyframes = atKeyframes;
function keyframesSpecialNames(input) {
return {
type: "keyframesSpecialNames",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^"initial"|^"None"/),
};
}
exports.keyframesSpecialNames = keyframesSpecialNames;
/** basically a percentage, to or from */
function keyframesSelector(input) {
return {
type: "keyframesSelector",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^\d+%|to|from/i),
};
}
exports.keyframesSelector = keyframesSelector;
// this intentionally does not include @import, @charset, @keyframes (look up) and @namespace
function nestedAtRuleName(input) {

@@ -83,3 +162,3 @@ return {

attributes: ["atRule"],
match: input.match(/^(?:color-profile|counter-style|document|font-face|font-feature-values|keyframes|media|page|property|supports)/i),
match: input.match(/^(?:color-profile|counter-style|document|font-face|font-feature-values|media|page|property|supports)/i),
};

@@ -222,2 +301,10 @@ }

exports.styleScope = styleScope;
function requiredWhiteSpace(input) {
return {
type: "requiredWhiteSpace",
domain: "void",
match: input.match(/^\s+/),
};
}
exports.requiredWhiteSpace = requiredWhiteSpace;
function styleScopeEnd(input) {

@@ -345,3 +432,3 @@ return {

domain: "selector",
match: input.match(/(^>|^~|^\+|^\|\|)\s+/),
match: input.match(/(^>|^~|^\+|^\|\|)/),
};

@@ -348,0 +435,0 @@ }

@@ -1,2 +0,2 @@

export type Domains = "selector" | "style" | "void";
export type Domains = "selector" | "style" | "void" | "flow";
export type Match = {

@@ -45,3 +45,27 @@ type: string;

/**
* Utility to borrow logic while still restricting syntax for the special keyframes case;
* where for example, nested DOM (non-keyframe) selectors are not allowed.
* @param token old token
* @param type new name
* @returns new token with keyframes attribute
*/
export function kf(...tokens: TokenMatcher[]): TokenMatcher[] {
return attributeAdder("keyframes", tokens);
}
function attributeAdder(attribute: string, tokens: TokenMatcher[]): TokenMatcher[] {
return tokens.map(token => {
return (input: string) => {
const match = token(input);
if (!match) return undefined;
return {
...match,
attributes: [...new Set(["keyframes", ...(match.attributes ?? [])])],
};
}
});
}
export function serializePropertyValues(match: RegExpMatchArray | null) {

@@ -53,2 +77,11 @@ if (!match) return match;

export function ifOperator(input: string): Match {
return {
type: "ifOperator",
domain: "flow",
attributes: [],
match: input.match(/^@if/),
}
}
export function notOperator(input: string): Match {

@@ -70,2 +103,10 @@ return {

}
export function notOperatorParenthesisEnd(input: string): Match {
return {
type: "notOperatorParenthesisEnd",
domain: "selector",
attributes: [],
match: input.match(/^\)/),
}
}

@@ -76,8 +117,42 @@ export function atSymbol(input: string): Match {

domain: "selector",
attributes: ["atRule"],
attributes: ["keyframes"],
match: input.match(/^@/),
}
}
export function keyframes(input: string): Match {
return {
type: "keyframes",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^keyframes/i),
}
}
export function atKeyframes(input: string): Match {
return {
type: "keyframes",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^@keyframes/i),
}
}
export function keyframesSpecialNames(input: string): Match {
return {
type: "keyframesSpecialNames",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^"initial"|^"None"/),
}
}
// this intentionally does not include @import, @charset and @namespace
/** basically a percentage, to or from */
export function keyframesSelector(input: string): Match {
return {
type: "keyframesSelector",
domain: "selector",
attributes: ["keyframes"],
match: input.match(/^\d+%|to|from/i),
}
}
// this intentionally does not include @import, @charset, @keyframes (look up) and @namespace
export function nestedAtRuleName(input: string): Match {

@@ -88,3 +163,3 @@ return {

attributes: ["atRule"],
match: input.match(/^(?:color-profile|counter-style|document|font-face|font-feature-values|keyframes|media|page|property|supports)/i),
match: input.match(/^(?:color-profile|counter-style|document|font-face|font-feature-values|media|page|property|supports)/i),
}

@@ -221,2 +296,9 @@ }

}
export function requiredWhiteSpace(input: string): Match {
return {
type: "requiredWhiteSpace",
domain: "void",
match: input.match(/^\s+/),
}
}
export function styleScopeEnd(input: string): Match {

@@ -263,3 +345,3 @@ return {

}
export function valueSemiColon(input: string): Match {
export function valueSemiColon(input: string): Match { // todo: rename to Semicolon
return {

@@ -333,3 +415,3 @@ type: "valueSemiColon",

domain: "selector",
match: input.match(/(^>|^~|^\+|^\|\|)\s+/),
match: input.match(/(^>|^~|^\+|^\|\|)/),
}

@@ -336,0 +418,0 @@ }

@@ -10,5 +10,6 @@ "use strict";

const compile = (0, index_1.default)();
(0, globals_1.test)("class name compilation", () => {
const name = "className";
(0, globals_1.test)((0, utilts_1.buildDesc)(name), () => {
(0, globals_1.expect)((0, utilts_1.stripNewLines)(compile((0, utilts_1.read)("./className/className.test.vcss"))?.static ?? ""))
.toEqual((0, utilts_1.stripNewLines)((0, utilts_1.read)("./className/className.test.css")));
});
import VoidCSS from "../../index";
import { expect, test } from "@jest/globals";
import { read, stripNewLines } from "../utilts";
import { buildDesc, read, stripNewLines } from "../utilts";

@@ -8,7 +8,7 @@

const name = "className";
test("class name compilation", () => {
test(buildDesc(name), () => {
expect(stripNewLines(compile(read("./className/className.test.vcss"))?.static ?? ""))
.toEqual(stripNewLines(read("./className/className.test.css")));
});

@@ -12,3 +12,4 @@ "use strict";

(0, globals_1.test)((0, utilts_1.buildDesc)(name), () => {
console.log(compile((0, utilts_1.read)(`./${name}/${name}.test.vcss`)));
const compiled = compile((0, utilts_1.read)(`./${name}/${name}.test.vcss`));
(0, globals_1.expect)(Object.keys(compiled?.classes ?? {})).toStrictEqual(["testClass"]);
});

@@ -13,4 +13,6 @@ import VoidCSS from "../../index";

console.log(compile(read(`./${name}/${name}.test.vcss`)));
const compiled = compile(read(`./${name}/${name}.test.vcss`));
expect(Object.keys(compiled?.classes ?? {})).toStrictEqual(["testClass"])
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc