@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
package/dist/index-umd-web.js
CHANGED
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
9
9
|
// '\\'
|
|
10
10
|
const REVERSE_SOLIDUS = 0x5c;
|
|
11
|
+
const dimensionUnits = [
|
|
12
|
+
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
13
|
+
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
14
|
+
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
15
|
+
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
16
|
+
];
|
|
11
17
|
function isLength(dimension) {
|
|
12
|
-
return 'unit' in dimension &&
|
|
13
|
-
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
14
|
-
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
15
|
-
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
16
|
-
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
17
|
-
].includes(dimension.unit.toLowerCase());
|
|
18
|
+
return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
|
|
18
19
|
}
|
|
19
20
|
function isResolution(dimension) {
|
|
20
21
|
return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
|
|
@@ -239,6 +240,22 @@
|
|
|
239
240
|
}
|
|
240
241
|
return true;
|
|
241
242
|
}
|
|
243
|
+
function isHexDigit(name) {
|
|
244
|
+
if (name.length || name.length > 6) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
for (let chr of name) {
|
|
248
|
+
let codepoint = chr.charCodeAt(0);
|
|
249
|
+
if (!isDigit(codepoint) &&
|
|
250
|
+
// A F
|
|
251
|
+
!(codepoint >= 0x41 && codepoint <= 0x46) &&
|
|
252
|
+
// a f
|
|
253
|
+
!(codepoint >= 0x61 && codepoint <= 0x66)) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
242
259
|
function isFunction(name) {
|
|
243
260
|
return name.endsWith('(') && isIdent(name.slice(0, -1));
|
|
244
261
|
}
|
|
@@ -374,6 +391,7 @@
|
|
|
374
391
|
},
|
|
375
392
|
"border-width": {
|
|
376
393
|
shorthand: "border-width",
|
|
394
|
+
map: "border",
|
|
377
395
|
properties: [
|
|
378
396
|
"border-top-width",
|
|
379
397
|
"border-right-width",
|
|
@@ -384,6 +402,9 @@
|
|
|
384
402
|
"Length",
|
|
385
403
|
"Perc"
|
|
386
404
|
],
|
|
405
|
+
"default": [
|
|
406
|
+
"medium"
|
|
407
|
+
],
|
|
387
408
|
keywords: [
|
|
388
409
|
"thin",
|
|
389
410
|
"medium",
|
|
@@ -391,19 +412,24 @@
|
|
|
391
412
|
]
|
|
392
413
|
},
|
|
393
414
|
"border-top-width": {
|
|
415
|
+
map: "border",
|
|
394
416
|
shorthand: "border-width"
|
|
395
417
|
},
|
|
396
418
|
"border-right-width": {
|
|
419
|
+
map: "border",
|
|
397
420
|
shorthand: "border-width"
|
|
398
421
|
},
|
|
399
422
|
"border-bottom-width": {
|
|
423
|
+
map: "border",
|
|
400
424
|
shorthand: "border-width"
|
|
401
425
|
},
|
|
402
426
|
"border-left-width": {
|
|
427
|
+
map: "border",
|
|
403
428
|
shorthand: "border-width"
|
|
404
429
|
},
|
|
405
430
|
"border-style": {
|
|
406
431
|
shorthand: "border-style",
|
|
432
|
+
map: "border",
|
|
407
433
|
properties: [
|
|
408
434
|
"border-top-style",
|
|
409
435
|
"border-right-style",
|
|
@@ -412,6 +438,9 @@
|
|
|
412
438
|
],
|
|
413
439
|
types: [
|
|
414
440
|
],
|
|
441
|
+
"default": [
|
|
442
|
+
"none"
|
|
443
|
+
],
|
|
415
444
|
keywords: [
|
|
416
445
|
"none",
|
|
417
446
|
"hidden",
|
|
@@ -426,19 +455,24 @@
|
|
|
426
455
|
]
|
|
427
456
|
},
|
|
428
457
|
"border-top-style": {
|
|
458
|
+
map: "border",
|
|
429
459
|
shorthand: "border-style"
|
|
430
460
|
},
|
|
431
461
|
"border-right-style": {
|
|
462
|
+
map: "border",
|
|
432
463
|
shorthand: "border-style"
|
|
433
464
|
},
|
|
434
465
|
"border-bottom-style": {
|
|
466
|
+
map: "border",
|
|
435
467
|
shorthand: "border-style"
|
|
436
468
|
},
|
|
437
469
|
"border-left-style": {
|
|
470
|
+
map: "border",
|
|
438
471
|
shorthand: "border-style"
|
|
439
472
|
},
|
|
440
473
|
"border-color": {
|
|
441
474
|
shorthand: "border-color",
|
|
475
|
+
map: "border",
|
|
442
476
|
properties: [
|
|
443
477
|
"border-top-color",
|
|
444
478
|
"border-right-color",
|
|
@@ -448,23 +482,95 @@
|
|
|
448
482
|
types: [
|
|
449
483
|
"Color"
|
|
450
484
|
],
|
|
485
|
+
"default": [
|
|
486
|
+
"currentcolor"
|
|
487
|
+
],
|
|
451
488
|
keywords: [
|
|
452
489
|
]
|
|
453
490
|
},
|
|
454
491
|
"border-top-color": {
|
|
492
|
+
map: "border",
|
|
455
493
|
shorthand: "border-color"
|
|
456
494
|
},
|
|
457
495
|
"border-right-color": {
|
|
496
|
+
map: "border",
|
|
458
497
|
shorthand: "border-color"
|
|
459
498
|
},
|
|
460
499
|
"border-bottom-color": {
|
|
500
|
+
map: "border",
|
|
461
501
|
shorthand: "border-color"
|
|
462
502
|
},
|
|
463
503
|
"border-left-color": {
|
|
504
|
+
map: "border",
|
|
464
505
|
shorthand: "border-color"
|
|
465
506
|
}
|
|
466
507
|
};
|
|
467
508
|
var map = {
|
|
509
|
+
border: {
|
|
510
|
+
shorthand: "border",
|
|
511
|
+
pattern: "border-color border-style border-width",
|
|
512
|
+
keywords: [
|
|
513
|
+
"none"
|
|
514
|
+
],
|
|
515
|
+
"default": [
|
|
516
|
+
"0",
|
|
517
|
+
"none"
|
|
518
|
+
],
|
|
519
|
+
properties: {
|
|
520
|
+
"border-color": {
|
|
521
|
+
types: [
|
|
522
|
+
"Color"
|
|
523
|
+
],
|
|
524
|
+
"default": [
|
|
525
|
+
"currentcolor"
|
|
526
|
+
],
|
|
527
|
+
keywords: [
|
|
528
|
+
]
|
|
529
|
+
},
|
|
530
|
+
"border-style": {
|
|
531
|
+
types: [
|
|
532
|
+
],
|
|
533
|
+
"default": [
|
|
534
|
+
"none"
|
|
535
|
+
],
|
|
536
|
+
keywords: [
|
|
537
|
+
"none",
|
|
538
|
+
"hidden",
|
|
539
|
+
"dotted",
|
|
540
|
+
"dashed",
|
|
541
|
+
"solid",
|
|
542
|
+
"double",
|
|
543
|
+
"groove",
|
|
544
|
+
"ridge",
|
|
545
|
+
"inset",
|
|
546
|
+
"outset"
|
|
547
|
+
]
|
|
548
|
+
},
|
|
549
|
+
"border-width": {
|
|
550
|
+
types: [
|
|
551
|
+
"Length",
|
|
552
|
+
"Perc"
|
|
553
|
+
],
|
|
554
|
+
"default": [
|
|
555
|
+
"medium"
|
|
556
|
+
],
|
|
557
|
+
keywords: [
|
|
558
|
+
"thin",
|
|
559
|
+
"medium",
|
|
560
|
+
"thick"
|
|
561
|
+
]
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
"border-color": {
|
|
566
|
+
shorthand: "border"
|
|
567
|
+
},
|
|
568
|
+
"border-style": {
|
|
569
|
+
shorthand: "border"
|
|
570
|
+
},
|
|
571
|
+
"border-width": {
|
|
572
|
+
shorthand: "border"
|
|
573
|
+
},
|
|
468
574
|
outline: {
|
|
469
575
|
shorthand: "outline",
|
|
470
576
|
pattern: "outline-color outline-style outline-width",
|
|
@@ -481,12 +587,10 @@
|
|
|
481
587
|
"Color"
|
|
482
588
|
],
|
|
483
589
|
"default": [
|
|
484
|
-
"currentColor"
|
|
485
|
-
"invert"
|
|
590
|
+
"currentColor"
|
|
486
591
|
],
|
|
487
592
|
keywords: [
|
|
488
|
-
"currentColor"
|
|
489
|
-
"invert"
|
|
593
|
+
"currentColor"
|
|
490
594
|
]
|
|
491
595
|
},
|
|
492
596
|
"outline-style": {
|
|
@@ -824,6 +928,7 @@
|
|
|
824
928
|
"default": [
|
|
825
929
|
"transparent"
|
|
826
930
|
],
|
|
931
|
+
multiple: true,
|
|
827
932
|
keywords: [
|
|
828
933
|
]
|
|
829
934
|
},
|
|
@@ -844,6 +949,7 @@
|
|
|
844
949
|
"default": [
|
|
845
950
|
"scroll"
|
|
846
951
|
],
|
|
952
|
+
multiple: true,
|
|
847
953
|
keywords: [
|
|
848
954
|
"scroll",
|
|
849
955
|
"fixed",
|
|
@@ -856,6 +962,7 @@
|
|
|
856
962
|
"default": [
|
|
857
963
|
"border-box"
|
|
858
964
|
],
|
|
965
|
+
multiple: true,
|
|
859
966
|
keywords: [
|
|
860
967
|
"border-box",
|
|
861
968
|
"padding-box",
|
|
@@ -869,6 +976,7 @@
|
|
|
869
976
|
"default": [
|
|
870
977
|
"padding-box"
|
|
871
978
|
],
|
|
979
|
+
multiple: true,
|
|
872
980
|
keywords: [
|
|
873
981
|
"border-box",
|
|
874
982
|
"padding-box",
|
|
@@ -1457,9 +1565,8 @@
|
|
|
1457
1565
|
return values;
|
|
1458
1566
|
}
|
|
1459
1567
|
|
|
1460
|
-
const indents = [];
|
|
1461
1568
|
function render(data, opt = {}) {
|
|
1462
|
-
const options = Object.assign(opt.
|
|
1569
|
+
const options = Object.assign(opt.minify ?? true ? {
|
|
1463
1570
|
indent: '',
|
|
1464
1571
|
newLine: '',
|
|
1465
1572
|
removeComments: true
|
|
@@ -1475,27 +1582,12 @@
|
|
|
1475
1582
|
return acc;
|
|
1476
1583
|
}
|
|
1477
1584
|
}
|
|
1478
|
-
// if (options.compress && curr.typ == 'Whitespace') {
|
|
1479
|
-
//
|
|
1480
|
-
// if (original[index + 1]?.typ == 'Start-parens' ||
|
|
1481
|
-
// (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
|
|
1482
|
-
// original[index - 1].typ == 'End-parens' ||
|
|
1483
|
-
// original[index - 1].typ == 'UrlFunc' ||
|
|
1484
|
-
// original[index - 1].typ == 'Func' ||
|
|
1485
|
-
// (
|
|
1486
|
-
// original[index - 1].typ == 'Color' &&
|
|
1487
|
-
// (<ColorToken>original[index - 1]).kin != 'hex' &&
|
|
1488
|
-
// (<ColorToken>original[index - 1]).kin != 'lit')))) {
|
|
1489
|
-
//
|
|
1490
|
-
// return acc;
|
|
1491
|
-
// }
|
|
1492
|
-
// }
|
|
1493
1585
|
return acc + renderToken(curr, options);
|
|
1494
1586
|
}
|
|
1495
|
-
return { code: doRender(data, options, reducer) };
|
|
1587
|
+
return { code: doRender(data, options, reducer, 0) };
|
|
1496
1588
|
}
|
|
1497
1589
|
// @ts-ignore
|
|
1498
|
-
function doRender(data, options, reducer, level = 0) {
|
|
1590
|
+
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
1499
1591
|
if (indents.length < level + 1) {
|
|
1500
1592
|
indents.push(options.indent.repeat(level));
|
|
1501
1593
|
}
|
|
@@ -1509,7 +1601,7 @@
|
|
|
1509
1601
|
return options.removeComments ? '' : data.val;
|
|
1510
1602
|
case 'StyleSheet':
|
|
1511
1603
|
return data.chi.reduce((css, node) => {
|
|
1512
|
-
const str = doRender(node, options, reducer, level);
|
|
1604
|
+
const str = doRender(node, options, reducer, level, indents);
|
|
1513
1605
|
if (str === '') {
|
|
1514
1606
|
return css;
|
|
1515
1607
|
}
|
|
@@ -1536,7 +1628,7 @@
|
|
|
1536
1628
|
str = `@${node.nam} ${node.val};`;
|
|
1537
1629
|
}
|
|
1538
1630
|
else {
|
|
1539
|
-
str = doRender(node, options, reducer, level + 1);
|
|
1631
|
+
str = doRender(node, options, reducer, level + 1, indents);
|
|
1540
1632
|
}
|
|
1541
1633
|
if (css === '') {
|
|
1542
1634
|
return str;
|
|
@@ -1544,8 +1636,7 @@
|
|
|
1544
1636
|
if (str === '') {
|
|
1545
1637
|
return css;
|
|
1546
1638
|
}
|
|
1547
|
-
|
|
1548
|
-
return `${css}${options.newLine}${indentSub}${str}`;
|
|
1639
|
+
return `${css}${options.newLine}${indentSub}${str}`;
|
|
1549
1640
|
}, '');
|
|
1550
1641
|
if (children.endsWith(';')) {
|
|
1551
1642
|
children = children.slice(0, -1);
|
|
@@ -1560,8 +1651,11 @@
|
|
|
1560
1651
|
function renderToken(token, options = {}) {
|
|
1561
1652
|
switch (token.typ) {
|
|
1562
1653
|
case 'Color':
|
|
1563
|
-
if (options.
|
|
1564
|
-
|
|
1654
|
+
if (options.minify || options.colorConvert) {
|
|
1655
|
+
if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
|
|
1656
|
+
return 'currentcolor';
|
|
1657
|
+
}
|
|
1658
|
+
let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
|
|
1565
1659
|
if (token.val == 'rgb' || token.val == 'rgba') {
|
|
1566
1660
|
value = rgb2Hex(token);
|
|
1567
1661
|
}
|
|
@@ -1605,7 +1699,7 @@
|
|
|
1605
1699
|
case 'UrlFunc':
|
|
1606
1700
|
case 'Pseudo-class-func':
|
|
1607
1701
|
// @ts-ignore
|
|
1608
|
-
return ( /* options.
|
|
1702
|
+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
|
|
1609
1703
|
if (options.removeComments && curr.typ == 'Comment') {
|
|
1610
1704
|
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1611
1705
|
return acc;
|
|
@@ -1696,21 +1790,45 @@
|
|
|
1696
1790
|
case 'String':
|
|
1697
1791
|
case 'Iden':
|
|
1698
1792
|
case 'Delim':
|
|
1699
|
-
return /* options.
|
|
1793
|
+
return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
|
|
1700
1794
|
}
|
|
1701
1795
|
throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
1702
1796
|
}
|
|
1703
1797
|
|
|
1704
1798
|
function eq(a, b) {
|
|
1705
|
-
if (
|
|
1799
|
+
if (a == null || b == null) {
|
|
1800
|
+
return a == b;
|
|
1801
|
+
}
|
|
1802
|
+
if (typeof a != 'object' || typeof b != 'object') {
|
|
1706
1803
|
return a === b;
|
|
1707
1804
|
}
|
|
1805
|
+
if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) {
|
|
1806
|
+
return false;
|
|
1807
|
+
}
|
|
1808
|
+
if (Array.isArray(a)) {
|
|
1809
|
+
if (a.length != b.length) {
|
|
1810
|
+
return false;
|
|
1811
|
+
}
|
|
1812
|
+
let i = 0;
|
|
1813
|
+
for (; i < a.length; i++) {
|
|
1814
|
+
if (!eq(a[i], b[i])) {
|
|
1815
|
+
return false;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
return true;
|
|
1819
|
+
}
|
|
1708
1820
|
const k1 = Object.keys(a);
|
|
1709
1821
|
const k2 = Object.keys(b);
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1822
|
+
if (k1.length != k2.length) {
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
let key;
|
|
1826
|
+
for (key of k1) {
|
|
1827
|
+
if (!eq(a[key], b[key])) {
|
|
1828
|
+
return false;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
return true;
|
|
1714
1832
|
}
|
|
1715
1833
|
|
|
1716
1834
|
class PropertySet {
|
|
@@ -1722,8 +1840,7 @@
|
|
|
1722
1840
|
}
|
|
1723
1841
|
add(declaration) {
|
|
1724
1842
|
if (declaration.nam == this.config.shorthand) {
|
|
1725
|
-
this.declarations
|
|
1726
|
-
this.declarations.set(declaration.nam, declaration);
|
|
1843
|
+
this.declarations = new Map;
|
|
1727
1844
|
}
|
|
1728
1845
|
else {
|
|
1729
1846
|
// expand shorthand
|
|
@@ -1746,6 +1863,10 @@
|
|
|
1746
1863
|
}
|
|
1747
1864
|
if (token.typ != 'Whitespace' && token.typ != 'Comment') {
|
|
1748
1865
|
if (token.typ == 'Iden' && this.config.keywords.includes(token.val)) {
|
|
1866
|
+
if (tokens.length == 0) {
|
|
1867
|
+
tokens.push([]);
|
|
1868
|
+
current++;
|
|
1869
|
+
}
|
|
1749
1870
|
tokens[current].push(token);
|
|
1750
1871
|
}
|
|
1751
1872
|
if (token.typ == 'Literal' && token.val == this.config.separator) {
|
|
@@ -1761,10 +1882,6 @@
|
|
|
1761
1882
|
this.declarations.delete(this.config.shorthand);
|
|
1762
1883
|
for (const values of tokens) {
|
|
1763
1884
|
this.config.properties.forEach((property, index) => {
|
|
1764
|
-
// if (property == declaration.nam) {
|
|
1765
|
-
//
|
|
1766
|
-
// return;
|
|
1767
|
-
// }
|
|
1768
1885
|
if (!this.declarations.has(property)) {
|
|
1769
1886
|
this.declarations.set(property, {
|
|
1770
1887
|
typ: 'Declaration',
|
|
@@ -1793,30 +1910,20 @@
|
|
|
1793
1910
|
this.declarations.set(declaration.nam, declaration);
|
|
1794
1911
|
return this;
|
|
1795
1912
|
}
|
|
1796
|
-
// declaration.chi = declaration.chi.reduce((acc: Token[], token: Token) => {
|
|
1797
|
-
//
|
|
1798
|
-
// if (this.config.types.includes(token.typ) || ('0' == (<DimensionToken>token).chi && (
|
|
1799
|
-
// this.config.types.includes('Length') ||
|
|
1800
|
-
// this.config.types.includes('Angle') ||
|
|
1801
|
-
// this.config.types.includes('Dimension'))) || (token.typ == 'Iden' && this.config.keywords.includes(token.chi))) {
|
|
1802
|
-
//
|
|
1803
|
-
// acc.push(token);
|
|
1804
|
-
// }
|
|
1805
|
-
//
|
|
1806
|
-
// return acc;
|
|
1807
|
-
// }, <Token[]>[]);
|
|
1808
|
-
this.declarations.set(declaration.nam, declaration);
|
|
1809
1913
|
}
|
|
1914
|
+
this.declarations.set(declaration.nam, declaration);
|
|
1810
1915
|
return this;
|
|
1811
1916
|
}
|
|
1917
|
+
isShortHand() {
|
|
1918
|
+
if (this.declarations.has(this.config.shorthand)) {
|
|
1919
|
+
return this.declarations.size == 1;
|
|
1920
|
+
}
|
|
1921
|
+
return this.config.properties.length == this.declarations.size;
|
|
1922
|
+
}
|
|
1812
1923
|
[Symbol.iterator]() {
|
|
1813
1924
|
let iterator;
|
|
1814
1925
|
const declarations = this.declarations;
|
|
1815
|
-
if (declarations.size < this.config.properties.length
|
|
1816
|
-
return !declarations.has(property) || (index > 0 &&
|
|
1817
|
-
// @ts-ignore
|
|
1818
|
-
declarations.get(property).val.length != declarations.get(this.config.properties[Math.floor(index / 2)]).val.length);
|
|
1819
|
-
})) {
|
|
1926
|
+
if (declarations.size < this.config.properties.length) {
|
|
1820
1927
|
iterator = declarations.values();
|
|
1821
1928
|
}
|
|
1822
1929
|
else {
|
|
@@ -1874,17 +1981,20 @@
|
|
|
1874
1981
|
return acc;
|
|
1875
1982
|
}, [])
|
|
1876
1983
|
}][Symbol.iterator]();
|
|
1877
|
-
return {
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
}
|
|
1984
|
+
// return {
|
|
1985
|
+
// next() {
|
|
1986
|
+
//
|
|
1987
|
+
// return iterator.next();
|
|
1988
|
+
// }
|
|
1989
|
+
// }
|
|
1882
1990
|
}
|
|
1883
|
-
return
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1991
|
+
return iterator;
|
|
1992
|
+
// return {
|
|
1993
|
+
// next() {
|
|
1994
|
+
//
|
|
1995
|
+
// return iterator.next();
|
|
1996
|
+
// }
|
|
1997
|
+
// }
|
|
1888
1998
|
}
|
|
1889
1999
|
}
|
|
1890
2000
|
|
|
@@ -1899,34 +2009,7 @@
|
|
|
1899
2009
|
return false;
|
|
1900
2010
|
}
|
|
1901
2011
|
|
|
1902
|
-
|
|
1903
|
-
if (val == 'transparent' || val == 'currentcolor') {
|
|
1904
|
-
return {
|
|
1905
|
-
typ: 'Color',
|
|
1906
|
-
val,
|
|
1907
|
-
kin: 'lit'
|
|
1908
|
-
};
|
|
1909
|
-
}
|
|
1910
|
-
if (val.endsWith('%')) {
|
|
1911
|
-
return {
|
|
1912
|
-
typ: 'Perc',
|
|
1913
|
-
val: val.slice(0, -1)
|
|
1914
|
-
};
|
|
1915
|
-
}
|
|
1916
|
-
return {
|
|
1917
|
-
typ: isNumber(val) ? 'Number' : 'Iden',
|
|
1918
|
-
val
|
|
1919
|
-
};
|
|
1920
|
-
}
|
|
1921
|
-
function parseString(val) {
|
|
1922
|
-
return val.split(/\s/).map(getTokenType).reduce((acc, curr) => {
|
|
1923
|
-
if (acc.length > 0) {
|
|
1924
|
-
acc.push({ typ: 'Whitespace' });
|
|
1925
|
-
}
|
|
1926
|
-
acc.push(curr);
|
|
1927
|
-
return acc;
|
|
1928
|
-
}, []);
|
|
1929
|
-
}
|
|
2012
|
+
const propertiesConfig = getConfig();
|
|
1930
2013
|
class PropertyMap {
|
|
1931
2014
|
config;
|
|
1932
2015
|
declarations;
|
|
@@ -1941,7 +2024,7 @@
|
|
|
1941
2024
|
}
|
|
1942
2025
|
add(declaration) {
|
|
1943
2026
|
if (declaration.nam == this.config.shorthand) {
|
|
1944
|
-
this.declarations
|
|
2027
|
+
this.declarations = new Map;
|
|
1945
2028
|
this.declarations.set(declaration.nam, declaration);
|
|
1946
2029
|
}
|
|
1947
2030
|
else {
|
|
@@ -2018,8 +2101,7 @@
|
|
|
2018
2101
|
const defaults = parseString(props.default[0]);
|
|
2019
2102
|
if (!(property in tokens)) {
|
|
2020
2103
|
tokens[property] = [
|
|
2021
|
-
[...defaults
|
|
2022
|
-
]
|
|
2104
|
+
[...defaults]
|
|
2023
2105
|
];
|
|
2024
2106
|
}
|
|
2025
2107
|
else {
|
|
@@ -2053,145 +2135,229 @@
|
|
|
2053
2135
|
}, new Map);
|
|
2054
2136
|
}
|
|
2055
2137
|
}
|
|
2056
|
-
|
|
2138
|
+
// @ts-ignore
|
|
2139
|
+
const config = propertiesConfig.properties[declaration.nam];
|
|
2140
|
+
let property = declaration.nam;
|
|
2141
|
+
if (config != null) {
|
|
2142
|
+
property = config.shorthand;
|
|
2143
|
+
let value = this.declarations.get(property);
|
|
2144
|
+
if (!(value instanceof PropertySet)) {
|
|
2145
|
+
// @ts-ignore
|
|
2146
|
+
this.declarations.set(property, new PropertySet(propertiesConfig.properties[config.shorthand]));
|
|
2147
|
+
// Token[]
|
|
2148
|
+
if (value != null) {
|
|
2149
|
+
// @ts-ignore
|
|
2150
|
+
this.declarations.get(property).add(value);
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
this.declarations.get(property).add(declaration);
|
|
2154
|
+
}
|
|
2155
|
+
else {
|
|
2156
|
+
this.declarations.set(declaration.nam, declaration);
|
|
2157
|
+
}
|
|
2057
2158
|
}
|
|
2058
2159
|
return this;
|
|
2059
2160
|
}
|
|
2060
2161
|
[Symbol.iterator]() {
|
|
2061
|
-
let
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
return this.declarations.values();
|
|
2071
|
-
}
|
|
2072
|
-
let count = 0;
|
|
2073
|
-
const separator = this.config.separator;
|
|
2074
|
-
const tokens = {};
|
|
2075
|
-
// @ts-ignore
|
|
2076
|
-
const valid = Object.entries(this.config.properties).reduce((acc, curr) => {
|
|
2077
|
-
if (!this.declarations.has(curr[0])) {
|
|
2078
|
-
if (curr[1].required) {
|
|
2079
|
-
acc.push(curr[0]);
|
|
2162
|
+
let iterable;
|
|
2163
|
+
let requiredCount = 0;
|
|
2164
|
+
let property;
|
|
2165
|
+
let isShorthand = true;
|
|
2166
|
+
for (property of Object.keys(this.config.properties)) {
|
|
2167
|
+
if (this.config.properties[property].required) {
|
|
2168
|
+
if (!this.declarations.has(property)) {
|
|
2169
|
+
isShorthand = false;
|
|
2170
|
+
break;
|
|
2080
2171
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
for (const val of this.declarations.get(curr[0]).val) {
|
|
2087
|
-
if (separator != null && separator.typ == val.typ && eq(separator, val)) {
|
|
2088
|
-
current++;
|
|
2089
|
-
if (tokens[curr[0]].length == current) {
|
|
2090
|
-
tokens[curr[0]].push([]);
|
|
2172
|
+
else {
|
|
2173
|
+
const val = this.declarations.get(property);
|
|
2174
|
+
if (val instanceof PropertySet && !val.isShortHand()) {
|
|
2175
|
+
isShorthand = false;
|
|
2176
|
+
break;
|
|
2091
2177
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2095
|
-
continue;
|
|
2096
|
-
}
|
|
2097
|
-
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(val, props.separator)) {
|
|
2098
|
-
continue;
|
|
2099
|
-
}
|
|
2100
|
-
if (matchType(val, curr[1])) {
|
|
2101
|
-
if (!(curr[0] in tokens)) {
|
|
2102
|
-
tokens[curr[0]] = [[]];
|
|
2178
|
+
else {
|
|
2179
|
+
requiredCount++;
|
|
2103
2180
|
}
|
|
2104
|
-
// is default value
|
|
2105
|
-
tokens[curr[0]][current].push(val);
|
|
2106
|
-
continue;
|
|
2107
2181
|
}
|
|
2108
|
-
acc.push(curr[0]);
|
|
2109
|
-
break;
|
|
2110
|
-
}
|
|
2111
|
-
if (count == 0) {
|
|
2112
|
-
count = current;
|
|
2113
2182
|
}
|
|
2114
|
-
return acc;
|
|
2115
|
-
}, []);
|
|
2116
|
-
if (valid.length > 0 || Object.values(tokens).every(v => v.every(v => v.length == count))) {
|
|
2117
|
-
return this.declarations.values();
|
|
2118
2183
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2184
|
+
if (requiredCount == 0) {
|
|
2185
|
+
requiredCount = this.declarations.size;
|
|
2186
|
+
}
|
|
2187
|
+
if (!isShorthand || requiredCount < this.requiredCount) {
|
|
2188
|
+
// @ts-ignore
|
|
2189
|
+
iterable = this.declarations.values();
|
|
2190
|
+
}
|
|
2191
|
+
else {
|
|
2192
|
+
let count = 0;
|
|
2193
|
+
const separator = this.config.separator;
|
|
2194
|
+
const tokens = {};
|
|
2195
|
+
// @ts-ignore
|
|
2196
|
+
/* const valid: string[] =*/ Object.entries(this.config.properties).reduce((acc, curr) => {
|
|
2197
|
+
if (!this.declarations.has(curr[0])) {
|
|
2198
|
+
if (curr[1].required) {
|
|
2199
|
+
acc.push(curr[0]);
|
|
2128
2200
|
}
|
|
2129
|
-
acc.push(curr);
|
|
2130
2201
|
return acc;
|
|
2131
|
-
}, []);
|
|
2132
|
-
if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
|
|
2133
|
-
continue;
|
|
2134
2202
|
}
|
|
2135
|
-
|
|
2203
|
+
let current = 0;
|
|
2204
|
+
const props = this.config.properties[curr[0]];
|
|
2205
|
+
const declaration = this.declarations.get(curr[0]);
|
|
2206
|
+
// @ts-ignore
|
|
2207
|
+
for (const val of (declaration instanceof PropertySet ? [...declaration][0] : declaration).val) {
|
|
2208
|
+
if (separator != null && separator.typ == val.typ && eq(separator, val)) {
|
|
2209
|
+
current++;
|
|
2210
|
+
if (tokens[curr[0]].length == current) {
|
|
2211
|
+
tokens[curr[0]].push([]);
|
|
2212
|
+
}
|
|
2213
|
+
continue;
|
|
2214
|
+
}
|
|
2136
2215
|
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2137
|
-
|
|
2216
|
+
continue;
|
|
2138
2217
|
}
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
if (
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2218
|
+
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
|
|
2219
|
+
continue;
|
|
2220
|
+
}
|
|
2221
|
+
if (matchType(val, curr[1])) {
|
|
2222
|
+
if (!(curr[0] in tokens)) {
|
|
2223
|
+
tokens[curr[0]] = [[]];
|
|
2224
|
+
}
|
|
2225
|
+
// is default value
|
|
2226
|
+
tokens[curr[0]][current].push(val);
|
|
2227
|
+
// continue;
|
|
2228
|
+
}
|
|
2229
|
+
else {
|
|
2230
|
+
acc.push(curr[0]);
|
|
2231
|
+
break;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
if (count == 0) {
|
|
2235
|
+
count = current;
|
|
2236
|
+
}
|
|
2237
|
+
return acc;
|
|
2238
|
+
}, []);
|
|
2239
|
+
count++;
|
|
2240
|
+
if (!Object.values(tokens).every(v => v.length == count)) {
|
|
2241
|
+
// @ts-ignore
|
|
2242
|
+
iterable = this.declarations.values();
|
|
2243
|
+
}
|
|
2244
|
+
else {
|
|
2245
|
+
const values = Object.entries(tokens).reduce((acc, curr) => {
|
|
2246
|
+
const props = this.config.properties[curr[0]];
|
|
2247
|
+
for (let i = 0; i < curr[1].length; i++) {
|
|
2248
|
+
if (acc.length == i) {
|
|
2249
|
+
acc.push([]);
|
|
2250
|
+
}
|
|
2251
|
+
let values = curr[1][i].reduce((acc, curr) => {
|
|
2252
|
+
if (acc.length > 0) {
|
|
2253
|
+
acc.push({ typ: 'Whitespace' });
|
|
2254
|
+
}
|
|
2255
|
+
acc.push(curr);
|
|
2256
|
+
return acc;
|
|
2257
|
+
}, []);
|
|
2258
|
+
// @todo remove renderToken call
|
|
2259
|
+
if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
|
|
2260
|
+
continue;
|
|
2261
|
+
}
|
|
2262
|
+
let doFilterDefault = true;
|
|
2263
|
+
if (curr[0] in propertiesConfig.properties) {
|
|
2264
|
+
for (let v of values) {
|
|
2265
|
+
if (!['Whitespace', 'Comment', 'Iden'].includes(v.typ)
|
|
2266
|
+
|| (v.typ == 'Iden' && !this.config.properties[curr[0]].default.includes(v.val))) {
|
|
2267
|
+
doFilterDefault = false;
|
|
2268
|
+
break;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
// remove default values
|
|
2273
|
+
values = values.filter((val) => {
|
|
2274
|
+
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2275
|
+
return false;
|
|
2276
|
+
}
|
|
2277
|
+
return !doFilterDefault || !(val.typ == 'Iden' && props.default.includes(val.val));
|
|
2278
|
+
});
|
|
2279
|
+
if (values.length > 0) {
|
|
2280
|
+
if ('mapping' in props) {
|
|
2147
2281
|
// @ts-ignore
|
|
2148
|
-
if (
|
|
2149
|
-
|
|
2150
|
-
|
|
2282
|
+
if (!('constraints' in props) || !('max' in props.constraints) || values.length <= props.constraints.mapping.max) {
|
|
2283
|
+
let i = values.length;
|
|
2284
|
+
while (i--) {
|
|
2285
|
+
// @ts-ignore
|
|
2286
|
+
if (values[i].typ == 'Iden' && values[i].val in props.mapping) {
|
|
2287
|
+
// @ts-ignore
|
|
2288
|
+
values.splice(i, 1, ...parseString(props.mapping[values[i].val]));
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2151
2291
|
}
|
|
2152
2292
|
}
|
|
2293
|
+
if ('prefix' in props) {
|
|
2294
|
+
// @ts-ignore
|
|
2295
|
+
acc[i].push({ ...props.prefix });
|
|
2296
|
+
}
|
|
2297
|
+
else if (acc[i].length > 0) {
|
|
2298
|
+
acc[i].push({ typ: 'Whitespace' });
|
|
2299
|
+
}
|
|
2300
|
+
acc[i].push(...values.reduce((acc, curr) => {
|
|
2301
|
+
if (acc.length > 0) {
|
|
2302
|
+
// @ts-ignore
|
|
2303
|
+
acc.push({ ...(props.separator ?? { typ: 'Whitespace' }) });
|
|
2304
|
+
}
|
|
2305
|
+
// @ts-ignore
|
|
2306
|
+
acc.push(curr);
|
|
2307
|
+
return acc;
|
|
2308
|
+
}, []));
|
|
2153
2309
|
}
|
|
2154
2310
|
}
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2311
|
+
return acc;
|
|
2312
|
+
}, []).reduce((acc, curr) => {
|
|
2313
|
+
if (acc.length > 0) {
|
|
2314
|
+
acc.push({ ...separator });
|
|
2158
2315
|
}
|
|
2159
|
-
|
|
2160
|
-
|
|
2316
|
+
if (curr.length == 0 && this.config.default.length > 0) {
|
|
2317
|
+
curr.push(...parseString(this.config.default[0]).reduce((acc, curr) => {
|
|
2318
|
+
if (acc.length > 0) {
|
|
2319
|
+
acc.push({ typ: 'Whitespace' });
|
|
2320
|
+
}
|
|
2321
|
+
acc.push(curr);
|
|
2322
|
+
return acc;
|
|
2323
|
+
}, []));
|
|
2161
2324
|
}
|
|
2162
|
-
acc
|
|
2163
|
-
|
|
2325
|
+
acc.push(...curr);
|
|
2326
|
+
return acc;
|
|
2327
|
+
}, []);
|
|
2328
|
+
iterable = [{
|
|
2329
|
+
typ: 'Declaration',
|
|
2330
|
+
nam: this.config.shorthand,
|
|
2331
|
+
val: values
|
|
2332
|
+
}][Symbol.iterator]();
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
const iterators = [];
|
|
2336
|
+
return {
|
|
2337
|
+
// @ts-ignore
|
|
2338
|
+
next() {
|
|
2339
|
+
let v = iterable.next();
|
|
2340
|
+
while (v.done || v.value instanceof PropertySet) {
|
|
2341
|
+
if (v.value instanceof PropertySet) {
|
|
2342
|
+
// @ts-ignore
|
|
2343
|
+
iterators.push(iterable);
|
|
2344
|
+
iterable = v.value[Symbol.iterator]();
|
|
2345
|
+
v = iterable.next();
|
|
2346
|
+
}
|
|
2347
|
+
if (v.done) {
|
|
2348
|
+
if (iterators.length > 0) {
|
|
2164
2349
|
// @ts-ignore
|
|
2165
|
-
|
|
2350
|
+
iterable = iterators.pop();
|
|
2351
|
+
v = iterable.next();
|
|
2166
2352
|
}
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
}
|
|
2353
|
+
if (v.done && iterators.length == 0) {
|
|
2354
|
+
break;
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2171
2357
|
}
|
|
2358
|
+
return v;
|
|
2172
2359
|
}
|
|
2173
|
-
|
|
2174
|
-
}, []).reduce((acc, curr) => {
|
|
2175
|
-
if (acc.length > 0) {
|
|
2176
|
-
acc.push({ ...separator });
|
|
2177
|
-
}
|
|
2178
|
-
if (curr.length == 0) {
|
|
2179
|
-
curr.push(...this.config.default[0].split(/\s/).map(getTokenType).reduce((acc, curr) => {
|
|
2180
|
-
if (acc.length > 0) {
|
|
2181
|
-
acc.push({ typ: 'Whitespace' });
|
|
2182
|
-
}
|
|
2183
|
-
acc.push(curr);
|
|
2184
|
-
return acc;
|
|
2185
|
-
}, []));
|
|
2186
|
-
}
|
|
2187
|
-
acc.push(...curr);
|
|
2188
|
-
return acc;
|
|
2189
|
-
}, []);
|
|
2190
|
-
return [{
|
|
2191
|
-
typ: 'Declaration',
|
|
2192
|
-
nam: this.config.shorthand,
|
|
2193
|
-
val: values
|
|
2194
|
-
}][Symbol.iterator]();
|
|
2360
|
+
};
|
|
2195
2361
|
}
|
|
2196
2362
|
}
|
|
2197
2363
|
|
|
@@ -2201,33 +2367,61 @@
|
|
|
2201
2367
|
constructor() {
|
|
2202
2368
|
this.declarations = new Map;
|
|
2203
2369
|
}
|
|
2370
|
+
set(nam, value) {
|
|
2371
|
+
return this.add({ typ: 'Declaration', nam, val: Array.isArray(value) ? value : parseString(String(value)) });
|
|
2372
|
+
}
|
|
2204
2373
|
add(declaration) {
|
|
2205
2374
|
if (declaration.typ != 'Declaration') {
|
|
2206
2375
|
this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
|
|
2207
2376
|
return this;
|
|
2208
2377
|
}
|
|
2209
|
-
|
|
2378
|
+
let propertyName = declaration.nam;
|
|
2379
|
+
let shortHandType;
|
|
2380
|
+
let shorthand;
|
|
2210
2381
|
if (propertyName in config.properties) {
|
|
2211
2382
|
// @ts-ignore
|
|
2212
|
-
|
|
2383
|
+
if ('map' in config.properties[propertyName]) {
|
|
2384
|
+
shortHandType = 'map';
|
|
2385
|
+
// @ts-ignore
|
|
2386
|
+
shorthand = config.properties[propertyName].map;
|
|
2387
|
+
}
|
|
2388
|
+
else {
|
|
2389
|
+
shortHandType = 'set';
|
|
2390
|
+
// @ts-ignore
|
|
2391
|
+
shorthand = config.properties[propertyName].shorthand;
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
else if (propertyName in config.map) {
|
|
2395
|
+
shortHandType = 'map';
|
|
2396
|
+
// @ts-ignore
|
|
2397
|
+
shorthand = config.map[propertyName].shorthand;
|
|
2398
|
+
}
|
|
2399
|
+
// @ts-ignore
|
|
2400
|
+
if (shortHandType == 'map') {
|
|
2401
|
+
// @ts-ignore
|
|
2213
2402
|
if (!this.declarations.has(shorthand)) {
|
|
2214
2403
|
// @ts-ignore
|
|
2215
|
-
this.declarations.set(shorthand, new
|
|
2404
|
+
this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
|
|
2216
2405
|
}
|
|
2406
|
+
// @ts-ignore
|
|
2217
2407
|
this.declarations.get(shorthand).add(declaration);
|
|
2218
|
-
return this;
|
|
2408
|
+
// return this;
|
|
2219
2409
|
}
|
|
2220
|
-
|
|
2410
|
+
// @ts-ignore
|
|
2411
|
+
else if (shortHandType == 'set') {
|
|
2221
2412
|
// @ts-ignore
|
|
2222
|
-
const shorthand = config.
|
|
2413
|
+
// const shorthand: string = <string>config.properties[propertyName].shorthand;
|
|
2223
2414
|
if (!this.declarations.has(shorthand)) {
|
|
2224
2415
|
// @ts-ignore
|
|
2225
|
-
this.declarations.set(shorthand, new
|
|
2416
|
+
this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
|
|
2226
2417
|
}
|
|
2418
|
+
// @ts-ignore
|
|
2227
2419
|
this.declarations.get(shorthand).add(declaration);
|
|
2228
|
-
return this;
|
|
2420
|
+
// return this;
|
|
2421
|
+
}
|
|
2422
|
+
else {
|
|
2423
|
+
this.declarations.set(propertyName, declaration);
|
|
2229
2424
|
}
|
|
2230
|
-
this.declarations.set(propertyName, declaration);
|
|
2231
2425
|
return this;
|
|
2232
2426
|
}
|
|
2233
2427
|
[Symbol.iterator]() {
|
|
@@ -2256,8 +2450,300 @@
|
|
|
2256
2450
|
}
|
|
2257
2451
|
}
|
|
2258
2452
|
|
|
2259
|
-
const
|
|
2260
|
-
|
|
2453
|
+
const combinators = ['+', '>', '~'];
|
|
2454
|
+
const notEndingWith = ['(', '['].concat(combinators);
|
|
2455
|
+
function minify(ast, options = {}, recursive = false) {
|
|
2456
|
+
function wrapNodes(previous, node, match, ast, i, nodeIndex) {
|
|
2457
|
+
// @ts-ignore
|
|
2458
|
+
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
2459
|
+
// @ts-ignore
|
|
2460
|
+
let nSel = match.selector2.reduce(reducer, []).join(',');
|
|
2461
|
+
// @ts-ignore
|
|
2462
|
+
const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
|
|
2463
|
+
// @ts-ignore
|
|
2464
|
+
Object.defineProperty(wrapper, 'raw', {
|
|
2465
|
+
enumerable: false,
|
|
2466
|
+
writable: true,
|
|
2467
|
+
// @ts-ignore
|
|
2468
|
+
value: match.match.map(t => t.slice())
|
|
2469
|
+
});
|
|
2470
|
+
if (pSel == '&' || pSel === '') {
|
|
2471
|
+
// @ts-ignore
|
|
2472
|
+
wrapper.chi.push(...previous.chi);
|
|
2473
|
+
// @ts-ignore
|
|
2474
|
+
if ((nSel == '&' || nSel === '') && hasOnlyDeclarations(previous)) {
|
|
2475
|
+
// @ts-ignore
|
|
2476
|
+
wrapper.chi.push(...node.chi);
|
|
2477
|
+
}
|
|
2478
|
+
else {
|
|
2479
|
+
// @ts-ignore
|
|
2480
|
+
wrapper.chi.push(node);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
else {
|
|
2484
|
+
// @ts-ignore
|
|
2485
|
+
wrapper.chi.push(previous, node);
|
|
2486
|
+
}
|
|
2487
|
+
// @ts-ignore
|
|
2488
|
+
ast.chi.splice(i, 1, wrapper);
|
|
2489
|
+
// @ts-ignore
|
|
2490
|
+
ast.chi.splice(nodeIndex, 1);
|
|
2491
|
+
// @ts-ignore
|
|
2492
|
+
previous.sel = pSel;
|
|
2493
|
+
// @ts-ignore
|
|
2494
|
+
previous.raw = match.selector1;
|
|
2495
|
+
// @ts-ignore
|
|
2496
|
+
node.sel = nSel;
|
|
2497
|
+
// @ts-ignore
|
|
2498
|
+
node.raw = match.selector2;
|
|
2499
|
+
reduceRuleSelector(wrapper);
|
|
2500
|
+
return wrapper;
|
|
2501
|
+
}
|
|
2502
|
+
function reducer(acc, curr, index, array) {
|
|
2503
|
+
// trim :is()
|
|
2504
|
+
if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
|
|
2505
|
+
curr = curr.slice(1, -1);
|
|
2506
|
+
}
|
|
2507
|
+
if (curr[0] == '&') {
|
|
2508
|
+
if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
|
|
2509
|
+
curr.splice(0, 2);
|
|
2510
|
+
}
|
|
2511
|
+
else if (combinators.includes(curr[1])) {
|
|
2512
|
+
curr.splice(0, 1);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
else if (ast.typ == 'Rule' && (isIdent(curr[0]) || isFunction(curr[0]))) {
|
|
2516
|
+
curr.unshift('&', ' ');
|
|
2517
|
+
}
|
|
2518
|
+
acc.push(curr.join(''));
|
|
2519
|
+
return acc;
|
|
2520
|
+
}
|
|
2521
|
+
function diff(n1, n2, options = {}) {
|
|
2522
|
+
let node1 = n1;
|
|
2523
|
+
let node2 = n2;
|
|
2524
|
+
let exchanged = false;
|
|
2525
|
+
if (node1.chi.length > node2.chi.length) {
|
|
2526
|
+
const t = node1;
|
|
2527
|
+
node1 = node2;
|
|
2528
|
+
node2 = t;
|
|
2529
|
+
exchanged = true;
|
|
2530
|
+
}
|
|
2531
|
+
let i = node1.chi.length;
|
|
2532
|
+
let j = node2.chi.length;
|
|
2533
|
+
if (i == 0 || j == 0) {
|
|
2534
|
+
// @ts-ignore
|
|
2535
|
+
return null;
|
|
2536
|
+
}
|
|
2537
|
+
// @ts-ignore
|
|
2538
|
+
const raw1 = node1.raw;
|
|
2539
|
+
// @ts-ignore
|
|
2540
|
+
const raw2 = node2.raw;
|
|
2541
|
+
// @ts-ignore
|
|
2542
|
+
node1 = { ...node1, chi: node1.chi.slice() };
|
|
2543
|
+
node2 = { ...node2, chi: node2.chi.slice() };
|
|
2544
|
+
if (raw1 != null) {
|
|
2545
|
+
Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
|
|
2546
|
+
}
|
|
2547
|
+
if (raw2 != null) {
|
|
2548
|
+
Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
|
|
2549
|
+
}
|
|
2550
|
+
const intersect = [];
|
|
2551
|
+
while (i--) {
|
|
2552
|
+
if (node1.chi[i].typ == 'Comment') {
|
|
2553
|
+
continue;
|
|
2554
|
+
}
|
|
2555
|
+
j = node2.chi.length;
|
|
2556
|
+
if (j == 0) {
|
|
2557
|
+
break;
|
|
2558
|
+
}
|
|
2559
|
+
while (j--) {
|
|
2560
|
+
if (node2.chi[j].typ == 'Comment') {
|
|
2561
|
+
continue;
|
|
2562
|
+
}
|
|
2563
|
+
if (node1.chi[i].nam == node2.chi[j].nam) {
|
|
2564
|
+
if (eq(node1.chi[i], node2.chi[j])) {
|
|
2565
|
+
intersect.push(node1.chi[i]);
|
|
2566
|
+
node1.chi.splice(i, 1);
|
|
2567
|
+
node2.chi.splice(j, 1);
|
|
2568
|
+
break;
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
// @ts-ignore
|
|
2574
|
+
const result = (intersect.length == 0 ? null : {
|
|
2575
|
+
...node1,
|
|
2576
|
+
// @ts-ignore
|
|
2577
|
+
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(','),
|
|
2578
|
+
chi: intersect.reverse()
|
|
2579
|
+
});
|
|
2580
|
+
if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0)) {
|
|
2581
|
+
// @ts-ignore
|
|
2582
|
+
return null;
|
|
2583
|
+
}
|
|
2584
|
+
return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 };
|
|
2585
|
+
}
|
|
2586
|
+
function matchSelectors(selector1, selector2, parentType) {
|
|
2587
|
+
let match = [[]];
|
|
2588
|
+
const j = Math.min(selector1.reduce((acc, curr) => Math.min(acc, curr.length), selector1.length > 0 ? selector1[0].length : 0), selector2.reduce((acc, curr) => Math.min(acc, curr.length), selector2.length > 0 ? selector2[0].length : 0));
|
|
2589
|
+
let i = 0;
|
|
2590
|
+
let k;
|
|
2591
|
+
let l;
|
|
2592
|
+
let token;
|
|
2593
|
+
let matching = true;
|
|
2594
|
+
let matchFunction = 0;
|
|
2595
|
+
let inAttr = 0;
|
|
2596
|
+
for (; i < j; i++) {
|
|
2597
|
+
k = 0;
|
|
2598
|
+
token = selector1[0][i];
|
|
2599
|
+
for (; k < selector1.length; k++) {
|
|
2600
|
+
if (selector1[k][i] != token) {
|
|
2601
|
+
matching = false;
|
|
2602
|
+
break;
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
if (matching) {
|
|
2606
|
+
l = 0;
|
|
2607
|
+
for (; l < selector2.length; l++) {
|
|
2608
|
+
if (selector2[l][i] != token) {
|
|
2609
|
+
matching = false;
|
|
2610
|
+
break;
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
if (!matching) {
|
|
2615
|
+
break;
|
|
2616
|
+
}
|
|
2617
|
+
if (token == ',') {
|
|
2618
|
+
match.push([]);
|
|
2619
|
+
}
|
|
2620
|
+
else {
|
|
2621
|
+
if (token.endsWith('(')) {
|
|
2622
|
+
matchFunction++;
|
|
2623
|
+
}
|
|
2624
|
+
if (token.endsWith('[')) {
|
|
2625
|
+
inAttr++;
|
|
2626
|
+
}
|
|
2627
|
+
else if (token == ')') {
|
|
2628
|
+
matchFunction--;
|
|
2629
|
+
}
|
|
2630
|
+
else if (token == ']') {
|
|
2631
|
+
inAttr--;
|
|
2632
|
+
}
|
|
2633
|
+
match.at(-1).push(token);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
// invalid function
|
|
2637
|
+
if (matchFunction != 0 || inAttr != 0) {
|
|
2638
|
+
return null;
|
|
2639
|
+
}
|
|
2640
|
+
if (parentType != 'Rule') {
|
|
2641
|
+
for (const part of match) {
|
|
2642
|
+
if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
|
|
2643
|
+
return null;
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
if (match.length > 1) {
|
|
2648
|
+
console.error(`unsupported multilevel matching`);
|
|
2649
|
+
console.error({ match, selector1, selector2 });
|
|
2650
|
+
return null;
|
|
2651
|
+
}
|
|
2652
|
+
for (const part of match) {
|
|
2653
|
+
while (part.length > 0) {
|
|
2654
|
+
const token = part.at(-1);
|
|
2655
|
+
if (token == ' ' || combinators.includes(token) || notEndingWith.includes(token.at(-1))) {
|
|
2656
|
+
part.pop();
|
|
2657
|
+
continue;
|
|
2658
|
+
}
|
|
2659
|
+
break;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
if (match.every(t => t.length == 0)) {
|
|
2663
|
+
return null;
|
|
2664
|
+
}
|
|
2665
|
+
if (eq([['&']], match)) {
|
|
2666
|
+
return null;
|
|
2667
|
+
}
|
|
2668
|
+
function reduce(acc, curr) {
|
|
2669
|
+
if (acc === null) {
|
|
2670
|
+
return null;
|
|
2671
|
+
}
|
|
2672
|
+
let hasCompoundSelector = true;
|
|
2673
|
+
curr = curr.slice(match[0].length);
|
|
2674
|
+
while (curr.length > 0) {
|
|
2675
|
+
if (curr[0] == ' ') {
|
|
2676
|
+
hasCompoundSelector = false;
|
|
2677
|
+
curr.unshift('&');
|
|
2678
|
+
continue;
|
|
2679
|
+
}
|
|
2680
|
+
break;
|
|
2681
|
+
}
|
|
2682
|
+
// invalid function match
|
|
2683
|
+
if (curr.length > 0 && curr[0].endsWith('(') && curr.at(-1) != ')') {
|
|
2684
|
+
return null;
|
|
2685
|
+
}
|
|
2686
|
+
if (curr.length == 1 && combinators.includes(curr[0].charAt(0))) {
|
|
2687
|
+
return null;
|
|
2688
|
+
}
|
|
2689
|
+
if (hasCompoundSelector && curr.length > 0) {
|
|
2690
|
+
hasCompoundSelector = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
2691
|
+
}
|
|
2692
|
+
if (curr[0] == ':is(') {
|
|
2693
|
+
let inFunction = 0;
|
|
2694
|
+
let canReduce = true;
|
|
2695
|
+
const isCompound = curr.reduce((acc, token, index) => {
|
|
2696
|
+
if (index == 0) {
|
|
2697
|
+
inFunction++;
|
|
2698
|
+
canReduce = curr[1] == '&';
|
|
2699
|
+
}
|
|
2700
|
+
else if (token.endsWith('(')) {
|
|
2701
|
+
if (inFunction == 0) {
|
|
2702
|
+
canReduce = false;
|
|
2703
|
+
}
|
|
2704
|
+
inFunction++;
|
|
2705
|
+
}
|
|
2706
|
+
else if (token == ')') {
|
|
2707
|
+
inFunction--;
|
|
2708
|
+
}
|
|
2709
|
+
else if (token == ',') {
|
|
2710
|
+
if (!canReduce) {
|
|
2711
|
+
canReduce = curr[index + 1] == '&';
|
|
2712
|
+
}
|
|
2713
|
+
acc.push([]);
|
|
2714
|
+
}
|
|
2715
|
+
else
|
|
2716
|
+
acc.at(-1)?.push(token);
|
|
2717
|
+
return acc;
|
|
2718
|
+
}, [[]]);
|
|
2719
|
+
if (inFunction > 0) {
|
|
2720
|
+
canReduce = false;
|
|
2721
|
+
}
|
|
2722
|
+
if (canReduce) {
|
|
2723
|
+
curr = isCompound.reduce((acc, curr) => {
|
|
2724
|
+
if (acc.length > 0) {
|
|
2725
|
+
acc.push(',');
|
|
2726
|
+
}
|
|
2727
|
+
acc.push(...curr);
|
|
2728
|
+
return acc;
|
|
2729
|
+
}, []);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
// @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
|
|
2733
|
+
acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
|
|
2734
|
+
return acc;
|
|
2735
|
+
}
|
|
2736
|
+
// @ts-ignore
|
|
2737
|
+
selector1 = selector1.reduce(reduce, []);
|
|
2738
|
+
// @ts-ignore
|
|
2739
|
+
selector2 = selector2.reduce(reduce, []);
|
|
2740
|
+
return selector1 == null || selector2 == null ? null : {
|
|
2741
|
+
eq: eq(selector1, selector2),
|
|
2742
|
+
match,
|
|
2743
|
+
selector1,
|
|
2744
|
+
selector2
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2261
2747
|
// @ts-ignore
|
|
2262
2748
|
if (('chi' in ast) && ast.chi?.length > 0) {
|
|
2263
2749
|
let i = 0;
|
|
@@ -2272,6 +2758,14 @@
|
|
|
2272
2758
|
}
|
|
2273
2759
|
// @ts-ignore
|
|
2274
2760
|
node = ast.chi[i];
|
|
2761
|
+
// @ts-ignore
|
|
2762
|
+
if (previous == node) {
|
|
2763
|
+
// console.error('idem!');
|
|
2764
|
+
// @ts-ignore
|
|
2765
|
+
ast.chi.splice(i, 1);
|
|
2766
|
+
i--;
|
|
2767
|
+
continue;
|
|
2768
|
+
}
|
|
2275
2769
|
if (node.typ == 'AtRule' && node.nam == 'font-face') {
|
|
2276
2770
|
continue;
|
|
2277
2771
|
}
|
|
@@ -2284,120 +2778,118 @@
|
|
|
2284
2778
|
// @ts-ignore
|
|
2285
2779
|
if (node.typ == 'Rule') {
|
|
2286
2780
|
reduceRuleSelector(node);
|
|
2781
|
+
let wrapper;
|
|
2782
|
+
let match;
|
|
2287
2783
|
// @ts-ignore
|
|
2288
|
-
if (options.nestingRules
|
|
2289
|
-
const match = [];
|
|
2784
|
+
if (options.nestingRules) {
|
|
2290
2785
|
// @ts-ignore
|
|
2291
|
-
|
|
2292
|
-
// @ts-ignore
|
|
2293
|
-
if (node.raw[0][0] != previous.raw[0][0]) {
|
|
2294
|
-
break;
|
|
2295
|
-
}
|
|
2296
|
-
// @ts-ignore
|
|
2297
|
-
match.push(node.raw[0].shift());
|
|
2298
|
-
// @ts-ignore
|
|
2299
|
-
previous.raw[0].shift();
|
|
2300
|
-
}
|
|
2301
|
-
if (match.length > 0) {
|
|
2786
|
+
if (previous?.typ == 'Rule') {
|
|
2302
2787
|
// @ts-ignore
|
|
2303
|
-
|
|
2788
|
+
reduceRuleSelector(previous);
|
|
2304
2789
|
// @ts-ignore
|
|
2305
|
-
|
|
2306
|
-
// @ts-ignore
|
|
2307
|
-
wrapper.chi.push(...previous.chi);
|
|
2308
|
-
}
|
|
2309
|
-
else {
|
|
2310
|
-
// @ts-ignore
|
|
2311
|
-
previous.sel = previous.raw.reduce((acc, curr) => {
|
|
2312
|
-
acc.push(curr.join(''));
|
|
2313
|
-
return acc;
|
|
2314
|
-
}, []).join(',');
|
|
2315
|
-
// @ts-ignore
|
|
2316
|
-
wrapper.chi.push(previous);
|
|
2317
|
-
}
|
|
2790
|
+
match = matchSelectors(previous.raw, node.raw, ast.typ);
|
|
2318
2791
|
// @ts-ignore
|
|
2319
|
-
if (
|
|
2320
|
-
// @ts-ignore
|
|
2321
|
-
if (previous.raw.length == 0) {
|
|
2322
|
-
// @ts-ignore
|
|
2323
|
-
wrapper.chi.push(...node.chi);
|
|
2324
|
-
}
|
|
2325
|
-
else {
|
|
2326
|
-
if (hasOnlyDeclarations(wrapper)) {
|
|
2327
|
-
wrapper.chi.push(...node.chi);
|
|
2328
|
-
}
|
|
2329
|
-
else {
|
|
2330
|
-
// @ts-ignore
|
|
2331
|
-
node.raw[0].push('&');
|
|
2332
|
-
// @ts-ignore
|
|
2333
|
-
node.sel = node.raw.reduce((acc, curr) => {
|
|
2334
|
-
acc.push(curr.join(''));
|
|
2335
|
-
return acc;
|
|
2336
|
-
}, []).join(',');
|
|
2337
|
-
// @ts-ignore
|
|
2338
|
-
wrapper.chi.push(node);
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
else {
|
|
2792
|
+
if (match != null) {
|
|
2343
2793
|
// @ts-ignore
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
return acc;
|
|
2347
|
-
}, []).join(',');
|
|
2794
|
+
wrapper = wrapNodes(previous, node, match, ast, i, nodeIndex);
|
|
2795
|
+
nodeIndex = i - 1;
|
|
2348
2796
|
// @ts-ignore
|
|
2349
|
-
|
|
2797
|
+
previous = ast.chi[nodeIndex];
|
|
2350
2798
|
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
// @ts-ignore
|
|
2355
|
-
ast.chi.splice(nodeIndex, 1);
|
|
2799
|
+
}
|
|
2800
|
+
// @ts-ignore
|
|
2801
|
+
if (wrapper != null) {
|
|
2356
2802
|
// @ts-ignore
|
|
2357
2803
|
while (i < ast.chi.length) {
|
|
2358
2804
|
// @ts-ignore
|
|
2359
2805
|
const nextNode = ast.chi[i];
|
|
2360
2806
|
// @ts-ignore
|
|
2361
|
-
if (nextNode.typ != 'Rule'
|
|
2807
|
+
if (nextNode.typ != 'Rule') {
|
|
2808
|
+
// i--;
|
|
2809
|
+
// previous = wrapper;
|
|
2810
|
+
// nodeIndex = i;
|
|
2362
2811
|
break;
|
|
2363
2812
|
}
|
|
2364
2813
|
reduceRuleSelector(nextNode);
|
|
2365
2814
|
// @ts-ignore
|
|
2366
|
-
|
|
2815
|
+
match = matchSelectors(wrapper.raw, nextNode.raw, ast.typ);
|
|
2816
|
+
// @ts-ignore
|
|
2817
|
+
if (match == null) {
|
|
2367
2818
|
break;
|
|
2368
2819
|
}
|
|
2369
2820
|
// @ts-ignore
|
|
2370
|
-
|
|
2821
|
+
wrapper = wrapNodes(wrapper, nextNode, match, ast, i, nodeIndex);
|
|
2822
|
+
}
|
|
2823
|
+
nodeIndex = --i;
|
|
2824
|
+
// @ts-ignore
|
|
2825
|
+
previous = ast.chi[nodeIndex];
|
|
2826
|
+
minify(wrapper, options, recursive);
|
|
2827
|
+
continue;
|
|
2828
|
+
}
|
|
2829
|
+
// @ts-ignore
|
|
2830
|
+
else if (node.optimized != null &&
|
|
2831
|
+
// @ts-ignore
|
|
2832
|
+
node.optimized.match &&
|
|
2833
|
+
// @ts-ignore
|
|
2834
|
+
node.optimized.selector.length > 1) {
|
|
2835
|
+
// @ts-ignore
|
|
2836
|
+
wrapper = { ...node, chi: [], sel: node.optimized.optimized[0] };
|
|
2837
|
+
// @ts-ignore
|
|
2838
|
+
Object.defineProperty(wrapper, 'raw', {
|
|
2839
|
+
enumerable: false,
|
|
2840
|
+
writable: true,
|
|
2371
2841
|
// @ts-ignore
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2842
|
+
value: [[node.optimized.optimized[0]]]
|
|
2843
|
+
});
|
|
2844
|
+
// @ts-ignore
|
|
2845
|
+
node.sel = node.optimized.selector.reduce(reducer, []).join(',');
|
|
2846
|
+
// @ts-ignore
|
|
2847
|
+
node.raw = node.optimized.selector.slice();
|
|
2848
|
+
// @ts-ignore
|
|
2849
|
+
wrapper.chi.push(node);
|
|
2850
|
+
// @ts-ignore
|
|
2851
|
+
ast.chi.splice(i, 1, wrapper);
|
|
2852
|
+
node = wrapper;
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
// @ts-ignore
|
|
2856
|
+
else if (node.optimized?.match) {
|
|
2857
|
+
let wrap = true;
|
|
2858
|
+
// @ts-ignore
|
|
2859
|
+
const selector = node.optimized.selector.reduce((acc, curr) => {
|
|
2860
|
+
if (curr[0] == '&') {
|
|
2861
|
+
if (curr[1] == ' ') {
|
|
2862
|
+
curr.splice(0, 2);
|
|
2863
|
+
}
|
|
2864
|
+
else {
|
|
2865
|
+
if (ast.typ != 'Rule' && combinators.includes(curr[1])) {
|
|
2866
|
+
wrap = false;
|
|
2380
2867
|
}
|
|
2381
2868
|
else {
|
|
2382
|
-
|
|
2383
|
-
nextNode.raw[0].push('&');
|
|
2869
|
+
curr.splice(0, 1);
|
|
2384
2870
|
}
|
|
2385
2871
|
}
|
|
2386
|
-
// @ts-ignore
|
|
2387
|
-
nextNode.sel = nextNode.raw.reduce((acc, curr) => {
|
|
2388
|
-
acc.push(curr.join(''));
|
|
2389
|
-
return acc;
|
|
2390
|
-
}, []).join(',');
|
|
2391
|
-
wrapper.chi.push(nextNode);
|
|
2392
|
-
// @ts-ignore
|
|
2393
|
-
ast.chi.splice(i, 1);
|
|
2394
2872
|
}
|
|
2395
|
-
|
|
2396
|
-
|
|
2873
|
+
else if (combinators.includes(curr[0])) {
|
|
2874
|
+
curr.unshift('&');
|
|
2875
|
+
wrap = false;
|
|
2876
|
+
}
|
|
2397
2877
|
// @ts-ignore
|
|
2398
|
-
|
|
2399
|
-
|
|
2878
|
+
acc.push(curr);
|
|
2879
|
+
return acc;
|
|
2880
|
+
}, []);
|
|
2881
|
+
if (!wrap) {
|
|
2882
|
+
wrap = selector.some(s => s[0] != '&');
|
|
2400
2883
|
}
|
|
2884
|
+
const rule = selector.map(s => {
|
|
2885
|
+
if (s[0] == '&') {
|
|
2886
|
+
// @ts-ignore
|
|
2887
|
+
s[0] = node.optimized.optimized[0];
|
|
2888
|
+
}
|
|
2889
|
+
return s.join('');
|
|
2890
|
+
}).join(',');
|
|
2891
|
+
// @ts-ignore
|
|
2892
|
+
node.sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
|
|
2401
2893
|
}
|
|
2402
2894
|
}
|
|
2403
2895
|
// @ts-ignore
|
|
@@ -2427,10 +2919,11 @@
|
|
|
2427
2919
|
ast.chi.splice(nodeIndex, 1);
|
|
2428
2920
|
// @ts-ignore
|
|
2429
2921
|
if (hasDeclaration(node)) {
|
|
2430
|
-
|
|
2922
|
+
// @ts-ignore
|
|
2923
|
+
minifyRule(node);
|
|
2431
2924
|
}
|
|
2432
2925
|
else {
|
|
2433
|
-
|
|
2926
|
+
minify(node, options, recursive);
|
|
2434
2927
|
}
|
|
2435
2928
|
i--;
|
|
2436
2929
|
previous = node;
|
|
@@ -2471,10 +2964,11 @@
|
|
|
2471
2964
|
if (recursive && previous != node) {
|
|
2472
2965
|
// @ts-ignore
|
|
2473
2966
|
if (hasDeclaration(previous)) {
|
|
2474
|
-
|
|
2967
|
+
// @ts-ignore
|
|
2968
|
+
minifyRule(previous);
|
|
2475
2969
|
}
|
|
2476
2970
|
else {
|
|
2477
|
-
|
|
2971
|
+
minify(previous, options, recursive);
|
|
2478
2972
|
}
|
|
2479
2973
|
}
|
|
2480
2974
|
}
|
|
@@ -2485,98 +2979,176 @@
|
|
|
2485
2979
|
if (recursive && node != null && ('chi' in node)) {
|
|
2486
2980
|
// @ts-ignore
|
|
2487
2981
|
if (node.chi.some(n => n.typ == 'Declaration')) {
|
|
2488
|
-
|
|
2982
|
+
minifyRule(node);
|
|
2489
2983
|
}
|
|
2490
2984
|
else {
|
|
2985
|
+
// @ts-ignore
|
|
2491
2986
|
if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
|
|
2492
|
-
|
|
2987
|
+
minify(node, options, recursive);
|
|
2493
2988
|
}
|
|
2494
2989
|
}
|
|
2495
2990
|
}
|
|
2496
2991
|
}
|
|
2497
2992
|
return ast;
|
|
2498
2993
|
}
|
|
2499
|
-
function
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
if (node.chi[k].typ == 'Comment') {
|
|
2503
|
-
continue;
|
|
2504
|
-
}
|
|
2505
|
-
return node.chi[k].typ == 'Declaration';
|
|
2506
|
-
}
|
|
2507
|
-
return true;
|
|
2508
|
-
}
|
|
2509
|
-
function hasDeclaration(node) {
|
|
2510
|
-
// @ts-ignore
|
|
2511
|
-
for (let i = 0; i < node.chi?.length; i++) {
|
|
2512
|
-
// @ts-ignore
|
|
2513
|
-
if (node.chi[i].typ == 'Comment') {
|
|
2514
|
-
continue;
|
|
2515
|
-
}
|
|
2516
|
-
// @ts-ignore
|
|
2517
|
-
return node.chi[i].typ == 'Declaration';
|
|
2994
|
+
function reduceSelector(selector) {
|
|
2995
|
+
if (selector.length == 0) {
|
|
2996
|
+
return null;
|
|
2518
2997
|
}
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2998
|
+
const optimized = [];
|
|
2999
|
+
const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
|
|
3000
|
+
let i = 0;
|
|
3001
|
+
let j;
|
|
3002
|
+
let match;
|
|
3003
|
+
for (; i < k; i++) {
|
|
3004
|
+
const item = selector[0][i];
|
|
3005
|
+
match = true;
|
|
3006
|
+
for (j = 1; j < selector.length; j++) {
|
|
3007
|
+
if (item != selector[j][i]) {
|
|
3008
|
+
match = false;
|
|
3009
|
+
break;
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
if (!match) {
|
|
3013
|
+
break;
|
|
3014
|
+
}
|
|
3015
|
+
optimized.push(item);
|
|
3016
|
+
}
|
|
3017
|
+
while (optimized.length > 0) {
|
|
3018
|
+
const last = optimized.at(-1);
|
|
3019
|
+
if ((last == ' ' || combinators.includes(last))) {
|
|
3020
|
+
optimized.pop();
|
|
3021
|
+
continue;
|
|
3022
|
+
}
|
|
3023
|
+
break;
|
|
3024
|
+
}
|
|
3025
|
+
selector.forEach((selector) => selector.splice(0, optimized.length));
|
|
3026
|
+
// combinator
|
|
3027
|
+
if (combinators.includes(optimized.at(-1))) {
|
|
3028
|
+
const combinator = optimized.pop();
|
|
3029
|
+
selector.forEach(selector => selector.unshift(combinator));
|
|
3030
|
+
}
|
|
3031
|
+
let reducible = optimized.length == 1;
|
|
3032
|
+
if (optimized[0] == '&' && optimized[1] == ' ') {
|
|
3033
|
+
optimized.splice(0, 2);
|
|
3034
|
+
}
|
|
3035
|
+
if (optimized.length == 0 ||
|
|
3036
|
+
(optimized[0].charAt(0) == '&' ||
|
|
3037
|
+
selector.length == 1)) {
|
|
3038
|
+
return {
|
|
3039
|
+
match: false,
|
|
3040
|
+
optimized,
|
|
3041
|
+
selector: selector.map(selector => selector[0] == '&' && selector[1] == ' ' ? selector.slice(2) : selector),
|
|
3042
|
+
reducible: selector.length > 1 && selector.every((selector) => !combinators.includes(selector[0]))
|
|
3043
|
+
};
|
|
3044
|
+
}
|
|
3045
|
+
return {
|
|
3046
|
+
match: true,
|
|
3047
|
+
optimized,
|
|
3048
|
+
selector: selector.reduce((acc, curr) => {
|
|
3049
|
+
let hasCompound = true;
|
|
3050
|
+
if (hasCompound && curr.length > 0) {
|
|
3051
|
+
hasCompound = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
3052
|
+
}
|
|
3053
|
+
// @ts-ignore
|
|
3054
|
+
if (hasCompound && curr[0] == ' ') {
|
|
3055
|
+
hasCompound = false;
|
|
3056
|
+
curr.unshift('&');
|
|
3057
|
+
}
|
|
3058
|
+
if (curr.length == 0) {
|
|
3059
|
+
curr.push('&');
|
|
3060
|
+
hasCompound = false;
|
|
3061
|
+
}
|
|
3062
|
+
if (reducible) {
|
|
3063
|
+
const chr = curr[0].charAt(0);
|
|
3064
|
+
// @ts-ignore
|
|
3065
|
+
reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
|
|
3066
|
+
}
|
|
3067
|
+
acc.push(hasCompound ? ['&'].concat(curr) : curr);
|
|
3068
|
+
return acc;
|
|
3069
|
+
}, []),
|
|
3070
|
+
reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
|
|
3071
|
+
};
|
|
3072
|
+
}
|
|
3073
|
+
function hasOnlyDeclarations(node) {
|
|
3074
|
+
let k = node.chi.length;
|
|
3075
|
+
while (k--) {
|
|
3076
|
+
if (node.chi[k].typ == 'Comment') {
|
|
3077
|
+
continue;
|
|
3078
|
+
}
|
|
3079
|
+
return node.chi[k].typ == 'Declaration';
|
|
3080
|
+
}
|
|
3081
|
+
return true;
|
|
3082
|
+
}
|
|
3083
|
+
function hasDeclaration(node) {
|
|
3084
|
+
// @ts-ignore
|
|
3085
|
+
for (let i = 0; i < node.chi?.length; i++) {
|
|
3086
|
+
// @ts-ignore
|
|
3087
|
+
if (node.chi[i].typ == 'Comment') {
|
|
3088
|
+
continue;
|
|
3089
|
+
}
|
|
3090
|
+
// @ts-ignore
|
|
3091
|
+
return node.chi[i].typ == 'Declaration';
|
|
3092
|
+
}
|
|
3093
|
+
return true;
|
|
3094
|
+
}
|
|
3095
|
+
function minifyRule(ast) {
|
|
3096
|
+
// @ts-ignore
|
|
2523
3097
|
if (!('chi' in ast) || ast.chi?.length <= 1) {
|
|
2524
3098
|
return ast;
|
|
2525
3099
|
}
|
|
2526
3100
|
// @ts-ignore
|
|
2527
3101
|
const j = ast.chi.length;
|
|
2528
3102
|
let k = 0;
|
|
2529
|
-
let
|
|
3103
|
+
let properties = new PropertyList();
|
|
2530
3104
|
// @ts-ignore
|
|
2531
3105
|
for (; k < j; k++) {
|
|
2532
3106
|
// @ts-ignore
|
|
2533
3107
|
const node = ast.chi[k];
|
|
2534
|
-
if (node.typ == 'Comment') {
|
|
2535
|
-
|
|
2536
|
-
map.set(node, node);
|
|
3108
|
+
if (node.typ == 'Comment' || node.typ == 'Declaration') {
|
|
3109
|
+
properties.add(node);
|
|
2537
3110
|
continue;
|
|
2538
3111
|
}
|
|
2539
|
-
|
|
2540
|
-
break;
|
|
2541
|
-
}
|
|
2542
|
-
if (node.nam in configuration.map ||
|
|
2543
|
-
node.nam in configuration.properties) {
|
|
2544
|
-
// @ts-ignore
|
|
2545
|
-
const shorthand = node.nam in configuration.map ? configuration.map[node.nam].shorthand : configuration.properties[node.nam].shorthand;
|
|
2546
|
-
if (!map.has(shorthand)) {
|
|
2547
|
-
map.set(shorthand, new PropertyList());
|
|
2548
|
-
}
|
|
2549
|
-
map.get(shorthand).add(node);
|
|
2550
|
-
}
|
|
2551
|
-
else {
|
|
2552
|
-
map.set(node.nam, node);
|
|
2553
|
-
}
|
|
2554
|
-
}
|
|
2555
|
-
const children = [];
|
|
2556
|
-
for (let child of map.values()) {
|
|
2557
|
-
if (child instanceof PropertyList) {
|
|
2558
|
-
// @ts-ignore
|
|
2559
|
-
children.push(...child);
|
|
2560
|
-
}
|
|
2561
|
-
else {
|
|
2562
|
-
// @ts-ignore
|
|
2563
|
-
children.push(child);
|
|
2564
|
-
}
|
|
3112
|
+
break;
|
|
2565
3113
|
}
|
|
2566
3114
|
// @ts-ignore
|
|
2567
|
-
ast.chi =
|
|
3115
|
+
ast.chi = [...properties].concat(ast.chi.slice(k));
|
|
2568
3116
|
return ast;
|
|
2569
3117
|
}
|
|
2570
3118
|
function splitRule(buffer) {
|
|
2571
|
-
const result = [];
|
|
3119
|
+
const result = [[]];
|
|
2572
3120
|
let str = '';
|
|
2573
3121
|
for (let i = 0; i < buffer.length; i++) {
|
|
2574
3122
|
let chr = buffer.charAt(i);
|
|
3123
|
+
if (isWhiteSpace(chr.charCodeAt(0))) {
|
|
3124
|
+
let k = i;
|
|
3125
|
+
while (k + 1 < buffer.length) {
|
|
3126
|
+
if (isWhiteSpace(buffer[k + 1].charCodeAt(0))) {
|
|
3127
|
+
k++;
|
|
3128
|
+
continue;
|
|
3129
|
+
}
|
|
3130
|
+
break;
|
|
3131
|
+
}
|
|
3132
|
+
if (str !== '') {
|
|
3133
|
+
// @ts-ignore
|
|
3134
|
+
result.at(-1).push(str);
|
|
3135
|
+
str = '';
|
|
3136
|
+
}
|
|
3137
|
+
// @ts-ignore
|
|
3138
|
+
if (result.at(-1).length > 0) {
|
|
3139
|
+
// @ts-ignore
|
|
3140
|
+
result.at(-1).push(' ');
|
|
3141
|
+
}
|
|
3142
|
+
i = k;
|
|
3143
|
+
continue;
|
|
3144
|
+
}
|
|
2575
3145
|
if (chr == ',') {
|
|
2576
3146
|
if (str !== '') {
|
|
2577
|
-
|
|
3147
|
+
// @ts-ignore
|
|
3148
|
+
result.at(-1).push(str);
|
|
2578
3149
|
str = '';
|
|
2579
3150
|
}
|
|
3151
|
+
result.push([]);
|
|
2580
3152
|
continue;
|
|
2581
3153
|
}
|
|
2582
3154
|
str += chr;
|
|
@@ -2626,198 +3198,64 @@
|
|
|
2626
3198
|
}
|
|
2627
3199
|
}
|
|
2628
3200
|
if (str !== '') {
|
|
2629
|
-
|
|
3201
|
+
// @ts-ignore
|
|
3202
|
+
result.at(-1).push(str);
|
|
2630
3203
|
}
|
|
2631
3204
|
return result;
|
|
2632
3205
|
}
|
|
2633
3206
|
function reduceRuleSelector(node) {
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
// @ts-ignore
|
|
2637
|
-
let optimized = reduceSelector(node.raw);
|
|
2638
|
-
if (optimized != null) {
|
|
2639
|
-
Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
|
|
2640
|
-
}
|
|
2641
|
-
if (optimized != null && optimized.match && optimized.reducible) {
|
|
2642
|
-
const raw = [
|
|
2643
|
-
[
|
|
2644
|
-
optimized.optimized[0], ':is('
|
|
2645
|
-
].concat(optimized.selector.reduce((acc, curr) => {
|
|
2646
|
-
if (acc.length > 0) {
|
|
2647
|
-
acc.push(',');
|
|
2648
|
-
}
|
|
2649
|
-
acc.push(...curr);
|
|
2650
|
-
return acc;
|
|
2651
|
-
}, [])).concat(')')
|
|
2652
|
-
];
|
|
2653
|
-
const sel = raw[0].join('');
|
|
2654
|
-
if (sel.length < node.sel.length) {
|
|
2655
|
-
node.sel = sel;
|
|
2656
|
-
// node.raw = raw;
|
|
2657
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
2658
|
-
}
|
|
2659
|
-
}
|
|
2660
|
-
}
|
|
2661
|
-
}
|
|
2662
|
-
function diff(n1, n2, options = {}) {
|
|
2663
|
-
let node1 = n1;
|
|
2664
|
-
let node2 = n2;
|
|
2665
|
-
let exchanged = false;
|
|
2666
|
-
if (node1.chi.length > node2.chi.length) {
|
|
2667
|
-
const t = node1;
|
|
2668
|
-
node1 = node2;
|
|
2669
|
-
node2 = t;
|
|
2670
|
-
exchanged = true;
|
|
2671
|
-
}
|
|
2672
|
-
let i = node1.chi.length;
|
|
2673
|
-
let j = node2.chi.length;
|
|
2674
|
-
if (i == 0 || j == 0) {
|
|
2675
|
-
// @ts-ignore
|
|
2676
|
-
return null;
|
|
3207
|
+
if (node.raw == null) {
|
|
3208
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: splitRule(node.sel) });
|
|
2677
3209
|
}
|
|
2678
3210
|
// @ts-ignore
|
|
2679
|
-
|
|
2680
|
-
// @ts-ignore
|
|
2681
|
-
const optimized1 = node1.optimized;
|
|
3211
|
+
// if (node.raw != null) {
|
|
2682
3212
|
// @ts-ignore
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
|
|
2690
|
-
}
|
|
2691
|
-
if (optimized1 != null) {
|
|
2692
|
-
Object.defineProperty(node1, 'optimized', { enumerable: false, writable: true, value: optimized1 });
|
|
2693
|
-
}
|
|
2694
|
-
if (raw2 != null) {
|
|
2695
|
-
Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
|
|
2696
|
-
}
|
|
2697
|
-
if (optimized2 != null) {
|
|
2698
|
-
Object.defineProperty(node2, 'optimized', { enumerable: false, writable: true, value: optimized2 });
|
|
3213
|
+
let optimized = reduceSelector(node.raw.reduce((acc, curr) => {
|
|
3214
|
+
acc.push(curr.slice());
|
|
3215
|
+
return acc;
|
|
3216
|
+
}, []));
|
|
3217
|
+
if (optimized != null) {
|
|
3218
|
+
Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
|
|
2699
3219
|
}
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
break;
|
|
2708
|
-
}
|
|
2709
|
-
while (j--) {
|
|
2710
|
-
if (node2.chi[j].typ == 'Comment') {
|
|
2711
|
-
continue;
|
|
2712
|
-
}
|
|
2713
|
-
if (node1.chi[i].nam == node2.chi[j].nam) {
|
|
2714
|
-
if (eq(node1.chi[i], node2.chi[j])) {
|
|
2715
|
-
intersect.push(node1.chi[i]);
|
|
2716
|
-
node1.chi.splice(i, 1);
|
|
2717
|
-
node2.chi.splice(j, 1);
|
|
2718
|
-
break;
|
|
3220
|
+
if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
|
|
3221
|
+
const raw = [
|
|
3222
|
+
[
|
|
3223
|
+
optimized.optimized[0], ':is('
|
|
3224
|
+
].concat(optimized.selector.reduce((acc, curr) => {
|
|
3225
|
+
if (acc.length > 0) {
|
|
3226
|
+
acc.push(',');
|
|
2719
3227
|
}
|
|
2720
|
-
|
|
3228
|
+
acc.push(...curr);
|
|
3229
|
+
return acc;
|
|
3230
|
+
}, [])).concat(')')
|
|
3231
|
+
];
|
|
3232
|
+
const sel = raw[0].join('');
|
|
3233
|
+
if (sel.length < node.sel.length) {
|
|
3234
|
+
node.sel = sel;
|
|
3235
|
+
// node.raw = raw;
|
|
3236
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
2721
3237
|
}
|
|
2722
3238
|
}
|
|
3239
|
+
// }
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3242
|
+
function* walk(node) {
|
|
2723
3243
|
// @ts-ignore
|
|
2724
|
-
|
|
2725
|
-
...node1,
|
|
2726
|
-
// @ts-ignore
|
|
2727
|
-
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(),
|
|
2728
|
-
chi: intersect.reverse()
|
|
2729
|
-
});
|
|
2730
|
-
if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0)) {
|
|
2731
|
-
// @ts-ignore
|
|
2732
|
-
return null;
|
|
2733
|
-
}
|
|
2734
|
-
return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 };
|
|
3244
|
+
yield* doWalk(node, null, null);
|
|
2735
3245
|
}
|
|
2736
|
-
function
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
|
|
2742
|
-
let i = 0;
|
|
2743
|
-
let j;
|
|
2744
|
-
let match;
|
|
2745
|
-
for (; i < k; i++) {
|
|
2746
|
-
const item = selector[0][i];
|
|
2747
|
-
match = true;
|
|
2748
|
-
for (j = 1; j < selector.length; j++) {
|
|
2749
|
-
if (item != selector[j][i]) {
|
|
2750
|
-
match = false;
|
|
2751
|
-
break;
|
|
2752
|
-
}
|
|
2753
|
-
}
|
|
2754
|
-
if (!match) {
|
|
2755
|
-
break;
|
|
3246
|
+
function* doWalk(node, parent, root) {
|
|
3247
|
+
yield { node, parent, root };
|
|
3248
|
+
if ('chi' in node) {
|
|
3249
|
+
for (const child of node.chi) {
|
|
3250
|
+
yield* doWalk(child, node, (root ?? node));
|
|
2756
3251
|
}
|
|
2757
|
-
optimized.push(item);
|
|
2758
|
-
}
|
|
2759
|
-
if (optimized.at(-1) == ' ') {
|
|
2760
|
-
optimized.pop();
|
|
2761
3252
|
}
|
|
2762
|
-
let reducible = optimized.length == 1;
|
|
2763
|
-
if (optimized.length == 0) {
|
|
2764
|
-
return { match: false, optimized, selector, reducible };
|
|
2765
|
-
}
|
|
2766
|
-
return {
|
|
2767
|
-
match: true,
|
|
2768
|
-
optimized,
|
|
2769
|
-
selector: selector.reduce((acc, curr) => {
|
|
2770
|
-
const slice = curr.slice(optimized.length);
|
|
2771
|
-
// @ts-ignore
|
|
2772
|
-
if (slice.length > 0 && slice[0] == ' ') {
|
|
2773
|
-
slice.shift();
|
|
2774
|
-
}
|
|
2775
|
-
if (slice.length == 0) {
|
|
2776
|
-
slice.push('&');
|
|
2777
|
-
}
|
|
2778
|
-
if (reducible) {
|
|
2779
|
-
const chr = slice[0].charAt(0);
|
|
2780
|
-
// @ts-ignore
|
|
2781
|
-
reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
|
|
2782
|
-
}
|
|
2783
|
-
acc.push(slice);
|
|
2784
|
-
return acc;
|
|
2785
|
-
}, []),
|
|
2786
|
-
reducible
|
|
2787
|
-
};
|
|
2788
|
-
}
|
|
2789
|
-
function reducer(acc, curr) {
|
|
2790
|
-
acc.push(curr.join(''));
|
|
2791
|
-
return acc;
|
|
2792
3253
|
}
|
|
2793
3254
|
|
|
2794
|
-
|
|
2795
|
-
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
2796
|
-
async function parse$1(iterator, opt = {}) {
|
|
2797
|
-
const errors = [];
|
|
2798
|
-
const options = {
|
|
2799
|
-
src: '',
|
|
2800
|
-
sourcemap: false,
|
|
2801
|
-
compress: false,
|
|
2802
|
-
nestingRules: false,
|
|
2803
|
-
resolveImport: false,
|
|
2804
|
-
resolveUrls: false,
|
|
2805
|
-
removeEmpty: true,
|
|
2806
|
-
...opt
|
|
2807
|
-
};
|
|
2808
|
-
if (options.resolveImport) {
|
|
2809
|
-
options.resolveUrls = true;
|
|
2810
|
-
}
|
|
3255
|
+
function* tokenize(iterator) {
|
|
2811
3256
|
let ind = -1;
|
|
2812
3257
|
let lin = 1;
|
|
2813
3258
|
let col = 0;
|
|
2814
|
-
const tokens = [];
|
|
2815
|
-
const src = options.src;
|
|
2816
|
-
const stack = [];
|
|
2817
|
-
const ast = {
|
|
2818
|
-
typ: "StyleSheet",
|
|
2819
|
-
chi: []
|
|
2820
|
-
};
|
|
2821
3259
|
const position = {
|
|
2822
3260
|
ind: Math.max(ind, 0),
|
|
2823
3261
|
lin: lin,
|
|
@@ -2825,899 +3263,965 @@
|
|
|
2825
3263
|
};
|
|
2826
3264
|
let value;
|
|
2827
3265
|
let buffer = '';
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
if (options.sourcemap) {
|
|
2833
|
-
ast.loc = {
|
|
2834
|
-
sta: {
|
|
2835
|
-
ind: ind,
|
|
2836
|
-
lin: lin,
|
|
2837
|
-
col: col
|
|
2838
|
-
},
|
|
2839
|
-
src: ''
|
|
2840
|
-
};
|
|
2841
|
-
}
|
|
2842
|
-
function getType(val) {
|
|
2843
|
-
if (val === '') {
|
|
2844
|
-
throw new Error('empty string?');
|
|
2845
|
-
}
|
|
2846
|
-
if (val == ':') {
|
|
2847
|
-
return { typ: 'Colon' };
|
|
2848
|
-
}
|
|
2849
|
-
if (val == ')') {
|
|
2850
|
-
return { typ: 'End-parens' };
|
|
2851
|
-
}
|
|
2852
|
-
if (val == '(') {
|
|
2853
|
-
return { typ: 'Start-parens' };
|
|
2854
|
-
}
|
|
2855
|
-
if (val == '=') {
|
|
2856
|
-
return { typ: 'Delim', val };
|
|
2857
|
-
}
|
|
2858
|
-
if (val == ';') {
|
|
2859
|
-
return { typ: 'Semi-colon' };
|
|
2860
|
-
}
|
|
2861
|
-
if (val == ',') {
|
|
2862
|
-
return { typ: 'Comma' };
|
|
2863
|
-
}
|
|
2864
|
-
if (val == '<') {
|
|
2865
|
-
return { typ: 'Lt' };
|
|
3266
|
+
function consumeWhiteSpace() {
|
|
3267
|
+
let count = 0;
|
|
3268
|
+
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
3269
|
+
count++;
|
|
2866
3270
|
}
|
|
2867
|
-
|
|
2868
|
-
|
|
3271
|
+
next(count);
|
|
3272
|
+
return count;
|
|
3273
|
+
}
|
|
3274
|
+
function pushToken(token, hint) {
|
|
3275
|
+
const result = { token, hint, position: { ...position }, bytesIn: ind };
|
|
3276
|
+
position.ind = ind;
|
|
3277
|
+
position.lin = lin;
|
|
3278
|
+
position.col = col == 0 ? 1 : col;
|
|
3279
|
+
return result;
|
|
3280
|
+
}
|
|
3281
|
+
function* consumeString(quoteStr) {
|
|
3282
|
+
const quote = quoteStr;
|
|
3283
|
+
let value;
|
|
3284
|
+
let hasNewLine = false;
|
|
3285
|
+
if (buffer.length > 0) {
|
|
3286
|
+
yield pushToken(buffer);
|
|
3287
|
+
buffer = '';
|
|
2869
3288
|
}
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
3289
|
+
buffer += quoteStr;
|
|
3290
|
+
while (value = peek()) {
|
|
3291
|
+
if (ind >= iterator.length) {
|
|
3292
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
3293
|
+
break;
|
|
2875
3294
|
}
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
};
|
|
2894
|
-
}
|
|
2895
|
-
if (isNumber(val)) {
|
|
2896
|
-
return {
|
|
2897
|
-
typ: 'Number',
|
|
2898
|
-
val
|
|
2899
|
-
};
|
|
2900
|
-
}
|
|
2901
|
-
if (isDimension(val)) {
|
|
2902
|
-
return parseDimension(val);
|
|
2903
|
-
}
|
|
2904
|
-
if (isPercentage(val)) {
|
|
2905
|
-
return {
|
|
2906
|
-
typ: 'Perc',
|
|
2907
|
-
val: val.slice(0, -1)
|
|
2908
|
-
};
|
|
2909
|
-
}
|
|
2910
|
-
if (val == 'currentColor') {
|
|
2911
|
-
return {
|
|
2912
|
-
typ: 'Color',
|
|
2913
|
-
val,
|
|
2914
|
-
kin: 'lit'
|
|
2915
|
-
};
|
|
2916
|
-
}
|
|
2917
|
-
if (isIdent(val)) {
|
|
2918
|
-
return {
|
|
2919
|
-
typ: 'Iden',
|
|
2920
|
-
val
|
|
2921
|
-
};
|
|
2922
|
-
}
|
|
2923
|
-
if (val.charAt(0) == '#' && isHash(val)) {
|
|
2924
|
-
return {
|
|
2925
|
-
typ: 'Hash',
|
|
2926
|
-
val
|
|
2927
|
-
};
|
|
2928
|
-
}
|
|
2929
|
-
if ('"\''.includes(val.charAt(0))) {
|
|
2930
|
-
return {
|
|
2931
|
-
typ: 'Unclosed-string',
|
|
2932
|
-
val
|
|
2933
|
-
};
|
|
2934
|
-
}
|
|
2935
|
-
return {
|
|
2936
|
-
typ: 'Literal',
|
|
2937
|
-
val
|
|
2938
|
-
};
|
|
2939
|
-
}
|
|
2940
|
-
// consume and throw away
|
|
2941
|
-
function consume(open, close) {
|
|
2942
|
-
let count = 1;
|
|
2943
|
-
let chr;
|
|
2944
|
-
while (true) {
|
|
2945
|
-
chr = next();
|
|
2946
|
-
if (chr == '\\') {
|
|
2947
|
-
if (peek() === '') {
|
|
3295
|
+
if (value == '\\') {
|
|
3296
|
+
const sequence = peek(6);
|
|
3297
|
+
let escapeSequence = '';
|
|
3298
|
+
let codepoint;
|
|
3299
|
+
let i;
|
|
3300
|
+
for (i = 1; i < sequence.length; i++) {
|
|
3301
|
+
codepoint = sequence.charCodeAt(i);
|
|
3302
|
+
if (codepoint == 0x20 ||
|
|
3303
|
+
(codepoint >= 0x61 && codepoint <= 0x66) ||
|
|
3304
|
+
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
3305
|
+
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
3306
|
+
escapeSequence += sequence[i];
|
|
3307
|
+
if (codepoint == 0x20) {
|
|
3308
|
+
break;
|
|
3309
|
+
}
|
|
3310
|
+
continue;
|
|
3311
|
+
}
|
|
2948
3312
|
break;
|
|
2949
3313
|
}
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
3314
|
+
// not hex or new line
|
|
3315
|
+
// @ts-ignore
|
|
3316
|
+
if (i == 1 && !isNewLine(codepoint)) {
|
|
3317
|
+
buffer += sequence[i];
|
|
3318
|
+
next(2);
|
|
3319
|
+
continue;
|
|
3320
|
+
}
|
|
3321
|
+
if (escapeSequence.trimEnd().length > 0) {
|
|
3322
|
+
const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
|
|
3323
|
+
if (codepoint == 0 ||
|
|
3324
|
+
// leading surrogate
|
|
3325
|
+
(0xD800 <= codepoint && codepoint <= 0xDBFF) ||
|
|
3326
|
+
// trailing surrogate
|
|
3327
|
+
(0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
|
|
3328
|
+
buffer += String.fromCodePoint(0xFFFD);
|
|
2958
3329
|
}
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
break;
|
|
3330
|
+
else {
|
|
3331
|
+
buffer += String.fromCodePoint(codepoint);
|
|
2962
3332
|
}
|
|
3333
|
+
next(escapeSequence.length + 1);
|
|
3334
|
+
continue;
|
|
2963
3335
|
}
|
|
3336
|
+
// buffer += value;
|
|
3337
|
+
if (ind >= iterator.length) {
|
|
3338
|
+
// drop '\\' at the end
|
|
3339
|
+
yield pushToken(buffer);
|
|
3340
|
+
break;
|
|
3341
|
+
}
|
|
3342
|
+
buffer += next(2);
|
|
3343
|
+
continue;
|
|
2964
3344
|
}
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
if (chr === '' || count == 0) {
|
|
3345
|
+
if (value == quote) {
|
|
3346
|
+
buffer += value;
|
|
3347
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
|
|
3348
|
+
next();
|
|
3349
|
+
// i += value.length;
|
|
3350
|
+
buffer = '';
|
|
2972
3351
|
break;
|
|
2973
3352
|
}
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
async function parseNode(tokens) {
|
|
2977
|
-
let i;
|
|
2978
|
-
let loc;
|
|
2979
|
-
for (i = 0; i < tokens.length; i++) {
|
|
2980
|
-
if (tokens[i].typ == 'Comment') {
|
|
2981
|
-
// @ts-ignore
|
|
2982
|
-
context.chi.push(tokens[i]);
|
|
2983
|
-
const position = map.get(tokens[i]);
|
|
2984
|
-
loc = {
|
|
2985
|
-
sta: position,
|
|
2986
|
-
src
|
|
2987
|
-
};
|
|
2988
|
-
if (options.sourcemap) {
|
|
2989
|
-
tokens[i].loc = loc;
|
|
2990
|
-
}
|
|
3353
|
+
if (isNewLine(value.charCodeAt(0))) {
|
|
3354
|
+
hasNewLine = true;
|
|
2991
3355
|
}
|
|
2992
|
-
|
|
3356
|
+
if (hasNewLine && value == ';') {
|
|
3357
|
+
yield pushToken(buffer, 'Bad-string');
|
|
3358
|
+
buffer = '';
|
|
2993
3359
|
break;
|
|
2994
3360
|
}
|
|
3361
|
+
buffer += value;
|
|
3362
|
+
// i += value.length;
|
|
3363
|
+
next();
|
|
2995
3364
|
}
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
let delim = tokens.at(-1);
|
|
3001
|
-
if (delim.typ == 'Semi-colon' || delim.typ == 'Block-start' || delim.typ == 'Block-end') {
|
|
3002
|
-
tokens.pop();
|
|
3365
|
+
}
|
|
3366
|
+
function peek(count = 1) {
|
|
3367
|
+
if (count == 1) {
|
|
3368
|
+
return iterator.charAt(ind + 1);
|
|
3003
3369
|
}
|
|
3004
|
-
|
|
3005
|
-
|
|
3370
|
+
return iterator.slice(ind + 1, ind + count + 1);
|
|
3371
|
+
}
|
|
3372
|
+
function prev(count = 1) {
|
|
3373
|
+
if (count == 1) {
|
|
3374
|
+
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
3006
3375
|
}
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3376
|
+
return iterator.slice(ind - 1 - count, ind - 1);
|
|
3377
|
+
}
|
|
3378
|
+
function next(count = 1) {
|
|
3379
|
+
let char = '';
|
|
3380
|
+
while (count-- > 0 && ind < iterator.length) {
|
|
3381
|
+
const codepoint = iterator.charCodeAt(++ind);
|
|
3382
|
+
if (isNaN(codepoint)) {
|
|
3383
|
+
return char;
|
|
3384
|
+
}
|
|
3385
|
+
char += iterator.charAt(ind);
|
|
3386
|
+
if (isNewLine(codepoint)) {
|
|
3387
|
+
lin++;
|
|
3388
|
+
col = 0;
|
|
3389
|
+
}
|
|
3390
|
+
else {
|
|
3391
|
+
col++;
|
|
3392
|
+
}
|
|
3010
3393
|
}
|
|
3011
|
-
|
|
3012
|
-
|
|
3394
|
+
return char;
|
|
3395
|
+
}
|
|
3396
|
+
while (value = next()) {
|
|
3397
|
+
if (ind >= iterator.length) {
|
|
3398
|
+
if (buffer.length > 0) {
|
|
3399
|
+
yield pushToken(buffer);
|
|
3400
|
+
buffer = '';
|
|
3401
|
+
}
|
|
3402
|
+
break;
|
|
3013
3403
|
}
|
|
3014
|
-
if (
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
errors.push({ action: 'drop', message: 'invalid @charset', location: { src, ...position } });
|
|
3019
|
-
return null;
|
|
3404
|
+
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
3405
|
+
if (buffer.length > 0) {
|
|
3406
|
+
yield pushToken(buffer);
|
|
3407
|
+
buffer = '';
|
|
3020
3408
|
}
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3409
|
+
while (value = next()) {
|
|
3410
|
+
if (ind >= iterator.length) {
|
|
3411
|
+
break;
|
|
3412
|
+
}
|
|
3413
|
+
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
3414
|
+
break;
|
|
3415
|
+
}
|
|
3024
3416
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3417
|
+
yield pushToken('', 'Whitespace');
|
|
3418
|
+
buffer = '';
|
|
3419
|
+
if (ind >= iterator.length) {
|
|
3420
|
+
break;
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
switch (value) {
|
|
3424
|
+
case '/':
|
|
3425
|
+
if (buffer.length > 0) {
|
|
3426
|
+
yield pushToken(buffer);
|
|
3427
|
+
buffer = '';
|
|
3428
|
+
if (peek() != '*') {
|
|
3429
|
+
yield pushToken(value);
|
|
3430
|
+
break;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
buffer += value;
|
|
3434
|
+
if (peek() == '*') {
|
|
3435
|
+
buffer += '*';
|
|
3436
|
+
// i++;
|
|
3437
|
+
next();
|
|
3438
|
+
while (value = next()) {
|
|
3439
|
+
if (ind >= iterator.length) {
|
|
3440
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3441
|
+
break;
|
|
3442
|
+
}
|
|
3443
|
+
if (value == '\\') {
|
|
3444
|
+
buffer += value;
|
|
3445
|
+
value = next();
|
|
3446
|
+
if (ind >= iterator.length) {
|
|
3447
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3448
|
+
break;
|
|
3449
|
+
}
|
|
3450
|
+
buffer += value;
|
|
3032
3451
|
continue;
|
|
3033
3452
|
}
|
|
3034
|
-
if (
|
|
3035
|
-
|
|
3036
|
-
|
|
3453
|
+
if (value == '*') {
|
|
3454
|
+
buffer += value;
|
|
3455
|
+
value = next();
|
|
3456
|
+
if (ind >= iterator.length) {
|
|
3457
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3458
|
+
break;
|
|
3459
|
+
}
|
|
3460
|
+
buffer += value;
|
|
3461
|
+
if (value == '/') {
|
|
3462
|
+
yield pushToken(buffer, 'Comment');
|
|
3463
|
+
buffer = '';
|
|
3464
|
+
break;
|
|
3465
|
+
}
|
|
3037
3466
|
}
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
3041
|
-
return null;
|
|
3467
|
+
else {
|
|
3468
|
+
buffer += value;
|
|
3042
3469
|
}
|
|
3043
|
-
break;
|
|
3044
3470
|
}
|
|
3045
3471
|
}
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
// @ts-ignore
|
|
3052
|
-
if (tokens[0].typ == 'UrlFunc' && tokens[1]?.typ != 'Url-token' && tokens[1]?.typ != 'String') {
|
|
3053
|
-
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
3054
|
-
return null;
|
|
3472
|
+
break;
|
|
3473
|
+
case '<':
|
|
3474
|
+
if (buffer.length > 0) {
|
|
3475
|
+
yield pushToken(buffer);
|
|
3476
|
+
buffer = '';
|
|
3055
3477
|
}
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
tokens.shift();
|
|
3061
|
-
// @ts-ignore
|
|
3062
|
-
tokens[0].typ = 'String';
|
|
3063
|
-
// @ts-ignore
|
|
3064
|
-
tokens[0].val = `"${tokens[0].val}"`;
|
|
3478
|
+
buffer += value;
|
|
3479
|
+
value = next();
|
|
3480
|
+
if (ind >= iterator.length) {
|
|
3481
|
+
break;
|
|
3065
3482
|
}
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
try {
|
|
3071
|
-
// @ts-ignore
|
|
3072
|
-
const root = await options.load(url, options.src).then((src) => {
|
|
3073
|
-
return parse$1(src, Object.assign({}, options, {
|
|
3074
|
-
compress: false,
|
|
3075
|
-
// @ts-ignore
|
|
3076
|
-
src: options.resolve(url, options.src).absolute
|
|
3077
|
-
}));
|
|
3078
|
-
});
|
|
3079
|
-
bytesIn += root.bytesIn;
|
|
3080
|
-
if (root.ast.chi.length > 0) {
|
|
3081
|
-
context.chi.push(...root.ast.chi);
|
|
3082
|
-
}
|
|
3083
|
-
if (root.errors.length > 0) {
|
|
3084
|
-
errors.push(...root.errors);
|
|
3085
|
-
}
|
|
3086
|
-
return null;
|
|
3483
|
+
if (peek(3) == '!--') {
|
|
3484
|
+
while (value = next()) {
|
|
3485
|
+
if (ind >= iterator.length) {
|
|
3486
|
+
break;
|
|
3087
3487
|
}
|
|
3088
|
-
|
|
3089
|
-
|
|
3488
|
+
buffer += value;
|
|
3489
|
+
if (value == '>' && prev(2) == '--') {
|
|
3490
|
+
yield pushToken(buffer, 'CDOCOMM');
|
|
3491
|
+
buffer = '';
|
|
3492
|
+
break;
|
|
3090
3493
|
}
|
|
3091
3494
|
}
|
|
3092
3495
|
}
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
// there must be a top level rule in the stack
|
|
3097
|
-
const raw = tokens.reduce((acc, curr, index, array) => {
|
|
3098
|
-
acc.push(renderToken(curr, { removeComments: true }));
|
|
3099
|
-
return acc;
|
|
3100
|
-
}, []);
|
|
3101
|
-
const node = {
|
|
3102
|
-
typ: 'AtRule',
|
|
3103
|
-
nam: renderToken(atRule, { removeComments: true }),
|
|
3104
|
-
val: raw.join('')
|
|
3105
|
-
};
|
|
3106
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: false, value: raw });
|
|
3107
|
-
if (delim.typ == 'Block-start') {
|
|
3108
|
-
node.chi = [];
|
|
3109
|
-
}
|
|
3110
|
-
loc = {
|
|
3111
|
-
sta: position,
|
|
3112
|
-
src
|
|
3113
|
-
};
|
|
3114
|
-
if (options.sourcemap) {
|
|
3115
|
-
node.loc = loc;
|
|
3116
|
-
}
|
|
3117
|
-
// @ts-ignore
|
|
3118
|
-
context.chi.push(node);
|
|
3119
|
-
return delim.typ == 'Block-start' ? node : null;
|
|
3120
|
-
}
|
|
3121
|
-
else {
|
|
3122
|
-
// rule
|
|
3123
|
-
if (delim.typ == 'Block-start') {
|
|
3124
|
-
const position = map.get(tokens[0]);
|
|
3125
|
-
if (context.typ == 'Rule') {
|
|
3126
|
-
if (tokens[0]?.typ == 'Iden') {
|
|
3127
|
-
errors.push({ action: 'drop', message: 'invalid nesting rule', location: { src, ...position } });
|
|
3128
|
-
return null;
|
|
3129
|
-
}
|
|
3496
|
+
if (ind >= iterator.length) {
|
|
3497
|
+
yield pushToken(buffer, 'BADCDO');
|
|
3498
|
+
buffer = '';
|
|
3130
3499
|
}
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
return acc;
|
|
3141
|
-
}, [[]]).reduce((acc, curr) => {
|
|
3142
|
-
acc.set(curr.join(''), curr);
|
|
3143
|
-
return acc;
|
|
3144
|
-
}, uniq);
|
|
3145
|
-
const node = {
|
|
3146
|
-
typ: 'Rule',
|
|
3147
|
-
// @ts-ignore
|
|
3148
|
-
sel: [...uniq.keys()].join(','),
|
|
3149
|
-
chi: []
|
|
3150
|
-
};
|
|
3151
|
-
let raw = [...uniq.values()];
|
|
3152
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
3153
|
-
loc = {
|
|
3154
|
-
sta: position,
|
|
3155
|
-
src
|
|
3156
|
-
};
|
|
3157
|
-
if (options.sourcemap) {
|
|
3158
|
-
node.loc = loc;
|
|
3500
|
+
break;
|
|
3501
|
+
case '\\':
|
|
3502
|
+
value = next();
|
|
3503
|
+
// EOF
|
|
3504
|
+
if (ind + 1 >= iterator.length) {
|
|
3505
|
+
// end of stream ignore \\
|
|
3506
|
+
yield pushToken(buffer);
|
|
3507
|
+
buffer = '';
|
|
3508
|
+
break;
|
|
3159
3509
|
}
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
if (tokens[i].typ == 'Comment') {
|
|
3172
|
-
continue;
|
|
3173
|
-
}
|
|
3174
|
-
if (tokens[i].typ == 'Colon') {
|
|
3175
|
-
name = tokens.slice(0, i);
|
|
3176
|
-
value = parseTokens(tokens.slice(i + 1), {
|
|
3177
|
-
parseColor: true,
|
|
3178
|
-
src: options.src,
|
|
3179
|
-
resolveUrls: options.resolveUrls,
|
|
3180
|
-
resolve: options.resolve,
|
|
3181
|
-
cwd: options.cwd
|
|
3182
|
-
});
|
|
3183
|
-
}
|
|
3510
|
+
buffer += value;
|
|
3511
|
+
break;
|
|
3512
|
+
case '"':
|
|
3513
|
+
case "'":
|
|
3514
|
+
yield* consumeString(value);
|
|
3515
|
+
break;
|
|
3516
|
+
case '~':
|
|
3517
|
+
case '|':
|
|
3518
|
+
if (buffer.length > 0) {
|
|
3519
|
+
yield pushToken(buffer);
|
|
3520
|
+
buffer = '';
|
|
3184
3521
|
}
|
|
3185
|
-
|
|
3186
|
-
|
|
3522
|
+
buffer += value;
|
|
3523
|
+
value = next();
|
|
3524
|
+
if (ind >= iterator.length) {
|
|
3525
|
+
yield pushToken(buffer);
|
|
3526
|
+
buffer = '';
|
|
3527
|
+
break;
|
|
3187
3528
|
}
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
action: 'drop',
|
|
3194
|
-
message: 'invalid declaration',
|
|
3195
|
-
location: { src, ...position }
|
|
3196
|
-
});
|
|
3197
|
-
return null;
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3529
|
+
if (value == '=') {
|
|
3530
|
+
buffer += value;
|
|
3531
|
+
yield pushToken(buffer, buffer[0] == '~' ? 'Includes' : 'Dash-matches');
|
|
3532
|
+
buffer = '';
|
|
3533
|
+
break;
|
|
3200
3534
|
}
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3535
|
+
yield pushToken(buffer);
|
|
3536
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3537
|
+
value = next();
|
|
3204
3538
|
}
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3539
|
+
buffer = value;
|
|
3540
|
+
break;
|
|
3541
|
+
case '>':
|
|
3542
|
+
if (buffer !== '') {
|
|
3543
|
+
yield pushToken(buffer);
|
|
3544
|
+
buffer = '';
|
|
3208
3545
|
}
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3546
|
+
yield pushToken('', 'Gt');
|
|
3547
|
+
consumeWhiteSpace();
|
|
3548
|
+
break;
|
|
3549
|
+
case '.':
|
|
3550
|
+
const codepoint = peek().charCodeAt(0);
|
|
3551
|
+
if (!isDigit(codepoint) && buffer !== '') {
|
|
3552
|
+
yield pushToken(buffer);
|
|
3553
|
+
buffer = value;
|
|
3554
|
+
break;
|
|
3218
3555
|
}
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3556
|
+
buffer += value;
|
|
3557
|
+
break;
|
|
3558
|
+
case '+':
|
|
3559
|
+
case ':':
|
|
3560
|
+
case ',':
|
|
3561
|
+
case '=':
|
|
3562
|
+
if (buffer.length > 0) {
|
|
3563
|
+
yield pushToken(buffer);
|
|
3564
|
+
buffer = '';
|
|
3565
|
+
}
|
|
3566
|
+
if (value == ':' && ':' == peek()) {
|
|
3567
|
+
buffer += value + next();
|
|
3568
|
+
break;
|
|
3569
|
+
}
|
|
3570
|
+
yield pushToken(value);
|
|
3571
|
+
buffer = '';
|
|
3572
|
+
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
3573
|
+
yield pushToken(next());
|
|
3574
|
+
}
|
|
3575
|
+
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
3576
|
+
next();
|
|
3222
3577
|
}
|
|
3223
|
-
// @ts-ignore
|
|
3224
|
-
context.chi.push(node);
|
|
3225
|
-
return null;
|
|
3226
|
-
}
|
|
3227
|
-
}
|
|
3228
|
-
}
|
|
3229
|
-
function peek(count = 1) {
|
|
3230
|
-
if (count == 1) {
|
|
3231
|
-
return iterator.charAt(ind + 1);
|
|
3232
|
-
}
|
|
3233
|
-
return iterator.slice(ind + 1, ind + count + 1);
|
|
3234
|
-
}
|
|
3235
|
-
function prev(count = 1) {
|
|
3236
|
-
if (count == 1) {
|
|
3237
|
-
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
3238
|
-
}
|
|
3239
|
-
return iterator.slice(ind - 1 - count, ind - 1);
|
|
3240
|
-
}
|
|
3241
|
-
function next(count = 1) {
|
|
3242
|
-
let char = '';
|
|
3243
|
-
while (count-- > 0 && ind < total) {
|
|
3244
|
-
const codepoint = iterator.charCodeAt(++ind);
|
|
3245
|
-
if (isNaN(codepoint)) {
|
|
3246
|
-
return char;
|
|
3247
|
-
}
|
|
3248
|
-
char += iterator.charAt(ind);
|
|
3249
|
-
if (isNewLine(codepoint)) {
|
|
3250
|
-
lin++;
|
|
3251
|
-
col = 0;
|
|
3252
|
-
}
|
|
3253
|
-
else {
|
|
3254
|
-
col++;
|
|
3255
|
-
}
|
|
3256
|
-
}
|
|
3257
|
-
return char;
|
|
3258
|
-
}
|
|
3259
|
-
function pushToken(token) {
|
|
3260
|
-
tokens.push(token);
|
|
3261
|
-
map.set(token, { ...position });
|
|
3262
|
-
position.ind = ind;
|
|
3263
|
-
position.lin = lin;
|
|
3264
|
-
position.col = col == 0 ? 1 : col;
|
|
3265
|
-
// }
|
|
3266
|
-
}
|
|
3267
|
-
function consumeWhiteSpace() {
|
|
3268
|
-
let count = 0;
|
|
3269
|
-
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
3270
|
-
count++;
|
|
3271
|
-
}
|
|
3272
|
-
next(count);
|
|
3273
|
-
return count;
|
|
3274
|
-
}
|
|
3275
|
-
function consumeString(quoteStr) {
|
|
3276
|
-
const quote = quoteStr;
|
|
3277
|
-
let value;
|
|
3278
|
-
let hasNewLine = false;
|
|
3279
|
-
if (buffer.length > 0) {
|
|
3280
|
-
pushToken(getType(buffer));
|
|
3281
|
-
buffer = '';
|
|
3282
|
-
}
|
|
3283
|
-
buffer += quoteStr;
|
|
3284
|
-
while (ind < total) {
|
|
3285
|
-
value = peek();
|
|
3286
|
-
if (ind >= total) {
|
|
3287
|
-
pushToken({ typ: hasNewLine ? 'Bad-string' : 'Unclosed-string', val: buffer });
|
|
3288
3578
|
break;
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
3300
|
-
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
3301
|
-
escapeSequence += sequence[i];
|
|
3302
|
-
if (codepoint == 0x20) {
|
|
3303
|
-
break;
|
|
3304
|
-
}
|
|
3305
|
-
continue;
|
|
3306
|
-
}
|
|
3579
|
+
case ')':
|
|
3580
|
+
if (buffer.length > 0) {
|
|
3581
|
+
yield pushToken(buffer);
|
|
3582
|
+
buffer = '';
|
|
3583
|
+
}
|
|
3584
|
+
yield pushToken('', 'End-parens');
|
|
3585
|
+
break;
|
|
3586
|
+
case '(':
|
|
3587
|
+
if (buffer.length == 0) {
|
|
3588
|
+
yield pushToken('', 'Start-parens');
|
|
3307
3589
|
break;
|
|
3308
3590
|
}
|
|
3309
|
-
|
|
3591
|
+
buffer += value;
|
|
3310
3592
|
// @ts-ignore
|
|
3311
|
-
if (
|
|
3312
|
-
buffer
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3593
|
+
if (buffer == 'url(') {
|
|
3594
|
+
yield pushToken(buffer);
|
|
3595
|
+
buffer = '';
|
|
3596
|
+
// consume either string or url token
|
|
3597
|
+
let whitespace = '';
|
|
3598
|
+
value = peek();
|
|
3599
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3600
|
+
whitespace += value;
|
|
3601
|
+
}
|
|
3602
|
+
if (whitespace.length > 0) {
|
|
3603
|
+
next(whitespace.length);
|
|
3604
|
+
}
|
|
3605
|
+
value = peek();
|
|
3606
|
+
if (value == '"' || value == "'") {
|
|
3607
|
+
yield* consumeString(next());
|
|
3608
|
+
break;
|
|
3324
3609
|
}
|
|
3325
3610
|
else {
|
|
3326
|
-
buffer
|
|
3611
|
+
buffer = '';
|
|
3612
|
+
do {
|
|
3613
|
+
let cp = value.charCodeAt(0);
|
|
3614
|
+
// EOF -
|
|
3615
|
+
if (cp == null) {
|
|
3616
|
+
yield pushToken('', 'Bad-url-token');
|
|
3617
|
+
break;
|
|
3618
|
+
}
|
|
3619
|
+
// ')'
|
|
3620
|
+
if (cp == 0x29 || cp == null) {
|
|
3621
|
+
if (buffer.length == 0) {
|
|
3622
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
3623
|
+
}
|
|
3624
|
+
else {
|
|
3625
|
+
yield pushToken(buffer, 'Url-token');
|
|
3626
|
+
}
|
|
3627
|
+
if (cp != null) {
|
|
3628
|
+
yield pushToken(next());
|
|
3629
|
+
}
|
|
3630
|
+
break;
|
|
3631
|
+
}
|
|
3632
|
+
if (isWhiteSpace(cp)) {
|
|
3633
|
+
whitespace = next();
|
|
3634
|
+
while (true) {
|
|
3635
|
+
value = peek();
|
|
3636
|
+
cp = value.charCodeAt(0);
|
|
3637
|
+
if (isWhiteSpace(cp)) {
|
|
3638
|
+
whitespace += value;
|
|
3639
|
+
continue;
|
|
3640
|
+
}
|
|
3641
|
+
break;
|
|
3642
|
+
}
|
|
3643
|
+
if (cp == null || cp == 0x29) {
|
|
3644
|
+
continue;
|
|
3645
|
+
}
|
|
3646
|
+
// bad url token
|
|
3647
|
+
buffer += next(whitespace.length);
|
|
3648
|
+
do {
|
|
3649
|
+
value = peek();
|
|
3650
|
+
cp = value.charCodeAt(0);
|
|
3651
|
+
if (cp == null || cp == 0x29) {
|
|
3652
|
+
break;
|
|
3653
|
+
}
|
|
3654
|
+
buffer += next();
|
|
3655
|
+
} while (true);
|
|
3656
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
3657
|
+
continue;
|
|
3658
|
+
}
|
|
3659
|
+
buffer += next();
|
|
3660
|
+
value = peek();
|
|
3661
|
+
} while (true);
|
|
3662
|
+
buffer = '';
|
|
3327
3663
|
}
|
|
3328
|
-
|
|
3329
|
-
continue;
|
|
3664
|
+
break;
|
|
3330
3665
|
}
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3666
|
+
yield pushToken(buffer);
|
|
3667
|
+
buffer = '';
|
|
3668
|
+
break;
|
|
3669
|
+
case '[':
|
|
3670
|
+
case ']':
|
|
3671
|
+
case '{':
|
|
3672
|
+
case '}':
|
|
3673
|
+
case ';':
|
|
3674
|
+
if (buffer.length > 0) {
|
|
3675
|
+
yield pushToken(buffer);
|
|
3676
|
+
buffer = '';
|
|
3677
|
+
}
|
|
3678
|
+
yield pushToken(value);
|
|
3679
|
+
break;
|
|
3680
|
+
case '!':
|
|
3681
|
+
if (buffer.length > 0) {
|
|
3682
|
+
yield pushToken(buffer);
|
|
3683
|
+
buffer = '';
|
|
3684
|
+
}
|
|
3685
|
+
const important = peek(9);
|
|
3686
|
+
if (important == 'important') {
|
|
3687
|
+
yield pushToken('', 'Important');
|
|
3688
|
+
next(9);
|
|
3689
|
+
buffer = '';
|
|
3335
3690
|
break;
|
|
3336
3691
|
}
|
|
3337
|
-
buffer
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
if (value == quote) {
|
|
3692
|
+
buffer = '!';
|
|
3693
|
+
break;
|
|
3694
|
+
default:
|
|
3341
3695
|
buffer += value;
|
|
3342
|
-
pushToken({ typ: hasNewLine ? 'Bad-string' : 'String', val: buffer });
|
|
3343
|
-
next();
|
|
3344
|
-
// i += value.length;
|
|
3345
|
-
buffer = '';
|
|
3346
3696
|
break;
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
if (buffer.length > 0) {
|
|
3700
|
+
yield pushToken(buffer);
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
|
|
3704
|
+
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
3705
|
+
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
3706
|
+
/**
|
|
3707
|
+
*
|
|
3708
|
+
* @param iterator
|
|
3709
|
+
* @param opt
|
|
3710
|
+
*/
|
|
3711
|
+
async function parse$1(iterator, opt = {}) {
|
|
3712
|
+
const errors = [];
|
|
3713
|
+
const options = {
|
|
3714
|
+
src: '',
|
|
3715
|
+
sourcemap: false,
|
|
3716
|
+
minify: true,
|
|
3717
|
+
nestingRules: false,
|
|
3718
|
+
resolveImport: false,
|
|
3719
|
+
resolveUrls: false,
|
|
3720
|
+
removeEmpty: true,
|
|
3721
|
+
...opt
|
|
3722
|
+
};
|
|
3723
|
+
if (options.resolveImport) {
|
|
3724
|
+
options.resolveUrls = true;
|
|
3725
|
+
}
|
|
3726
|
+
const src = options.src;
|
|
3727
|
+
const stack = [];
|
|
3728
|
+
const ast = {
|
|
3729
|
+
typ: "StyleSheet",
|
|
3730
|
+
chi: []
|
|
3731
|
+
};
|
|
3732
|
+
let tokens = [];
|
|
3733
|
+
let map = new Map;
|
|
3734
|
+
let bytesIn = 0;
|
|
3735
|
+
let context = ast;
|
|
3736
|
+
if (options.sourcemap) {
|
|
3737
|
+
ast.loc = {
|
|
3738
|
+
sta: {
|
|
3739
|
+
ind: 0,
|
|
3740
|
+
lin: 1,
|
|
3741
|
+
col: 1
|
|
3742
|
+
},
|
|
3743
|
+
src: ''
|
|
3744
|
+
};
|
|
3745
|
+
}
|
|
3746
|
+
async function parseNode(results) {
|
|
3747
|
+
let tokens = results.map(mapToken);
|
|
3748
|
+
let i;
|
|
3749
|
+
let loc;
|
|
3750
|
+
for (i = 0; i < tokens.length; i++) {
|
|
3751
|
+
if (tokens[i].typ == 'Comment') {
|
|
3752
|
+
// @ts-ignore
|
|
3753
|
+
context.chi.push(tokens[i]);
|
|
3754
|
+
const position = map.get(tokens[i]);
|
|
3755
|
+
loc = {
|
|
3756
|
+
sta: position,
|
|
3757
|
+
src
|
|
3758
|
+
};
|
|
3759
|
+
if (options.sourcemap) {
|
|
3760
|
+
tokens[i].loc = loc;
|
|
3761
|
+
}
|
|
3347
3762
|
}
|
|
3348
|
-
if (
|
|
3349
|
-
hasNewLine = true;
|
|
3350
|
-
}
|
|
3351
|
-
if (hasNewLine && value == ';') {
|
|
3352
|
-
pushToken({ typ: 'Bad-string', val: buffer });
|
|
3353
|
-
buffer = '';
|
|
3763
|
+
else if (tokens[i].typ != 'Whitespace') {
|
|
3354
3764
|
break;
|
|
3355
3765
|
}
|
|
3356
|
-
buffer += value;
|
|
3357
|
-
// i += value.length;
|
|
3358
|
-
next();
|
|
3359
3766
|
}
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
if (ind >= total) {
|
|
3364
|
-
if (buffer.length > 0) {
|
|
3365
|
-
pushToken(getType(buffer));
|
|
3366
|
-
buffer = '';
|
|
3367
|
-
}
|
|
3368
|
-
break;
|
|
3767
|
+
tokens = tokens.slice(i);
|
|
3768
|
+
if (tokens.length == 0) {
|
|
3769
|
+
return null;
|
|
3369
3770
|
}
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3771
|
+
let delim = tokens.at(-1);
|
|
3772
|
+
if (delim.typ == 'Semi-colon' || delim.typ == 'Block-start' || delim.typ == 'Block-end') {
|
|
3773
|
+
tokens.pop();
|
|
3774
|
+
}
|
|
3775
|
+
else {
|
|
3776
|
+
delim = { typ: 'Semi-colon' };
|
|
3777
|
+
}
|
|
3778
|
+
// @ts-ignore
|
|
3779
|
+
while (['Whitespace', 'Bad-string', 'Bad-comment'].includes(tokens.at(-1)?.typ)) {
|
|
3780
|
+
tokens.pop();
|
|
3781
|
+
}
|
|
3782
|
+
if (tokens.length == 0) {
|
|
3783
|
+
return null;
|
|
3784
|
+
}
|
|
3785
|
+
if (tokens[0]?.typ == 'At-rule') {
|
|
3786
|
+
const atRule = tokens.shift();
|
|
3787
|
+
const position = map.get(atRule);
|
|
3788
|
+
if (atRule.val == 'charset' && position.ind > 0) {
|
|
3789
|
+
errors.push({ action: 'drop', message: 'invalid @charset', location: { src, ...position } });
|
|
3790
|
+
return null;
|
|
3383
3791
|
}
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
break;
|
|
3792
|
+
// @ts-ignore
|
|
3793
|
+
while (['Whitespace'].includes(tokens[0]?.typ)) {
|
|
3794
|
+
tokens.shift();
|
|
3388
3795
|
}
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
pushToken(getType(value));
|
|
3397
|
-
break;
|
|
3398
|
-
}
|
|
3399
|
-
}
|
|
3400
|
-
buffer += value;
|
|
3401
|
-
if (peek() == '*') {
|
|
3402
|
-
buffer += '*';
|
|
3403
|
-
// i++;
|
|
3404
|
-
next();
|
|
3405
|
-
while (ind < total) {
|
|
3406
|
-
value = next();
|
|
3407
|
-
if (ind >= total) {
|
|
3408
|
-
pushToken({
|
|
3409
|
-
typ: 'Bad-comment', val: buffer
|
|
3410
|
-
});
|
|
3411
|
-
break;
|
|
3412
|
-
}
|
|
3413
|
-
if (value == '\\') {
|
|
3414
|
-
buffer += value;
|
|
3415
|
-
value = next();
|
|
3416
|
-
if (ind >= total) {
|
|
3417
|
-
pushToken({
|
|
3418
|
-
typ: 'Bad-comment',
|
|
3419
|
-
val: buffer
|
|
3420
|
-
});
|
|
3421
|
-
break;
|
|
3422
|
-
}
|
|
3423
|
-
buffer += value;
|
|
3796
|
+
if (atRule.val == 'import') {
|
|
3797
|
+
// only @charset and @layer are accepted before @import
|
|
3798
|
+
if (context.chi.length > 0) {
|
|
3799
|
+
let i = context.chi.length;
|
|
3800
|
+
while (i--) {
|
|
3801
|
+
const type = context.chi[i].typ;
|
|
3802
|
+
if (type == 'Comment') {
|
|
3424
3803
|
continue;
|
|
3425
3804
|
}
|
|
3426
|
-
if (
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
if (ind >= total) {
|
|
3430
|
-
pushToken({
|
|
3431
|
-
typ: 'Bad-comment', val: buffer
|
|
3432
|
-
});
|
|
3433
|
-
break;
|
|
3434
|
-
}
|
|
3435
|
-
buffer += value;
|
|
3436
|
-
if (value == '/') {
|
|
3437
|
-
pushToken({ typ: 'Comment', val: buffer });
|
|
3438
|
-
buffer = '';
|
|
3439
|
-
break;
|
|
3440
|
-
}
|
|
3805
|
+
if (type != 'AtRule') {
|
|
3806
|
+
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
3807
|
+
return null;
|
|
3441
3808
|
}
|
|
3442
|
-
|
|
3443
|
-
|
|
3809
|
+
const name = context.chi[i].nam;
|
|
3810
|
+
if (name != 'charset' && name != 'import' && name != 'layer') {
|
|
3811
|
+
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
3812
|
+
return null;
|
|
3444
3813
|
}
|
|
3814
|
+
break;
|
|
3445
3815
|
}
|
|
3446
3816
|
}
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
buffer = '';
|
|
3817
|
+
// @ts-ignore
|
|
3818
|
+
if (tokens[0]?.typ != 'String' && tokens[0]?.typ != 'UrlFunc') {
|
|
3819
|
+
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
3820
|
+
return null;
|
|
3452
3821
|
}
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3822
|
+
// @ts-ignore
|
|
3823
|
+
if (tokens[0].typ == 'UrlFunc' && tokens[1]?.typ != 'Url-token' && tokens[1]?.typ != 'String') {
|
|
3824
|
+
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
3825
|
+
return null;
|
|
3457
3826
|
}
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3827
|
+
}
|
|
3828
|
+
if (atRule.val == 'import') {
|
|
3829
|
+
// @ts-ignore
|
|
3830
|
+
if (tokens[0].typ == 'UrlFunc' && tokens[1].typ == 'Url-token') {
|
|
3831
|
+
tokens.shift();
|
|
3832
|
+
// @ts-ignore
|
|
3833
|
+
tokens[0].typ = 'String';
|
|
3834
|
+
// @ts-ignore
|
|
3835
|
+
tokens[0].val = `"${tokens[0].val}"`;
|
|
3836
|
+
}
|
|
3837
|
+
// @ts-ignore
|
|
3838
|
+
if (tokens[0].typ == 'String') {
|
|
3839
|
+
if (options.resolveImport) {
|
|
3840
|
+
const url = tokens[0].val.slice(1, -1);
|
|
3841
|
+
try {
|
|
3842
|
+
// @ts-ignore
|
|
3843
|
+
const root = await options.load(url, options.src).then((src) => {
|
|
3844
|
+
return parse$1(src, Object.assign({}, options, {
|
|
3845
|
+
minify: false,
|
|
3846
|
+
// @ts-ignore
|
|
3847
|
+
src: options.resolve(url, options.src).absolute
|
|
3848
|
+
}));
|
|
3469
3849
|
});
|
|
3470
|
-
|
|
3471
|
-
|
|
3850
|
+
bytesIn += root.bytesIn;
|
|
3851
|
+
if (root.ast.chi.length > 0) {
|
|
3852
|
+
context.chi.push(...root.ast.chi);
|
|
3853
|
+
}
|
|
3854
|
+
if (root.errors.length > 0) {
|
|
3855
|
+
errors.push(...root.errors);
|
|
3856
|
+
}
|
|
3857
|
+
return null;
|
|
3858
|
+
}
|
|
3859
|
+
catch (error) {
|
|
3860
|
+
console.error(error);
|
|
3472
3861
|
}
|
|
3473
3862
|
}
|
|
3474
3863
|
}
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
}
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3864
|
+
}
|
|
3865
|
+
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
3866
|
+
// allowed nesting at-rules
|
|
3867
|
+
// there must be a top level rule in the stack
|
|
3868
|
+
const raw = tokens.reduce((acc, curr) => {
|
|
3869
|
+
acc.push(renderToken(curr, { removeComments: true }));
|
|
3870
|
+
return acc;
|
|
3871
|
+
}, []);
|
|
3872
|
+
const node = {
|
|
3873
|
+
typ: 'AtRule',
|
|
3874
|
+
nam: renderToken(atRule, { removeComments: true }),
|
|
3875
|
+
val: raw.join('')
|
|
3876
|
+
};
|
|
3877
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: false, value: raw });
|
|
3878
|
+
if (delim.typ == 'Block-start') {
|
|
3879
|
+
node.chi = [];
|
|
3880
|
+
}
|
|
3881
|
+
loc = {
|
|
3882
|
+
sta: position,
|
|
3883
|
+
src
|
|
3884
|
+
};
|
|
3885
|
+
if (options.sourcemap) {
|
|
3886
|
+
node.loc = loc;
|
|
3887
|
+
}
|
|
3888
|
+
// @ts-ignore
|
|
3889
|
+
context.chi.push(node);
|
|
3890
|
+
return delim.typ == 'Block-start' ? node : null;
|
|
3891
|
+
}
|
|
3892
|
+
else {
|
|
3893
|
+
// rule
|
|
3894
|
+
if (delim.typ == 'Block-start') {
|
|
3895
|
+
const position = map.get(tokens[0]);
|
|
3896
|
+
// if (context.typ == 'Rule') {
|
|
3897
|
+
//
|
|
3898
|
+
// if (tokens[0]?.typ == 'Iden') {
|
|
3899
|
+
// errors.push({action: 'drop', message: 'invalid nesting rule', location: {src, ...position}});
|
|
3900
|
+
// return null;
|
|
3901
|
+
// }
|
|
3902
|
+
// }
|
|
3903
|
+
const uniq = new Map;
|
|
3904
|
+
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
|
|
3905
|
+
if (curr.typ == 'Whitespace') {
|
|
3906
|
+
if (array[index - 1]?.typ == 'Gt' ||
|
|
3907
|
+
array[index + 1]?.typ == 'Gt' ||
|
|
3908
|
+
combinators.includes(array[index - 1]?.val) ||
|
|
3909
|
+
combinators.includes(array[index + 1]?.val)) {
|
|
3910
|
+
return acc;
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
let t = renderToken(curr, { minify: true });
|
|
3914
|
+
if (t == ',') {
|
|
3915
|
+
acc.push([]);
|
|
3916
|
+
}
|
|
3917
|
+
else {
|
|
3918
|
+
acc[acc.length - 1].push(t);
|
|
3919
|
+
}
|
|
3920
|
+
return acc;
|
|
3921
|
+
}, [[]]).reduce((acc, curr) => {
|
|
3922
|
+
acc.set(curr.join(''), curr);
|
|
3923
|
+
return acc;
|
|
3924
|
+
}, uniq);
|
|
3925
|
+
const node = {
|
|
3926
|
+
typ: 'Rule',
|
|
3927
|
+
// @ts-ignore
|
|
3928
|
+
sel: [...uniq.keys()].join(','),
|
|
3929
|
+
chi: []
|
|
3930
|
+
};
|
|
3931
|
+
let raw = [...uniq.values()];
|
|
3932
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
3933
|
+
loc = {
|
|
3934
|
+
sta: position,
|
|
3935
|
+
src
|
|
3936
|
+
};
|
|
3937
|
+
if (options.sourcemap) {
|
|
3938
|
+
node.loc = loc;
|
|
3546
3939
|
}
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3940
|
+
// @ts-ignore
|
|
3941
|
+
context.chi.push(node);
|
|
3942
|
+
return node;
|
|
3943
|
+
}
|
|
3944
|
+
else {
|
|
3945
|
+
// declaration
|
|
3946
|
+
// @ts-ignore
|
|
3947
|
+
let name = null;
|
|
3948
|
+
// @ts-ignore
|
|
3949
|
+
let value = null;
|
|
3950
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
3951
|
+
if (tokens[i].typ == 'Comment') {
|
|
3952
|
+
continue;
|
|
3953
|
+
}
|
|
3954
|
+
if (tokens[i].typ == 'Colon') {
|
|
3955
|
+
name = tokens.slice(0, i);
|
|
3956
|
+
value = parseTokens(tokens.slice(i + 1), {
|
|
3957
|
+
parseColor: true,
|
|
3958
|
+
src: options.src,
|
|
3959
|
+
resolveUrls: options.resolveUrls,
|
|
3960
|
+
resolve: options.resolve,
|
|
3961
|
+
cwd: options.cwd
|
|
3962
|
+
});
|
|
3963
|
+
}
|
|
3552
3964
|
}
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
case '(':
|
|
3556
|
-
if (buffer.length == 0) {
|
|
3557
|
-
pushToken({ typ: 'Start-parens' });
|
|
3965
|
+
if (name == null) {
|
|
3966
|
+
name = tokens;
|
|
3558
3967
|
}
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
whitespace += value;
|
|
3570
|
-
}
|
|
3571
|
-
if (whitespace.length > 0) {
|
|
3572
|
-
next(whitespace.length);
|
|
3573
|
-
}
|
|
3574
|
-
value = peek();
|
|
3575
|
-
if (value == '"' || value == "'") {
|
|
3576
|
-
consumeString(next());
|
|
3577
|
-
let token = tokens[tokens.length - 1];
|
|
3578
|
-
if (['String', 'Literal'].includes(token.typ) && urlTokenMatcher.test(token.val)) {
|
|
3579
|
-
if (token.val.slice(1, 6) != 'data:') {
|
|
3580
|
-
if (token.typ == 'String') {
|
|
3581
|
-
token.val = token.val.slice(1, -1);
|
|
3582
|
-
}
|
|
3583
|
-
// @ts-ignore
|
|
3584
|
-
token.typ = 'Url-token';
|
|
3585
|
-
}
|
|
3586
|
-
}
|
|
3587
|
-
break;
|
|
3588
|
-
}
|
|
3589
|
-
else {
|
|
3590
|
-
buffer = '';
|
|
3591
|
-
do {
|
|
3592
|
-
let cp = value.charCodeAt(0);
|
|
3593
|
-
// EOF -
|
|
3594
|
-
if (cp == null) {
|
|
3595
|
-
pushToken({ typ: 'Bad-url-token', val: buffer });
|
|
3596
|
-
break;
|
|
3597
|
-
}
|
|
3598
|
-
// ')'
|
|
3599
|
-
if (cp == 0x29 || cp == null) {
|
|
3600
|
-
if (buffer.length == 0) {
|
|
3601
|
-
pushToken({ typ: 'Bad-url-token', val: '' });
|
|
3602
|
-
}
|
|
3603
|
-
else {
|
|
3604
|
-
pushToken({ typ: 'Url-token', val: buffer });
|
|
3605
|
-
}
|
|
3606
|
-
if (cp != null) {
|
|
3607
|
-
pushToken(getType(next()));
|
|
3608
|
-
}
|
|
3609
|
-
break;
|
|
3610
|
-
}
|
|
3611
|
-
if (isWhiteSpace(cp)) {
|
|
3612
|
-
whitespace = next();
|
|
3613
|
-
while (true) {
|
|
3614
|
-
value = peek();
|
|
3615
|
-
cp = value.charCodeAt(0);
|
|
3616
|
-
if (isWhiteSpace(cp)) {
|
|
3617
|
-
whitespace += value;
|
|
3618
|
-
continue;
|
|
3619
|
-
}
|
|
3620
|
-
break;
|
|
3621
|
-
}
|
|
3622
|
-
if (cp == null || cp == 0x29) {
|
|
3623
|
-
continue;
|
|
3624
|
-
}
|
|
3625
|
-
// bad url token
|
|
3626
|
-
buffer += next(whitespace.length);
|
|
3627
|
-
do {
|
|
3628
|
-
value = peek();
|
|
3629
|
-
cp = value.charCodeAt(0);
|
|
3630
|
-
if (cp == null || cp == 0x29) {
|
|
3631
|
-
break;
|
|
3632
|
-
}
|
|
3633
|
-
buffer += next();
|
|
3634
|
-
} while (true);
|
|
3635
|
-
pushToken({ typ: 'Bad-url-token', val: buffer });
|
|
3636
|
-
continue;
|
|
3637
|
-
}
|
|
3638
|
-
buffer += next();
|
|
3639
|
-
value = peek();
|
|
3640
|
-
} while (true);
|
|
3641
|
-
buffer = '';
|
|
3968
|
+
const position = map.get(name[0]);
|
|
3969
|
+
if (name.length > 0) {
|
|
3970
|
+
for (let i = 1; i < name.length; i++) {
|
|
3971
|
+
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
3972
|
+
errors.push({
|
|
3973
|
+
action: 'drop',
|
|
3974
|
+
message: 'invalid declaration',
|
|
3975
|
+
location: { src, ...position }
|
|
3976
|
+
});
|
|
3977
|
+
return null;
|
|
3642
3978
|
}
|
|
3643
3979
|
}
|
|
3644
3980
|
}
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
pushToken(getType(buffer));
|
|
3653
|
-
buffer = '';
|
|
3981
|
+
if (value == null) {
|
|
3982
|
+
errors.push({
|
|
3983
|
+
action: 'drop',
|
|
3984
|
+
message: 'invalid declaration',
|
|
3985
|
+
location: { src, ...position }
|
|
3986
|
+
});
|
|
3987
|
+
return null;
|
|
3654
3988
|
}
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
context = node;
|
|
3663
|
-
}
|
|
3664
|
-
else if (value == '{') {
|
|
3665
|
-
// node == null
|
|
3666
|
-
// consume and throw away until the closing '}' or EOF
|
|
3667
|
-
consume('{', '}');
|
|
3668
|
-
}
|
|
3669
|
-
tokens.length = 0;
|
|
3670
|
-
map.clear();
|
|
3989
|
+
if (value.length == 0) {
|
|
3990
|
+
errors.push({
|
|
3991
|
+
action: 'drop',
|
|
3992
|
+
message: 'invalid declaration',
|
|
3993
|
+
location: { src, ...position }
|
|
3994
|
+
});
|
|
3995
|
+
return null;
|
|
3671
3996
|
}
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
const previousNode = stack.pop();
|
|
3997
|
+
const node = {
|
|
3998
|
+
typ: 'Declaration',
|
|
3675
3999
|
// @ts-ignore
|
|
3676
|
-
|
|
4000
|
+
nam: renderToken(name.shift(), { removeComments: true }),
|
|
3677
4001
|
// @ts-ignore
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
map.clear();
|
|
3683
|
-
buffer = '';
|
|
3684
|
-
}
|
|
3685
|
-
break;
|
|
3686
|
-
case '!':
|
|
3687
|
-
if (buffer.length > 0) {
|
|
3688
|
-
pushToken(getType(buffer));
|
|
3689
|
-
buffer = '';
|
|
4002
|
+
val: value
|
|
4003
|
+
};
|
|
4004
|
+
while (node.val[0]?.typ == 'Whitespace') {
|
|
4005
|
+
node.val.shift();
|
|
3690
4006
|
}
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
buffer = '';
|
|
3699
|
-
break;
|
|
4007
|
+
if (node.val.length == 0) {
|
|
4008
|
+
errors.push({
|
|
4009
|
+
action: 'drop',
|
|
4010
|
+
message: 'invalid declaration',
|
|
4011
|
+
location: { src, ...position }
|
|
4012
|
+
});
|
|
4013
|
+
return null;
|
|
3700
4014
|
}
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
break;
|
|
4015
|
+
// @ts-ignore
|
|
4016
|
+
context.chi.push(node);
|
|
4017
|
+
return null;
|
|
4018
|
+
}
|
|
3706
4019
|
}
|
|
3707
4020
|
}
|
|
3708
|
-
|
|
3709
|
-
|
|
4021
|
+
function mapToken(token) {
|
|
4022
|
+
const node = getTokenType(token.token, token.hint);
|
|
4023
|
+
map.set(node, token.position);
|
|
4024
|
+
return node;
|
|
4025
|
+
}
|
|
4026
|
+
const iter = tokenize(iterator);
|
|
4027
|
+
let item;
|
|
4028
|
+
while (true) {
|
|
4029
|
+
item = iter.next().value;
|
|
4030
|
+
if (item == null) {
|
|
4031
|
+
break;
|
|
4032
|
+
}
|
|
4033
|
+
tokens.push(item);
|
|
4034
|
+
bytesIn = item.bytesIn;
|
|
4035
|
+
if (item.token == ';' || item.token == '{') {
|
|
4036
|
+
let node = await parseNode(tokens);
|
|
4037
|
+
if (node != null) {
|
|
4038
|
+
stack.push(node);
|
|
4039
|
+
// @ts-ignore
|
|
4040
|
+
context = node;
|
|
4041
|
+
}
|
|
4042
|
+
else if (item.token == '{') {
|
|
4043
|
+
// node == null
|
|
4044
|
+
// consume and throw away until the closing '}' or EOF
|
|
4045
|
+
let inBlock = 1;
|
|
4046
|
+
do {
|
|
4047
|
+
item = iter.next().value;
|
|
4048
|
+
if (item == null) {
|
|
4049
|
+
break;
|
|
4050
|
+
}
|
|
4051
|
+
if (item.token == '{') {
|
|
4052
|
+
inBlock++;
|
|
4053
|
+
}
|
|
4054
|
+
else if (item.token == '}') {
|
|
4055
|
+
inBlock--;
|
|
4056
|
+
}
|
|
4057
|
+
} while (inBlock != 0);
|
|
4058
|
+
}
|
|
4059
|
+
tokens = [];
|
|
4060
|
+
map = new Map;
|
|
4061
|
+
}
|
|
4062
|
+
else if (item.token == '}') {
|
|
4063
|
+
await parseNode(tokens);
|
|
4064
|
+
const previousNode = stack.pop();
|
|
4065
|
+
// @ts-ignore
|
|
4066
|
+
context = stack[stack.length - 1] || ast;
|
|
4067
|
+
// @ts-ignore
|
|
4068
|
+
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
4069
|
+
context.chi.pop();
|
|
4070
|
+
}
|
|
4071
|
+
tokens = [];
|
|
4072
|
+
map = new Map;
|
|
4073
|
+
}
|
|
3710
4074
|
}
|
|
3711
4075
|
if (tokens.length > 0) {
|
|
3712
4076
|
await parseNode(tokens);
|
|
3713
4077
|
}
|
|
3714
|
-
if (options.
|
|
4078
|
+
if (options.minify) {
|
|
3715
4079
|
if (ast.chi.length > 0) {
|
|
3716
|
-
|
|
4080
|
+
minify(ast, options, true);
|
|
3717
4081
|
}
|
|
3718
4082
|
}
|
|
3719
4083
|
return { ast, errors, bytesIn };
|
|
3720
4084
|
}
|
|
4085
|
+
function parseString(src, options = { location: false }) {
|
|
4086
|
+
return [...tokenize(src)].map(t => {
|
|
4087
|
+
const token = getTokenType(t.token, t.hint);
|
|
4088
|
+
if (options.location) {
|
|
4089
|
+
Object.assign(token, { loc: t.position });
|
|
4090
|
+
}
|
|
4091
|
+
return token;
|
|
4092
|
+
});
|
|
4093
|
+
}
|
|
4094
|
+
function getTokenType(val, hint) {
|
|
4095
|
+
if (val === '' && hint == null) {
|
|
4096
|
+
throw new Error('empty string?');
|
|
4097
|
+
}
|
|
4098
|
+
if (hint != null) {
|
|
4099
|
+
return ([
|
|
4100
|
+
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
|
|
4101
|
+
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
|
|
4102
|
+
'Comma', 'Gt', 'Lt'
|
|
4103
|
+
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
4104
|
+
}
|
|
4105
|
+
if (val == ' ') {
|
|
4106
|
+
return { typ: 'Whitespace' };
|
|
4107
|
+
}
|
|
4108
|
+
if (val == ';') {
|
|
4109
|
+
return { typ: 'Semi-colon' };
|
|
4110
|
+
}
|
|
4111
|
+
if (val == '{') {
|
|
4112
|
+
return { typ: 'Block-start' };
|
|
4113
|
+
}
|
|
4114
|
+
if (val == '}') {
|
|
4115
|
+
return { typ: 'Block-end' };
|
|
4116
|
+
}
|
|
4117
|
+
if (val == '[') {
|
|
4118
|
+
return { typ: 'Attr-start' };
|
|
4119
|
+
}
|
|
4120
|
+
if (val == ']') {
|
|
4121
|
+
return { typ: 'Attr-end' };
|
|
4122
|
+
}
|
|
4123
|
+
if (val == ':') {
|
|
4124
|
+
return { typ: 'Colon' };
|
|
4125
|
+
}
|
|
4126
|
+
if (val == ')') {
|
|
4127
|
+
return { typ: 'End-parens' };
|
|
4128
|
+
}
|
|
4129
|
+
if (val == '(') {
|
|
4130
|
+
return { typ: 'Start-parens' };
|
|
4131
|
+
}
|
|
4132
|
+
if (val == '=') {
|
|
4133
|
+
return { typ: 'Delim', val };
|
|
4134
|
+
}
|
|
4135
|
+
if (val == ';') {
|
|
4136
|
+
return { typ: 'Semi-colon' };
|
|
4137
|
+
}
|
|
4138
|
+
if (val == ',') {
|
|
4139
|
+
return { typ: 'Comma' };
|
|
4140
|
+
}
|
|
4141
|
+
if (val == '<') {
|
|
4142
|
+
return { typ: 'Lt' };
|
|
4143
|
+
}
|
|
4144
|
+
if (val == '>') {
|
|
4145
|
+
return { typ: 'Gt' };
|
|
4146
|
+
}
|
|
4147
|
+
if (isPseudo(val)) {
|
|
4148
|
+
return val.endsWith('(') ? {
|
|
4149
|
+
typ: 'Pseudo-class-func',
|
|
4150
|
+
val: val.slice(0, -1),
|
|
4151
|
+
chi: []
|
|
4152
|
+
}
|
|
4153
|
+
: {
|
|
4154
|
+
typ: 'Pseudo-class',
|
|
4155
|
+
val
|
|
4156
|
+
};
|
|
4157
|
+
}
|
|
4158
|
+
if (isAtKeyword(val)) {
|
|
4159
|
+
return {
|
|
4160
|
+
typ: 'At-rule',
|
|
4161
|
+
val: val.slice(1)
|
|
4162
|
+
};
|
|
4163
|
+
}
|
|
4164
|
+
if (isFunction(val)) {
|
|
4165
|
+
val = val.slice(0, -1);
|
|
4166
|
+
return {
|
|
4167
|
+
typ: val == 'url' ? 'UrlFunc' : 'Func',
|
|
4168
|
+
val,
|
|
4169
|
+
chi: []
|
|
4170
|
+
};
|
|
4171
|
+
}
|
|
4172
|
+
if (isNumber(val)) {
|
|
4173
|
+
return {
|
|
4174
|
+
typ: 'Number',
|
|
4175
|
+
val
|
|
4176
|
+
};
|
|
4177
|
+
}
|
|
4178
|
+
if (isDimension(val)) {
|
|
4179
|
+
return parseDimension(val);
|
|
4180
|
+
}
|
|
4181
|
+
if (isPercentage(val)) {
|
|
4182
|
+
return {
|
|
4183
|
+
typ: 'Perc',
|
|
4184
|
+
val: val.slice(0, -1)
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
const v = val.toLowerCase();
|
|
4188
|
+
if (v == 'currentcolor' || val == 'transparent' || v in COLORS_NAMES) {
|
|
4189
|
+
return {
|
|
4190
|
+
typ: 'Color',
|
|
4191
|
+
val,
|
|
4192
|
+
kin: 'lit'
|
|
4193
|
+
};
|
|
4194
|
+
}
|
|
4195
|
+
if (isIdent(val)) {
|
|
4196
|
+
return {
|
|
4197
|
+
typ: 'Iden',
|
|
4198
|
+
val
|
|
4199
|
+
};
|
|
4200
|
+
}
|
|
4201
|
+
if (val.charAt(0) == '#' && isHexColor(val)) {
|
|
4202
|
+
return {
|
|
4203
|
+
typ: 'Color',
|
|
4204
|
+
val,
|
|
4205
|
+
kin: 'hex'
|
|
4206
|
+
};
|
|
4207
|
+
}
|
|
4208
|
+
if (val.charAt(0) == '#' && isHash(val)) {
|
|
4209
|
+
return {
|
|
4210
|
+
typ: 'Hash',
|
|
4211
|
+
val
|
|
4212
|
+
};
|
|
4213
|
+
}
|
|
4214
|
+
if ('"\''.includes(val.charAt(0))) {
|
|
4215
|
+
return {
|
|
4216
|
+
typ: 'Unclosed-string',
|
|
4217
|
+
val
|
|
4218
|
+
};
|
|
4219
|
+
}
|
|
4220
|
+
return {
|
|
4221
|
+
typ: 'Literal',
|
|
4222
|
+
val
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
3721
4225
|
function parseTokens(tokens, options = {}) {
|
|
3722
4226
|
for (let i = 0; i < tokens.length; i++) {
|
|
3723
4227
|
const t = tokens[i];
|
|
@@ -3725,6 +4229,7 @@
|
|
|
3725
4229
|
i + 1 == tokens.length ||
|
|
3726
4230
|
['Comma'].includes(tokens[i + 1].typ) ||
|
|
3727
4231
|
(i > 0 &&
|
|
4232
|
+
tokens[i + 1]?.typ != 'Literal' &&
|
|
3728
4233
|
funcLike.includes(tokens[i - 1].typ) &&
|
|
3729
4234
|
!['var', 'calc'].includes(tokens[i - 1].val))))) {
|
|
3730
4235
|
tokens.splice(i--, 1);
|
|
@@ -3771,7 +4276,7 @@
|
|
|
3771
4276
|
if (t.chi.length > 1) {
|
|
3772
4277
|
/*(<AttrToken>t).chi =*/
|
|
3773
4278
|
// @ts-ignore
|
|
3774
|
-
parseTokens(t.chi,
|
|
4279
|
+
parseTokens(t.chi, t.typ);
|
|
3775
4280
|
}
|
|
3776
4281
|
// @ts-ignore
|
|
3777
4282
|
t.chi.forEach(val => {
|
|
@@ -3883,8 +4388,8 @@
|
|
|
3883
4388
|
// @ts-ignore
|
|
3884
4389
|
if (t.chi.length > 0) {
|
|
3885
4390
|
// @ts-ignore
|
|
3886
|
-
parseTokens(t.chi,
|
|
3887
|
-
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.
|
|
4391
|
+
parseTokens(t.chi, t.typ);
|
|
4392
|
+
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.minify) {
|
|
3888
4393
|
//
|
|
3889
4394
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
3890
4395
|
if (count == 1 ||
|
|
@@ -3922,40 +4427,9 @@
|
|
|
3922
4427
|
}
|
|
3923
4428
|
return tokens;
|
|
3924
4429
|
}
|
|
3925
|
-
function getBlockType(chr) {
|
|
3926
|
-
if (chr == ';') {
|
|
3927
|
-
return { typ: 'Semi-colon' };
|
|
3928
|
-
}
|
|
3929
|
-
if (chr == '{') {
|
|
3930
|
-
return { typ: 'Block-start' };
|
|
3931
|
-
}
|
|
3932
|
-
if (chr == '}') {
|
|
3933
|
-
return { typ: 'Block-end' };
|
|
3934
|
-
}
|
|
3935
|
-
if (chr == '[') {
|
|
3936
|
-
return { typ: 'Attr-start' };
|
|
3937
|
-
}
|
|
3938
|
-
if (chr == ']') {
|
|
3939
|
-
return { typ: 'Attr-end' };
|
|
3940
|
-
}
|
|
3941
|
-
throw new Error(`unhandled token: '${chr}'`);
|
|
3942
|
-
}
|
|
3943
|
-
|
|
3944
|
-
function* walk(node) {
|
|
3945
|
-
// @ts-ignore
|
|
3946
|
-
yield* doWalk(node, null, null);
|
|
3947
|
-
}
|
|
3948
|
-
function* doWalk(node, parent, root) {
|
|
3949
|
-
yield { node, parent, root };
|
|
3950
|
-
if ('chi' in node) {
|
|
3951
|
-
for (const child of node.chi) {
|
|
3952
|
-
yield* doWalk(child, node, (root == null ? node : root));
|
|
3953
|
-
}
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
4430
|
|
|
3957
4431
|
async function transform$1(css, options = {}) {
|
|
3958
|
-
options = {
|
|
4432
|
+
options = { minify: true, removeEmpty: true, ...options };
|
|
3959
4433
|
const startTime = performance.now();
|
|
3960
4434
|
const parseResult = await parse$1(css, options);
|
|
3961
4435
|
const renderTime = performance.now();
|
|
@@ -4103,18 +4577,44 @@
|
|
|
4103
4577
|
}));
|
|
4104
4578
|
}
|
|
4105
4579
|
|
|
4106
|
-
exports.
|
|
4107
|
-
exports.deduplicateRule = deduplicateRule;
|
|
4580
|
+
exports.combinators = combinators;
|
|
4108
4581
|
exports.dirname = dirname;
|
|
4582
|
+
exports.getConfig = getConfig;
|
|
4109
4583
|
exports.hasDeclaration = hasDeclaration;
|
|
4584
|
+
exports.isAngle = isAngle;
|
|
4585
|
+
exports.isAtKeyword = isAtKeyword;
|
|
4586
|
+
exports.isDigit = isDigit;
|
|
4587
|
+
exports.isDimension = isDimension;
|
|
4588
|
+
exports.isFrequency = isFrequency;
|
|
4589
|
+
exports.isFunction = isFunction;
|
|
4590
|
+
exports.isHash = isHash;
|
|
4591
|
+
exports.isHexColor = isHexColor;
|
|
4592
|
+
exports.isHexDigit = isHexDigit;
|
|
4593
|
+
exports.isIdent = isIdent;
|
|
4594
|
+
exports.isIdentCodepoint = isIdentCodepoint;
|
|
4595
|
+
exports.isIdentStart = isIdentStart;
|
|
4596
|
+
exports.isLength = isLength;
|
|
4597
|
+
exports.isNewLine = isNewLine;
|
|
4598
|
+
exports.isNumber = isNumber;
|
|
4599
|
+
exports.isPercentage = isPercentage;
|
|
4600
|
+
exports.isPseudo = isPseudo;
|
|
4601
|
+
exports.isResolution = isResolution;
|
|
4602
|
+
exports.isTime = isTime;
|
|
4603
|
+
exports.isWhiteSpace = isWhiteSpace;
|
|
4110
4604
|
exports.load = load;
|
|
4111
4605
|
exports.matchUrl = matchUrl;
|
|
4606
|
+
exports.minify = minify;
|
|
4607
|
+
exports.minifyRule = minifyRule;
|
|
4112
4608
|
exports.parse = parse;
|
|
4609
|
+
exports.parseDimension = parseDimension;
|
|
4610
|
+
exports.parseString = parseString;
|
|
4113
4611
|
exports.reduceSelector = reduceSelector;
|
|
4114
4612
|
exports.render = render;
|
|
4115
4613
|
exports.renderToken = renderToken;
|
|
4116
4614
|
exports.resolve = resolve;
|
|
4615
|
+
exports.tokenize = tokenize;
|
|
4117
4616
|
exports.transform = transform;
|
|
4617
|
+
exports.urlTokenMatcher = urlTokenMatcher;
|
|
4118
4618
|
exports.walk = walk;
|
|
4119
4619
|
|
|
4120
4620
|
}));
|