Skip to content

Commit 9350eae

Browse files
committed
parse at-rule prelude
1 parent 997ff5f commit 9350eae

File tree

18 files changed

+512
-212
lines changed

18 files changed

+512
-212
lines changed

dist/index-umd-web.js

Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,15 +1589,15 @@
15891589
compress: false,
15901590
removeComments: false,
15911591
}, { colorConvert: true, preserveLicense: false }, opt);
1592-
function reducer(acc, curr, index, original) {
1593-
if (curr.typ == 'Comment' && options.removeComments) {
1594-
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1595-
return acc;
1592+
return { code: doRender(data, options, function reducer(acc, curr) {
1593+
if (curr.typ == 'Comment' && options.removeComments) {
1594+
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1595+
return acc;
1596+
}
1597+
return acc + curr.val;
15961598
}
1597-
}
1598-
return acc + renderToken(curr, options);
1599-
}
1600-
return { code: doRender(data, options, reducer, 0), stats: {
1599+
return acc + renderToken(curr, options, reducer);
1600+
}, 0), stats: {
16011601
total: `${(performance.now() - startTime).toFixed(2)}ms`
16021602
} };
16031603
}
@@ -1613,9 +1613,9 @@
16131613
const indentSub = indents[level + 1];
16141614
switch (data.typ) {
16151615
case 'Declaration':
1616-
return `${data.nam}:${options.indent}${data.val.reduce((acc, curr) => acc + renderToken(curr), '')}`;
1616+
return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
16171617
case 'Comment':
1618-
return options.removeComments ? '' : data.val;
1618+
return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
16191619
case 'StyleSheet':
16201620
return data.chi.reduce((css, node) => {
16211621
const str = doRender(node, options, reducer, level, indents);
@@ -1636,7 +1636,7 @@
16361636
let children = data.chi.reduce((css, node) => {
16371637
let str;
16381638
if (node.typ == 'Comment') {
1639-
str = options.removeComments ? '' : node.val;
1639+
str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
16401640
}
16411641
else if (node.typ == 'Declaration') {
16421642
if (node.val.length == 0) {
@@ -1669,7 +1669,18 @@
16691669
}
16701670
return '';
16711671
}
1672-
function renderToken(token, options = {}) {
1672+
function renderToken(token, options = {}, reducer) {
1673+
if (reducer == null) {
1674+
reducer = function (acc, curr) {
1675+
if (curr.typ == 'Comment' && options.removeComments) {
1676+
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1677+
return acc;
1678+
}
1679+
return acc + curr.val;
1680+
}
1681+
return acc + renderToken(curr, options, reducer);
1682+
};
1683+
}
16731684
switch (token.typ) {
16741685
case 'Color':
16751686
if (options.minify || options.colorConvert) {
@@ -1720,22 +1731,19 @@
17201731
case 'UrlFunc':
17211732
case 'Pseudo-class-func':
17221733
// @ts-ignore
1723-
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
1724-
if (options.removeComments && curr.typ == 'Comment') {
1725-
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1726-
return acc;
1727-
}
1728-
}
1729-
return acc + renderToken(curr, options);
1730-
}, '') + ')';
1734+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
17311735
case 'Includes':
17321736
return '~=';
17331737
case 'Dash-match':
17341738
return '|=';
17351739
case 'Lt':
17361740
return '<';
1741+
case 'Lte':
1742+
return '<=';
17371743
case 'Gt':
17381744
return '>';
1745+
case 'Gte':
1746+
return '>=';
17391747
case 'End-parens':
17401748
return ')';
17411749
case 'Attr-start':
@@ -1753,7 +1761,7 @@
17531761
case 'Important':
17541762
return '!important';
17551763
case 'Attr':
1756-
return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options), '') + ']';
1764+
return '[' + token.chi.reduce(reducer, '') + ']';
17571765
case 'Time':
17581766
case 'Frequency':
17591767
case 'Angle':
@@ -1800,7 +1808,7 @@
18001808
}
18011809
return num;
18021810
case 'Comment':
1803-
if (options.removeComments) {
1811+
if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
18041812
return '';
18051813
}
18061814
case 'Url-token':
@@ -2071,6 +2079,7 @@
20712079
i--;
20722080
continue;
20732081
}
2082+
// @ts-ignore
20742083
if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
20752084
if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
20762085
return acc;
@@ -2236,17 +2245,18 @@
22362245
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
22372246
continue;
22382247
}
2239-
match = matchType(val, curr[1]);
2248+
// @ts-ignore
2249+
match = val.typ == 'Comment' || matchType(val, curr[1]);
22402250
if (isShorthand) {
22412251
isShorthand = match;
22422252
}
2253+
// @ts-ignore
22432254
if (('propertyName' in val && val.propertyName == property) || match) {
22442255
if (!(curr[0] in tokens)) {
22452256
tokens[curr[0]] = [[]];
22462257
}
22472258
// is default value
22482259
tokens[curr[0]][current].push(val);
2249-
// continue;
22502260
}
22512261
else {
22522262
acc.push(curr[0]);
@@ -2263,7 +2273,9 @@
22632273
if (!isShorthand || Object.entries(this.config.properties).some(entry => {
22642274
// missing required property
22652275
return entry[1].required && !(entry[0] in tokens);
2266-
}) || !Object.values(tokens).every(v => v.length == count)) {
2276+
}) ||
2277+
// @ts-ignore
2278+
!Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
22672279
// @ts-ignore
22682280
iterable = this.declarations.values();
22692281
}
@@ -2816,6 +2828,17 @@
28162828
continue;
28172829
// }
28182830
}
2831+
// @ts-ignore
2832+
if (hasDeclaration(node)) {
2833+
// @ts-ignore
2834+
minifyRule(node);
2835+
}
2836+
else {
2837+
minify(node, options, recursive);
2838+
}
2839+
previous = node;
2840+
nodeIndex = i;
2841+
continue;
28192842
}
28202843
// @ts-ignore
28212844
if (node.typ == 'Rule') {
@@ -3330,11 +3353,6 @@
33303353
}
33313354
buffer += quoteStr;
33323355
while (value = peek()) {
3333-
// if (ind >= iterator.length) {
3334-
//
3335-
// yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
3336-
// break;
3337-
// }
33383356
if (value == '\\') {
33393357
const sequence = peek(6);
33403358
let escapeSequence = '';
@@ -3376,13 +3394,6 @@
33763394
next(escapeSequence.length + 1);
33773395
continue;
33783396
}
3379-
// buffer += value;
3380-
// if (ind >= iterator.length) {
3381-
//
3382-
// // drop '\\' at the end
3383-
// yield pushToken(buffer);
3384-
// break;
3385-
// }
33863397
buffer += next(2);
33873398
continue;
33883399
}
@@ -3403,7 +3414,6 @@
34033414
break;
34043415
}
34053416
buffer += value;
3406-
// i += value.length;
34073417
next();
34083418
}
34093419
}
@@ -3519,6 +3529,11 @@
35193529
yield pushToken(buffer);
35203530
buffer = '';
35213531
}
3532+
if (peek() == '=') {
3533+
yield pushToken('', 'Lte');
3534+
next();
3535+
break;
3536+
}
35223537
buffer += value;
35233538
value = next();
35243539
if (ind >= iterator.length) {
@@ -3587,7 +3602,13 @@
35873602
yield pushToken(buffer);
35883603
buffer = '';
35893604
}
3590-
yield pushToken('', 'Gt');
3605+
if (peek() == '=') {
3606+
yield pushToken('', 'Gte');
3607+
next();
3608+
}
3609+
else {
3610+
yield pushToken('', 'Gt');
3611+
}
35913612
consumeWhiteSpace();
35923613
break;
35933614
case '.':
@@ -3746,6 +3767,7 @@
37463767
}
37473768

37483769
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
3770+
const trimWhiteSpace = ['Gt', 'Gte', 'Lt', 'Lte'];
37493771
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
37503772
/**
37513773
*
@@ -3910,7 +3932,7 @@
39103932
// https://www.w3.org/TR/css-nesting-1/#conditionals
39113933
// allowed nesting at-rules
39123934
// there must be a top level rule in the stack
3913-
const raw = tokens.reduce((acc, curr) => {
3935+
const raw = parseTokens(tokens, { minify: options.minify }).reduce((acc, curr) => {
39143936
acc.push(renderToken(curr, { removeComments: true }));
39153937
return acc;
39163938
}, []);
@@ -3941,8 +3963,8 @@
39413963
const uniq = new Map;
39423964
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
39433965
if (curr.typ == 'Whitespace') {
3944-
if (array[index - 1]?.typ == 'Gt' ||
3945-
array[index + 1]?.typ == 'Gt' ||
3966+
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
3967+
trimWhiteSpace.includes(array[index + 1]?.typ) ||
39463968
combinators.includes(array[index - 1]?.val) ||
39473969
combinators.includes(array[index + 1]?.val)) {
39483970
return acc;
@@ -4146,7 +4168,7 @@
41464168
return ([
41474169
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
41484170
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
4149-
'Comma', 'Gt', 'Lt'
4171+
'Comma', 'Gt', 'Lt', 'Gte', 'Lte'
41504172
].includes(hint) ? { typ: hint } : { typ: hint, val });
41514173
}
41524174
if (val == ' ') {
@@ -4274,11 +4296,12 @@
42744296
const t = tokens[i];
42754297
if (t.typ == 'Whitespace' && ((i == 0 ||
42764298
i + 1 == tokens.length ||
4277-
['Comma'].includes(tokens[i + 1].typ) ||
4299+
['Comma', 'Gte', 'Lte'].includes(tokens[i + 1].typ)) ||
42784300
(i > 0 &&
4279-
tokens[i + 1]?.typ != 'Literal' &&
4280-
funcLike.includes(tokens[i - 1].typ) &&
4281-
!['var', 'calc'].includes(tokens[i - 1].val))))) {
4301+
// tokens[i + 1]?.typ != 'Literal' ||
4302+
// funcLike.includes(tokens[i - 1].typ) &&
4303+
// !['var', 'calc'].includes((<FunctionToken>tokens[i - 1]).val)))) &&
4304+
trimWhiteSpace.includes(tokens[i - 1].typ)))) {
42824305
tokens.splice(i--, 1);
42834306
continue;
42844307
}
@@ -4395,7 +4418,7 @@
43954418
let m = t.chi.length;
43964419
while (m-- > 0) {
43974420
// @ts-ignore
4398-
if (t.chi[m].typ == 'Literal') {
4421+
if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
43994422
// @ts-ignore
44004423
if (t.chi[m + 1]?.typ == 'Whitespace') {
44014424
// @ts-ignore

0 commit comments

Comments
 (0)