@tbela99/css-parser 1.3.2 → 1.3.3
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/CHANGELOG.md +5 -0
- package/README.md +41 -5
- package/dist/index-umd-web.js +1272 -961
- package/dist/index.cjs +1194 -920
- package/dist/index.d.ts +921 -264
- package/dist/lib/ast/features/calc.js +5 -6
- package/dist/lib/ast/features/inlinecssvariables.js +5 -6
- package/dist/lib/ast/features/prefix.js +4 -14
- package/dist/lib/ast/features/shorthand.js +4 -6
- package/dist/lib/ast/features/transform.js +5 -6
- package/dist/lib/ast/features/type.js +4 -2
- package/dist/lib/ast/minify.js +55 -114
- package/dist/lib/ast/types.js +2 -2
- package/dist/lib/ast/walk.js +149 -59
- package/dist/lib/fs/resolve.js +6 -4
- package/dist/lib/parser/declaration/list.js +1 -1
- package/dist/lib/parser/parse.js +297 -57
- package/dist/lib/parser/tokenize.js +1 -1
- package/dist/lib/renderer/render.js +5 -5
- package/dist/lib/syntax/color/cmyk.js +6 -3
- package/dist/lib/syntax/color/color-mix.js +2 -3
- package/dist/lib/syntax/color/color.js +28 -6
- package/dist/lib/syntax/color/hex.js +3 -0
- package/dist/lib/syntax/color/hsl.js +18 -7
- package/dist/lib/syntax/color/hwb.js +3 -3
- package/dist/lib/syntax/color/lab.js +4 -4
- package/dist/lib/syntax/color/lch.js +7 -4
- package/dist/lib/syntax/color/oklab.js +4 -4
- package/dist/lib/syntax/color/oklch.js +18 -6
- package/dist/lib/syntax/color/relativecolor.js +9 -56
- package/dist/lib/syntax/color/srgb.js +1 -1
- package/dist/lib/validation/config.json.js +4 -12
- package/dist/node.js +53 -31
- package/dist/web.js +76 -17
- package/package.json +2 -3
package/dist/lib/ast/walk.js
CHANGED
|
@@ -1,60 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* options for the walk function
|
|
3
|
+
*/
|
|
1
4
|
var WalkerOptionEnum;
|
|
2
5
|
(function (WalkerOptionEnum) {
|
|
3
6
|
/**
|
|
4
7
|
* ignore the current node and its children
|
|
5
8
|
*/
|
|
6
|
-
WalkerOptionEnum[WalkerOptionEnum["Ignore"] =
|
|
9
|
+
WalkerOptionEnum[WalkerOptionEnum["Ignore"] = 1] = "Ignore";
|
|
7
10
|
/**
|
|
8
11
|
* stop walking the tree
|
|
9
12
|
*/
|
|
10
|
-
WalkerOptionEnum[WalkerOptionEnum["Stop"] =
|
|
13
|
+
WalkerOptionEnum[WalkerOptionEnum["Stop"] = 2] = "Stop";
|
|
11
14
|
/**
|
|
12
15
|
* ignore node and process children
|
|
13
16
|
*/
|
|
14
|
-
WalkerOptionEnum[WalkerOptionEnum["Children"] =
|
|
17
|
+
WalkerOptionEnum[WalkerOptionEnum["Children"] = 4] = "Children";
|
|
15
18
|
/**
|
|
16
19
|
* ignore children
|
|
17
20
|
*/
|
|
18
|
-
WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] =
|
|
21
|
+
WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] = 8] = "IgnoreChildren";
|
|
19
22
|
})(WalkerOptionEnum || (WalkerOptionEnum = {}));
|
|
23
|
+
/**
|
|
24
|
+
* event types for the walkValues function
|
|
25
|
+
*/
|
|
20
26
|
var WalkerValueEvent;
|
|
21
27
|
(function (WalkerValueEvent) {
|
|
22
28
|
/**
|
|
23
29
|
* enter node
|
|
24
30
|
*/
|
|
25
|
-
WalkerValueEvent[WalkerValueEvent["Enter"] =
|
|
31
|
+
WalkerValueEvent[WalkerValueEvent["Enter"] = 1] = "Enter";
|
|
26
32
|
/**
|
|
27
33
|
* leave node
|
|
28
34
|
*/
|
|
29
|
-
WalkerValueEvent[WalkerValueEvent["Leave"] =
|
|
35
|
+
WalkerValueEvent[WalkerValueEvent["Leave"] = 2] = "Leave";
|
|
30
36
|
})(WalkerValueEvent || (WalkerValueEvent = {}));
|
|
31
37
|
/**
|
|
32
38
|
* walk ast nodes
|
|
33
|
-
* @param node
|
|
34
|
-
* @param filter
|
|
39
|
+
* @param node initial node
|
|
40
|
+
* @param filter control the walk process
|
|
41
|
+
* @param reverse walk in reverse order
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
*
|
|
45
|
+
* import {walk} from '@tbela99/css-parser';
|
|
46
|
+
*
|
|
47
|
+
* const css = `
|
|
48
|
+
* body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
|
|
49
|
+
*
|
|
50
|
+
* html,
|
|
51
|
+
* body {
|
|
52
|
+
* line-height: 1.474;
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* .ruler {
|
|
56
|
+
*
|
|
57
|
+
* height: 10px;
|
|
58
|
+
* }
|
|
59
|
+
* `;
|
|
60
|
+
*
|
|
61
|
+
* for (const {node, parent, root} of walk(ast)) {
|
|
62
|
+
*
|
|
63
|
+
* // do something with node
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* Using a filter to control the walk process:
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
*
|
|
71
|
+
* import {walk} from '@tbela99/css-parser';
|
|
72
|
+
*
|
|
73
|
+
* const css = `
|
|
74
|
+
* body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
|
|
75
|
+
*
|
|
76
|
+
* html,
|
|
77
|
+
* body {
|
|
78
|
+
* line-height: 1.474;
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* .ruler {
|
|
82
|
+
*
|
|
83
|
+
* height: 10px;
|
|
84
|
+
* }
|
|
85
|
+
* `;
|
|
86
|
+
*
|
|
87
|
+
* for (const {node, parent, root} of walk(ast, (node) => {
|
|
88
|
+
*
|
|
89
|
+
* if (node.typ == EnumToken.AstRule && node.sel.includes('html')) {
|
|
90
|
+
*
|
|
91
|
+
* // skip the children of the current node
|
|
92
|
+
* return WalkerOptionEnum.IgnoreChildren;
|
|
93
|
+
* }
|
|
94
|
+
* })) {
|
|
95
|
+
*
|
|
96
|
+
* // do something with node
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
35
99
|
*/
|
|
36
|
-
function* walk(node, filter) {
|
|
100
|
+
function* walk(node, filter, reverse) {
|
|
37
101
|
const parents = [node];
|
|
38
102
|
const root = node;
|
|
39
103
|
const map = new Map;
|
|
104
|
+
let isNumeric = false;
|
|
40
105
|
while ((node = parents.shift())) {
|
|
41
106
|
let option = null;
|
|
42
107
|
if (filter != null) {
|
|
43
108
|
option = filter(node);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
109
|
+
isNumeric = typeof option == 'number';
|
|
110
|
+
if (isNumeric) {
|
|
111
|
+
if ((option & WalkerOptionEnum.Ignore)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if ((option & WalkerOptionEnum.Stop)) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
49
117
|
}
|
|
50
118
|
}
|
|
51
|
-
|
|
52
|
-
if (option !== 'children') {
|
|
119
|
+
if (!isNumeric || (option & WalkerOptionEnum.Children) === 0) {
|
|
53
120
|
// @ts-ignore
|
|
54
121
|
yield { node, parent: map.get(node), root };
|
|
55
122
|
}
|
|
56
|
-
if (option
|
|
57
|
-
parents.unshift(...node.chi);
|
|
123
|
+
if ('chi' in node && (!isNumeric || ((option & WalkerOptionEnum.IgnoreChildren) === 0))) {
|
|
124
|
+
parents.unshift(...node.chi[reverse ? 'reverse' : 'slice']());
|
|
58
125
|
for (const child of node.chi.slice()) {
|
|
59
126
|
map.set(child, node);
|
|
60
127
|
}
|
|
@@ -67,13 +134,38 @@ function* walk(node, filter) {
|
|
|
67
134
|
* @param root
|
|
68
135
|
* @param filter
|
|
69
136
|
* @param reverse
|
|
137
|
+
*
|
|
138
|
+
* Example:
|
|
139
|
+
*
|
|
140
|
+
* ```ts
|
|
141
|
+
*
|
|
142
|
+
* import {EnumToken, walk} from '@tbela99/css-parser';
|
|
143
|
+
*
|
|
144
|
+
* const css = `
|
|
145
|
+
* body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
|
|
146
|
+
*
|
|
147
|
+
* html,
|
|
148
|
+
* body {
|
|
149
|
+
* line-height: 1.474;
|
|
150
|
+
* }
|
|
151
|
+
*
|
|
152
|
+
* .ruler {
|
|
153
|
+
*
|
|
154
|
+
* height: 10px;
|
|
155
|
+
* }
|
|
156
|
+
* `;
|
|
157
|
+
*
|
|
158
|
+
* for (const {value} of walkValues(result.ast.chi[0].chi[0].val, null, null,true)) {
|
|
159
|
+
*
|
|
160
|
+
* console.error([EnumToken[value.typ], value.val]);
|
|
161
|
+
* }
|
|
162
|
+
*
|
|
70
163
|
*/
|
|
71
164
|
function* walkValues(values, root = null, filter, reverse) {
|
|
72
165
|
// const set = new Set<Token>();
|
|
73
166
|
const stack = values.slice();
|
|
74
167
|
const map = new Map;
|
|
75
168
|
let previous = null;
|
|
76
|
-
// let parent: FunctionToken | ParensToken | BinaryExpressionToken | null = null;
|
|
77
169
|
if (filter != null && typeof filter == 'function') {
|
|
78
170
|
filter = {
|
|
79
171
|
event: WalkerValueEvent.Enter,
|
|
@@ -85,21 +177,23 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
85
177
|
event: WalkerValueEvent.Enter
|
|
86
178
|
};
|
|
87
179
|
}
|
|
180
|
+
let isNumeric = false;
|
|
88
181
|
const eventType = filter.event ?? WalkerValueEvent.Enter;
|
|
89
182
|
while (stack.length > 0) {
|
|
90
183
|
let value = reverse ? stack.pop() : stack.shift();
|
|
91
184
|
let option = null;
|
|
92
|
-
if (filter.fn != null && eventType
|
|
185
|
+
if (filter.fn != null && (eventType & WalkerValueEvent.Enter)) {
|
|
93
186
|
const isValid = filter.type == null || value.typ == filter.type ||
|
|
94
187
|
(Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
|
|
95
188
|
(typeof filter.type == 'function' && filter.type(value));
|
|
96
189
|
if (isValid) {
|
|
97
|
-
option = filter.fn(value, map.get(value) ?? root);
|
|
98
|
-
|
|
99
|
-
|
|
190
|
+
option = filter.fn(value, map.get(value) ?? root, WalkerValueEvent.Enter);
|
|
191
|
+
isNumeric = typeof option == 'number';
|
|
192
|
+
if (isNumeric && (option & WalkerOptionEnum.Stop)) {
|
|
193
|
+
return;
|
|
100
194
|
}
|
|
101
|
-
if (option
|
|
102
|
-
|
|
195
|
+
if (isNumeric && (option & WalkerOptionEnum.Ignore)) {
|
|
196
|
+
continue;
|
|
103
197
|
}
|
|
104
198
|
// @ts-ignore
|
|
105
199
|
if (option != null && typeof option == 'object' && 'typ' in option) {
|
|
@@ -107,38 +201,33 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
107
201
|
}
|
|
108
202
|
}
|
|
109
203
|
}
|
|
110
|
-
if (eventType
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
if (option
|
|
204
|
+
// if ((eventType & WalkerValueEvent.Enter) && (!isNumeric || ((option as number) & WalkerOptionEnum.Children) === 0)) {
|
|
205
|
+
yield {
|
|
206
|
+
value,
|
|
207
|
+
parent: map.get(value) ?? root,
|
|
208
|
+
previousValue: previous,
|
|
209
|
+
nextValue: stack[0] ?? null,
|
|
210
|
+
// @ts-ignore
|
|
211
|
+
root: root ?? null
|
|
212
|
+
};
|
|
213
|
+
// }
|
|
214
|
+
if ('chi' in value && (!isNumeric || (option & WalkerOptionEnum.IgnoreChildren) === 0)) {
|
|
121
215
|
const sliced = value.chi.slice();
|
|
122
216
|
for (const child of sliced) {
|
|
123
217
|
map.set(child, value);
|
|
124
218
|
}
|
|
125
|
-
|
|
126
|
-
stack.push(...sliced);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
stack.unshift(...sliced);
|
|
130
|
-
}
|
|
219
|
+
stack[reverse ? 'push' : 'unshift'](...sliced);
|
|
131
220
|
}
|
|
132
221
|
else {
|
|
133
222
|
const values = [];
|
|
134
223
|
if ('l' in value && value.l != null) {
|
|
135
224
|
// @ts-ignore
|
|
136
|
-
values
|
|
225
|
+
values[reverse ? 'push' : 'unshift'](value.l);
|
|
137
226
|
// @ts-ignore
|
|
138
227
|
map.set(value.l, value);
|
|
139
228
|
}
|
|
140
229
|
if ('op' in value && typeof value.op == 'object') {
|
|
141
|
-
values
|
|
230
|
+
values[reverse ? 'push' : 'unshift'](value.op);
|
|
142
231
|
// @ts-ignore
|
|
143
232
|
map.set(value.op, value);
|
|
144
233
|
}
|
|
@@ -146,44 +235,45 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
146
235
|
if (Array.isArray(value.r)) {
|
|
147
236
|
for (const r of value.r) {
|
|
148
237
|
// @ts-ignore
|
|
149
|
-
values
|
|
238
|
+
values[reverse ? 'push' : 'unshift'](r);
|
|
150
239
|
// @ts-ignore
|
|
151
240
|
map.set(r, value);
|
|
152
241
|
}
|
|
153
242
|
}
|
|
154
243
|
else {
|
|
155
244
|
// @ts-ignore
|
|
156
|
-
values
|
|
245
|
+
values[reverse ? 'push' : 'unshift'](value.r);
|
|
157
246
|
// @ts-ignore
|
|
158
247
|
map.set(value.r, value);
|
|
159
248
|
}
|
|
160
249
|
}
|
|
161
250
|
if (values.length > 0) {
|
|
162
|
-
stack
|
|
251
|
+
stack[reverse ? 'push' : 'unshift'](...values);
|
|
163
252
|
}
|
|
164
253
|
}
|
|
165
|
-
if (eventType
|
|
254
|
+
if ((eventType & WalkerValueEvent.Leave) && filter.fn != null) {
|
|
166
255
|
const isValid = filter.type == null || value.typ == filter.type ||
|
|
167
256
|
(Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
|
|
168
257
|
(typeof filter.type == 'function' && filter.type(value));
|
|
169
258
|
if (isValid) {
|
|
170
|
-
option = filter.fn(value, map.get(value));
|
|
259
|
+
option = filter.fn(value, map.get(value), WalkerValueEvent.Leave);
|
|
171
260
|
// @ts-ignore
|
|
172
261
|
if (option != null && 'typ' in option) {
|
|
173
262
|
map.set(option, map.get(value) ?? root);
|
|
174
263
|
}
|
|
175
264
|
}
|
|
176
265
|
}
|
|
177
|
-
if (eventType
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
266
|
+
// if ((eventType & WalkerValueEvent.Leave) && (!isNumeric && ((option as number) & WalkerOptionEnum.Children) === 0)) {
|
|
267
|
+
//
|
|
268
|
+
// yield {
|
|
269
|
+
// value,
|
|
270
|
+
// parent: <FunctionToken | ParensToken>map.get(value) ?? root,
|
|
271
|
+
// previousValue: previous,
|
|
272
|
+
// nextValue: <Token>stack[0] ?? null,
|
|
273
|
+
// // @ts-ignore
|
|
274
|
+
// root: root ?? null
|
|
275
|
+
// };
|
|
276
|
+
// }
|
|
187
277
|
previous = value;
|
|
188
278
|
}
|
|
189
279
|
}
|
package/dist/lib/fs/resolve.js
CHANGED
|
@@ -2,12 +2,14 @@ const matchUrl = /^(https?:)?\/\//;
|
|
|
2
2
|
/**
|
|
3
3
|
* return the directory name of a path
|
|
4
4
|
* @param path
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* @private
|
|
6
7
|
*/
|
|
7
8
|
function dirname(path) {
|
|
8
|
-
if (path == '/' || path === '') {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// if (path == '/' || path === '') {
|
|
10
|
+
//
|
|
11
|
+
// return path;
|
|
12
|
+
// }
|
|
11
13
|
let i = 0;
|
|
12
14
|
let parts = [''];
|
|
13
15
|
for (; i < path.length; i++) {
|
|
@@ -26,7 +26,7 @@ class PropertyList {
|
|
|
26
26
|
}
|
|
27
27
|
add(...declarations) {
|
|
28
28
|
for (const declaration of declarations) {
|
|
29
|
-
if (declaration.typ != EnumToken.DeclarationNodeType || !this.options.removeDuplicateDeclarations) {
|
|
29
|
+
if (declaration.typ != EnumToken.DeclarationNodeType || (Array.isArray(this.options.removeDuplicateDeclarations) ? this.options.removeDuplicateDeclarations.includes(declaration.nam) : !this.options.removeDuplicateDeclarations)) {
|
|
30
30
|
this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
|
|
31
31
|
continue;
|
|
32
32
|
}
|