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.29 to 1.0.30

4

package.json
{
"name": "void-css",
"version": "1.0.29",
"version": "1.0.30",
"description": "A JIT & statically compiled CSS processor",

@@ -30,2 +30,2 @@ "main": "index.js",

}
}
}

@@ -22,3 +22,3 @@ "use strict";

return term;
const match = /^(?<name>[a-zA-Z]+)\((?<funcArgument>.*?)\)$/.exec(term);
const match = /^(?<name>[a-zA-Z]*)\((?<funcArgument>.*?)\)$/.exec(term);
if (!match)

@@ -29,2 +29,5 @@ return term;

const resolvedArgument = reduce(operands(funcArgument)).join("");
if (!name)
return resolvedArgument;
console.log("yes");
return `${name}(${resolvedArgument})`;

@@ -81,6 +84,6 @@ }

return false;
return /(?:\-\-|\$)[a-zA-Z0-9-_]+|\d*\.?\d+[a-zA-Z]*|^[a-zA-Z%]+\(/.test(input);
return /(?:\-\-|\$)[a-zA-Z0-9-_]+|\d*\.?-?\d+[a-zA-Z]*|^[a-zA-Z%]+\(/.test(input);
}
function operands(input) {
const tokens = input.split(/((?:\-\-|\$)[a-zA-Z0-9-_]+|\s+(?:[\+\-\/\*]|\*\*)\s+|[a-zA-Z]+\(|\s+|\d*\.?\d+[a-zA-Z%]*|.)/g);
const tokens = input.split(/((?:\-\-|\$)[a-zA-Z0-9-_]+|\s+(?:[\+\-\/\*]|\*\*)\s+|[a-zA-Z]+\(|\s+|-?\d*\.?\d+[a-zA-Z%]*|.)/g);
const result = [];

@@ -87,0 +90,0 @@ let resolvingParenthesis = false;

/** Calcify cache does not need to be tied to a context because the engine is pure and not
* dependant on any state. */
const cache = new Map<string, string>();
const arithmetic = /[-+/*]/;
/**
* Wrap css arithmetic operations in calc
*/
export default function calcify(input: string): string {
if (!arithmetic.test(input)) return resolveForwardSlashes(input);
if (cache.has(input)) return cache.get(input) as string;
const terms = operands(input);
// Here everything outside a function such as translateX are resolved
const reduced = reduce(terms);
// Resolve non calc functions such as translateX
const resolved = reduced.map(term => {
if (!arithmetic.test(term)) return term;
const match = /^(?<name>[a-zA-Z]+)\((?<funcArgument>.*?)\)$/.exec(term);
if (!match) return term;
const {
funcArgument,
name
} = match?.groups ?? {};
if (funcArgument && !["calc", "var"].includes(name)) {
const resolvedArgument = reduce(operands(funcArgument)).join("");
return `${name}(${resolvedArgument})`;
}
return term;
}).join("");
const slashResolved = resolveForwardSlashes(resolved);
void cache.set(input, slashResolved);
return slashResolved;
}
/**
* This function handles the unfortunate scenario where particularly grid properties containing
* forward slashes have to be remade.
*
* `|` -> `/`
*
* `\/` -> `/`
*
* This transforming behavior can be ignored by preceding with a backslash, in which case the escaped
* forward slash will be ignored by the compiler and can be used normally according to css specification.
*
* unless escaped with backslash or as pipe character, forward slash characters will be treated as
* arithmetic division operator.
*/
function resolveForwardSlashes(value: string) {
return value.replace(/(?<!\\)(?:\\\/|\|)/g, "/");
}
function reduce(terms: string[]): string[] {
const operatorIndex = ((terms) => {
//for (const [i, m] of terms.entries()) if (/^\s+\*\*\s+$/.test(m)) return i;
for (const [i, m] of terms.entries()) if (/^\s+[\/\*]\s+$/.test(m)) return i;
for (const [i, m] of terms.entries()) if (/^\s+[\+\-]\s+$/.test(m)) return i;
return 0;
})(terms);
if (operatorIndex) {
const [left, operator, right] = [terms[operatorIndex - 1], terms[operatorIndex], terms[operatorIndex + 1]];
if (isOperand(left) && isOperand(right)) {
return reduce([...terms.slice(0, operatorIndex - 1), `calc(${[left, operator, right].join("").replace("calc(", "(")})`, ...terms.slice(operatorIndex + 2)]);
}
return terms;
} else {
return terms;
}
}
function isOperand(input: string | undefined): boolean {
if (!input) return false;
return /(?:\-\-|\$)[a-zA-Z0-9-_]+|\d*\.?\d+[a-zA-Z]*|^[a-zA-Z%]+\(/.test(input);
}
function operands(input: string) {
const tokens = input.split(/((?:\-\-|\$)[a-zA-Z0-9-_]+|\s+(?:[\+\-\/\*]|\*\*)\s+|[a-zA-Z]+\(|\s+|\d*\.?\d+[a-zA-Z%]*|.)/g);
const result: string[] = [];
let resolvingParenthesis = false;
let depth = 0;
for (const token of tokens) {
if (resolvingParenthesis && token) {
result[result.length - 1] += token;
} else if (token) {
result.push(token);
}
if (/[a-zA-Z]*\(/.test(token)) {
if (!resolvingParenthesis) {
resolvingParenthesis = true;
} else {
depth++;
}
} else if (token === ")") {
if (resolvingParenthesis && depth === 0) {
resolvingParenthesis = false;
} else if (resolvingParenthesis) {
depth--;
}
}
}
return result;
}
const cache = new Map<string, string>();
const arithmetic = /[-+/*]/;
/**
* Wrap css arithmetic operations in calc
*/
export default function calcify(input: string): string {
if (!arithmetic.test(input)) return resolveForwardSlashes(input);
if (cache.has(input)) return cache.get(input) as string;
const terms = operands(input);
// Here everything outside a function such as translateX are resolved
const reduced = reduce(terms);
// Resolve non calc functions such as translateX
const resolved = reduced.map(term => {
if (!arithmetic.test(term)) return term;
const match = /^(?<name>[a-zA-Z]*)\((?<funcArgument>.*?)\)$/.exec(term);
if (!match) return term;
const {
funcArgument,
name
} = match?.groups ?? {};
if (funcArgument && !["calc", "var"].includes(name)) {
const resolvedArgument = reduce(operands(funcArgument)).join("");
if (!name) return resolvedArgument;
console.log("yes")
return `${name}(${resolvedArgument})`;
}
return term;
}).join("");
const slashResolved = resolveForwardSlashes(resolved);
void cache.set(input, slashResolved);
return slashResolved;
}
/**
* This function handles the unfortunate scenario where particularly grid properties containing
* forward slashes have to be remade.
*
* `|` -> `/`
*
* `\/` -> `/`
*
* This transforming behavior can be ignored by preceding with a backslash, in which case the escaped
* forward slash will be ignored by the compiler and can be used normally according to css specification.
*
* unless escaped with backslash or as pipe character, forward slash characters will be treated as
* arithmetic division operator.
*/
function resolveForwardSlashes(value: string) {
return value.replace(/(?<!\\)(?:\\\/|\|)/g, "/");
}
function reduce(terms: string[]): string[] {
const operatorIndex = ((terms) => {
//for (const [i, m] of terms.entries()) if (/^\s+\*\*\s+$/.test(m)) return i;
for (const [i, m] of terms.entries()) if (/^\s+[\/\*]\s+$/.test(m)) return i;
for (const [i, m] of terms.entries()) if (/^\s+[\+\-]\s+$/.test(m)) return i;
return 0;
})(terms);
if (operatorIndex) {
const [left, operator, right] = [terms[operatorIndex - 1], terms[operatorIndex], terms[operatorIndex + 1]];
if (isOperand(left) && isOperand(right)) {
return reduce([...terms.slice(0, operatorIndex - 1), `calc(${[left, operator, right].join("").replace("calc(", "(")})`, ...terms.slice(operatorIndex + 2)]);
}
return terms;
} else {
return terms;
}
}
function isOperand(input: string | undefined): boolean {
if (!input) return false;
return /(?:\-\-|\$)[a-zA-Z0-9-_]+|\d*\.?-?\d+[a-zA-Z]*|^[a-zA-Z%]+\(/.test(input);
}
function operands(input: string) {
const tokens = input.split(/((?:\-\-|\$)[a-zA-Z0-9-_]+|\s+(?:[\+\-\/\*]|\*\*)\s+|[a-zA-Z]+\(|\s+|-?\d*\.?\d+[a-zA-Z%]*|.)/g);
const result: string[] = [];
let resolvingParenthesis = false;
let depth = 0;
for (const token of tokens) {
if (resolvingParenthesis && token) {
result[result.length - 1] += token;
} else if (token) {
result.push(token);
}
if (/[a-zA-Z]*\(/.test(token)) {
if (!resolvingParenthesis) {
resolvingParenthesis = true;
} else {
depth++;
}
} else if (token === ")") {
if (resolvingParenthesis && depth === 0) {
resolvingParenthesis = false;
} else if (resolvingParenthesis) {
depth--;
}
}
}
return result;
}

@@ -12,2 +12,5 @@ "use strict";

["red", "red"],
["-24px * --scaleFactor", "calc(-24px * --scaleFactor)"],
["-24px * -30px", "calc(-24px * -30px)"],
["--scaleFactor * -24px", "calc(--scaleFactor * -24px)"],
["transition 30ms background ease-in-out", "transition 30ms background ease-in-out"],

@@ -23,3 +26,3 @@ ["10px + 20vh", "calc(10px + 20vh)"],

for (const [input, output] of tests) {
(0, globals_1.expect)(output).toBe((0, calcEngine_1.default)(input));
(0, globals_1.expect)((0, calcEngine_1.default)(input)).toBe(output);
}

@@ -26,0 +29,0 @@ // test cache

@@ -10,2 +10,5 @@ import { expect, test } from "@jest/globals";

["red", "red"],
["-24px * --scaleFactor", "calc(-24px * --scaleFactor)"],
["-24px * -30px", "calc(-24px * -30px)"],
["--scaleFactor * -24px", "calc(--scaleFactor * -24px)"],
["transition 30ms background ease-in-out", "transition 30ms background ease-in-out"],

@@ -23,3 +26,3 @@ ["10px + 20vh", "calc(10px + 20vh)"],

for (const [input, output] of tests) {
expect(output).toBe(calcify(input));
expect(calcify(input)).toBe(output);
}

@@ -26,0 +29,0 @@

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