@tbela99/css-parser 0.0.1-rc6 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -7
- package/dist/index-umd-web.js +230 -194
- package/dist/index.cjs +230 -194
- package/dist/index.d.ts +4 -3
- package/dist/lib/ast/expand.js +4 -10
- package/dist/lib/ast/minify.js +57 -15
- package/dist/lib/ast/walk.js +2 -6
- package/dist/lib/parser/parse.js +2 -2
- package/dist/lib/parser/tokenize.js +6 -2
- package/dist/lib/parser/utils/eq.js +1 -1
- package/dist/lib/parser/utils/syntax.js +1 -1
- package/dist/lib/renderer/render.js +2 -1
- package/dist/node/index.js +1 -1
- package/dist/web/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,19 +10,15 @@ CSS parser for node and the browser
|
|
|
10
10
|
$ npm install @tbela99/css-parser
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Features
|
|
14
14
|
|
|
15
15
|
- fault tolerant parser, will try to fix invalid tokens according to the CSS syntax module 3 recommendations.
|
|
16
16
|
- efficient minification, see [benchmark](https://tbela99.github.io/css-parser/benchmark/index.html)
|
|
17
|
-
- replace @import at-rules with actual css content of the imported rule
|
|
18
17
|
- automatically generate nested css rules
|
|
18
|
+
- compute css shorthands. see the list below
|
|
19
19
|
- expand nested css
|
|
20
20
|
- works the same way in node and web browser
|
|
21
21
|
|
|
22
|
-
### Performance
|
|
23
|
-
|
|
24
|
-
- flatten @import
|
|
25
|
-
|
|
26
22
|
## Transform
|
|
27
23
|
|
|
28
24
|
Parse and render css in a single pass.
|
|
@@ -131,7 +127,7 @@ import as a CommonJS module
|
|
|
131
127
|
|
|
132
128
|
```javascript
|
|
133
129
|
|
|
134
|
-
|
|
130
|
+
const {transform} = require('@tbela99/css-parser/cjs');
|
|
135
131
|
|
|
136
132
|
// ...
|
|
137
133
|
```
|
|
@@ -303,3 +299,42 @@ table.colortable th {
|
|
|
303
299
|
|
|
304
300
|
- typ: string 'Stylesheet'
|
|
305
301
|
- chi: array of children
|
|
302
|
+
|
|
303
|
+
## Minification
|
|
304
|
+
|
|
305
|
+
- [x] merge identical rules
|
|
306
|
+
- [x] merge adjacent rules
|
|
307
|
+
- [x] minify colors
|
|
308
|
+
- [x] minify numbers and Dimensions tokens
|
|
309
|
+
- [x] compute shorthand: see the list below
|
|
310
|
+
- [x] remove redundant declarations
|
|
311
|
+
- [x] conditionally unwrap :is()
|
|
312
|
+
- [x] automatic css nesting
|
|
313
|
+
- [x] automatically wrap selectors using :is()
|
|
314
|
+
- [x] multi-level shorthand properties (border - [border-width, border-color, border-style, etc.]) https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties
|
|
315
|
+
- [x] avoid reparsing (declarations, selectors, at-rule)
|
|
316
|
+
- [x] node and browser versions
|
|
317
|
+
- [x] decode and replace utf-8 escape sequence
|
|
318
|
+
|
|
319
|
+
## Computed shorthands
|
|
320
|
+
- [x] background
|
|
321
|
+
- [x] border
|
|
322
|
+
- [x] border-bottom
|
|
323
|
+
- [x] border-color
|
|
324
|
+
- [x] border-left
|
|
325
|
+
- [x] border-radius
|
|
326
|
+
- [x] border-right
|
|
327
|
+
- [x] border-style
|
|
328
|
+
- [x] border-top
|
|
329
|
+
- [x] border-width
|
|
330
|
+
- [x] font
|
|
331
|
+
- [x] inset
|
|
332
|
+
- [x] margin
|
|
333
|
+
- [x] outline
|
|
334
|
+
- [x] overflow
|
|
335
|
+
- [x] padding
|
|
336
|
+
- [x] text-decoration
|
|
337
|
+
|
|
338
|
+
## Performance
|
|
339
|
+
|
|
340
|
+
- [x] flatten @import
|
package/dist/index-umd-web.js
CHANGED
|
@@ -772,7 +772,8 @@
|
|
|
772
772
|
}
|
|
773
773
|
return val + unit;
|
|
774
774
|
case 'Perc':
|
|
775
|
-
|
|
775
|
+
const perc = reduceNumber(token.val);
|
|
776
|
+
return options.minify && perc == '0' ? '0' : perc + '%';
|
|
776
777
|
case 'Number':
|
|
777
778
|
return reduceNumber(token.val);
|
|
778
779
|
case 'Comment':
|
|
@@ -829,7 +830,7 @@
|
|
|
829
830
|
if (token.typ == 'Func' && token.chi.length > 0 && colorsFunc.includes(token.val)) {
|
|
830
831
|
// @ts-ignore
|
|
831
832
|
for (const v of token.chi) {
|
|
832
|
-
if (!['Number', 'Perc', 'Comma', 'Whitespace'].includes(v.typ)) {
|
|
833
|
+
if (!['Number', 'Angle', 'Perc', 'Comma', 'Whitespace', 'Literal'].includes(v.typ)) {
|
|
833
834
|
return false;
|
|
834
835
|
}
|
|
835
836
|
}
|
|
@@ -1949,7 +1950,7 @@
|
|
|
1949
1950
|
}
|
|
1950
1951
|
let key;
|
|
1951
1952
|
for (key of k1) {
|
|
1952
|
-
if (!eq(a[key], b[key])) {
|
|
1953
|
+
if (!(key in b) || !eq(a[key], b[key])) {
|
|
1953
1954
|
return false;
|
|
1954
1955
|
}
|
|
1955
1956
|
}
|
|
@@ -2244,12 +2245,16 @@
|
|
|
2244
2245
|
}
|
|
2245
2246
|
function next(count = 1) {
|
|
2246
2247
|
let char = '';
|
|
2247
|
-
|
|
2248
|
+
let chr = '';
|
|
2249
|
+
if (count < 0) {
|
|
2250
|
+
return '';
|
|
2251
|
+
}
|
|
2252
|
+
while (count-- && (chr = iterator.charAt(ind + 1))) {
|
|
2253
|
+
char += chr;
|
|
2248
2254
|
const codepoint = iterator.charCodeAt(++ind);
|
|
2249
2255
|
if (isNaN(codepoint)) {
|
|
2250
2256
|
return char;
|
|
2251
2257
|
}
|
|
2252
|
-
char += iterator.charAt(ind);
|
|
2253
2258
|
if (isNewLine(codepoint)) {
|
|
2254
2259
|
lin++;
|
|
2255
2260
|
col = 0;
|
|
@@ -2816,7 +2821,7 @@
|
|
|
2816
2821
|
if (delim.typ == 'Block-start') {
|
|
2817
2822
|
const position = map.get(tokens[0]);
|
|
2818
2823
|
const uniq = new Map;
|
|
2819
|
-
parseTokens(tokens, { minify:
|
|
2824
|
+
parseTokens(tokens, { minify: true }).reduce((acc, curr, index, array) => {
|
|
2820
2825
|
if (curr.typ == 'Whitespace') {
|
|
2821
2826
|
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
2822
2827
|
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
@@ -2825,7 +2830,7 @@
|
|
|
2825
2830
|
return acc;
|
|
2826
2831
|
}
|
|
2827
2832
|
}
|
|
2828
|
-
let t = renderToken(curr, { minify:
|
|
2833
|
+
let t = renderToken(curr, { minify: false });
|
|
2829
2834
|
if (t == ',') {
|
|
2830
2835
|
acc.push([]);
|
|
2831
2836
|
}
|
|
@@ -3826,10 +3831,174 @@
|
|
|
3826
3831
|
}
|
|
3827
3832
|
}
|
|
3828
3833
|
|
|
3834
|
+
function* walk(node, parent, root) {
|
|
3835
|
+
yield { node, parent, root };
|
|
3836
|
+
if ('chi' in node) {
|
|
3837
|
+
for (const child of node.chi) {
|
|
3838
|
+
yield* walk(child, node, (root ?? node));
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
function* walkValues(values, parent) {
|
|
3843
|
+
for (const value of values) {
|
|
3844
|
+
// @ts-ignore
|
|
3845
|
+
yield { value, parent };
|
|
3846
|
+
if ('chi' in value) {
|
|
3847
|
+
yield* walkValues(value.chi, value);
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
|
|
3852
|
+
function expand(ast) {
|
|
3853
|
+
//
|
|
3854
|
+
if (!['Rule', 'StyleSheet', 'AtRule'].includes(ast.typ)) {
|
|
3855
|
+
return ast;
|
|
3856
|
+
}
|
|
3857
|
+
if ('Rule' == ast.typ) {
|
|
3858
|
+
return {
|
|
3859
|
+
typ: 'StyleSheet',
|
|
3860
|
+
chi: expandRule(ast)
|
|
3861
|
+
};
|
|
3862
|
+
}
|
|
3863
|
+
if (!('chi' in ast)) {
|
|
3864
|
+
return { ...ast };
|
|
3865
|
+
}
|
|
3866
|
+
const result = { ...ast, chi: [] };
|
|
3867
|
+
// @ts-ignore
|
|
3868
|
+
for (let i = 0; i < ast.chi.length; i++) {
|
|
3869
|
+
// @ts-ignore
|
|
3870
|
+
const node = ast.chi[i];
|
|
3871
|
+
if (node.typ == 'Rule') {
|
|
3872
|
+
// @ts-ignore
|
|
3873
|
+
result.chi.push(...expandRule(node));
|
|
3874
|
+
// i += expanded.length - 1;
|
|
3875
|
+
}
|
|
3876
|
+
else if (node.typ == 'AtRule' && 'chi' in node) {
|
|
3877
|
+
let hasRule = false;
|
|
3878
|
+
let j = node.chi.length;
|
|
3879
|
+
while (j--) {
|
|
3880
|
+
if (node.chi[j].typ == 'Rule' || node.chi[j].typ == 'AtRule') {
|
|
3881
|
+
hasRule = true;
|
|
3882
|
+
break;
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
// @ts-ignore
|
|
3886
|
+
result.chi.push({ ...(hasRule ? expand(node) : node) });
|
|
3887
|
+
}
|
|
3888
|
+
else {
|
|
3889
|
+
// @ts-ignore
|
|
3890
|
+
result.chi.push(node);
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
return result;
|
|
3894
|
+
}
|
|
3895
|
+
function expandRule(node) {
|
|
3896
|
+
const ast = { ...node, chi: node.chi.slice() };
|
|
3897
|
+
const result = [];
|
|
3898
|
+
if (ast.typ == 'Rule') {
|
|
3899
|
+
let i = 0;
|
|
3900
|
+
for (; i < ast.chi.length; i++) {
|
|
3901
|
+
if (ast.chi[i].typ == 'Rule') {
|
|
3902
|
+
const rule = ast.chi[i];
|
|
3903
|
+
if (!rule.sel.includes('&')) {
|
|
3904
|
+
const selRule = splitRule(rule.sel);
|
|
3905
|
+
selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
|
|
3906
|
+
rule.sel = selRule.reduce((acc, curr) => {
|
|
3907
|
+
acc.push(curr.join(''));
|
|
3908
|
+
return acc;
|
|
3909
|
+
}, []).join(',');
|
|
3910
|
+
}
|
|
3911
|
+
else {
|
|
3912
|
+
rule.sel = replaceCompound(rule.sel, ast.sel);
|
|
3913
|
+
}
|
|
3914
|
+
ast.chi.splice(i--, 1);
|
|
3915
|
+
result.push(...expandRule(rule));
|
|
3916
|
+
}
|
|
3917
|
+
else if (ast.chi[i].typ == 'AtRule') {
|
|
3918
|
+
let astAtRule = ast.chi[i];
|
|
3919
|
+
const values = [];
|
|
3920
|
+
if (astAtRule.nam == 'scope') {
|
|
3921
|
+
if (astAtRule.val.includes('&')) {
|
|
3922
|
+
astAtRule.val = replaceCompound(astAtRule.val, ast.sel);
|
|
3923
|
+
}
|
|
3924
|
+
// @ts-ignore
|
|
3925
|
+
astAtRule = expand(astAtRule);
|
|
3926
|
+
}
|
|
3927
|
+
else {
|
|
3928
|
+
// @ts-ignore
|
|
3929
|
+
const clone = { ...ast, chi: astAtRule.chi.slice() };
|
|
3930
|
+
// @ts-ignore
|
|
3931
|
+
astAtRule.chi.length = 0;
|
|
3932
|
+
for (const r of expandRule(clone)) {
|
|
3933
|
+
if (r.typ == 'AtRule' && 'chi' in r) {
|
|
3934
|
+
if (astAtRule.val !== '' && r.val !== '') {
|
|
3935
|
+
if (astAtRule.nam == 'media' && r.nam == 'media') {
|
|
3936
|
+
r.val = astAtRule.val + ' and ' + r.val;
|
|
3937
|
+
}
|
|
3938
|
+
else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
|
|
3939
|
+
r.val = astAtRule.val + '.' + r.val;
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
// @ts-ignore
|
|
3943
|
+
values.push(r);
|
|
3944
|
+
}
|
|
3945
|
+
else if (r.typ == 'Rule') {
|
|
3946
|
+
// @ts-ignore
|
|
3947
|
+
astAtRule.chi.push(...expandRule(r));
|
|
3948
|
+
}
|
|
3949
|
+
else {
|
|
3950
|
+
// @ts-ignore
|
|
3951
|
+
astAtRule.chi.push(r);
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
// @ts-ignore
|
|
3956
|
+
result.push(...(astAtRule.chi.length > 0 ? [astAtRule].concat(values) : values));
|
|
3957
|
+
ast.chi.splice(i--, 1);
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
// @ts-ignore
|
|
3962
|
+
return ast.chi.length > 0 ? [ast].concat(result) : result;
|
|
3963
|
+
}
|
|
3964
|
+
function replaceCompound(input, replace) {
|
|
3965
|
+
const tokens = parseString(input);
|
|
3966
|
+
for (const t of walkValues(tokens)) {
|
|
3967
|
+
if (t.value.typ == 'Literal') {
|
|
3968
|
+
if (t.value.val == '&') {
|
|
3969
|
+
t.value.val = replace;
|
|
3970
|
+
}
|
|
3971
|
+
else if (t.value.val.length > 1 && t.value.val.charAt(0) == '&') {
|
|
3972
|
+
t.value.val = replaceCompoundLiteral(t.value.val, replace);
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
|
|
3977
|
+
}
|
|
3978
|
+
function replaceCompoundLiteral(selector, replace) {
|
|
3979
|
+
const tokens = [''];
|
|
3980
|
+
let i = 0;
|
|
3981
|
+
for (; i < selector.length; i++) {
|
|
3982
|
+
if (selector.charAt(i) == '&') {
|
|
3983
|
+
tokens.push('&');
|
|
3984
|
+
tokens.push('');
|
|
3985
|
+
}
|
|
3986
|
+
else {
|
|
3987
|
+
tokens[tokens.length - 1] += selector.charAt(i);
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
return tokens.sort((a, b) => {
|
|
3991
|
+
if (a == '&') {
|
|
3992
|
+
return 1;
|
|
3993
|
+
}
|
|
3994
|
+
return b == '&' ? -1 : 0;
|
|
3995
|
+
}).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
|
|
3996
|
+
}
|
|
3997
|
+
|
|
3829
3998
|
const combinators = ['+', '>', '~'];
|
|
3830
3999
|
const notEndingWith = ['(', '['].concat(combinators);
|
|
3831
4000
|
const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
|
|
3832
|
-
function minify(ast, options = {}, recursive = false, errors) {
|
|
4001
|
+
function minify(ast, options = {}, recursive = false, errors, nestingContent) {
|
|
3833
4002
|
function wrapNodes(previous, node, match, ast, i, nodeIndex) {
|
|
3834
4003
|
// @ts-ignore
|
|
3835
4004
|
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
@@ -4118,8 +4287,28 @@
|
|
|
4118
4287
|
selector2
|
|
4119
4288
|
};
|
|
4120
4289
|
}
|
|
4290
|
+
function fixSelector(node) {
|
|
4291
|
+
// @ts-ignore
|
|
4292
|
+
if (node.sel.includes('&')) {
|
|
4293
|
+
const attributes = parseString(node.sel);
|
|
4294
|
+
for (const attr of walkValues(attributes)) {
|
|
4295
|
+
if (attr.value.typ == 'Pseudo-class-func' && attr.value.val == ':is') {
|
|
4296
|
+
let i = attr.value.chi.length;
|
|
4297
|
+
while (i--) {
|
|
4298
|
+
if (attr.value.chi[i].typ == 'Literal' && attr.value.chi[i].val == '&') {
|
|
4299
|
+
attr.value.chi.splice(i, 1);
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
node.sel = attributes.reduce((acc, curr) => acc + renderToken(curr), '');
|
|
4305
|
+
}
|
|
4306
|
+
}
|
|
4121
4307
|
// @ts-ignore
|
|
4122
4308
|
if (('chi' in ast) && ast.chi?.length > 0) {
|
|
4309
|
+
if (!nestingContent) {
|
|
4310
|
+
nestingContent = options.nestingRules && ast.typ == 'Rule';
|
|
4311
|
+
}
|
|
4123
4312
|
let i = 0;
|
|
4124
4313
|
let previous;
|
|
4125
4314
|
let node;
|
|
@@ -4134,7 +4323,6 @@
|
|
|
4134
4323
|
node = ast.chi[i];
|
|
4135
4324
|
// @ts-ignore
|
|
4136
4325
|
if (previous == node) {
|
|
4137
|
-
// console.error('idem!');
|
|
4138
4326
|
// @ts-ignore
|
|
4139
4327
|
ast.chi.splice(i, 1);
|
|
4140
4328
|
i--;
|
|
@@ -4150,7 +4338,6 @@
|
|
|
4150
4338
|
i--;
|
|
4151
4339
|
continue;
|
|
4152
4340
|
}
|
|
4153
|
-
// console.debug({previous, node});
|
|
4154
4341
|
// @ts-ignore
|
|
4155
4342
|
if (previous?.typ == 'AtRule' &&
|
|
4156
4343
|
previous.nam == node.nam &&
|
|
@@ -4170,7 +4357,7 @@
|
|
|
4170
4357
|
minifyRule(node);
|
|
4171
4358
|
}
|
|
4172
4359
|
else {
|
|
4173
|
-
minify(node, options, recursive, errors);
|
|
4360
|
+
minify(node, options, recursive, errors, nestingContent);
|
|
4174
4361
|
}
|
|
4175
4362
|
previous = node;
|
|
4176
4363
|
nodeIndex = i;
|
|
@@ -4224,7 +4411,7 @@
|
|
|
4224
4411
|
nodeIndex = --i;
|
|
4225
4412
|
// @ts-ignore
|
|
4226
4413
|
previous = ast.chi[nodeIndex];
|
|
4227
|
-
minify(wrapper, options, recursive, errors);
|
|
4414
|
+
minify(wrapper, options, recursive, errors, nestingContent);
|
|
4228
4415
|
continue;
|
|
4229
4416
|
}
|
|
4230
4417
|
// @ts-ignore
|
|
@@ -4257,7 +4444,7 @@
|
|
|
4257
4444
|
let wrap = true;
|
|
4258
4445
|
// @ts-ignore
|
|
4259
4446
|
const selector = node.optimized.selector.reduce((acc, curr) => {
|
|
4260
|
-
if (curr[0] == '&') {
|
|
4447
|
+
if (curr[0] == '&' && curr.length > 1) {
|
|
4261
4448
|
if (curr[1] == ' ') {
|
|
4262
4449
|
curr.splice(0, 2);
|
|
4263
4450
|
}
|
|
@@ -4281,7 +4468,7 @@
|
|
|
4281
4468
|
if (!wrap) {
|
|
4282
4469
|
wrap = selector.some(s => s[0] != '&');
|
|
4283
4470
|
}
|
|
4284
|
-
|
|
4471
|
+
let rule = selector.map(s => {
|
|
4285
4472
|
if (s[0] == '&') {
|
|
4286
4473
|
// @ts-ignore
|
|
4287
4474
|
s[0] = node.optimized.optimized[0];
|
|
@@ -4289,7 +4476,14 @@
|
|
|
4289
4476
|
return s.join('');
|
|
4290
4477
|
}).join(',');
|
|
4291
4478
|
// @ts-ignore
|
|
4292
|
-
|
|
4479
|
+
let sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
|
|
4480
|
+
if (rule.includes('&')) {
|
|
4481
|
+
// @ts-ignore
|
|
4482
|
+
rule = replaceCompound(rule, node.optimized.optimized[0]);
|
|
4483
|
+
}
|
|
4484
|
+
if (sel.length < node.sel.length) {
|
|
4485
|
+
node.sel = sel;
|
|
4486
|
+
}
|
|
4293
4487
|
}
|
|
4294
4488
|
}
|
|
4295
4489
|
// @ts-ignore
|
|
@@ -4325,7 +4519,7 @@
|
|
|
4325
4519
|
minifyRule(node);
|
|
4326
4520
|
}
|
|
4327
4521
|
else {
|
|
4328
|
-
minify(node, options, recursive, errors);
|
|
4522
|
+
minify(node, options, recursive, errors, nestingContent);
|
|
4329
4523
|
}
|
|
4330
4524
|
i--;
|
|
4331
4525
|
previous = node;
|
|
@@ -4370,7 +4564,7 @@
|
|
|
4370
4564
|
minifyRule(previous);
|
|
4371
4565
|
}
|
|
4372
4566
|
else {
|
|
4373
|
-
minify(previous, options, recursive, errors);
|
|
4567
|
+
minify(previous, options, recursive, errors, nestingContent);
|
|
4374
4568
|
}
|
|
4375
4569
|
}
|
|
4376
4570
|
}
|
|
@@ -4382,11 +4576,19 @@
|
|
|
4382
4576
|
minifyRule(previous);
|
|
4383
4577
|
}
|
|
4384
4578
|
else {
|
|
4385
|
-
minify(previous, options, recursive, errors);
|
|
4579
|
+
minify(previous, options, recursive, errors, nestingContent);
|
|
4386
4580
|
}
|
|
4387
4581
|
}
|
|
4388
4582
|
}
|
|
4389
4583
|
}
|
|
4584
|
+
if (!nestingContent &&
|
|
4585
|
+
// @ts-ignore
|
|
4586
|
+
previous != null &&
|
|
4587
|
+
// previous.optimized != null &&
|
|
4588
|
+
previous.typ == 'Rule' &&
|
|
4589
|
+
previous.sel.includes('&')) {
|
|
4590
|
+
fixSelector(previous);
|
|
4591
|
+
}
|
|
4390
4592
|
previous = node;
|
|
4391
4593
|
nodeIndex = i;
|
|
4392
4594
|
}
|
|
@@ -4399,10 +4601,18 @@
|
|
|
4399
4601
|
else {
|
|
4400
4602
|
// @ts-ignore
|
|
4401
4603
|
if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
|
|
4402
|
-
minify(node, options, recursive, errors);
|
|
4604
|
+
minify(node, options, recursive, errors, nestingContent);
|
|
4403
4605
|
}
|
|
4404
4606
|
}
|
|
4405
4607
|
}
|
|
4608
|
+
if (!nestingContent &&
|
|
4609
|
+
// @ts-ignore
|
|
4610
|
+
node != null &&
|
|
4611
|
+
// previous.optimized != null &&
|
|
4612
|
+
node.typ == 'Rule' &&
|
|
4613
|
+
node.sel.includes('&')) {
|
|
4614
|
+
fixSelector(node);
|
|
4615
|
+
}
|
|
4406
4616
|
}
|
|
4407
4617
|
return ast;
|
|
4408
4618
|
}
|
|
@@ -4641,181 +4851,6 @@
|
|
|
4641
4851
|
Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
|
|
4642
4852
|
}
|
|
4643
4853
|
}
|
|
4644
|
-
// }
|
|
4645
|
-
}
|
|
4646
|
-
|
|
4647
|
-
function* walk(node) {
|
|
4648
|
-
// @ts-ignore
|
|
4649
|
-
yield* doWalk(node, null, null);
|
|
4650
|
-
}
|
|
4651
|
-
function* doWalk(node, parent, root) {
|
|
4652
|
-
yield { node, parent, root };
|
|
4653
|
-
if ('chi' in node) {
|
|
4654
|
-
for (const child of node.chi) {
|
|
4655
|
-
yield* doWalk(child, node, (root ?? node));
|
|
4656
|
-
}
|
|
4657
|
-
}
|
|
4658
|
-
}
|
|
4659
|
-
function* walkValues(values, parent) {
|
|
4660
|
-
for (const value of values) {
|
|
4661
|
-
// @ts-ignore
|
|
4662
|
-
yield { value, parent };
|
|
4663
|
-
if ('chi' in value) {
|
|
4664
|
-
yield* walkValues(value.chi, value);
|
|
4665
|
-
}
|
|
4666
|
-
}
|
|
4667
|
-
}
|
|
4668
|
-
|
|
4669
|
-
function expand(ast) {
|
|
4670
|
-
//
|
|
4671
|
-
if (!['Rule', 'StyleSheet', 'AtRule'].includes(ast.typ)) {
|
|
4672
|
-
return ast;
|
|
4673
|
-
}
|
|
4674
|
-
if ('Rule' == ast.typ) {
|
|
4675
|
-
return {
|
|
4676
|
-
typ: 'StyleSheet',
|
|
4677
|
-
chi: expandRule(ast)
|
|
4678
|
-
};
|
|
4679
|
-
}
|
|
4680
|
-
if (!('chi' in ast)) {
|
|
4681
|
-
return { ...ast };
|
|
4682
|
-
}
|
|
4683
|
-
const result = { ...ast, chi: [] };
|
|
4684
|
-
// @ts-ignore
|
|
4685
|
-
for (let i = 0; i < ast.chi.length; i++) {
|
|
4686
|
-
// @ts-ignore
|
|
4687
|
-
const node = ast.chi[i];
|
|
4688
|
-
if (node.typ == 'Rule') {
|
|
4689
|
-
// @ts-ignore
|
|
4690
|
-
result.chi.push(...expandRule(node));
|
|
4691
|
-
// i += expanded.length - 1;
|
|
4692
|
-
}
|
|
4693
|
-
else if (node.typ == 'AtRule' && 'chi' in node) {
|
|
4694
|
-
let hasRule = false;
|
|
4695
|
-
let j = node.chi.length;
|
|
4696
|
-
while (j--) {
|
|
4697
|
-
if (node.chi[j].typ == 'Rule' || node.chi[j].typ == 'AtRule') {
|
|
4698
|
-
hasRule = true;
|
|
4699
|
-
break;
|
|
4700
|
-
}
|
|
4701
|
-
}
|
|
4702
|
-
// @ts-ignore
|
|
4703
|
-
result.chi.push({ ...(hasRule ? expand(node) : node) });
|
|
4704
|
-
}
|
|
4705
|
-
else {
|
|
4706
|
-
// @ts-ignore
|
|
4707
|
-
result.chi.push(node);
|
|
4708
|
-
}
|
|
4709
|
-
}
|
|
4710
|
-
return result;
|
|
4711
|
-
}
|
|
4712
|
-
function expandRule(node) {
|
|
4713
|
-
const ast = { ...node, chi: node.chi.slice() };
|
|
4714
|
-
const result = [];
|
|
4715
|
-
if (ast.typ == 'Rule') {
|
|
4716
|
-
let i = 0;
|
|
4717
|
-
// @ts-ignore
|
|
4718
|
-
delete ast.raw;
|
|
4719
|
-
// @ts-ignore
|
|
4720
|
-
delete ast.optimized;
|
|
4721
|
-
for (; i < ast.chi.length; i++) {
|
|
4722
|
-
if (ast.chi[i].typ == 'Rule') {
|
|
4723
|
-
const rule = ast.chi[i];
|
|
4724
|
-
if (!rule.sel.includes('&')) {
|
|
4725
|
-
const selRule = splitRule(rule.sel);
|
|
4726
|
-
selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
|
|
4727
|
-
rule.sel = selRule.reduce((acc, curr) => {
|
|
4728
|
-
acc.push(curr.join(''));
|
|
4729
|
-
return acc;
|
|
4730
|
-
}, []).join(',');
|
|
4731
|
-
}
|
|
4732
|
-
else {
|
|
4733
|
-
rule.sel = replaceCompount(rule.sel, ast.sel);
|
|
4734
|
-
}
|
|
4735
|
-
delete rule.raw;
|
|
4736
|
-
delete rule.optimized;
|
|
4737
|
-
ast.chi.splice(i--, 1);
|
|
4738
|
-
result.push(...expandRule(rule));
|
|
4739
|
-
}
|
|
4740
|
-
else if (ast.chi[i].typ == 'AtRule') {
|
|
4741
|
-
let astAtRule = ast.chi[i];
|
|
4742
|
-
const values = [];
|
|
4743
|
-
if (astAtRule.nam == 'scope') {
|
|
4744
|
-
if (astAtRule.val.includes('&')) {
|
|
4745
|
-
astAtRule.val = replaceCompount(astAtRule.val, ast.sel);
|
|
4746
|
-
}
|
|
4747
|
-
// @ts-ignore
|
|
4748
|
-
astAtRule = expand(astAtRule);
|
|
4749
|
-
}
|
|
4750
|
-
else {
|
|
4751
|
-
// @ts-ignore
|
|
4752
|
-
const clone = { ...ast, chi: astAtRule.chi.slice() };
|
|
4753
|
-
// @ts-ignore
|
|
4754
|
-
astAtRule.chi.length = 0;
|
|
4755
|
-
for (const r of expandRule(clone)) {
|
|
4756
|
-
if (r.typ == 'AtRule' && 'chi' in r) {
|
|
4757
|
-
if (astAtRule.val !== '' && r.val !== '') {
|
|
4758
|
-
if (astAtRule.nam == 'media' && r.nam == 'media') {
|
|
4759
|
-
r.val = astAtRule.val + ' and ' + r.val;
|
|
4760
|
-
}
|
|
4761
|
-
else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
|
|
4762
|
-
r.val = astAtRule.val + '.' + r.val;
|
|
4763
|
-
}
|
|
4764
|
-
}
|
|
4765
|
-
// @ts-ignore
|
|
4766
|
-
values.push(r);
|
|
4767
|
-
}
|
|
4768
|
-
else if (r.typ == 'Rule') {
|
|
4769
|
-
// @ts-ignore
|
|
4770
|
-
astAtRule.chi.push(...expandRule(r));
|
|
4771
|
-
}
|
|
4772
|
-
else {
|
|
4773
|
-
// @ts-ignore
|
|
4774
|
-
astAtRule.chi.push(r);
|
|
4775
|
-
}
|
|
4776
|
-
}
|
|
4777
|
-
}
|
|
4778
|
-
// @ts-ignore
|
|
4779
|
-
result.push(...(astAtRule.chi.length > 0 ? [astAtRule].concat(values) : values));
|
|
4780
|
-
ast.chi.splice(i--, 1);
|
|
4781
|
-
}
|
|
4782
|
-
}
|
|
4783
|
-
}
|
|
4784
|
-
// @ts-ignore
|
|
4785
|
-
return ast.chi.length > 0 ? [ast].concat(result) : result;
|
|
4786
|
-
}
|
|
4787
|
-
function replaceCompount(input, replace) {
|
|
4788
|
-
const tokens = parseString(input);
|
|
4789
|
-
for (const t of walkValues(tokens)) {
|
|
4790
|
-
if (t.value.typ == 'Literal') {
|
|
4791
|
-
if (t.value.val == '&') {
|
|
4792
|
-
t.value.val = replace;
|
|
4793
|
-
}
|
|
4794
|
-
else if (t.value.val.length > 1 && t.value.val.charAt(0) == '&') {
|
|
4795
|
-
t.value.val = replaceCompoundLiteral(t.value.val, replace);
|
|
4796
|
-
}
|
|
4797
|
-
}
|
|
4798
|
-
}
|
|
4799
|
-
return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
|
|
4800
|
-
}
|
|
4801
|
-
function replaceCompoundLiteral(selector, replace) {
|
|
4802
|
-
const tokens = [''];
|
|
4803
|
-
let i = 0;
|
|
4804
|
-
for (; i < selector.length; i++) {
|
|
4805
|
-
if (selector.charAt(i) == '&') {
|
|
4806
|
-
tokens.push('&');
|
|
4807
|
-
tokens.push('');
|
|
4808
|
-
}
|
|
4809
|
-
else {
|
|
4810
|
-
tokens[tokens.length - 1] += selector.charAt(i);
|
|
4811
|
-
}
|
|
4812
|
-
}
|
|
4813
|
-
return tokens.sort((a, b) => {
|
|
4814
|
-
if (a == '&') {
|
|
4815
|
-
return 1;
|
|
4816
|
-
}
|
|
4817
|
-
return b == '&' ? -1 : 0;
|
|
4818
|
-
}).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
|
|
4819
4854
|
}
|
|
4820
4855
|
|
|
4821
4856
|
async function transform$1(css, options = {}) {
|
|
@@ -5007,6 +5042,7 @@
|
|
|
5007
5042
|
exports.reduceSelector = reduceSelector;
|
|
5008
5043
|
exports.render = render;
|
|
5009
5044
|
exports.renderToken = renderToken;
|
|
5045
|
+
exports.replaceCompound = replaceCompound;
|
|
5010
5046
|
exports.resolve = resolve;
|
|
5011
5047
|
exports.splitRule = splitRule;
|
|
5012
5048
|
exports.tokenize = tokenize;
|