@tbela99/css-parser 0.0.1-alpha5 → 0.0.1-rc1
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/.gitattributes +1 -0
- package/README.md +18 -6
- package/dist/config.json.js +95 -4
- package/dist/index-umd-web.js +1609 -1391
- package/dist/index.cjs +1609 -1391
- package/dist/index.d.ts +317 -9
- package/dist/index.js +6 -2
- package/dist/lib/{parser/deduplicate.js → ast/minify.js} +393 -414
- package/dist/lib/parser/declaration/list.js +38 -9
- package/dist/lib/parser/declaration/map.js +203 -145
- package/dist/lib/parser/declaration/set.js +26 -34
- package/dist/lib/parser/parse.js +237 -683
- package/dist/lib/parser/tokenize.js +452 -0
- package/dist/lib/parser/utils/eq.js +29 -5
- package/dist/lib/parser/utils/syntax.js +24 -7
- package/dist/lib/renderer/render.js +9 -6
- package/dist/lib/transform.js +1 -1
- package/dist/node/index.js +1 -0
- package/dist/web/index.js +6 -2
- package/package.json +11 -5
- /package/dist/lib/{walker → ast}/walk.js +0 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import { isWhiteSpace, isDigit, isNewLine } from './utils/syntax.js';
|
|
2
|
+
|
|
3
|
+
function* tokenize(iterator) {
|
|
4
|
+
let ind = -1;
|
|
5
|
+
let lin = 1;
|
|
6
|
+
let col = 0;
|
|
7
|
+
const position = {
|
|
8
|
+
ind: Math.max(ind, 0),
|
|
9
|
+
lin: lin,
|
|
10
|
+
col: Math.max(col, 1)
|
|
11
|
+
};
|
|
12
|
+
let value;
|
|
13
|
+
let buffer = '';
|
|
14
|
+
function consumeWhiteSpace() {
|
|
15
|
+
let count = 0;
|
|
16
|
+
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
17
|
+
count++;
|
|
18
|
+
}
|
|
19
|
+
next(count);
|
|
20
|
+
return count;
|
|
21
|
+
}
|
|
22
|
+
function pushToken(token, hint) {
|
|
23
|
+
const result = { token, hint, position: { ...position }, bytesIn: ind };
|
|
24
|
+
position.ind = ind;
|
|
25
|
+
position.lin = lin;
|
|
26
|
+
position.col = col == 0 ? 1 : col;
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
function* consumeString(quoteStr) {
|
|
30
|
+
const quote = quoteStr;
|
|
31
|
+
let value;
|
|
32
|
+
let hasNewLine = false;
|
|
33
|
+
if (buffer.length > 0) {
|
|
34
|
+
yield pushToken(buffer);
|
|
35
|
+
buffer = '';
|
|
36
|
+
}
|
|
37
|
+
buffer += quoteStr;
|
|
38
|
+
while (value = peek()) {
|
|
39
|
+
if (ind >= iterator.length) {
|
|
40
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (value == '\\') {
|
|
44
|
+
const sequence = peek(6);
|
|
45
|
+
let escapeSequence = '';
|
|
46
|
+
let codepoint;
|
|
47
|
+
let i;
|
|
48
|
+
for (i = 1; i < sequence.length; i++) {
|
|
49
|
+
codepoint = sequence.charCodeAt(i);
|
|
50
|
+
if (codepoint == 0x20 ||
|
|
51
|
+
(codepoint >= 0x61 && codepoint <= 0x66) ||
|
|
52
|
+
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
53
|
+
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
54
|
+
escapeSequence += sequence[i];
|
|
55
|
+
if (codepoint == 0x20) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
// not hex or new line
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
if (i == 1 && !isNewLine(codepoint)) {
|
|
65
|
+
buffer += sequence[i];
|
|
66
|
+
next(2);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (escapeSequence.trimEnd().length > 0) {
|
|
70
|
+
const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
|
|
71
|
+
if (codepoint == 0 ||
|
|
72
|
+
// leading surrogate
|
|
73
|
+
(0xD800 <= codepoint && codepoint <= 0xDBFF) ||
|
|
74
|
+
// trailing surrogate
|
|
75
|
+
(0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
|
|
76
|
+
buffer += String.fromCodePoint(0xFFFD);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
buffer += String.fromCodePoint(codepoint);
|
|
80
|
+
}
|
|
81
|
+
next(escapeSequence.length + 1);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// buffer += value;
|
|
85
|
+
if (ind >= iterator.length) {
|
|
86
|
+
// drop '\\' at the end
|
|
87
|
+
yield pushToken(buffer);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
buffer += next(2);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (value == quote) {
|
|
94
|
+
buffer += value;
|
|
95
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
|
|
96
|
+
next();
|
|
97
|
+
// i += value.length;
|
|
98
|
+
buffer = '';
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
if (isNewLine(value.charCodeAt(0))) {
|
|
102
|
+
hasNewLine = true;
|
|
103
|
+
}
|
|
104
|
+
if (hasNewLine && value == ';') {
|
|
105
|
+
yield pushToken(buffer, 'Bad-string');
|
|
106
|
+
buffer = '';
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
buffer += value;
|
|
110
|
+
// i += value.length;
|
|
111
|
+
next();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function peek(count = 1) {
|
|
115
|
+
if (count == 1) {
|
|
116
|
+
return iterator.charAt(ind + 1);
|
|
117
|
+
}
|
|
118
|
+
return iterator.slice(ind + 1, ind + count + 1);
|
|
119
|
+
}
|
|
120
|
+
function prev(count = 1) {
|
|
121
|
+
if (count == 1) {
|
|
122
|
+
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
123
|
+
}
|
|
124
|
+
return iterator.slice(ind - 1 - count, ind - 1);
|
|
125
|
+
}
|
|
126
|
+
function next(count = 1) {
|
|
127
|
+
let char = '';
|
|
128
|
+
while (count-- > 0 && ind < iterator.length) {
|
|
129
|
+
const codepoint = iterator.charCodeAt(++ind);
|
|
130
|
+
if (isNaN(codepoint)) {
|
|
131
|
+
return char;
|
|
132
|
+
}
|
|
133
|
+
char += iterator.charAt(ind);
|
|
134
|
+
if (isNewLine(codepoint)) {
|
|
135
|
+
lin++;
|
|
136
|
+
col = 0;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
col++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return char;
|
|
143
|
+
}
|
|
144
|
+
while (value = next()) {
|
|
145
|
+
if (ind >= iterator.length) {
|
|
146
|
+
if (buffer.length > 0) {
|
|
147
|
+
yield pushToken(buffer);
|
|
148
|
+
buffer = '';
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
153
|
+
if (buffer.length > 0) {
|
|
154
|
+
yield pushToken(buffer);
|
|
155
|
+
buffer = '';
|
|
156
|
+
}
|
|
157
|
+
while (value = next()) {
|
|
158
|
+
if (ind >= iterator.length) {
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
yield pushToken('', 'Whitespace');
|
|
166
|
+
buffer = '';
|
|
167
|
+
if (ind >= iterator.length) {
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
switch (value) {
|
|
172
|
+
case '/':
|
|
173
|
+
if (buffer.length > 0) {
|
|
174
|
+
yield pushToken(buffer);
|
|
175
|
+
buffer = '';
|
|
176
|
+
if (peek() != '*') {
|
|
177
|
+
yield pushToken(value);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
buffer += value;
|
|
182
|
+
if (peek() == '*') {
|
|
183
|
+
buffer += '*';
|
|
184
|
+
// i++;
|
|
185
|
+
next();
|
|
186
|
+
while (value = next()) {
|
|
187
|
+
if (ind >= iterator.length) {
|
|
188
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
if (value == '\\') {
|
|
192
|
+
buffer += value;
|
|
193
|
+
value = next();
|
|
194
|
+
if (ind >= iterator.length) {
|
|
195
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
buffer += value;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (value == '*') {
|
|
202
|
+
buffer += value;
|
|
203
|
+
value = next();
|
|
204
|
+
if (ind >= iterator.length) {
|
|
205
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
buffer += value;
|
|
209
|
+
if (value == '/') {
|
|
210
|
+
yield pushToken(buffer, 'Comment');
|
|
211
|
+
buffer = '';
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
buffer += value;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
case '<':
|
|
222
|
+
if (buffer.length > 0) {
|
|
223
|
+
yield pushToken(buffer);
|
|
224
|
+
buffer = '';
|
|
225
|
+
}
|
|
226
|
+
buffer += value;
|
|
227
|
+
value = next();
|
|
228
|
+
if (ind >= iterator.length) {
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
if (peek(3) == '!--') {
|
|
232
|
+
while (value = next()) {
|
|
233
|
+
if (ind >= iterator.length) {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
buffer += value;
|
|
237
|
+
if (value == '>' && prev(2) == '--') {
|
|
238
|
+
yield pushToken(buffer, 'CDOCOMM');
|
|
239
|
+
buffer = '';
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (ind >= iterator.length) {
|
|
245
|
+
yield pushToken(buffer, 'BADCDO');
|
|
246
|
+
buffer = '';
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
case '\\':
|
|
250
|
+
value = next();
|
|
251
|
+
// EOF
|
|
252
|
+
if (ind + 1 >= iterator.length) {
|
|
253
|
+
// end of stream ignore \\
|
|
254
|
+
yield pushToken(buffer);
|
|
255
|
+
buffer = '';
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
buffer += value;
|
|
259
|
+
break;
|
|
260
|
+
case '"':
|
|
261
|
+
case "'":
|
|
262
|
+
yield* consumeString(value);
|
|
263
|
+
break;
|
|
264
|
+
case '~':
|
|
265
|
+
case '|':
|
|
266
|
+
if (buffer.length > 0) {
|
|
267
|
+
yield pushToken(buffer);
|
|
268
|
+
buffer = '';
|
|
269
|
+
}
|
|
270
|
+
buffer += value;
|
|
271
|
+
value = next();
|
|
272
|
+
if (ind >= iterator.length) {
|
|
273
|
+
yield pushToken(buffer);
|
|
274
|
+
buffer = '';
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
if (value == '=') {
|
|
278
|
+
buffer += value;
|
|
279
|
+
yield pushToken(buffer, buffer[0] == '~' ? 'Includes' : 'Dash-matches');
|
|
280
|
+
buffer = '';
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
yield pushToken(buffer);
|
|
284
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
285
|
+
value = next();
|
|
286
|
+
}
|
|
287
|
+
buffer = value;
|
|
288
|
+
break;
|
|
289
|
+
case '>':
|
|
290
|
+
if (buffer !== '') {
|
|
291
|
+
yield pushToken(buffer);
|
|
292
|
+
buffer = '';
|
|
293
|
+
}
|
|
294
|
+
yield pushToken('', 'Gt');
|
|
295
|
+
consumeWhiteSpace();
|
|
296
|
+
break;
|
|
297
|
+
case '.':
|
|
298
|
+
const codepoint = peek().charCodeAt(0);
|
|
299
|
+
if (!isDigit(codepoint) && buffer !== '') {
|
|
300
|
+
yield pushToken(buffer);
|
|
301
|
+
buffer = value;
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
buffer += value;
|
|
305
|
+
break;
|
|
306
|
+
case '+':
|
|
307
|
+
case ':':
|
|
308
|
+
case ',':
|
|
309
|
+
case '=':
|
|
310
|
+
if (buffer.length > 0) {
|
|
311
|
+
yield pushToken(buffer);
|
|
312
|
+
buffer = '';
|
|
313
|
+
}
|
|
314
|
+
if (value == ':' && ':' == peek()) {
|
|
315
|
+
buffer += value + next();
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
yield pushToken(value);
|
|
319
|
+
buffer = '';
|
|
320
|
+
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
321
|
+
yield pushToken(next());
|
|
322
|
+
}
|
|
323
|
+
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
324
|
+
next();
|
|
325
|
+
}
|
|
326
|
+
break;
|
|
327
|
+
case ')':
|
|
328
|
+
if (buffer.length > 0) {
|
|
329
|
+
yield pushToken(buffer);
|
|
330
|
+
buffer = '';
|
|
331
|
+
}
|
|
332
|
+
yield pushToken('', 'End-parens');
|
|
333
|
+
break;
|
|
334
|
+
case '(':
|
|
335
|
+
if (buffer.length == 0) {
|
|
336
|
+
yield pushToken('', 'Start-parens');
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
buffer += value;
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
if (buffer == 'url(') {
|
|
342
|
+
yield pushToken(buffer);
|
|
343
|
+
buffer = '';
|
|
344
|
+
// consume either string or url token
|
|
345
|
+
let whitespace = '';
|
|
346
|
+
value = peek();
|
|
347
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
348
|
+
whitespace += value;
|
|
349
|
+
}
|
|
350
|
+
if (whitespace.length > 0) {
|
|
351
|
+
next(whitespace.length);
|
|
352
|
+
}
|
|
353
|
+
value = peek();
|
|
354
|
+
if (value == '"' || value == "'") {
|
|
355
|
+
yield* consumeString(next());
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
buffer = '';
|
|
360
|
+
do {
|
|
361
|
+
let cp = value.charCodeAt(0);
|
|
362
|
+
// EOF -
|
|
363
|
+
if (cp == null) {
|
|
364
|
+
yield pushToken('', 'Bad-url-token');
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
// ')'
|
|
368
|
+
if (cp == 0x29 || cp == null) {
|
|
369
|
+
if (buffer.length == 0) {
|
|
370
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
yield pushToken(buffer, 'Url-token');
|
|
374
|
+
}
|
|
375
|
+
if (cp != null) {
|
|
376
|
+
yield pushToken(next());
|
|
377
|
+
}
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
if (isWhiteSpace(cp)) {
|
|
381
|
+
whitespace = next();
|
|
382
|
+
while (true) {
|
|
383
|
+
value = peek();
|
|
384
|
+
cp = value.charCodeAt(0);
|
|
385
|
+
if (isWhiteSpace(cp)) {
|
|
386
|
+
whitespace += value;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
if (cp == null || cp == 0x29) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
// bad url token
|
|
395
|
+
buffer += next(whitespace.length);
|
|
396
|
+
do {
|
|
397
|
+
value = peek();
|
|
398
|
+
cp = value.charCodeAt(0);
|
|
399
|
+
if (cp == null || cp == 0x29) {
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
buffer += next();
|
|
403
|
+
} while (true);
|
|
404
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
buffer += next();
|
|
408
|
+
value = peek();
|
|
409
|
+
} while (true);
|
|
410
|
+
buffer = '';
|
|
411
|
+
}
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
yield pushToken(buffer);
|
|
415
|
+
buffer = '';
|
|
416
|
+
break;
|
|
417
|
+
case '[':
|
|
418
|
+
case ']':
|
|
419
|
+
case '{':
|
|
420
|
+
case '}':
|
|
421
|
+
case ';':
|
|
422
|
+
if (buffer.length > 0) {
|
|
423
|
+
yield pushToken(buffer);
|
|
424
|
+
buffer = '';
|
|
425
|
+
}
|
|
426
|
+
yield pushToken(value);
|
|
427
|
+
break;
|
|
428
|
+
case '!':
|
|
429
|
+
if (buffer.length > 0) {
|
|
430
|
+
yield pushToken(buffer);
|
|
431
|
+
buffer = '';
|
|
432
|
+
}
|
|
433
|
+
const important = peek(9);
|
|
434
|
+
if (important == 'important') {
|
|
435
|
+
yield pushToken('', 'Important');
|
|
436
|
+
next(9);
|
|
437
|
+
buffer = '';
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
buffer = '!';
|
|
441
|
+
break;
|
|
442
|
+
default:
|
|
443
|
+
buffer += value;
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (buffer.length > 0) {
|
|
448
|
+
yield pushToken(buffer);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export { tokenize };
|
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
function eq(a, b) {
|
|
2
|
-
if (
|
|
2
|
+
if (a == null || b == null) {
|
|
3
|
+
return a == b;
|
|
4
|
+
}
|
|
5
|
+
if (typeof a != 'object' || typeof b != 'object') {
|
|
3
6
|
return a === b;
|
|
4
7
|
}
|
|
8
|
+
if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(a)) {
|
|
12
|
+
if (a.length != b.length) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
let i = 0;
|
|
16
|
+
for (; i < a.length; i++) {
|
|
17
|
+
if (!eq(a[i], b[i])) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
5
23
|
const k1 = Object.keys(a);
|
|
6
24
|
const k2 = Object.keys(b);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
25
|
+
if (k1.length != k2.length) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
let key;
|
|
29
|
+
for (key of k1) {
|
|
30
|
+
if (!eq(a[key], b[key])) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
11
35
|
}
|
|
12
36
|
|
|
13
37
|
export { eq };
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
3
3
|
// '\\'
|
|
4
4
|
const REVERSE_SOLIDUS = 0x5c;
|
|
5
|
+
const dimensionUnits = [
|
|
6
|
+
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
7
|
+
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
8
|
+
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
9
|
+
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
10
|
+
];
|
|
5
11
|
function isLength(dimension) {
|
|
6
|
-
return 'unit' in dimension &&
|
|
7
|
-
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
8
|
-
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
9
|
-
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
10
|
-
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
11
|
-
].includes(dimension.unit.toLowerCase());
|
|
12
|
+
return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
|
|
12
13
|
}
|
|
13
14
|
function isResolution(dimension) {
|
|
14
15
|
return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
|
|
@@ -233,6 +234,22 @@ function isHexColor(name) {
|
|
|
233
234
|
}
|
|
234
235
|
return true;
|
|
235
236
|
}
|
|
237
|
+
function isHexDigit(name) {
|
|
238
|
+
if (name.length || name.length > 6) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
for (let chr of name) {
|
|
242
|
+
let codepoint = chr.charCodeAt(0);
|
|
243
|
+
if (!isDigit(codepoint) &&
|
|
244
|
+
// A F
|
|
245
|
+
!(codepoint >= 0x41 && codepoint <= 0x46) &&
|
|
246
|
+
// a f
|
|
247
|
+
!(codepoint >= 0x61 && codepoint <= 0x66)) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
236
253
|
function isFunction(name) {
|
|
237
254
|
return name.endsWith('(') && isIdent(name.slice(0, -1));
|
|
238
255
|
}
|
|
@@ -249,4 +266,4 @@ function isWhiteSpace(codepoint) {
|
|
|
249
266
|
codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
|
|
250
267
|
}
|
|
251
268
|
|
|
252
|
-
export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|
|
269
|
+
export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
|
|
1
|
+
import { COLORS_NAMES, rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
|
|
2
2
|
|
|
3
3
|
function render(data, opt = {}) {
|
|
4
|
-
const options = Object.assign(opt.
|
|
4
|
+
const options = Object.assign(opt.minify ?? true ? {
|
|
5
5
|
indent: '',
|
|
6
6
|
newLine: '',
|
|
7
7
|
removeComments: true
|
|
@@ -86,8 +86,11 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
86
86
|
function renderToken(token, options = {}) {
|
|
87
87
|
switch (token.typ) {
|
|
88
88
|
case 'Color':
|
|
89
|
-
if (options.
|
|
90
|
-
|
|
89
|
+
if (options.minify || options.colorConvert) {
|
|
90
|
+
if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
|
|
91
|
+
return 'currentcolor';
|
|
92
|
+
}
|
|
93
|
+
let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
|
|
91
94
|
if (token.val == 'rgb' || token.val == 'rgba') {
|
|
92
95
|
value = rgb2Hex(token);
|
|
93
96
|
}
|
|
@@ -131,7 +134,7 @@ function renderToken(token, options = {}) {
|
|
|
131
134
|
case 'UrlFunc':
|
|
132
135
|
case 'Pseudo-class-func':
|
|
133
136
|
// @ts-ignore
|
|
134
|
-
return ( /* options.
|
|
137
|
+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
|
|
135
138
|
if (options.removeComments && curr.typ == 'Comment') {
|
|
136
139
|
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
137
140
|
return acc;
|
|
@@ -222,7 +225,7 @@ function renderToken(token, options = {}) {
|
|
|
222
225
|
case 'String':
|
|
223
226
|
case 'Iden':
|
|
224
227
|
case 'Delim':
|
|
225
|
-
return /* options.
|
|
228
|
+
return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
|
|
226
229
|
}
|
|
227
230
|
throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
228
231
|
}
|
package/dist/lib/transform.js
CHANGED
|
@@ -2,7 +2,7 @@ import { parse } from './parser/parse.js';
|
|
|
2
2
|
import { render } from './renderer/render.js';
|
|
3
3
|
|
|
4
4
|
async function transform(css, options = {}) {
|
|
5
|
-
options = {
|
|
5
|
+
options = { minify: true, removeEmpty: true, ...options };
|
|
6
6
|
const startTime = performance.now();
|
|
7
7
|
const parseResult = await parse(css, options);
|
|
8
8
|
const renderTime = performance.now();
|
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parse as parse$1 } from '../lib/parser/parse.js';
|
|
2
|
+
export { parseString, urlTokenMatcher } from '../lib/parser/parse.js';
|
|
2
3
|
import '../lib/renderer/utils/color.js';
|
|
3
4
|
import { transform as transform$1 } from '../lib/transform.js';
|
|
4
5
|
import { load } from './load.js';
|
package/dist/web/index.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { parse as parse$1 } from '../lib/parser/parse.js';
|
|
2
|
-
export {
|
|
2
|
+
export { parseString, urlTokenMatcher } from '../lib/parser/parse.js';
|
|
3
|
+
export { tokenize } from '../lib/parser/tokenize.js';
|
|
4
|
+
export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension } from '../lib/parser/utils/syntax.js';
|
|
5
|
+
export { getConfig } from '../lib/parser/utils/config.js';
|
|
3
6
|
export { render, renderToken } from '../lib/renderer/render.js';
|
|
4
|
-
export { walk } from '../lib/walker/walk.js';
|
|
5
7
|
import { transform as transform$1 } from '../lib/transform.js';
|
|
8
|
+
export { combinators, hasDeclaration, minify, minifyRule, reduceSelector } from '../lib/ast/minify.js';
|
|
9
|
+
export { walk } from '../lib/ast/walk.js';
|
|
6
10
|
import { load } from './load.js';
|
|
7
11
|
import { resolve, dirname } from '../lib/fs/resolve.js';
|
|
8
12
|
export { matchUrl } from '../lib/fs/resolve.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tbela99/css-parser",
|
|
3
3
|
"description": "CSS parser for node and the browser",
|
|
4
|
-
"version": "0.0.1-
|
|
4
|
+
"version": "0.0.1-rc1",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
7
7
|
"./web": "./dist/web/index.js",
|
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
"typings": "dist/index.d.ts",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "rollup -c",
|
|
14
|
-
"
|
|
15
|
-
"test": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir
|
|
16
|
-
"
|
|
14
|
+
"test": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir=.; mocha --reporter-options='maxDiffSize=1801920' \"test/**/*.spec.js\"",
|
|
15
|
+
"test:cov": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir=. --coverage; c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' \"test/**/*.spec.js\"",
|
|
16
|
+
"profile": "node --inspect-brk test/inspect.mjs",
|
|
17
|
+
"debug": "web-test-runner \"test/**/*.web.js\" --manual --open --node-resolve --root-dir=."
|
|
17
18
|
},
|
|
18
19
|
"repository": {
|
|
19
20
|
"type": "git",
|
|
@@ -22,9 +23,14 @@
|
|
|
22
23
|
"keywords": [
|
|
23
24
|
"parser",
|
|
24
25
|
"css",
|
|
26
|
+
"css parser",
|
|
25
27
|
"css-parser",
|
|
26
28
|
"node",
|
|
27
|
-
"
|
|
29
|
+
"ast",
|
|
30
|
+
"browser",
|
|
31
|
+
"css nesting",
|
|
32
|
+
"css compiler",
|
|
33
|
+
"nested css"
|
|
28
34
|
],
|
|
29
35
|
"author": "Thierry Bela",
|
|
30
36
|
"license": "MIT OR LGPL-3.0",
|
|
File without changes
|