@tbela99/css-parser 0.0.1-alpha4 → 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 +3 -0
- package/README.md +20 -6
- package/dist/config.json.js +95 -4
- package/dist/index-umd-web.js +1885 -1385
- package/dist/index.cjs +1885 -1385
- package/dist/index.d.ts +333 -14
- package/dist/index.js +6 -2
- package/dist/lib/ast/minify.js +796 -0
- package/dist/lib/{walker → ast}/walk.js +1 -1
- 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 +241 -663
- 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 +14 -28
- package/dist/lib/transform.js +1 -1
- package/dist/node/index.js +1 -0
- package/dist/web/index.js +6 -2
- package/package.json +12 -5
- package/dist/lib/parser/deduplicate.js +0 -542
|
@@ -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,8 +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
|
-
const indents = [];
|
|
4
3
|
function render(data, opt = {}) {
|
|
5
|
-
const options = Object.assign(opt.
|
|
4
|
+
const options = Object.assign(opt.minify ?? true ? {
|
|
6
5
|
indent: '',
|
|
7
6
|
newLine: '',
|
|
8
7
|
removeComments: true
|
|
@@ -18,27 +17,12 @@ function render(data, opt = {}) {
|
|
|
18
17
|
return acc;
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
|
-
// if (options.compress && curr.typ == 'Whitespace') {
|
|
22
|
-
//
|
|
23
|
-
// if (original[index + 1]?.typ == 'Start-parens' ||
|
|
24
|
-
// (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
|
|
25
|
-
// original[index - 1].typ == 'End-parens' ||
|
|
26
|
-
// original[index - 1].typ == 'UrlFunc' ||
|
|
27
|
-
// original[index - 1].typ == 'Func' ||
|
|
28
|
-
// (
|
|
29
|
-
// original[index - 1].typ == 'Color' &&
|
|
30
|
-
// (<ColorToken>original[index - 1]).kin != 'hex' &&
|
|
31
|
-
// (<ColorToken>original[index - 1]).kin != 'lit')))) {
|
|
32
|
-
//
|
|
33
|
-
// return acc;
|
|
34
|
-
// }
|
|
35
|
-
// }
|
|
36
20
|
return acc + renderToken(curr, options);
|
|
37
21
|
}
|
|
38
|
-
return { code: doRender(data, options, reducer) };
|
|
22
|
+
return { code: doRender(data, options, reducer, 0) };
|
|
39
23
|
}
|
|
40
24
|
// @ts-ignore
|
|
41
|
-
function doRender(data, options, reducer, level = 0) {
|
|
25
|
+
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
42
26
|
if (indents.length < level + 1) {
|
|
43
27
|
indents.push(options.indent.repeat(level));
|
|
44
28
|
}
|
|
@@ -52,7 +36,7 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
52
36
|
return options.removeComments ? '' : data.val;
|
|
53
37
|
case 'StyleSheet':
|
|
54
38
|
return data.chi.reduce((css, node) => {
|
|
55
|
-
const str = doRender(node, options, reducer, level);
|
|
39
|
+
const str = doRender(node, options, reducer, level, indents);
|
|
56
40
|
if (str === '') {
|
|
57
41
|
return css;
|
|
58
42
|
}
|
|
@@ -79,7 +63,7 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
79
63
|
str = `@${node.nam} ${node.val};`;
|
|
80
64
|
}
|
|
81
65
|
else {
|
|
82
|
-
str = doRender(node, options, reducer, level + 1);
|
|
66
|
+
str = doRender(node, options, reducer, level + 1, indents);
|
|
83
67
|
}
|
|
84
68
|
if (css === '') {
|
|
85
69
|
return str;
|
|
@@ -87,8 +71,7 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
87
71
|
if (str === '') {
|
|
88
72
|
return css;
|
|
89
73
|
}
|
|
90
|
-
|
|
91
|
-
return `${css}${options.newLine}${indentSub}${str}`;
|
|
74
|
+
return `${css}${options.newLine}${indentSub}${str}`;
|
|
92
75
|
}, '');
|
|
93
76
|
if (children.endsWith(';')) {
|
|
94
77
|
children = children.slice(0, -1);
|
|
@@ -103,8 +86,11 @@ function doRender(data, options, reducer, level = 0) {
|
|
|
103
86
|
function renderToken(token, options = {}) {
|
|
104
87
|
switch (token.typ) {
|
|
105
88
|
case 'Color':
|
|
106
|
-
if (options.
|
|
107
|
-
|
|
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()] : '');
|
|
108
94
|
if (token.val == 'rgb' || token.val == 'rgba') {
|
|
109
95
|
value = rgb2Hex(token);
|
|
110
96
|
}
|
|
@@ -148,7 +134,7 @@ function renderToken(token, options = {}) {
|
|
|
148
134
|
case 'UrlFunc':
|
|
149
135
|
case 'Pseudo-class-func':
|
|
150
136
|
// @ts-ignore
|
|
151
|
-
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) => {
|
|
152
138
|
if (options.removeComments && curr.typ == 'Comment') {
|
|
153
139
|
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
154
140
|
return acc;
|
|
@@ -239,7 +225,7 @@ function renderToken(token, options = {}) {
|
|
|
239
225
|
case 'String':
|
|
240
226
|
case 'Iden':
|
|
241
227
|
case 'Delim':
|
|
242
|
-
return /* options.
|
|
228
|
+
return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
|
|
243
229
|
}
|
|
244
230
|
throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
245
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';
|