Skip to content

Commit 5720c4d

Browse files
committed
Fixed handling of calc() function in CSS minifier
1 parent 5fb03b0 commit 5720c4d

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

src/index.js

+47-7
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,58 @@ export default (options = {}) => {
2626
return result;
2727
};
2828

29+
const findClosingParenthesis = (content, from) => {
30+
let depth = 1;
31+
for (let i = from; i < content.length; i += 1) {
32+
const char = content[i];
33+
if (char == "(") {
34+
depth += 1;
35+
} else if (char == ")") {
36+
if (depth === 1) {
37+
return i;
38+
}
39+
40+
depth -= 1;
41+
}
42+
}
43+
44+
return undefined;
45+
};
46+
47+
const replaceCalc = (content) => {
48+
const calc_functions = [];
49+
const calc_start_regex = /\bcalc\([^)]/g;
50+
let match;
51+
while ((match = calc_start_regex.exec(content)) !== null) {
52+
if (match.index === calc_start_regex.lastIndex) {
53+
break;
54+
}
55+
56+
const start = match.index + 5;
57+
const end = findClosingParenthesis(content, start);
58+
if (end === undefined) {
59+
throw new Error("Missing closing parenthesis in calc() function");
60+
}
61+
62+
const calc_function = content.slice(start, end);
63+
calc_functions.push(calc_function);
64+
65+
const before = content.slice(0, start);
66+
const after = content.slice(end);
67+
content = `${before}__CALC__${after}`;
68+
}
69+
70+
return { calc_functions, result: content };
71+
};
72+
2973
/* minify css */
3074
const minifyCSS = (content) => {
31-
const calc_functions = [];
32-
const calc_regex = /\bcalc\(([^)]+)\)/g;
3375
const comments = /("(?:[^"\\]+|\\.)*"|'(?:[^'\\]+|\\.)*')|\/\*[\s\S]*?\*\//g;
3476
const syntax = /("(?:[^"\\]+|\\.)*"|'(?:[^'\\]+|\\.)*')|\s*([{};,>~])\s*|\s*([*$~^|]?=)\s*|\s+([+-])(?=.*\{)|([[(:])\s+|\s+([\])])|\s+(:)(?![^}]*\{)|^\s+|\s+$|(\s)\s+(?![^(]*\))/g;
3577

36-
return content
37-
.replace(calc_regex, (_, group) => {
38-
calc_functions.push(group);
39-
return "__CALC__";
40-
})
78+
const { result, calc_functions } = replaceCalc(content);
79+
80+
return result
4181
.replace(comments, "$1")
4282
.replace(syntax, "$1$2$3$4$5$6$7$8")
4383
.replace(/__CALC__/g, () => `calc(${calc_functions.shift()})`)

0 commit comments

Comments
 (0)