@tbela99/css-parser 0.0.1-rc7 → 0.1.0
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 +157 -41
- package/dist/index-umd-web.js +2058 -1242
- package/dist/index.cjs +2052 -1238
- package/dist/index.d.ts +677 -332
- package/dist/lib/ast/expand.js +14 -20
- package/dist/lib/ast/features/calc.js +256 -0
- package/dist/lib/ast/features/index.js +3 -0
- package/dist/lib/ast/features/inlinecssvariables.js +115 -0
- package/dist/lib/ast/features/shorthand.js +45 -0
- package/dist/lib/ast/minify.js +395 -371
- package/dist/lib/ast/types.js +88 -0
- package/dist/lib/ast/utiles/minifyfeature.js +8 -0
- package/dist/lib/ast/walk.js +24 -9
- package/dist/lib/parser/declaration/list.js +18 -4
- package/dist/lib/parser/declaration/map.js +51 -30
- package/dist/lib/parser/declaration/set.js +18 -12
- package/dist/lib/parser/parse.js +176 -136
- package/dist/lib/parser/tokenize.js +42 -35
- package/dist/lib/parser/utils/eq.js +1 -1
- package/dist/lib/parser/utils/syntax.js +13 -10
- package/dist/lib/parser/utils/type.js +18 -6
- package/dist/lib/renderer/render.js +201 -79
- package/dist/lib/renderer/sourcemap/lib/encode.js +37 -0
- package/dist/lib/renderer/sourcemap/sourcemap.js +58 -0
- package/dist/lib/renderer/utils/color.js +25 -20
- package/dist/node/index.js +29 -10
- package/dist/web/index.js +33 -12
- package/package.json +5 -4
- package/dist/lib/transform.js +0 -24
package/dist/lib/ast/expand.js
CHANGED
|
@@ -2,37 +2,38 @@ import { splitRule, combinators } from './minify.js';
|
|
|
2
2
|
import { parseString } from '../parser/parse.js';
|
|
3
3
|
import { renderToken } from '../renderer/render.js';
|
|
4
4
|
import '../renderer/utils/color.js';
|
|
5
|
+
import { EnumToken } from './types.js';
|
|
5
6
|
import { walkValues } from './walk.js';
|
|
6
7
|
|
|
7
8
|
function expand(ast) {
|
|
8
9
|
//
|
|
9
|
-
if (![
|
|
10
|
+
if (![4 /* NodeType.RuleNodeType */, 2 /* NodeType.StyleSheetNodeType */, 3 /* NodeType.AtRuleNodeType */].includes(ast.typ)) {
|
|
10
11
|
return ast;
|
|
11
12
|
}
|
|
12
|
-
if (
|
|
13
|
+
if (4 /* NodeType.RuleNodeType */ == ast.typ) {
|
|
13
14
|
return {
|
|
14
|
-
typ:
|
|
15
|
+
typ: 2 /* NodeType.StyleSheetNodeType */,
|
|
15
16
|
chi: expandRule(ast)
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
if (!('chi' in ast)) {
|
|
19
|
-
return
|
|
20
|
+
return ast;
|
|
20
21
|
}
|
|
21
22
|
const result = { ...ast, chi: [] };
|
|
22
23
|
// @ts-ignore
|
|
23
24
|
for (let i = 0; i < ast.chi.length; i++) {
|
|
24
25
|
// @ts-ignore
|
|
25
26
|
const node = ast.chi[i];
|
|
26
|
-
if (node.typ ==
|
|
27
|
+
if (node.typ == 4 /* NodeType.RuleNodeType */) {
|
|
27
28
|
// @ts-ignore
|
|
28
29
|
result.chi.push(...expandRule(node));
|
|
29
30
|
// i += expanded.length - 1;
|
|
30
31
|
}
|
|
31
|
-
else if (node.typ ==
|
|
32
|
+
else if (node.typ == 3 /* NodeType.AtRuleNodeType */ && 'chi' in node) {
|
|
32
33
|
let hasRule = false;
|
|
33
34
|
let j = node.chi.length;
|
|
34
35
|
while (j--) {
|
|
35
|
-
if (node.chi[j].typ ==
|
|
36
|
+
if (node.chi[j].typ == 4 /* NodeType.RuleNodeType */ || node.chi[j].typ == 3 /* NodeType.AtRuleNodeType */) {
|
|
36
37
|
hasRule = true;
|
|
37
38
|
break;
|
|
38
39
|
}
|
|
@@ -50,14 +51,10 @@ function expand(ast) {
|
|
|
50
51
|
function expandRule(node) {
|
|
51
52
|
const ast = { ...node, chi: node.chi.slice() };
|
|
52
53
|
const result = [];
|
|
53
|
-
if (ast.typ ==
|
|
54
|
+
if (ast.typ == 4 /* NodeType.RuleNodeType */) {
|
|
54
55
|
let i = 0;
|
|
55
|
-
// @ts-ignore
|
|
56
|
-
delete ast.raw;
|
|
57
|
-
// @ts-ignore
|
|
58
|
-
delete ast.optimized;
|
|
59
56
|
for (; i < ast.chi.length; i++) {
|
|
60
|
-
if (ast.chi[i].typ ==
|
|
57
|
+
if (ast.chi[i].typ == 4 /* NodeType.RuleNodeType */) {
|
|
61
58
|
const rule = ast.chi[i];
|
|
62
59
|
if (!rule.sel.includes('&')) {
|
|
63
60
|
const selRule = splitRule(rule.sel);
|
|
@@ -70,19 +67,16 @@ function expandRule(node) {
|
|
|
70
67
|
else {
|
|
71
68
|
rule.sel = replaceCompound(rule.sel, ast.sel);
|
|
72
69
|
}
|
|
73
|
-
delete rule.raw;
|
|
74
|
-
delete rule.optimized;
|
|
75
70
|
ast.chi.splice(i--, 1);
|
|
76
71
|
result.push(...expandRule(rule));
|
|
77
72
|
}
|
|
78
|
-
else if (ast.chi[i].typ ==
|
|
73
|
+
else if (ast.chi[i].typ == 3 /* NodeType.AtRuleNodeType */) {
|
|
79
74
|
let astAtRule = ast.chi[i];
|
|
80
75
|
const values = [];
|
|
81
76
|
if (astAtRule.nam == 'scope') {
|
|
82
77
|
if (astAtRule.val.includes('&')) {
|
|
83
78
|
astAtRule.val = replaceCompound(astAtRule.val, ast.sel);
|
|
84
79
|
}
|
|
85
|
-
// @ts-ignore
|
|
86
80
|
astAtRule = expand(astAtRule);
|
|
87
81
|
}
|
|
88
82
|
else {
|
|
@@ -91,7 +85,7 @@ function expandRule(node) {
|
|
|
91
85
|
// @ts-ignore
|
|
92
86
|
astAtRule.chi.length = 0;
|
|
93
87
|
for (const r of expandRule(clone)) {
|
|
94
|
-
if (r.typ ==
|
|
88
|
+
if (r.typ == 3 /* NodeType.AtRuleNodeType */ && 'chi' in r) {
|
|
95
89
|
if (astAtRule.val !== '' && r.val !== '') {
|
|
96
90
|
if (astAtRule.nam == 'media' && r.nam == 'media') {
|
|
97
91
|
r.val = astAtRule.val + ' and ' + r.val;
|
|
@@ -103,7 +97,7 @@ function expandRule(node) {
|
|
|
103
97
|
// @ts-ignore
|
|
104
98
|
values.push(r);
|
|
105
99
|
}
|
|
106
|
-
else if (r.typ ==
|
|
100
|
+
else if (r.typ == 4 /* NodeType.RuleNodeType */) {
|
|
107
101
|
// @ts-ignore
|
|
108
102
|
astAtRule.chi.push(...expandRule(r));
|
|
109
103
|
}
|
|
@@ -125,7 +119,7 @@ function expandRule(node) {
|
|
|
125
119
|
function replaceCompound(input, replace) {
|
|
126
120
|
const tokens = parseString(input);
|
|
127
121
|
for (const t of walkValues(tokens)) {
|
|
128
|
-
if (t.value.typ ==
|
|
122
|
+
if (t.value.typ == EnumToken.LiteralTokenType) {
|
|
129
123
|
if (t.value.val == '&') {
|
|
130
124
|
t.value.val = replace;
|
|
131
125
|
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { EnumToken } from '../types.js';
|
|
2
|
+
import { reduceNumber, renderToken } from '../../renderer/render.js';
|
|
3
|
+
import { walkValues } from '../walk.js';
|
|
4
|
+
import { MinifyFeature } from '../utiles/minifyfeature.js';
|
|
5
|
+
|
|
6
|
+
class ComputeCalcExpression extends MinifyFeature {
|
|
7
|
+
static get ordering() {
|
|
8
|
+
return 1;
|
|
9
|
+
}
|
|
10
|
+
static register(options) {
|
|
11
|
+
if (options.computeCalcExpression) {
|
|
12
|
+
for (const feature of options.features) {
|
|
13
|
+
if (feature instanceof ComputeCalcExpression) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
options.features.push(new ComputeCalcExpression());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
run(ast) {
|
|
22
|
+
if (!('chi' in ast)) {
|
|
23
|
+
return ast;
|
|
24
|
+
}
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
for (const node of ast.chi) {
|
|
27
|
+
if (node.typ != 5 /* NodeType.DeclarationNodeType */) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const set = new Set;
|
|
31
|
+
for (const { parent } of walkValues(node.val)) {
|
|
32
|
+
if (parent != null && parent.typ == EnumToken.FunctionTokenType && parent.val == 'calc') {
|
|
33
|
+
if (!set.has(parent)) {
|
|
34
|
+
set.add(parent);
|
|
35
|
+
parent.chi = evaluate(parent.chi);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return ast;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* evaluate arithmetic operation
|
|
45
|
+
* @param l
|
|
46
|
+
* @param r
|
|
47
|
+
* @param op
|
|
48
|
+
*/
|
|
49
|
+
function doEvaluate(l, r, op) {
|
|
50
|
+
const defaultReturn = {
|
|
51
|
+
typ: EnumToken.BinaryExpressionTokenType,
|
|
52
|
+
op,
|
|
53
|
+
l,
|
|
54
|
+
r
|
|
55
|
+
};
|
|
56
|
+
if (!isScalarToken(l) || !isScalarToken(r)) {
|
|
57
|
+
return defaultReturn;
|
|
58
|
+
}
|
|
59
|
+
if ((op == EnumToken.Add || op == EnumToken.Sub)) {
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
if (l.typ != r.typ || Number.isNaN(+l.val) || Number.isNaN(r.val)) {
|
|
62
|
+
return defaultReturn;
|
|
63
|
+
}
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
return { ...l, val: reduceNumber(+l.val + (op == EnumToken.Add ? +r.val : -1 * r.val)) };
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
let val;
|
|
70
|
+
if (op == EnumToken.Div) {
|
|
71
|
+
if (r.typ != EnumToken.NumberTokenType || r.val == '0') {
|
|
72
|
+
return defaultReturn;
|
|
73
|
+
}
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
val = reduceNumber(l.val / r.val);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
val = reduceNumber(r.val * l.val);
|
|
80
|
+
}
|
|
81
|
+
let result;
|
|
82
|
+
if (r.typ == EnumToken.NumberTokenType || op == EnumToken.Div) {
|
|
83
|
+
result = { ...l, val };
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
result = { ...r, val };
|
|
88
|
+
}
|
|
89
|
+
if (renderToken(result).length <= renderToken(defaultReturn).length) {
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return defaultReturn;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* evaluate an array of tokens
|
|
97
|
+
* @param tokens
|
|
98
|
+
*/
|
|
99
|
+
function evaluate(tokens) {
|
|
100
|
+
const nodes = inlineExpression(evaluateExpression(buildExpression(tokens)));
|
|
101
|
+
if (nodes.length <= 1) {
|
|
102
|
+
return nodes;
|
|
103
|
+
}
|
|
104
|
+
const map = new Map;
|
|
105
|
+
let token;
|
|
106
|
+
let i;
|
|
107
|
+
for (i = 0; i < nodes.length; i++) {
|
|
108
|
+
token = nodes[i];
|
|
109
|
+
if (token.typ == EnumToken.Add) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (token.typ == EnumToken.Sub) {
|
|
113
|
+
if (!isScalarToken(nodes[i + 1])) {
|
|
114
|
+
token = { typ: EnumToken.ListToken, chi: [nodes[i], nodes[i + 1]] };
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
token = doEvaluate(nodes[i + 1], { typ: EnumToken.NumberTokenType, val: '-1' }, EnumToken.Mul);
|
|
118
|
+
}
|
|
119
|
+
i++;
|
|
120
|
+
}
|
|
121
|
+
if (!map.has(token.typ)) {
|
|
122
|
+
map.set(token.typ, [token]);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
map.get(token.typ).push(token);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return [...map].reduce((acc, curr) => {
|
|
129
|
+
const token = curr[1].reduce((acc, curr) => doEvaluate(acc, curr, EnumToken.Add));
|
|
130
|
+
if (token.typ != EnumToken.BinaryExpressionTokenType) {
|
|
131
|
+
if ('val' in token && +token.val < 0) {
|
|
132
|
+
acc.push({ typ: EnumToken.Sub }, { ...token, val: String(-token.val) });
|
|
133
|
+
return acc;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (acc.length > 0 && curr[0] != EnumToken.ListToken) {
|
|
137
|
+
acc.push({ typ: EnumToken.Add });
|
|
138
|
+
}
|
|
139
|
+
acc.push(token);
|
|
140
|
+
return acc;
|
|
141
|
+
}, []);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* convert BinaryExpression into an array
|
|
145
|
+
* @param token
|
|
146
|
+
*/
|
|
147
|
+
function inlineExpression(token) {
|
|
148
|
+
const result = [];
|
|
149
|
+
if (token.typ == EnumToken.BinaryExpressionTokenType) {
|
|
150
|
+
if ([EnumToken.Mul, EnumToken.Div].includes(token.op)) {
|
|
151
|
+
result.push(token);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
result.push(...inlineExpression(token.l), { typ: token.op }, ...inlineExpression(token.r));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
result.push(token);
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* evaluate expression
|
|
164
|
+
* @param token
|
|
165
|
+
*/
|
|
166
|
+
function evaluateExpression(token) {
|
|
167
|
+
if (token.typ != EnumToken.BinaryExpressionTokenType) {
|
|
168
|
+
return token;
|
|
169
|
+
}
|
|
170
|
+
if (token.r.typ == EnumToken.BinaryExpressionTokenType) {
|
|
171
|
+
token.r = evaluateExpression(token.r);
|
|
172
|
+
}
|
|
173
|
+
if (token.l.typ == EnumToken.BinaryExpressionTokenType) {
|
|
174
|
+
token.l = evaluateExpression(token.l);
|
|
175
|
+
}
|
|
176
|
+
const result = doEvaluate(token.l, token.r, token.op);
|
|
177
|
+
if (result.typ == EnumToken.BinaryExpressionTokenType &&
|
|
178
|
+
[EnumToken.Mul, EnumToken.Div].includes(result.op)) {
|
|
179
|
+
// wrap expression
|
|
180
|
+
if (result.l.typ == EnumToken.BinaryExpressionTokenType && [EnumToken.Sub, EnumToken.Add].includes(result.l.op)) {
|
|
181
|
+
result.l = { typ: EnumToken.ParensTokenType, chi: [result.l] };
|
|
182
|
+
}
|
|
183
|
+
else if (result.r.typ == EnumToken.BinaryExpressionTokenType && [EnumToken.Sub, EnumToken.Add].includes(result.r.op)) {
|
|
184
|
+
result.r = { typ: EnumToken.ParensTokenType, chi: [result.r] };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
function isScalarToken(token) {
|
|
190
|
+
return token.typ != EnumToken.BinaryExpressionTokenType && token.typ != EnumToken.ParensTokenType && token.typ != EnumToken.FunctionTokenType;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
*
|
|
194
|
+
* generate binary expression tree
|
|
195
|
+
* @param tokens
|
|
196
|
+
*/
|
|
197
|
+
function buildExpression(tokens) {
|
|
198
|
+
return factor(factor(tokens.filter(t => t.typ != EnumToken.WhitespaceTokenType), ['/', '*']), ['+', '-'])[0];
|
|
199
|
+
}
|
|
200
|
+
function getArithmeticOperation(op) {
|
|
201
|
+
if (op == '+') {
|
|
202
|
+
return EnumToken.Add;
|
|
203
|
+
}
|
|
204
|
+
if (op == '-') {
|
|
205
|
+
return EnumToken.Sub;
|
|
206
|
+
}
|
|
207
|
+
if (op == '/') {
|
|
208
|
+
return EnumToken.Div;
|
|
209
|
+
}
|
|
210
|
+
return EnumToken.Mul;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
*
|
|
214
|
+
* generate binary expression tree
|
|
215
|
+
* @param token
|
|
216
|
+
*/
|
|
217
|
+
function factorToken(token) {
|
|
218
|
+
if (token.typ == EnumToken.ParensTokenType || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc')) {
|
|
219
|
+
if (token.typ == EnumToken.FunctionTokenType && token.val == 'calc') {
|
|
220
|
+
token = { ...token, typ: EnumToken.ParensTokenType };
|
|
221
|
+
// @ts-ignore
|
|
222
|
+
delete token.val;
|
|
223
|
+
}
|
|
224
|
+
return buildExpression(token.chi);
|
|
225
|
+
}
|
|
226
|
+
return token;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* generate binary expression tree
|
|
230
|
+
* @param tokens
|
|
231
|
+
* @param ops
|
|
232
|
+
*/
|
|
233
|
+
function factor(tokens, ops) {
|
|
234
|
+
let isOp;
|
|
235
|
+
const opList = [EnumToken.Add, EnumToken.Sub, EnumToken.Div, EnumToken.Mul];
|
|
236
|
+
if (tokens.length == 1) {
|
|
237
|
+
return [factorToken(tokens[0])];
|
|
238
|
+
}
|
|
239
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
240
|
+
isOp = opList.includes(tokens[i].typ);
|
|
241
|
+
if (isOp ||
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
(tokens[i].typ == EnumToken.LiteralTokenType && ops.includes(tokens[i].val))) {
|
|
244
|
+
tokens.splice(i - 1, 3, {
|
|
245
|
+
typ: EnumToken.BinaryExpressionTokenType,
|
|
246
|
+
op: isOp ? tokens[i].typ : getArithmeticOperation(tokens[i].val),
|
|
247
|
+
l: factorToken(tokens[i - 1]),
|
|
248
|
+
r: factorToken(tokens[i + 1])
|
|
249
|
+
});
|
|
250
|
+
i--;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return tokens;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export { ComputeCalcExpression };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { EnumToken } from '../types.js';
|
|
2
|
+
import { walkValues } from '../walk.js';
|
|
3
|
+
import { MinifyFeature } from '../utiles/minifyfeature.js';
|
|
4
|
+
|
|
5
|
+
class InlineCssVariables extends MinifyFeature {
|
|
6
|
+
static get ordering() {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
static register(options) {
|
|
10
|
+
if (options.inlineCssVariables) {
|
|
11
|
+
for (const feature of options.features) {
|
|
12
|
+
if (feature instanceof InlineCssVariables) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
options.features.push(new InlineCssVariables());
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
run(ast, options = {}, parent, context) {
|
|
21
|
+
if (!('variableScope' in context)) {
|
|
22
|
+
context.variableScope = new Map;
|
|
23
|
+
}
|
|
24
|
+
const isRoot = parent.typ == 2 /* NodeType.StyleSheetNodeType */ && ast.typ == 4 /* NodeType.RuleNodeType */ && ast.sel == ':root';
|
|
25
|
+
const variableScope = context.variableScope;
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
for (const node of ast.chi) {
|
|
28
|
+
if (node.typ == 1 /* NodeType.CDOCOMMNodeType */ || node.typ == 0 /* NodeType.CommentNodeType */) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (node.typ != 5 /* NodeType.DeclarationNodeType */) {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
// css variable
|
|
35
|
+
if (node.nam.startsWith('--')) {
|
|
36
|
+
if (!variableScope.has(node.nam)) {
|
|
37
|
+
const info = {
|
|
38
|
+
globalScope: isRoot,
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
parent: new Set(),
|
|
41
|
+
declarationCount: 1,
|
|
42
|
+
replaceable: isRoot,
|
|
43
|
+
node: node
|
|
44
|
+
};
|
|
45
|
+
info.parent.add(ast);
|
|
46
|
+
variableScope.set(node.nam, info);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const info = variableScope.get(node.nam);
|
|
50
|
+
info.globalScope = isRoot;
|
|
51
|
+
if (!isRoot) {
|
|
52
|
+
++info.declarationCount;
|
|
53
|
+
}
|
|
54
|
+
if (info.replaceable) {
|
|
55
|
+
info.replaceable = isRoot && info.declarationCount == 1;
|
|
56
|
+
}
|
|
57
|
+
info.parent.add(ast);
|
|
58
|
+
info.node = node;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
for (const { value, parent: parentValue } of walkValues(node.val)) {
|
|
63
|
+
if (value?.typ == EnumToken.FunctionTokenType && value.val == 'var') {
|
|
64
|
+
if (value.chi.length == 1 && value.chi[0].typ == EnumToken.IdenTokenType) {
|
|
65
|
+
const info = variableScope.get(value.chi[0].val);
|
|
66
|
+
if (info?.replaceable) {
|
|
67
|
+
if (parentValue != null) {
|
|
68
|
+
let i = 0;
|
|
69
|
+
for (; i < parentValue.chi.length; i++) {
|
|
70
|
+
if (parentValue.chi[i] == value) {
|
|
71
|
+
parentValue.chi.splice(i, 1, ...info.node.val);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
node.val = info.node.val.slice();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
cleanup(ast, options = {}, context) {
|
|
87
|
+
const variableScope = context.variableScope;
|
|
88
|
+
for (const info of variableScope.values()) {
|
|
89
|
+
if (info.replaceable) {
|
|
90
|
+
let i;
|
|
91
|
+
for (const parent of info.parent) {
|
|
92
|
+
i = parent.chi?.length ?? 0;
|
|
93
|
+
while (i--) {
|
|
94
|
+
if (parent.chi[i].typ == 5 /* NodeType.DeclarationNodeType */ && parent.chi[i].nam == info.node.nam) {
|
|
95
|
+
parent.chi.splice(i, 1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (parent.chi?.length == 0 && 'parent' in parent) {
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
for (i = 0; i < parent.parent.chi?.length; i++) {
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
if (parent.parent.chi[i] == parent) {
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
parent.parent.chi.splice(i, 1);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { InlineCssVariables };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { PropertyList } from '../../parser/declaration/list.js';
|
|
2
|
+
import '../../renderer/utils/color.js';
|
|
3
|
+
import '../types.js';
|
|
4
|
+
import '../minify.js';
|
|
5
|
+
import '../../parser/parse.js';
|
|
6
|
+
import '../../renderer/sourcemap/lib/encode.js';
|
|
7
|
+
import { MinifyFeature } from '../utiles/minifyfeature.js';
|
|
8
|
+
|
|
9
|
+
class ComputeShorthand extends MinifyFeature {
|
|
10
|
+
static get ordering() {
|
|
11
|
+
return 2;
|
|
12
|
+
}
|
|
13
|
+
static register(options) {
|
|
14
|
+
if (options.computeShorthand) {
|
|
15
|
+
for (const feature of options.features) {
|
|
16
|
+
if (feature instanceof ComputeShorthand) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
options.features.push(new ComputeShorthand());
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
run(ast, options = {}, parent, context) {
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
const j = ast.chi.length;
|
|
27
|
+
let k = 0;
|
|
28
|
+
let properties = new PropertyList(options);
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
for (; k < j; k++) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
const node = ast.chi[k];
|
|
33
|
+
if (node.typ == 0 /* NodeType.CommentNodeType */ || node.typ == 5 /* NodeType.DeclarationNodeType */) {
|
|
34
|
+
properties.add(node);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
ast.chi = [...properties].concat(ast.chi.slice(k));
|
|
41
|
+
return ast;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { ComputeShorthand };
|