@tbela99/css-parser 0.0.1-alpha5 → 0.0.1-rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +1 -0
- package/README.md +20 -8
- package/dist/config.json.js +95 -4
- package/dist/index-umd-web.js +1639 -1400
- package/dist/index.cjs +1639 -1400
- package/dist/index.d.ts +327 -10
- package/dist/index.js +6 -2
- package/dist/lib/{parser/deduplicate.js → ast/minify.js} +413 -418
- 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 +242 -685
- package/dist/lib/parser/tokenize.js +454 -0
- package/dist/lib/parser/utils/eq.js +29 -5
- package/dist/lib/parser/utils/syntax.js +25 -11
- package/dist/lib/renderer/render.js +19 -11
- package/dist/lib/transform.js +12 -14
- package/dist/node/index.js +1 -0
- package/dist/web/index.js +6 -2
- package/package.json +12 -5
- /package/dist/lib/{walker → ast}/walk.js +0 -0
package/dist/index.cjs
CHANGED
|
@@ -6,13 +6,14 @@ var promises = require('fs/promises');
|
|
|
6
6
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
7
7
|
// '\\'
|
|
8
8
|
const REVERSE_SOLIDUS = 0x5c;
|
|
9
|
+
const dimensionUnits = [
|
|
10
|
+
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
11
|
+
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
12
|
+
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
13
|
+
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
14
|
+
];
|
|
9
15
|
function isLength(dimension) {
|
|
10
|
-
return 'unit' in dimension &&
|
|
11
|
-
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
12
|
-
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
13
|
-
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
14
|
-
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
15
|
-
].includes(dimension.unit.toLowerCase());
|
|
16
|
+
return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
|
|
16
17
|
}
|
|
17
18
|
function isResolution(dimension) {
|
|
18
19
|
return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
|
|
@@ -90,10 +91,7 @@ function isHash(name) {
|
|
|
90
91
|
if (name.charAt(0) != '#') {
|
|
91
92
|
return false;
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
return true;
|
|
94
|
+
return isIdent(name.charAt(1));
|
|
97
95
|
}
|
|
98
96
|
function isNumber(name) {
|
|
99
97
|
if (name.length == 0) {
|
|
@@ -237,6 +235,22 @@ function isHexColor(name) {
|
|
|
237
235
|
}
|
|
238
236
|
return true;
|
|
239
237
|
}
|
|
238
|
+
function isHexDigit(name) {
|
|
239
|
+
if (name.length || name.length > 6) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
for (let chr of name) {
|
|
243
|
+
let codepoint = chr.charCodeAt(0);
|
|
244
|
+
if (!isDigit(codepoint) &&
|
|
245
|
+
// A F
|
|
246
|
+
!(codepoint >= 0x41 && codepoint <= 0x46) &&
|
|
247
|
+
// a f
|
|
248
|
+
!(codepoint >= 0x61 && codepoint <= 0x66)) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
240
254
|
function isFunction(name) {
|
|
241
255
|
return name.endsWith('(') && isIdent(name.slice(0, -1));
|
|
242
256
|
}
|
|
@@ -372,6 +386,7 @@ var properties = {
|
|
|
372
386
|
},
|
|
373
387
|
"border-width": {
|
|
374
388
|
shorthand: "border-width",
|
|
389
|
+
map: "border",
|
|
375
390
|
properties: [
|
|
376
391
|
"border-top-width",
|
|
377
392
|
"border-right-width",
|
|
@@ -382,6 +397,9 @@ var properties = {
|
|
|
382
397
|
"Length",
|
|
383
398
|
"Perc"
|
|
384
399
|
],
|
|
400
|
+
"default": [
|
|
401
|
+
"medium"
|
|
402
|
+
],
|
|
385
403
|
keywords: [
|
|
386
404
|
"thin",
|
|
387
405
|
"medium",
|
|
@@ -389,19 +407,24 @@ var properties = {
|
|
|
389
407
|
]
|
|
390
408
|
},
|
|
391
409
|
"border-top-width": {
|
|
410
|
+
map: "border",
|
|
392
411
|
shorthand: "border-width"
|
|
393
412
|
},
|
|
394
413
|
"border-right-width": {
|
|
414
|
+
map: "border",
|
|
395
415
|
shorthand: "border-width"
|
|
396
416
|
},
|
|
397
417
|
"border-bottom-width": {
|
|
418
|
+
map: "border",
|
|
398
419
|
shorthand: "border-width"
|
|
399
420
|
},
|
|
400
421
|
"border-left-width": {
|
|
422
|
+
map: "border",
|
|
401
423
|
shorthand: "border-width"
|
|
402
424
|
},
|
|
403
425
|
"border-style": {
|
|
404
426
|
shorthand: "border-style",
|
|
427
|
+
map: "border",
|
|
405
428
|
properties: [
|
|
406
429
|
"border-top-style",
|
|
407
430
|
"border-right-style",
|
|
@@ -410,6 +433,9 @@ var properties = {
|
|
|
410
433
|
],
|
|
411
434
|
types: [
|
|
412
435
|
],
|
|
436
|
+
"default": [
|
|
437
|
+
"none"
|
|
438
|
+
],
|
|
413
439
|
keywords: [
|
|
414
440
|
"none",
|
|
415
441
|
"hidden",
|
|
@@ -424,19 +450,24 @@ var properties = {
|
|
|
424
450
|
]
|
|
425
451
|
},
|
|
426
452
|
"border-top-style": {
|
|
453
|
+
map: "border",
|
|
427
454
|
shorthand: "border-style"
|
|
428
455
|
},
|
|
429
456
|
"border-right-style": {
|
|
457
|
+
map: "border",
|
|
430
458
|
shorthand: "border-style"
|
|
431
459
|
},
|
|
432
460
|
"border-bottom-style": {
|
|
461
|
+
map: "border",
|
|
433
462
|
shorthand: "border-style"
|
|
434
463
|
},
|
|
435
464
|
"border-left-style": {
|
|
465
|
+
map: "border",
|
|
436
466
|
shorthand: "border-style"
|
|
437
467
|
},
|
|
438
468
|
"border-color": {
|
|
439
469
|
shorthand: "border-color",
|
|
470
|
+
map: "border",
|
|
440
471
|
properties: [
|
|
441
472
|
"border-top-color",
|
|
442
473
|
"border-right-color",
|
|
@@ -446,23 +477,95 @@ var properties = {
|
|
|
446
477
|
types: [
|
|
447
478
|
"Color"
|
|
448
479
|
],
|
|
480
|
+
"default": [
|
|
481
|
+
"currentcolor"
|
|
482
|
+
],
|
|
449
483
|
keywords: [
|
|
450
484
|
]
|
|
451
485
|
},
|
|
452
486
|
"border-top-color": {
|
|
487
|
+
map: "border",
|
|
453
488
|
shorthand: "border-color"
|
|
454
489
|
},
|
|
455
490
|
"border-right-color": {
|
|
491
|
+
map: "border",
|
|
456
492
|
shorthand: "border-color"
|
|
457
493
|
},
|
|
458
494
|
"border-bottom-color": {
|
|
495
|
+
map: "border",
|
|
459
496
|
shorthand: "border-color"
|
|
460
497
|
},
|
|
461
498
|
"border-left-color": {
|
|
499
|
+
map: "border",
|
|
462
500
|
shorthand: "border-color"
|
|
463
501
|
}
|
|
464
502
|
};
|
|
465
503
|
var map = {
|
|
504
|
+
border: {
|
|
505
|
+
shorthand: "border",
|
|
506
|
+
pattern: "border-color border-style border-width",
|
|
507
|
+
keywords: [
|
|
508
|
+
"none"
|
|
509
|
+
],
|
|
510
|
+
"default": [
|
|
511
|
+
"0",
|
|
512
|
+
"none"
|
|
513
|
+
],
|
|
514
|
+
properties: {
|
|
515
|
+
"border-color": {
|
|
516
|
+
types: [
|
|
517
|
+
"Color"
|
|
518
|
+
],
|
|
519
|
+
"default": [
|
|
520
|
+
"currentcolor"
|
|
521
|
+
],
|
|
522
|
+
keywords: [
|
|
523
|
+
]
|
|
524
|
+
},
|
|
525
|
+
"border-style": {
|
|
526
|
+
types: [
|
|
527
|
+
],
|
|
528
|
+
"default": [
|
|
529
|
+
"none"
|
|
530
|
+
],
|
|
531
|
+
keywords: [
|
|
532
|
+
"none",
|
|
533
|
+
"hidden",
|
|
534
|
+
"dotted",
|
|
535
|
+
"dashed",
|
|
536
|
+
"solid",
|
|
537
|
+
"double",
|
|
538
|
+
"groove",
|
|
539
|
+
"ridge",
|
|
540
|
+
"inset",
|
|
541
|
+
"outset"
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
"border-width": {
|
|
545
|
+
types: [
|
|
546
|
+
"Length",
|
|
547
|
+
"Perc"
|
|
548
|
+
],
|
|
549
|
+
"default": [
|
|
550
|
+
"medium"
|
|
551
|
+
],
|
|
552
|
+
keywords: [
|
|
553
|
+
"thin",
|
|
554
|
+
"medium",
|
|
555
|
+
"thick"
|
|
556
|
+
]
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
"border-color": {
|
|
561
|
+
shorthand: "border"
|
|
562
|
+
},
|
|
563
|
+
"border-style": {
|
|
564
|
+
shorthand: "border"
|
|
565
|
+
},
|
|
566
|
+
"border-width": {
|
|
567
|
+
shorthand: "border"
|
|
568
|
+
},
|
|
466
569
|
outline: {
|
|
467
570
|
shorthand: "outline",
|
|
468
571
|
pattern: "outline-color outline-style outline-width",
|
|
@@ -479,12 +582,10 @@ var map = {
|
|
|
479
582
|
"Color"
|
|
480
583
|
],
|
|
481
584
|
"default": [
|
|
482
|
-
"currentColor"
|
|
483
|
-
"invert"
|
|
585
|
+
"currentColor"
|
|
484
586
|
],
|
|
485
587
|
keywords: [
|
|
486
|
-
"currentColor"
|
|
487
|
-
"invert"
|
|
588
|
+
"currentColor"
|
|
488
589
|
]
|
|
489
590
|
},
|
|
490
591
|
"outline-style": {
|
|
@@ -822,6 +923,7 @@ var map = {
|
|
|
822
923
|
"default": [
|
|
823
924
|
"transparent"
|
|
824
925
|
],
|
|
926
|
+
multiple: true,
|
|
825
927
|
keywords: [
|
|
826
928
|
]
|
|
827
929
|
},
|
|
@@ -842,6 +944,7 @@ var map = {
|
|
|
842
944
|
"default": [
|
|
843
945
|
"scroll"
|
|
844
946
|
],
|
|
947
|
+
multiple: true,
|
|
845
948
|
keywords: [
|
|
846
949
|
"scroll",
|
|
847
950
|
"fixed",
|
|
@@ -854,6 +957,7 @@ var map = {
|
|
|
854
957
|
"default": [
|
|
855
958
|
"border-box"
|
|
856
959
|
],
|
|
960
|
+
multiple: true,
|
|
857
961
|
keywords: [
|
|
858
962
|
"border-box",
|
|
859
963
|
"padding-box",
|
|
@@ -867,6 +971,7 @@ var map = {
|
|
|
867
971
|
"default": [
|
|
868
972
|
"padding-box"
|
|
869
973
|
],
|
|
974
|
+
multiple: true,
|
|
870
975
|
keywords: [
|
|
871
976
|
"border-box",
|
|
872
977
|
"padding-box",
|
|
@@ -1456,7 +1561,8 @@ function hsl2rgb(h, s, l, a = null) {
|
|
|
1456
1561
|
}
|
|
1457
1562
|
|
|
1458
1563
|
function render(data, opt = {}) {
|
|
1459
|
-
const
|
|
1564
|
+
const startTime = performance.now();
|
|
1565
|
+
const options = Object.assign(opt.minify ?? true ? {
|
|
1460
1566
|
indent: '',
|
|
1461
1567
|
newLine: '',
|
|
1462
1568
|
removeComments: true
|
|
@@ -1474,7 +1580,9 @@ function render(data, opt = {}) {
|
|
|
1474
1580
|
}
|
|
1475
1581
|
return acc + renderToken(curr, options);
|
|
1476
1582
|
}
|
|
1477
|
-
return { code: doRender(data, options, reducer, 0)
|
|
1583
|
+
return { code: doRender(data, options, reducer, 0), stats: {
|
|
1584
|
+
total: `${(performance.now() - startTime).toFixed(2)}ms`
|
|
1585
|
+
} };
|
|
1478
1586
|
}
|
|
1479
1587
|
// @ts-ignore
|
|
1480
1588
|
function doRender(data, options, reducer, level = 0, indents = []) {
|
|
@@ -1503,7 +1611,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1503
1611
|
case 'AtRule':
|
|
1504
1612
|
case 'Rule':
|
|
1505
1613
|
if (data.typ == 'AtRule' && !('chi' in data)) {
|
|
1506
|
-
return `${indent}@${data.nam} ${data.val};`;
|
|
1614
|
+
return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
|
|
1507
1615
|
}
|
|
1508
1616
|
// @ts-ignore
|
|
1509
1617
|
let children = data.chi.reduce((css, node) => {
|
|
@@ -1515,7 +1623,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1515
1623
|
str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
|
|
1516
1624
|
}
|
|
1517
1625
|
else if (node.typ == 'AtRule' && !('chi' in node)) {
|
|
1518
|
-
str =
|
|
1626
|
+
str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
|
|
1519
1627
|
}
|
|
1520
1628
|
else {
|
|
1521
1629
|
str = doRender(node, options, reducer, level + 1, indents);
|
|
@@ -1532,7 +1640,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1532
1640
|
children = children.slice(0, -1);
|
|
1533
1641
|
}
|
|
1534
1642
|
if (data.typ == 'AtRule') {
|
|
1535
|
-
return `@${data.nam}${data.val
|
|
1643
|
+
return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
|
|
1536
1644
|
}
|
|
1537
1645
|
return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
|
|
1538
1646
|
}
|
|
@@ -1541,8 +1649,11 @@ function doRender(data, options, reducer, level = 0, indents = []) {
|
|
|
1541
1649
|
function renderToken(token, options = {}) {
|
|
1542
1650
|
switch (token.typ) {
|
|
1543
1651
|
case 'Color':
|
|
1544
|
-
if (options.
|
|
1545
|
-
|
|
1652
|
+
if (options.minify || options.colorConvert) {
|
|
1653
|
+
if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
|
|
1654
|
+
return 'currentcolor';
|
|
1655
|
+
}
|
|
1656
|
+
let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
|
|
1546
1657
|
if (token.val == 'rgb' || token.val == 'rgba') {
|
|
1547
1658
|
value = rgb2Hex(token);
|
|
1548
1659
|
}
|
|
@@ -1586,7 +1697,7 @@ function renderToken(token, options = {}) {
|
|
|
1586
1697
|
case 'UrlFunc':
|
|
1587
1698
|
case 'Pseudo-class-func':
|
|
1588
1699
|
// @ts-ignore
|
|
1589
|
-
return ( /* options.
|
|
1700
|
+
return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
|
|
1590
1701
|
if (options.removeComments && curr.typ == 'Comment') {
|
|
1591
1702
|
if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
|
|
1592
1703
|
return acc;
|
|
@@ -1677,21 +1788,47 @@ function renderToken(token, options = {}) {
|
|
|
1677
1788
|
case 'String':
|
|
1678
1789
|
case 'Iden':
|
|
1679
1790
|
case 'Delim':
|
|
1680
|
-
return /* options.
|
|
1791
|
+
return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
|
|
1681
1792
|
}
|
|
1682
|
-
|
|
1793
|
+
console.error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
1794
|
+
// throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
|
|
1795
|
+
return '';
|
|
1683
1796
|
}
|
|
1684
1797
|
|
|
1685
1798
|
function eq(a, b) {
|
|
1686
|
-
if (
|
|
1799
|
+
if (a == null || b == null) {
|
|
1800
|
+
return a == b;
|
|
1801
|
+
}
|
|
1802
|
+
if (typeof a != 'object' || typeof b != 'object') {
|
|
1687
1803
|
return a === b;
|
|
1688
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
|
+
}
|
|
1689
1820
|
const k1 = Object.keys(a);
|
|
1690
1821
|
const k2 = Object.keys(b);
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
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;
|
|
1695
1832
|
}
|
|
1696
1833
|
|
|
1697
1834
|
class PropertySet {
|
|
@@ -1703,8 +1840,7 @@ class PropertySet {
|
|
|
1703
1840
|
}
|
|
1704
1841
|
add(declaration) {
|
|
1705
1842
|
if (declaration.nam == this.config.shorthand) {
|
|
1706
|
-
this.declarations
|
|
1707
|
-
this.declarations.set(declaration.nam, declaration);
|
|
1843
|
+
this.declarations = new Map;
|
|
1708
1844
|
}
|
|
1709
1845
|
else {
|
|
1710
1846
|
// expand shorthand
|
|
@@ -1727,6 +1863,10 @@ class PropertySet {
|
|
|
1727
1863
|
}
|
|
1728
1864
|
if (token.typ != 'Whitespace' && token.typ != 'Comment') {
|
|
1729
1865
|
if (token.typ == 'Iden' && this.config.keywords.includes(token.val)) {
|
|
1866
|
+
if (tokens.length == 0) {
|
|
1867
|
+
tokens.push([]);
|
|
1868
|
+
current++;
|
|
1869
|
+
}
|
|
1730
1870
|
tokens[current].push(token);
|
|
1731
1871
|
}
|
|
1732
1872
|
if (token.typ == 'Literal' && token.val == this.config.separator) {
|
|
@@ -1742,10 +1882,6 @@ class PropertySet {
|
|
|
1742
1882
|
this.declarations.delete(this.config.shorthand);
|
|
1743
1883
|
for (const values of tokens) {
|
|
1744
1884
|
this.config.properties.forEach((property, index) => {
|
|
1745
|
-
// if (property == declaration.nam) {
|
|
1746
|
-
//
|
|
1747
|
-
// return;
|
|
1748
|
-
// }
|
|
1749
1885
|
if (!this.declarations.has(property)) {
|
|
1750
1886
|
this.declarations.set(property, {
|
|
1751
1887
|
typ: 'Declaration',
|
|
@@ -1774,30 +1910,20 @@ class PropertySet {
|
|
|
1774
1910
|
this.declarations.set(declaration.nam, declaration);
|
|
1775
1911
|
return this;
|
|
1776
1912
|
}
|
|
1777
|
-
// declaration.chi = declaration.chi.reduce((acc: Token[], token: Token) => {
|
|
1778
|
-
//
|
|
1779
|
-
// if (this.config.types.includes(token.typ) || ('0' == (<DimensionToken>token).chi && (
|
|
1780
|
-
// this.config.types.includes('Length') ||
|
|
1781
|
-
// this.config.types.includes('Angle') ||
|
|
1782
|
-
// this.config.types.includes('Dimension'))) || (token.typ == 'Iden' && this.config.keywords.includes(token.chi))) {
|
|
1783
|
-
//
|
|
1784
|
-
// acc.push(token);
|
|
1785
|
-
// }
|
|
1786
|
-
//
|
|
1787
|
-
// return acc;
|
|
1788
|
-
// }, <Token[]>[]);
|
|
1789
|
-
this.declarations.set(declaration.nam, declaration);
|
|
1790
1913
|
}
|
|
1914
|
+
this.declarations.set(declaration.nam, declaration);
|
|
1791
1915
|
return this;
|
|
1792
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
|
+
}
|
|
1793
1923
|
[Symbol.iterator]() {
|
|
1794
1924
|
let iterator;
|
|
1795
1925
|
const declarations = this.declarations;
|
|
1796
|
-
if (declarations.size < this.config.properties.length
|
|
1797
|
-
return !declarations.has(property) || (index > 0 &&
|
|
1798
|
-
// @ts-ignore
|
|
1799
|
-
declarations.get(property).val.length != declarations.get(this.config.properties[Math.floor(index / 2)]).val.length);
|
|
1800
|
-
})) {
|
|
1926
|
+
if (declarations.size < this.config.properties.length) {
|
|
1801
1927
|
iterator = declarations.values();
|
|
1802
1928
|
}
|
|
1803
1929
|
else {
|
|
@@ -1855,17 +1981,20 @@ class PropertySet {
|
|
|
1855
1981
|
return acc;
|
|
1856
1982
|
}, [])
|
|
1857
1983
|
}][Symbol.iterator]();
|
|
1858
|
-
return {
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
}
|
|
1984
|
+
// return {
|
|
1985
|
+
// next() {
|
|
1986
|
+
//
|
|
1987
|
+
// return iterator.next();
|
|
1988
|
+
// }
|
|
1989
|
+
// }
|
|
1863
1990
|
}
|
|
1864
|
-
return
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1991
|
+
return iterator;
|
|
1992
|
+
// return {
|
|
1993
|
+
// next() {
|
|
1994
|
+
//
|
|
1995
|
+
// return iterator.next();
|
|
1996
|
+
// }
|
|
1997
|
+
// }
|
|
1869
1998
|
}
|
|
1870
1999
|
}
|
|
1871
2000
|
|
|
@@ -1880,34 +2009,7 @@ function matchType(val, properties) {
|
|
|
1880
2009
|
return false;
|
|
1881
2010
|
}
|
|
1882
2011
|
|
|
1883
|
-
|
|
1884
|
-
if (val == 'transparent' || val == 'currentcolor') {
|
|
1885
|
-
return {
|
|
1886
|
-
typ: 'Color',
|
|
1887
|
-
val,
|
|
1888
|
-
kin: 'lit'
|
|
1889
|
-
};
|
|
1890
|
-
}
|
|
1891
|
-
if (val.endsWith('%')) {
|
|
1892
|
-
return {
|
|
1893
|
-
typ: 'Perc',
|
|
1894
|
-
val: val.slice(0, -1)
|
|
1895
|
-
};
|
|
1896
|
-
}
|
|
1897
|
-
return {
|
|
1898
|
-
typ: isNumber(val) ? 'Number' : 'Iden',
|
|
1899
|
-
val
|
|
1900
|
-
};
|
|
1901
|
-
}
|
|
1902
|
-
function parseString(val) {
|
|
1903
|
-
return val.split(/\s/).map(getTokenType).reduce((acc, curr) => {
|
|
1904
|
-
if (acc.length > 0) {
|
|
1905
|
-
acc.push({ typ: 'Whitespace' });
|
|
1906
|
-
}
|
|
1907
|
-
acc.push(curr);
|
|
1908
|
-
return acc;
|
|
1909
|
-
}, []);
|
|
1910
|
-
}
|
|
2012
|
+
const propertiesConfig = getConfig();
|
|
1911
2013
|
class PropertyMap {
|
|
1912
2014
|
config;
|
|
1913
2015
|
declarations;
|
|
@@ -1922,7 +2024,7 @@ class PropertyMap {
|
|
|
1922
2024
|
}
|
|
1923
2025
|
add(declaration) {
|
|
1924
2026
|
if (declaration.nam == this.config.shorthand) {
|
|
1925
|
-
this.declarations
|
|
2027
|
+
this.declarations = new Map;
|
|
1926
2028
|
this.declarations.set(declaration.nam, declaration);
|
|
1927
2029
|
}
|
|
1928
2030
|
else {
|
|
@@ -1999,8 +2101,7 @@ class PropertyMap {
|
|
|
1999
2101
|
const defaults = parseString(props.default[0]);
|
|
2000
2102
|
if (!(property in tokens)) {
|
|
2001
2103
|
tokens[property] = [
|
|
2002
|
-
[...defaults
|
|
2003
|
-
]
|
|
2104
|
+
[...defaults]
|
|
2004
2105
|
];
|
|
2005
2106
|
}
|
|
2006
2107
|
else {
|
|
@@ -2034,145 +2135,229 @@ class PropertyMap {
|
|
|
2034
2135
|
}, new Map);
|
|
2035
2136
|
}
|
|
2036
2137
|
}
|
|
2037
|
-
|
|
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
|
+
}
|
|
2038
2158
|
}
|
|
2039
2159
|
return this;
|
|
2040
2160
|
}
|
|
2041
2161
|
[Symbol.iterator]() {
|
|
2042
|
-
let
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
return this.declarations.values();
|
|
2052
|
-
}
|
|
2053
|
-
let count = 0;
|
|
2054
|
-
const separator = this.config.separator;
|
|
2055
|
-
const tokens = {};
|
|
2056
|
-
// @ts-ignore
|
|
2057
|
-
const valid = Object.entries(this.config.properties).reduce((acc, curr) => {
|
|
2058
|
-
if (!this.declarations.has(curr[0])) {
|
|
2059
|
-
if (curr[1].required) {
|
|
2060
|
-
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;
|
|
2061
2171
|
}
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
for (const val of this.declarations.get(curr[0]).val) {
|
|
2068
|
-
if (separator != null && separator.typ == val.typ && eq(separator, val)) {
|
|
2069
|
-
current++;
|
|
2070
|
-
if (tokens[curr[0]].length == current) {
|
|
2071
|
-
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;
|
|
2072
2177
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2076
|
-
continue;
|
|
2077
|
-
}
|
|
2078
|
-
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(val, props.separator)) {
|
|
2079
|
-
continue;
|
|
2080
|
-
}
|
|
2081
|
-
if (matchType(val, curr[1])) {
|
|
2082
|
-
if (!(curr[0] in tokens)) {
|
|
2083
|
-
tokens[curr[0]] = [[]];
|
|
2178
|
+
else {
|
|
2179
|
+
requiredCount++;
|
|
2084
2180
|
}
|
|
2085
|
-
// is default value
|
|
2086
|
-
tokens[curr[0]][current].push(val);
|
|
2087
|
-
continue;
|
|
2088
2181
|
}
|
|
2089
|
-
acc.push(curr[0]);
|
|
2090
|
-
break;
|
|
2091
|
-
}
|
|
2092
|
-
if (count == 0) {
|
|
2093
|
-
count = current;
|
|
2094
2182
|
}
|
|
2095
|
-
return acc;
|
|
2096
|
-
}, []);
|
|
2097
|
-
if (valid.length > 0 || Object.values(tokens).every(v => v.every(v => v.length == count))) {
|
|
2098
|
-
return this.declarations.values();
|
|
2099
2183
|
}
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
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]);
|
|
2109
2200
|
}
|
|
2110
|
-
acc.push(curr);
|
|
2111
2201
|
return acc;
|
|
2112
|
-
}, []);
|
|
2113
|
-
if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
|
|
2114
|
-
continue;
|
|
2115
2202
|
}
|
|
2116
|
-
|
|
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
|
+
}
|
|
2117
2215
|
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
|
|
2118
|
-
|
|
2216
|
+
continue;
|
|
2119
2217
|
}
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
if (
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
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) {
|
|
2128
2281
|
// @ts-ignore
|
|
2129
|
-
if (
|
|
2130
|
-
|
|
2131
|
-
|
|
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
|
+
}
|
|
2132
2291
|
}
|
|
2133
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
|
+
}, []));
|
|
2134
2309
|
}
|
|
2135
2310
|
}
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2311
|
+
return acc;
|
|
2312
|
+
}, []).reduce((acc, curr) => {
|
|
2313
|
+
if (acc.length > 0) {
|
|
2314
|
+
acc.push({ ...separator });
|
|
2139
2315
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
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
|
+
}, []));
|
|
2142
2324
|
}
|
|
2143
|
-
acc
|
|
2144
|
-
|
|
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) {
|
|
2145
2349
|
// @ts-ignore
|
|
2146
|
-
|
|
2350
|
+
iterable = iterators.pop();
|
|
2351
|
+
v = iterable.next();
|
|
2147
2352
|
}
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
}
|
|
2353
|
+
if (v.done && iterators.length == 0) {
|
|
2354
|
+
break;
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2152
2357
|
}
|
|
2358
|
+
return v;
|
|
2153
2359
|
}
|
|
2154
|
-
|
|
2155
|
-
}, []).reduce((acc, curr) => {
|
|
2156
|
-
if (acc.length > 0) {
|
|
2157
|
-
acc.push({ ...separator });
|
|
2158
|
-
}
|
|
2159
|
-
if (curr.length == 0) {
|
|
2160
|
-
curr.push(...this.config.default[0].split(/\s/).map(getTokenType).reduce((acc, curr) => {
|
|
2161
|
-
if (acc.length > 0) {
|
|
2162
|
-
acc.push({ typ: 'Whitespace' });
|
|
2163
|
-
}
|
|
2164
|
-
acc.push(curr);
|
|
2165
|
-
return acc;
|
|
2166
|
-
}, []));
|
|
2167
|
-
}
|
|
2168
|
-
acc.push(...curr);
|
|
2169
|
-
return acc;
|
|
2170
|
-
}, []);
|
|
2171
|
-
return [{
|
|
2172
|
-
typ: 'Declaration',
|
|
2173
|
-
nam: this.config.shorthand,
|
|
2174
|
-
val: values
|
|
2175
|
-
}][Symbol.iterator]();
|
|
2360
|
+
};
|
|
2176
2361
|
}
|
|
2177
2362
|
}
|
|
2178
2363
|
|
|
@@ -2182,33 +2367,61 @@ class PropertyList {
|
|
|
2182
2367
|
constructor() {
|
|
2183
2368
|
this.declarations = new Map;
|
|
2184
2369
|
}
|
|
2370
|
+
set(nam, value) {
|
|
2371
|
+
return this.add({ typ: 'Declaration', nam, val: Array.isArray(value) ? value : parseString(String(value)) });
|
|
2372
|
+
}
|
|
2185
2373
|
add(declaration) {
|
|
2186
2374
|
if (declaration.typ != 'Declaration') {
|
|
2187
2375
|
this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
|
|
2188
2376
|
return this;
|
|
2189
2377
|
}
|
|
2190
|
-
|
|
2378
|
+
let propertyName = declaration.nam;
|
|
2379
|
+
let shortHandType;
|
|
2380
|
+
let shorthand;
|
|
2191
2381
|
if (propertyName in config.properties) {
|
|
2192
2382
|
// @ts-ignore
|
|
2193
|
-
|
|
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
|
|
2194
2402
|
if (!this.declarations.has(shorthand)) {
|
|
2195
2403
|
// @ts-ignore
|
|
2196
|
-
this.declarations.set(shorthand, new
|
|
2404
|
+
this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
|
|
2197
2405
|
}
|
|
2406
|
+
// @ts-ignore
|
|
2198
2407
|
this.declarations.get(shorthand).add(declaration);
|
|
2199
|
-
return this;
|
|
2408
|
+
// return this;
|
|
2200
2409
|
}
|
|
2201
|
-
|
|
2410
|
+
// @ts-ignore
|
|
2411
|
+
else if (shortHandType == 'set') {
|
|
2202
2412
|
// @ts-ignore
|
|
2203
|
-
const shorthand = config.
|
|
2413
|
+
// const shorthand: string = <string>config.properties[propertyName].shorthand;
|
|
2204
2414
|
if (!this.declarations.has(shorthand)) {
|
|
2205
2415
|
// @ts-ignore
|
|
2206
|
-
this.declarations.set(shorthand, new
|
|
2416
|
+
this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
|
|
2207
2417
|
}
|
|
2418
|
+
// @ts-ignore
|
|
2208
2419
|
this.declarations.get(shorthand).add(declaration);
|
|
2209
|
-
return this;
|
|
2420
|
+
// return this;
|
|
2421
|
+
}
|
|
2422
|
+
else {
|
|
2423
|
+
this.declarations.set(propertyName, declaration);
|
|
2210
2424
|
}
|
|
2211
|
-
this.declarations.set(propertyName, declaration);
|
|
2212
2425
|
return this;
|
|
2213
2426
|
}
|
|
2214
2427
|
[Symbol.iterator]() {
|
|
@@ -2237,56 +2450,300 @@ class PropertyList {
|
|
|
2237
2450
|
}
|
|
2238
2451
|
}
|
|
2239
2452
|
|
|
2240
|
-
const configuration = getConfig();
|
|
2241
2453
|
const combinators = ['+', '>', '~'];
|
|
2242
2454
|
const notEndingWith = ['(', '['].concat(combinators);
|
|
2243
|
-
function
|
|
2244
|
-
|
|
2245
|
-
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
2246
|
-
// @ts-ignore
|
|
2247
|
-
let nSel = match.selector2.reduce(reducer, []).join(',');
|
|
2248
|
-
// @ts-ignore
|
|
2249
|
-
const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
|
|
2250
|
-
// @ts-ignore
|
|
2251
|
-
Object.defineProperty(wrapper, 'raw', {
|
|
2252
|
-
enumerable: false,
|
|
2253
|
-
writable: true,
|
|
2455
|
+
function minify(ast, options = {}, recursive = false) {
|
|
2456
|
+
function wrapNodes(previous, node, match, ast, i, nodeIndex) {
|
|
2254
2457
|
// @ts-ignore
|
|
2255
|
-
|
|
2256
|
-
});
|
|
2257
|
-
if (pSel == '&' || pSel === '') {
|
|
2458
|
+
let pSel = match.selector1.reduce(reducer, []).join(',');
|
|
2258
2459
|
// @ts-ignore
|
|
2259
|
-
|
|
2460
|
+
let nSel = match.selector2.reduce(reducer, []).join(',');
|
|
2260
2461
|
// @ts-ignore
|
|
2261
|
-
|
|
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);
|
|
2262
2473
|
// @ts-ignore
|
|
2263
|
-
|
|
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
|
+
}
|
|
2264
2482
|
}
|
|
2265
2483
|
else {
|
|
2266
2484
|
// @ts-ignore
|
|
2267
|
-
wrapper.chi.push(node);
|
|
2485
|
+
wrapper.chi.push(previous, node);
|
|
2268
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;
|
|
2269
2501
|
}
|
|
2270
|
-
|
|
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
|
+
}
|
|
2271
2573
|
// @ts-ignore
|
|
2272
|
-
|
|
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 ? node1 : 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
|
+
};
|
|
2273
2746
|
}
|
|
2274
|
-
// @ts-ignore
|
|
2275
|
-
ast.chi.splice(i, 1, wrapper);
|
|
2276
|
-
// @ts-ignore
|
|
2277
|
-
ast.chi.splice(nodeIndex, 1);
|
|
2278
|
-
// @ts-ignore
|
|
2279
|
-
previous.sel = pSel;
|
|
2280
|
-
// @ts-ignore
|
|
2281
|
-
previous.raw = match.selector1;
|
|
2282
|
-
// @ts-ignore
|
|
2283
|
-
node.sel = nSel;
|
|
2284
|
-
// @ts-ignore
|
|
2285
|
-
node.raw = match.selector2;
|
|
2286
|
-
reduceRuleSelector(wrapper);
|
|
2287
|
-
return wrapper;
|
|
2288
|
-
}
|
|
2289
|
-
function deduplicate(ast, options = {}, recursive = false) {
|
|
2290
2747
|
// @ts-ignore
|
|
2291
2748
|
if (('chi' in ast) && ast.chi?.length > 0) {
|
|
2292
2749
|
let i = 0;
|
|
@@ -2312,11 +2769,27 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2312
2769
|
if (node.typ == 'AtRule' && node.nam == 'font-face') {
|
|
2313
2770
|
continue;
|
|
2314
2771
|
}
|
|
2315
|
-
if (node.typ == 'AtRule'
|
|
2772
|
+
if (node.typ == 'AtRule') {
|
|
2773
|
+
if (node.nam == 'media' && node.val == 'all') {
|
|
2774
|
+
// @ts-ignore
|
|
2775
|
+
ast.chi?.splice(i, 1, ...node.chi);
|
|
2776
|
+
i--;
|
|
2777
|
+
continue;
|
|
2778
|
+
}
|
|
2779
|
+
// console.debug({previous, node});
|
|
2316
2780
|
// @ts-ignore
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2781
|
+
if (previous?.typ == 'AtRule' &&
|
|
2782
|
+
previous.nam == node.nam &&
|
|
2783
|
+
previous.val == node.val) {
|
|
2784
|
+
if ('chi' in node) {
|
|
2785
|
+
// @ts-ignore
|
|
2786
|
+
previous.chi.push(...node.chi);
|
|
2787
|
+
}
|
|
2788
|
+
// else {
|
|
2789
|
+
ast?.chi?.splice(i--, 1);
|
|
2790
|
+
continue;
|
|
2791
|
+
// }
|
|
2792
|
+
}
|
|
2320
2793
|
}
|
|
2321
2794
|
// @ts-ignore
|
|
2322
2795
|
if (node.typ == 'Rule') {
|
|
@@ -2326,7 +2799,8 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2326
2799
|
// @ts-ignore
|
|
2327
2800
|
if (options.nestingRules) {
|
|
2328
2801
|
// @ts-ignore
|
|
2329
|
-
if (previous
|
|
2802
|
+
if (previous?.typ == 'Rule') {
|
|
2803
|
+
// @ts-ignore
|
|
2330
2804
|
reduceRuleSelector(previous);
|
|
2331
2805
|
// @ts-ignore
|
|
2332
2806
|
match = matchSelectors(previous.raw, node.raw, ast.typ);
|
|
@@ -2365,7 +2839,7 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2365
2839
|
nodeIndex = --i;
|
|
2366
2840
|
// @ts-ignore
|
|
2367
2841
|
previous = ast.chi[nodeIndex];
|
|
2368
|
-
|
|
2842
|
+
minify(wrapper, options, recursive);
|
|
2369
2843
|
continue;
|
|
2370
2844
|
}
|
|
2371
2845
|
// @ts-ignore
|
|
@@ -2414,13 +2888,24 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2414
2888
|
}
|
|
2415
2889
|
else if (combinators.includes(curr[0])) {
|
|
2416
2890
|
curr.unshift('&');
|
|
2891
|
+
wrap = false;
|
|
2417
2892
|
}
|
|
2418
2893
|
// @ts-ignore
|
|
2419
|
-
acc.push(curr
|
|
2894
|
+
acc.push(curr);
|
|
2420
2895
|
return acc;
|
|
2421
2896
|
}, []);
|
|
2897
|
+
if (!wrap) {
|
|
2898
|
+
wrap = selector.some(s => s[0] != '&');
|
|
2899
|
+
}
|
|
2900
|
+
const rule = selector.map(s => {
|
|
2901
|
+
if (s[0] == '&') {
|
|
2902
|
+
// @ts-ignore
|
|
2903
|
+
s[0] = node.optimized.optimized[0];
|
|
2904
|
+
}
|
|
2905
|
+
return s.join('');
|
|
2906
|
+
}).join(',');
|
|
2422
2907
|
// @ts-ignore
|
|
2423
|
-
node.sel =
|
|
2908
|
+
node.sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
|
|
2424
2909
|
}
|
|
2425
2910
|
}
|
|
2426
2911
|
// @ts-ignore
|
|
@@ -2451,10 +2936,10 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2451
2936
|
// @ts-ignore
|
|
2452
2937
|
if (hasDeclaration(node)) {
|
|
2453
2938
|
// @ts-ignore
|
|
2454
|
-
|
|
2939
|
+
minifyRule(node);
|
|
2455
2940
|
}
|
|
2456
2941
|
else {
|
|
2457
|
-
|
|
2942
|
+
minify(node, options, recursive);
|
|
2458
2943
|
}
|
|
2459
2944
|
i--;
|
|
2460
2945
|
previous = node;
|
|
@@ -2496,10 +2981,10 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2496
2981
|
// @ts-ignore
|
|
2497
2982
|
if (hasDeclaration(previous)) {
|
|
2498
2983
|
// @ts-ignore
|
|
2499
|
-
|
|
2984
|
+
minifyRule(previous);
|
|
2500
2985
|
}
|
|
2501
2986
|
else {
|
|
2502
|
-
|
|
2987
|
+
minify(previous, options, recursive);
|
|
2503
2988
|
}
|
|
2504
2989
|
}
|
|
2505
2990
|
}
|
|
@@ -2510,18 +2995,97 @@ function deduplicate(ast, options = {}, recursive = false) {
|
|
|
2510
2995
|
if (recursive && node != null && ('chi' in node)) {
|
|
2511
2996
|
// @ts-ignore
|
|
2512
2997
|
if (node.chi.some(n => n.typ == 'Declaration')) {
|
|
2513
|
-
|
|
2998
|
+
minifyRule(node);
|
|
2514
2999
|
}
|
|
2515
3000
|
else {
|
|
2516
3001
|
// @ts-ignore
|
|
2517
3002
|
if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
|
|
2518
|
-
|
|
3003
|
+
minify(node, options, recursive);
|
|
2519
3004
|
}
|
|
2520
3005
|
}
|
|
2521
3006
|
}
|
|
2522
3007
|
}
|
|
2523
3008
|
return ast;
|
|
2524
3009
|
}
|
|
3010
|
+
function reduceSelector(selector) {
|
|
3011
|
+
if (selector.length == 0) {
|
|
3012
|
+
return null;
|
|
3013
|
+
}
|
|
3014
|
+
const optimized = [];
|
|
3015
|
+
const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
|
|
3016
|
+
let i = 0;
|
|
3017
|
+
let j;
|
|
3018
|
+
let match;
|
|
3019
|
+
for (; i < k; i++) {
|
|
3020
|
+
const item = selector[0][i];
|
|
3021
|
+
match = true;
|
|
3022
|
+
for (j = 1; j < selector.length; j++) {
|
|
3023
|
+
if (item != selector[j][i]) {
|
|
3024
|
+
match = false;
|
|
3025
|
+
break;
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
if (!match) {
|
|
3029
|
+
break;
|
|
3030
|
+
}
|
|
3031
|
+
optimized.push(item);
|
|
3032
|
+
}
|
|
3033
|
+
while (optimized.length > 0) {
|
|
3034
|
+
const last = optimized.at(-1);
|
|
3035
|
+
if ((last == ' ' || combinators.includes(last))) {
|
|
3036
|
+
optimized.pop();
|
|
3037
|
+
continue;
|
|
3038
|
+
}
|
|
3039
|
+
break;
|
|
3040
|
+
}
|
|
3041
|
+
selector.forEach((selector) => selector.splice(0, optimized.length));
|
|
3042
|
+
// combinator
|
|
3043
|
+
if (combinators.includes(optimized.at(-1))) {
|
|
3044
|
+
const combinator = optimized.pop();
|
|
3045
|
+
selector.forEach(selector => selector.unshift(combinator));
|
|
3046
|
+
}
|
|
3047
|
+
let reducible = optimized.length == 1;
|
|
3048
|
+
if (optimized[0] == '&' && optimized[1] == ' ') {
|
|
3049
|
+
optimized.splice(0, 2);
|
|
3050
|
+
}
|
|
3051
|
+
if (optimized.length == 0 ||
|
|
3052
|
+
(optimized[0].charAt(0) == '&' ||
|
|
3053
|
+
selector.length == 1)) {
|
|
3054
|
+
return {
|
|
3055
|
+
match: false,
|
|
3056
|
+
optimized,
|
|
3057
|
+
selector: selector.map(selector => selector[0] == '&' && selector[1] == ' ' ? selector.slice(2) : selector),
|
|
3058
|
+
reducible: selector.length > 1 && selector.every((selector) => !combinators.includes(selector[0]))
|
|
3059
|
+
};
|
|
3060
|
+
}
|
|
3061
|
+
return {
|
|
3062
|
+
match: true,
|
|
3063
|
+
optimized,
|
|
3064
|
+
selector: selector.reduce((acc, curr) => {
|
|
3065
|
+
let hasCompound = true;
|
|
3066
|
+
if (hasCompound && curr.length > 0) {
|
|
3067
|
+
hasCompound = !['&'].concat(combinators).includes(curr[0].charAt(0));
|
|
3068
|
+
}
|
|
3069
|
+
// @ts-ignore
|
|
3070
|
+
if (hasCompound && curr[0] == ' ') {
|
|
3071
|
+
hasCompound = false;
|
|
3072
|
+
curr.unshift('&');
|
|
3073
|
+
}
|
|
3074
|
+
if (curr.length == 0) {
|
|
3075
|
+
curr.push('&');
|
|
3076
|
+
hasCompound = false;
|
|
3077
|
+
}
|
|
3078
|
+
if (reducible) {
|
|
3079
|
+
const chr = curr[0].charAt(0);
|
|
3080
|
+
// @ts-ignore
|
|
3081
|
+
reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
|
|
3082
|
+
}
|
|
3083
|
+
acc.push(hasCompound ? ['&'].concat(curr) : curr);
|
|
3084
|
+
return acc;
|
|
3085
|
+
}, []),
|
|
3086
|
+
reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
|
|
3087
|
+
};
|
|
3088
|
+
}
|
|
2525
3089
|
function hasOnlyDeclarations(node) {
|
|
2526
3090
|
let k = node.chi.length;
|
|
2527
3091
|
while (k--) {
|
|
@@ -2544,7 +3108,7 @@ function hasDeclaration(node) {
|
|
|
2544
3108
|
}
|
|
2545
3109
|
return true;
|
|
2546
3110
|
}
|
|
2547
|
-
function
|
|
3111
|
+
function minifyRule(ast) {
|
|
2548
3112
|
// @ts-ignore
|
|
2549
3113
|
if (!('chi' in ast) || ast.chi?.length <= 1) {
|
|
2550
3114
|
return ast;
|
|
@@ -2552,45 +3116,19 @@ function deduplicateRule(ast) {
|
|
|
2552
3116
|
// @ts-ignore
|
|
2553
3117
|
const j = ast.chi.length;
|
|
2554
3118
|
let k = 0;
|
|
2555
|
-
let
|
|
3119
|
+
let properties = new PropertyList();
|
|
2556
3120
|
// @ts-ignore
|
|
2557
3121
|
for (; k < j; k++) {
|
|
2558
3122
|
// @ts-ignore
|
|
2559
3123
|
const node = ast.chi[k];
|
|
2560
|
-
if (node.typ == 'Comment') {
|
|
2561
|
-
|
|
2562
|
-
map.set(node, node);
|
|
3124
|
+
if (node.typ == 'Comment' || node.typ == 'Declaration') {
|
|
3125
|
+
properties.add(node);
|
|
2563
3126
|
continue;
|
|
2564
3127
|
}
|
|
2565
|
-
|
|
2566
|
-
break;
|
|
2567
|
-
}
|
|
2568
|
-
if (node.nam in configuration.map ||
|
|
2569
|
-
node.nam in configuration.properties) {
|
|
2570
|
-
// @ts-ignore
|
|
2571
|
-
const shorthand = node.nam in configuration.map ? configuration.map[node.nam].shorthand : configuration.properties[node.nam].shorthand;
|
|
2572
|
-
if (!map.has(shorthand)) {
|
|
2573
|
-
map.set(shorthand, new PropertyList());
|
|
2574
|
-
}
|
|
2575
|
-
map.get(shorthand).add(node);
|
|
2576
|
-
}
|
|
2577
|
-
else {
|
|
2578
|
-
map.set(node.nam, node);
|
|
2579
|
-
}
|
|
2580
|
-
}
|
|
2581
|
-
const children = [];
|
|
2582
|
-
for (let child of map.values()) {
|
|
2583
|
-
if (child instanceof PropertyList) {
|
|
2584
|
-
// @ts-ignore
|
|
2585
|
-
children.push(...child);
|
|
2586
|
-
}
|
|
2587
|
-
else {
|
|
2588
|
-
// @ts-ignore
|
|
2589
|
-
children.push(child);
|
|
2590
|
-
}
|
|
3128
|
+
break;
|
|
2591
3129
|
}
|
|
2592
3130
|
// @ts-ignore
|
|
2593
|
-
ast.chi =
|
|
3131
|
+
ast.chi = [...properties].concat(ast.chi.slice(k));
|
|
2594
3132
|
return ast;
|
|
2595
3133
|
}
|
|
2596
3134
|
function splitRule(buffer) {
|
|
@@ -2716,345 +3254,485 @@ function reduceRuleSelector(node) {
|
|
|
2716
3254
|
}
|
|
2717
3255
|
// }
|
|
2718
3256
|
}
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
let node2 = n2;
|
|
2722
|
-
let exchanged = false;
|
|
2723
|
-
if (node1.chi.length > node2.chi.length) {
|
|
2724
|
-
const t = node1;
|
|
2725
|
-
node1 = node2;
|
|
2726
|
-
node2 = t;
|
|
2727
|
-
exchanged = true;
|
|
2728
|
-
}
|
|
2729
|
-
let i = node1.chi.length;
|
|
2730
|
-
let j = node2.chi.length;
|
|
2731
|
-
if (i == 0 || j == 0) {
|
|
2732
|
-
// @ts-ignore
|
|
2733
|
-
return null;
|
|
2734
|
-
}
|
|
2735
|
-
// @ts-ignore
|
|
2736
|
-
const raw1 = node1.raw;
|
|
2737
|
-
// @ts-ignore
|
|
2738
|
-
// const optimized1 = node1.optimized;
|
|
2739
|
-
// @ts-ignore
|
|
2740
|
-
const raw2 = node2.raw;
|
|
3257
|
+
|
|
3258
|
+
function* walk(node) {
|
|
2741
3259
|
// @ts-ignore
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
// Object.defineProperty(node1, 'optimized', {enumerable: false, writable: true, value: optimized1});
|
|
2750
|
-
// }
|
|
2751
|
-
if (raw2 != null) {
|
|
2752
|
-
Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
|
|
2753
|
-
}
|
|
2754
|
-
// if (optimized2 != null) {
|
|
2755
|
-
// Object.defineProperty(node2, 'optimized', {enumerable: false, writable: true, value: optimized2});
|
|
2756
|
-
// }
|
|
2757
|
-
const intersect = [];
|
|
2758
|
-
while (i--) {
|
|
2759
|
-
if (node1.chi[i].typ == 'Comment') {
|
|
2760
|
-
continue;
|
|
2761
|
-
}
|
|
2762
|
-
j = node2.chi.length;
|
|
2763
|
-
if (j == 0) {
|
|
2764
|
-
break;
|
|
3260
|
+
yield* doWalk(node, null, null);
|
|
3261
|
+
}
|
|
3262
|
+
function* doWalk(node, parent, root) {
|
|
3263
|
+
yield { node, parent, root };
|
|
3264
|
+
if ('chi' in node) {
|
|
3265
|
+
for (const child of node.chi) {
|
|
3266
|
+
yield* doWalk(child, node, (root ?? node));
|
|
2765
3267
|
}
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
function* tokenize(iterator) {
|
|
3272
|
+
let ind = -1;
|
|
3273
|
+
let lin = 1;
|
|
3274
|
+
let col = 0;
|
|
3275
|
+
const position = {
|
|
3276
|
+
ind: Math.max(ind, 0),
|
|
3277
|
+
lin: lin,
|
|
3278
|
+
col: Math.max(col, 1)
|
|
3279
|
+
};
|
|
3280
|
+
let value;
|
|
3281
|
+
let buffer = '';
|
|
3282
|
+
function consumeWhiteSpace() {
|
|
3283
|
+
let count = 0;
|
|
3284
|
+
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
3285
|
+
count++;
|
|
2778
3286
|
}
|
|
3287
|
+
next(count);
|
|
3288
|
+
return count;
|
|
2779
3289
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
});
|
|
2787
|
-
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)) {
|
|
2788
|
-
// @ts-ignore
|
|
2789
|
-
return null;
|
|
3290
|
+
function pushToken(token, hint) {
|
|
3291
|
+
const result = { token, hint, position: { ...position }, bytesIn: ind };
|
|
3292
|
+
position.ind = ind;
|
|
3293
|
+
position.lin = lin;
|
|
3294
|
+
position.col = col == 0 ? 1 : col;
|
|
3295
|
+
return result;
|
|
2790
3296
|
}
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
let l;
|
|
2799
|
-
let token;
|
|
2800
|
-
let matching = true;
|
|
2801
|
-
let matchFunction = 0;
|
|
2802
|
-
let inAttr = 0;
|
|
2803
|
-
for (; i < j; i++) {
|
|
2804
|
-
k = 0;
|
|
2805
|
-
token = selector1[0][i];
|
|
2806
|
-
for (; k < selector1.length; k++) {
|
|
2807
|
-
if (selector1[k][i] != token) {
|
|
2808
|
-
matching = false;
|
|
2809
|
-
break;
|
|
2810
|
-
}
|
|
3297
|
+
function* consumeString(quoteStr) {
|
|
3298
|
+
const quote = quoteStr;
|
|
3299
|
+
let value;
|
|
3300
|
+
let hasNewLine = false;
|
|
3301
|
+
if (buffer.length > 0) {
|
|
3302
|
+
yield pushToken(buffer);
|
|
3303
|
+
buffer = '';
|
|
2811
3304
|
}
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
3305
|
+
buffer += quoteStr;
|
|
3306
|
+
while (value = peek()) {
|
|
3307
|
+
// if (ind >= iterator.length) {
|
|
3308
|
+
//
|
|
3309
|
+
// yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
3310
|
+
// break;
|
|
3311
|
+
// }
|
|
3312
|
+
if (value == '\\') {
|
|
3313
|
+
const sequence = peek(6);
|
|
3314
|
+
let escapeSequence = '';
|
|
3315
|
+
let codepoint;
|
|
3316
|
+
let i;
|
|
3317
|
+
for (i = 1; i < sequence.length; i++) {
|
|
3318
|
+
codepoint = sequence.charCodeAt(i);
|
|
3319
|
+
if (codepoint == 0x20 ||
|
|
3320
|
+
(codepoint >= 0x61 && codepoint <= 0x66) ||
|
|
3321
|
+
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
3322
|
+
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
3323
|
+
escapeSequence += sequence[i];
|
|
3324
|
+
if (codepoint == 0x20) {
|
|
3325
|
+
break;
|
|
3326
|
+
}
|
|
3327
|
+
continue;
|
|
3328
|
+
}
|
|
2817
3329
|
break;
|
|
2818
3330
|
}
|
|
3331
|
+
// not hex or new line
|
|
3332
|
+
// @ts-ignore
|
|
3333
|
+
if (i == 1 && !isNewLine(codepoint)) {
|
|
3334
|
+
buffer += value + sequence[i];
|
|
3335
|
+
next(2);
|
|
3336
|
+
continue;
|
|
3337
|
+
}
|
|
3338
|
+
if (escapeSequence.trimEnd().length > 0) {
|
|
3339
|
+
const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
|
|
3340
|
+
if (codepoint == 0 ||
|
|
3341
|
+
// leading surrogate
|
|
3342
|
+
(0xD800 <= codepoint && codepoint <= 0xDBFF) ||
|
|
3343
|
+
// trailing surrogate
|
|
3344
|
+
(0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
|
|
3345
|
+
buffer += String.fromCodePoint(0xFFFD);
|
|
3346
|
+
}
|
|
3347
|
+
else {
|
|
3348
|
+
buffer += String.fromCodePoint(codepoint);
|
|
3349
|
+
}
|
|
3350
|
+
next(escapeSequence.length + 1);
|
|
3351
|
+
continue;
|
|
3352
|
+
}
|
|
3353
|
+
// buffer += value;
|
|
3354
|
+
// if (ind >= iterator.length) {
|
|
3355
|
+
//
|
|
3356
|
+
// // drop '\\' at the end
|
|
3357
|
+
// yield pushToken(buffer);
|
|
3358
|
+
// break;
|
|
3359
|
+
// }
|
|
3360
|
+
buffer += next(2);
|
|
3361
|
+
continue;
|
|
2819
3362
|
}
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
else {
|
|
2828
|
-
if (token.endsWith('(')) {
|
|
2829
|
-
matchFunction++;
|
|
2830
|
-
}
|
|
2831
|
-
if (token.endsWith('[')) {
|
|
2832
|
-
inAttr++;
|
|
3363
|
+
if (value == quote) {
|
|
3364
|
+
buffer += value;
|
|
3365
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
|
|
3366
|
+
next();
|
|
3367
|
+
// i += value.length;
|
|
3368
|
+
buffer = '';
|
|
3369
|
+
break;
|
|
2833
3370
|
}
|
|
2834
|
-
|
|
2835
|
-
|
|
3371
|
+
if (isNewLine(value.charCodeAt(0))) {
|
|
3372
|
+
hasNewLine = true;
|
|
2836
3373
|
}
|
|
2837
|
-
|
|
2838
|
-
|
|
3374
|
+
if (hasNewLine && value == ';') {
|
|
3375
|
+
yield pushToken(buffer, 'Bad-string');
|
|
3376
|
+
buffer = '';
|
|
3377
|
+
break;
|
|
2839
3378
|
}
|
|
2840
|
-
|
|
3379
|
+
buffer += value;
|
|
3380
|
+
// i += value.length;
|
|
3381
|
+
next();
|
|
2841
3382
|
}
|
|
2842
3383
|
}
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
}
|
|
2847
|
-
if (parentType != 'Rule') {
|
|
2848
|
-
for (const part of match) {
|
|
2849
|
-
if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
|
|
2850
|
-
return null;
|
|
2851
|
-
}
|
|
3384
|
+
function peek(count = 1) {
|
|
3385
|
+
if (count == 1) {
|
|
3386
|
+
return iterator.charAt(ind + 1);
|
|
2852
3387
|
}
|
|
3388
|
+
return iterator.slice(ind + 1, ind + count + 1);
|
|
2853
3389
|
}
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
3390
|
+
function prev(count = 1) {
|
|
3391
|
+
if (count == 1) {
|
|
3392
|
+
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
3393
|
+
}
|
|
3394
|
+
return iterator.slice(ind - 1 - count, ind - 1);
|
|
2858
3395
|
}
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
3396
|
+
function next(count = 1) {
|
|
3397
|
+
let char = '';
|
|
3398
|
+
while (count-- > 0 && ind < iterator.length) {
|
|
3399
|
+
const codepoint = iterator.charCodeAt(++ind);
|
|
3400
|
+
if (isNaN(codepoint)) {
|
|
3401
|
+
return char;
|
|
3402
|
+
}
|
|
3403
|
+
char += iterator.charAt(ind);
|
|
3404
|
+
if (isNewLine(codepoint)) {
|
|
3405
|
+
lin++;
|
|
3406
|
+
col = 0;
|
|
3407
|
+
}
|
|
3408
|
+
else {
|
|
3409
|
+
col++;
|
|
2865
3410
|
}
|
|
2866
|
-
break;
|
|
2867
3411
|
}
|
|
3412
|
+
return char;
|
|
2868
3413
|
}
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
}
|
|
2875
|
-
function reduce(acc, curr) {
|
|
2876
|
-
if (acc === null) {
|
|
2877
|
-
return null;
|
|
2878
|
-
}
|
|
2879
|
-
let hasCompoundSelector = true;
|
|
2880
|
-
curr = curr.slice(match[0].length);
|
|
2881
|
-
while (curr.length > 0) {
|
|
2882
|
-
if (curr[0] == ' ') {
|
|
2883
|
-
hasCompoundSelector = false;
|
|
2884
|
-
curr.unshift('&');
|
|
2885
|
-
continue;
|
|
3414
|
+
while (value = next()) {
|
|
3415
|
+
if (ind >= iterator.length) {
|
|
3416
|
+
if (buffer.length > 0) {
|
|
3417
|
+
yield pushToken(buffer);
|
|
3418
|
+
buffer = '';
|
|
2886
3419
|
}
|
|
2887
3420
|
break;
|
|
2888
3421
|
}
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
3422
|
+
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
3423
|
+
if (buffer.length > 0) {
|
|
3424
|
+
yield pushToken(buffer);
|
|
3425
|
+
buffer = '';
|
|
3426
|
+
}
|
|
3427
|
+
while (value = next()) {
|
|
3428
|
+
if (ind >= iterator.length) {
|
|
3429
|
+
break;
|
|
3430
|
+
}
|
|
3431
|
+
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
3432
|
+
break;
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
yield pushToken('', 'Whitespace');
|
|
3436
|
+
buffer = '';
|
|
3437
|
+
if (ind >= iterator.length) {
|
|
3438
|
+
break;
|
|
3439
|
+
}
|
|
2898
3440
|
}
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
3441
|
+
switch (value) {
|
|
3442
|
+
case '/':
|
|
3443
|
+
if (buffer.length > 0) {
|
|
3444
|
+
yield pushToken(buffer);
|
|
3445
|
+
buffer = '';
|
|
3446
|
+
if (peek() != '*') {
|
|
3447
|
+
yield pushToken(value);
|
|
3448
|
+
break;
|
|
3449
|
+
}
|
|
2906
3450
|
}
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3451
|
+
buffer += value;
|
|
3452
|
+
if (peek() == '*') {
|
|
3453
|
+
buffer += '*';
|
|
3454
|
+
// i++;
|
|
3455
|
+
next();
|
|
3456
|
+
while (value = next()) {
|
|
3457
|
+
if (ind >= iterator.length) {
|
|
3458
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3459
|
+
break;
|
|
3460
|
+
}
|
|
3461
|
+
if (value == '\\') {
|
|
3462
|
+
buffer += value;
|
|
3463
|
+
value = next();
|
|
3464
|
+
if (ind >= iterator.length) {
|
|
3465
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3466
|
+
break;
|
|
3467
|
+
}
|
|
3468
|
+
buffer += value;
|
|
3469
|
+
continue;
|
|
3470
|
+
}
|
|
3471
|
+
if (value == '*') {
|
|
3472
|
+
buffer += value;
|
|
3473
|
+
value = next();
|
|
3474
|
+
if (ind >= iterator.length) {
|
|
3475
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
3476
|
+
break;
|
|
3477
|
+
}
|
|
3478
|
+
buffer += value;
|
|
3479
|
+
if (value == '/') {
|
|
3480
|
+
yield pushToken(buffer, 'Comment');
|
|
3481
|
+
buffer = '';
|
|
3482
|
+
break;
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
else {
|
|
3486
|
+
buffer += value;
|
|
3487
|
+
}
|
|
2910
3488
|
}
|
|
2911
|
-
inFunction++;
|
|
2912
3489
|
}
|
|
2913
|
-
|
|
2914
|
-
|
|
3490
|
+
break;
|
|
3491
|
+
case '<':
|
|
3492
|
+
if (buffer.length > 0) {
|
|
3493
|
+
yield pushToken(buffer);
|
|
3494
|
+
buffer = '';
|
|
2915
3495
|
}
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
acc.push([]);
|
|
3496
|
+
buffer += value;
|
|
3497
|
+
value = next();
|
|
3498
|
+
if (ind >= iterator.length) {
|
|
3499
|
+
break;
|
|
2921
3500
|
}
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
3501
|
+
if (peek(3) == '!--') {
|
|
3502
|
+
while (value = next()) {
|
|
3503
|
+
if (ind >= iterator.length) {
|
|
3504
|
+
break;
|
|
3505
|
+
}
|
|
3506
|
+
buffer += value;
|
|
3507
|
+
if (value == '>' && prev(2) == '--') {
|
|
3508
|
+
yield pushToken(buffer, 'CDOCOMM');
|
|
3509
|
+
buffer = '';
|
|
3510
|
+
break;
|
|
3511
|
+
}
|
|
2933
3512
|
}
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
// @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
|
|
2940
|
-
acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
|
|
2941
|
-
return acc;
|
|
2942
|
-
}
|
|
2943
|
-
// @ts-ignore
|
|
2944
|
-
selector1 = selector1.reduce(reduce, []);
|
|
2945
|
-
// @ts-ignore
|
|
2946
|
-
selector2 = selector2.reduce(reduce, []);
|
|
2947
|
-
return selector1 == null || selector2 == null ? null : {
|
|
2948
|
-
eq: eq(selector1, selector2),
|
|
2949
|
-
match,
|
|
2950
|
-
selector1,
|
|
2951
|
-
selector2
|
|
2952
|
-
};
|
|
2953
|
-
}
|
|
2954
|
-
function reduceSelector(selector) {
|
|
2955
|
-
if (selector.length == 0) {
|
|
2956
|
-
return null;
|
|
2957
|
-
}
|
|
2958
|
-
const optimized = [];
|
|
2959
|
-
const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
|
|
2960
|
-
let i = 0;
|
|
2961
|
-
let j;
|
|
2962
|
-
let match;
|
|
2963
|
-
for (; i < k; i++) {
|
|
2964
|
-
const item = selector[0][i];
|
|
2965
|
-
match = true;
|
|
2966
|
-
for (j = 1; j < selector.length; j++) {
|
|
2967
|
-
if (item != selector[j][i]) {
|
|
2968
|
-
match = false;
|
|
3513
|
+
}
|
|
3514
|
+
if (ind >= iterator.length) {
|
|
3515
|
+
yield pushToken(buffer, 'BADCDO');
|
|
3516
|
+
buffer = '';
|
|
3517
|
+
}
|
|
2969
3518
|
break;
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3519
|
+
case '\\':
|
|
3520
|
+
value = next();
|
|
3521
|
+
// EOF
|
|
3522
|
+
if (ind + 1 >= iterator.length) {
|
|
3523
|
+
// end of stream ignore \\
|
|
3524
|
+
yield pushToken(buffer);
|
|
3525
|
+
buffer = '';
|
|
3526
|
+
break;
|
|
3527
|
+
}
|
|
3528
|
+
buffer += prev() + value;
|
|
3529
|
+
break;
|
|
3530
|
+
case '"':
|
|
3531
|
+
case "'":
|
|
3532
|
+
yield* consumeString(value);
|
|
3533
|
+
break;
|
|
3534
|
+
case '~':
|
|
3535
|
+
case '|':
|
|
3536
|
+
if (buffer.length > 0) {
|
|
3537
|
+
yield pushToken(buffer);
|
|
3538
|
+
buffer = '';
|
|
3539
|
+
}
|
|
3540
|
+
buffer += value;
|
|
3541
|
+
value = next();
|
|
3542
|
+
if (ind >= iterator.length) {
|
|
3543
|
+
yield pushToken(buffer);
|
|
3544
|
+
buffer = '';
|
|
3545
|
+
break;
|
|
3546
|
+
}
|
|
3547
|
+
if (value == '=') {
|
|
3548
|
+
buffer += value;
|
|
3549
|
+
yield pushToken(buffer, buffer[0] == '~' ? 'Includes' : 'Dash-matches');
|
|
3550
|
+
buffer = '';
|
|
3551
|
+
break;
|
|
3552
|
+
}
|
|
3553
|
+
yield pushToken(buffer);
|
|
3554
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3555
|
+
value = next();
|
|
3556
|
+
}
|
|
3557
|
+
buffer = value;
|
|
3558
|
+
break;
|
|
3559
|
+
case '>':
|
|
3560
|
+
if (buffer !== '') {
|
|
3561
|
+
yield pushToken(buffer);
|
|
3562
|
+
buffer = '';
|
|
3563
|
+
}
|
|
3564
|
+
yield pushToken('', 'Gt');
|
|
3565
|
+
consumeWhiteSpace();
|
|
3566
|
+
break;
|
|
3567
|
+
case '.':
|
|
3568
|
+
const codepoint = peek().charCodeAt(0);
|
|
3569
|
+
if (!isDigit(codepoint) && buffer !== '') {
|
|
3570
|
+
yield pushToken(buffer);
|
|
3571
|
+
buffer = value;
|
|
3572
|
+
break;
|
|
3573
|
+
}
|
|
3574
|
+
buffer += value;
|
|
3575
|
+
break;
|
|
3576
|
+
case '+':
|
|
3577
|
+
case ':':
|
|
3578
|
+
case ',':
|
|
3579
|
+
case '=':
|
|
3580
|
+
if (buffer.length > 0) {
|
|
3581
|
+
yield pushToken(buffer);
|
|
3582
|
+
buffer = '';
|
|
3583
|
+
}
|
|
3584
|
+
if (value == ':' && ':' == peek()) {
|
|
3585
|
+
buffer += value + next();
|
|
3586
|
+
break;
|
|
3587
|
+
}
|
|
3588
|
+
yield pushToken(value);
|
|
3589
|
+
buffer = '';
|
|
3590
|
+
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
3591
|
+
yield pushToken(next());
|
|
3592
|
+
}
|
|
3593
|
+
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
3594
|
+
next();
|
|
3595
|
+
}
|
|
3596
|
+
break;
|
|
3597
|
+
case ')':
|
|
3598
|
+
if (buffer.length > 0) {
|
|
3599
|
+
yield pushToken(buffer);
|
|
3600
|
+
buffer = '';
|
|
3601
|
+
}
|
|
3602
|
+
yield pushToken('', 'End-parens');
|
|
3603
|
+
break;
|
|
3604
|
+
case '(':
|
|
3605
|
+
if (buffer.length == 0) {
|
|
3606
|
+
yield pushToken('', 'Start-parens');
|
|
3607
|
+
break;
|
|
3608
|
+
}
|
|
3609
|
+
buffer += value;
|
|
3024
3610
|
// @ts-ignore
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3611
|
+
if (buffer == 'url(') {
|
|
3612
|
+
yield pushToken(buffer);
|
|
3613
|
+
buffer = '';
|
|
3614
|
+
// consume either string or url token
|
|
3615
|
+
let whitespace = '';
|
|
3616
|
+
value = peek();
|
|
3617
|
+
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3618
|
+
whitespace += value;
|
|
3619
|
+
}
|
|
3620
|
+
if (whitespace.length > 0) {
|
|
3621
|
+
next(whitespace.length);
|
|
3622
|
+
}
|
|
3623
|
+
value = peek();
|
|
3624
|
+
if (value == '"' || value == "'") {
|
|
3625
|
+
yield* consumeString(next());
|
|
3626
|
+
break;
|
|
3627
|
+
}
|
|
3628
|
+
else {
|
|
3629
|
+
buffer = '';
|
|
3630
|
+
do {
|
|
3631
|
+
let cp = value.charCodeAt(0);
|
|
3632
|
+
// EOF -
|
|
3633
|
+
if (cp == null) {
|
|
3634
|
+
yield pushToken('', 'Bad-url-token');
|
|
3635
|
+
break;
|
|
3636
|
+
}
|
|
3637
|
+
// ')'
|
|
3638
|
+
if (cp == 0x29 || cp == null) {
|
|
3639
|
+
if (buffer.length == 0) {
|
|
3640
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
3641
|
+
}
|
|
3642
|
+
else {
|
|
3643
|
+
yield pushToken(buffer, 'Url-token');
|
|
3644
|
+
}
|
|
3645
|
+
if (cp != null) {
|
|
3646
|
+
yield pushToken(next());
|
|
3647
|
+
}
|
|
3648
|
+
break;
|
|
3649
|
+
}
|
|
3650
|
+
if (isWhiteSpace(cp)) {
|
|
3651
|
+
whitespace = next();
|
|
3652
|
+
while (true) {
|
|
3653
|
+
value = peek();
|
|
3654
|
+
cp = value.charCodeAt(0);
|
|
3655
|
+
if (isWhiteSpace(cp)) {
|
|
3656
|
+
whitespace += value;
|
|
3657
|
+
continue;
|
|
3658
|
+
}
|
|
3659
|
+
break;
|
|
3660
|
+
}
|
|
3661
|
+
if (cp == null || cp == 0x29) {
|
|
3662
|
+
continue;
|
|
3663
|
+
}
|
|
3664
|
+
// bad url token
|
|
3665
|
+
buffer += next(whitespace.length);
|
|
3666
|
+
do {
|
|
3667
|
+
value = peek();
|
|
3668
|
+
cp = value.charCodeAt(0);
|
|
3669
|
+
if (cp == null || cp == 0x29) {
|
|
3670
|
+
break;
|
|
3671
|
+
}
|
|
3672
|
+
buffer += next();
|
|
3673
|
+
} while (true);
|
|
3674
|
+
yield pushToken(buffer, 'Bad-url-token');
|
|
3675
|
+
continue;
|
|
3676
|
+
}
|
|
3677
|
+
buffer += next();
|
|
3678
|
+
value = peek();
|
|
3679
|
+
} while (true);
|
|
3680
|
+
buffer = '';
|
|
3681
|
+
}
|
|
3682
|
+
break;
|
|
3683
|
+
}
|
|
3684
|
+
yield pushToken(buffer);
|
|
3685
|
+
buffer = '';
|
|
3686
|
+
break;
|
|
3687
|
+
case '[':
|
|
3688
|
+
case ']':
|
|
3689
|
+
case '{':
|
|
3690
|
+
case '}':
|
|
3691
|
+
case ';':
|
|
3692
|
+
if (buffer.length > 0) {
|
|
3693
|
+
yield pushToken(buffer);
|
|
3694
|
+
buffer = '';
|
|
3695
|
+
}
|
|
3696
|
+
yield pushToken(value);
|
|
3697
|
+
break;
|
|
3698
|
+
case '!':
|
|
3699
|
+
if (buffer.length > 0) {
|
|
3700
|
+
yield pushToken(buffer);
|
|
3701
|
+
buffer = '';
|
|
3702
|
+
}
|
|
3703
|
+
const important = peek(9);
|
|
3704
|
+
if (important == 'important') {
|
|
3705
|
+
yield pushToken('', 'Important');
|
|
3706
|
+
next(9);
|
|
3707
|
+
buffer = '';
|
|
3708
|
+
break;
|
|
3709
|
+
}
|
|
3710
|
+
buffer = '!';
|
|
3711
|
+
break;
|
|
3712
|
+
default:
|
|
3713
|
+
buffer += value;
|
|
3714
|
+
break;
|
|
3044
3715
|
}
|
|
3045
3716
|
}
|
|
3046
|
-
|
|
3047
|
-
|
|
3717
|
+
if (buffer.length > 0) {
|
|
3718
|
+
yield pushToken(buffer);
|
|
3719
|
+
}
|
|
3048
3720
|
}
|
|
3049
3721
|
|
|
3050
3722
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
3051
3723
|
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
3724
|
+
/**
|
|
3725
|
+
*
|
|
3726
|
+
* @param iterator
|
|
3727
|
+
* @param opt
|
|
3728
|
+
*/
|
|
3052
3729
|
async function parse$1(iterator, opt = {}) {
|
|
3730
|
+
const startTime = performance.now();
|
|
3053
3731
|
const errors = [];
|
|
3054
3732
|
const options = {
|
|
3055
3733
|
src: '',
|
|
3056
3734
|
sourcemap: false,
|
|
3057
|
-
|
|
3735
|
+
minify: true,
|
|
3058
3736
|
nestingRules: false,
|
|
3059
3737
|
resolveImport: false,
|
|
3060
3738
|
resolveUrls: false,
|
|
@@ -3064,201 +3742,57 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3064
3742
|
if (options.resolveImport) {
|
|
3065
3743
|
options.resolveUrls = true;
|
|
3066
3744
|
}
|
|
3067
|
-
let ind = -1;
|
|
3068
|
-
let lin = 1;
|
|
3069
|
-
let col = 0;
|
|
3070
|
-
const tokens = [];
|
|
3071
3745
|
const src = options.src;
|
|
3072
3746
|
const stack = [];
|
|
3073
3747
|
const ast = {
|
|
3074
3748
|
typ: "StyleSheet",
|
|
3075
3749
|
chi: []
|
|
3076
3750
|
};
|
|
3077
|
-
|
|
3078
|
-
ind: Math.max(ind, 0),
|
|
3079
|
-
lin: lin,
|
|
3080
|
-
col: Math.max(col, 1)
|
|
3081
|
-
};
|
|
3082
|
-
let value;
|
|
3083
|
-
let buffer = '';
|
|
3084
|
-
let total = iterator.length;
|
|
3085
|
-
let bytesIn = total;
|
|
3751
|
+
let tokens = [];
|
|
3086
3752
|
let map = new Map;
|
|
3753
|
+
let bytesIn = 0;
|
|
3087
3754
|
let context = ast;
|
|
3088
3755
|
if (options.sourcemap) {
|
|
3089
3756
|
ast.loc = {
|
|
3090
3757
|
sta: {
|
|
3091
|
-
ind:
|
|
3092
|
-
lin:
|
|
3093
|
-
col:
|
|
3758
|
+
ind: 0,
|
|
3759
|
+
lin: 1,
|
|
3760
|
+
col: 1
|
|
3094
3761
|
},
|
|
3095
3762
|
src: ''
|
|
3096
3763
|
};
|
|
3097
3764
|
}
|
|
3098
|
-
function
|
|
3099
|
-
|
|
3100
|
-
|
|
3765
|
+
async function parseNode(results) {
|
|
3766
|
+
let tokens = results.map(mapToken);
|
|
3767
|
+
let i;
|
|
3768
|
+
let loc;
|
|
3769
|
+
for (i = 0; i < tokens.length; i++) {
|
|
3770
|
+
if (tokens[i].typ == 'Comment') {
|
|
3771
|
+
// @ts-ignore
|
|
3772
|
+
context.chi.push(tokens[i]);
|
|
3773
|
+
const position = map.get(tokens[i]);
|
|
3774
|
+
loc = {
|
|
3775
|
+
sta: position,
|
|
3776
|
+
src
|
|
3777
|
+
};
|
|
3778
|
+
if (options.sourcemap) {
|
|
3779
|
+
tokens[i].loc = loc;
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
else if (tokens[i].typ != 'Whitespace') {
|
|
3783
|
+
break;
|
|
3784
|
+
}
|
|
3101
3785
|
}
|
|
3102
|
-
|
|
3103
|
-
|
|
3786
|
+
tokens = tokens.slice(i);
|
|
3787
|
+
if (tokens.length == 0) {
|
|
3788
|
+
return null;
|
|
3104
3789
|
}
|
|
3105
|
-
|
|
3106
|
-
|
|
3790
|
+
let delim = tokens.at(-1);
|
|
3791
|
+
if (delim.typ == 'Semi-colon' || delim.typ == 'Block-start' || delim.typ == 'Block-end') {
|
|
3792
|
+
tokens.pop();
|
|
3107
3793
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
}
|
|
3111
|
-
if (val == '=') {
|
|
3112
|
-
return { typ: 'Delim', val };
|
|
3113
|
-
}
|
|
3114
|
-
if (val == ';') {
|
|
3115
|
-
return { typ: 'Semi-colon' };
|
|
3116
|
-
}
|
|
3117
|
-
if (val == ',') {
|
|
3118
|
-
return { typ: 'Comma' };
|
|
3119
|
-
}
|
|
3120
|
-
if (val == '<') {
|
|
3121
|
-
return { typ: 'Lt' };
|
|
3122
|
-
}
|
|
3123
|
-
if (val == '>') {
|
|
3124
|
-
return { typ: 'Gt' };
|
|
3125
|
-
}
|
|
3126
|
-
if (isPseudo(val)) {
|
|
3127
|
-
return val.endsWith('(') ? {
|
|
3128
|
-
typ: 'Pseudo-class-func',
|
|
3129
|
-
val: val.slice(0, -1),
|
|
3130
|
-
chi: []
|
|
3131
|
-
}
|
|
3132
|
-
: {
|
|
3133
|
-
typ: 'Pseudo-class',
|
|
3134
|
-
val
|
|
3135
|
-
};
|
|
3136
|
-
}
|
|
3137
|
-
if (isAtKeyword(val)) {
|
|
3138
|
-
return {
|
|
3139
|
-
typ: 'At-rule',
|
|
3140
|
-
val: val.slice(1)
|
|
3141
|
-
};
|
|
3142
|
-
}
|
|
3143
|
-
if (isFunction(val)) {
|
|
3144
|
-
val = val.slice(0, -1);
|
|
3145
|
-
return {
|
|
3146
|
-
typ: val == 'url' ? 'UrlFunc' : 'Func',
|
|
3147
|
-
val,
|
|
3148
|
-
chi: []
|
|
3149
|
-
};
|
|
3150
|
-
}
|
|
3151
|
-
if (isNumber(val)) {
|
|
3152
|
-
return {
|
|
3153
|
-
typ: 'Number',
|
|
3154
|
-
val
|
|
3155
|
-
};
|
|
3156
|
-
}
|
|
3157
|
-
if (isDimension(val)) {
|
|
3158
|
-
return parseDimension(val);
|
|
3159
|
-
}
|
|
3160
|
-
if (isPercentage(val)) {
|
|
3161
|
-
return {
|
|
3162
|
-
typ: 'Perc',
|
|
3163
|
-
val: val.slice(0, -1)
|
|
3164
|
-
};
|
|
3165
|
-
}
|
|
3166
|
-
if (val == 'currentColor') {
|
|
3167
|
-
return {
|
|
3168
|
-
typ: 'Color',
|
|
3169
|
-
val,
|
|
3170
|
-
kin: 'lit'
|
|
3171
|
-
};
|
|
3172
|
-
}
|
|
3173
|
-
if (isIdent(val)) {
|
|
3174
|
-
return {
|
|
3175
|
-
typ: 'Iden',
|
|
3176
|
-
val
|
|
3177
|
-
};
|
|
3178
|
-
}
|
|
3179
|
-
if (val.charAt(0) == '#' && isHash(val)) {
|
|
3180
|
-
return {
|
|
3181
|
-
typ: 'Hash',
|
|
3182
|
-
val
|
|
3183
|
-
};
|
|
3184
|
-
}
|
|
3185
|
-
if ('"\''.includes(val.charAt(0))) {
|
|
3186
|
-
return {
|
|
3187
|
-
typ: 'Unclosed-string',
|
|
3188
|
-
val
|
|
3189
|
-
};
|
|
3190
|
-
}
|
|
3191
|
-
return {
|
|
3192
|
-
typ: 'Literal',
|
|
3193
|
-
val
|
|
3194
|
-
};
|
|
3195
|
-
}
|
|
3196
|
-
// consume and throw away
|
|
3197
|
-
function consume(open, close) {
|
|
3198
|
-
let count = 1;
|
|
3199
|
-
let chr;
|
|
3200
|
-
while (true) {
|
|
3201
|
-
chr = next();
|
|
3202
|
-
if (chr == '\\') {
|
|
3203
|
-
if (peek() === '') {
|
|
3204
|
-
break;
|
|
3205
|
-
}
|
|
3206
|
-
continue;
|
|
3207
|
-
}
|
|
3208
|
-
else if (chr == '/' && peek() == '*') {
|
|
3209
|
-
next();
|
|
3210
|
-
while (true) {
|
|
3211
|
-
chr = next();
|
|
3212
|
-
if (chr === '') {
|
|
3213
|
-
break;
|
|
3214
|
-
}
|
|
3215
|
-
if (chr == '*' && peek() == '/') {
|
|
3216
|
-
next();
|
|
3217
|
-
break;
|
|
3218
|
-
}
|
|
3219
|
-
}
|
|
3220
|
-
}
|
|
3221
|
-
else if (chr == close) {
|
|
3222
|
-
count--;
|
|
3223
|
-
}
|
|
3224
|
-
else if (chr == open) {
|
|
3225
|
-
count++;
|
|
3226
|
-
}
|
|
3227
|
-
if (chr === '' || count == 0) {
|
|
3228
|
-
break;
|
|
3229
|
-
}
|
|
3230
|
-
}
|
|
3231
|
-
}
|
|
3232
|
-
async function parseNode(tokens) {
|
|
3233
|
-
let i;
|
|
3234
|
-
let loc;
|
|
3235
|
-
for (i = 0; i < tokens.length; i++) {
|
|
3236
|
-
if (tokens[i].typ == 'Comment') {
|
|
3237
|
-
// @ts-ignore
|
|
3238
|
-
context.chi.push(tokens[i]);
|
|
3239
|
-
const position = map.get(tokens[i]);
|
|
3240
|
-
loc = {
|
|
3241
|
-
sta: position,
|
|
3242
|
-
src
|
|
3243
|
-
};
|
|
3244
|
-
if (options.sourcemap) {
|
|
3245
|
-
tokens[i].loc = loc;
|
|
3246
|
-
}
|
|
3247
|
-
}
|
|
3248
|
-
else if (tokens[i].typ != 'Whitespace') {
|
|
3249
|
-
break;
|
|
3250
|
-
}
|
|
3251
|
-
}
|
|
3252
|
-
tokens = tokens.slice(i);
|
|
3253
|
-
if (tokens.length == 0) {
|
|
3254
|
-
return null;
|
|
3255
|
-
}
|
|
3256
|
-
let delim = tokens.at(-1);
|
|
3257
|
-
if (delim.typ == 'Semi-colon' || delim.typ == 'Block-start' || delim.typ == 'Block-end') {
|
|
3258
|
-
tokens.pop();
|
|
3259
|
-
}
|
|
3260
|
-
else {
|
|
3261
|
-
delim = { typ: 'Semi-colon' };
|
|
3794
|
+
else {
|
|
3795
|
+
delim = { typ: 'Semi-colon' };
|
|
3262
3796
|
}
|
|
3263
3797
|
// @ts-ignore
|
|
3264
3798
|
while (['Whitespace', 'Bad-string', 'Bad-comment'].includes(tokens.at(-1)?.typ)) {
|
|
@@ -3327,12 +3861,12 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3327
3861
|
// @ts-ignore
|
|
3328
3862
|
const root = await options.load(url, options.src).then((src) => {
|
|
3329
3863
|
return parse$1(src, Object.assign({}, options, {
|
|
3330
|
-
|
|
3864
|
+
minify: false,
|
|
3331
3865
|
// @ts-ignore
|
|
3332
3866
|
src: options.resolve(url, options.src).absolute
|
|
3333
3867
|
}));
|
|
3334
3868
|
});
|
|
3335
|
-
bytesIn += root.bytesIn;
|
|
3869
|
+
bytesIn += root.stats.bytesIn;
|
|
3336
3870
|
if (root.ast.chi.length > 0) {
|
|
3337
3871
|
context.chi.push(...root.ast.chi);
|
|
3338
3872
|
}
|
|
@@ -3378,20 +3912,17 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3378
3912
|
// rule
|
|
3379
3913
|
if (delim.typ == 'Block-start') {
|
|
3380
3914
|
const position = map.get(tokens[0]);
|
|
3381
|
-
if (context.typ == 'Rule') {
|
|
3382
|
-
if (tokens[0]?.typ == 'Iden') {
|
|
3383
|
-
errors.push({ action: 'drop', message: 'invalid nesting rule', location: { src, ...position } });
|
|
3384
|
-
return null;
|
|
3385
|
-
}
|
|
3386
|
-
}
|
|
3387
3915
|
const uniq = new Map;
|
|
3388
|
-
parseTokens(tokens,
|
|
3916
|
+
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
|
|
3389
3917
|
if (curr.typ == 'Whitespace') {
|
|
3390
|
-
if (array[index - 1]?.
|
|
3918
|
+
if (array[index - 1]?.typ == 'Gt' ||
|
|
3919
|
+
array[index + 1]?.typ == 'Gt' ||
|
|
3920
|
+
combinators.includes(array[index - 1]?.val) ||
|
|
3921
|
+
combinators.includes(array[index + 1]?.val)) {
|
|
3391
3922
|
return acc;
|
|
3392
3923
|
}
|
|
3393
3924
|
}
|
|
3394
|
-
let t = renderToken(curr, {
|
|
3925
|
+
let t = renderToken(curr, { minify: true });
|
|
3395
3926
|
if (t == ',') {
|
|
3396
3927
|
acc.push([]);
|
|
3397
3928
|
}
|
|
@@ -3409,595 +3940,310 @@ async function parse$1(iterator, opt = {}) {
|
|
|
3409
3940
|
sel: [...uniq.keys()].join(','),
|
|
3410
3941
|
chi: []
|
|
3411
3942
|
};
|
|
3412
|
-
let raw = [...uniq.values()];
|
|
3413
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
3414
|
-
loc = {
|
|
3415
|
-
sta: position,
|
|
3416
|
-
src
|
|
3417
|
-
};
|
|
3418
|
-
if (options.sourcemap) {
|
|
3419
|
-
node.loc = loc;
|
|
3420
|
-
}
|
|
3421
|
-
// @ts-ignore
|
|
3422
|
-
context.chi.push(node);
|
|
3423
|
-
return node;
|
|
3424
|
-
}
|
|
3425
|
-
else {
|
|
3426
|
-
// declaration
|
|
3427
|
-
// @ts-ignore
|
|
3428
|
-
let name = null;
|
|
3429
|
-
// @ts-ignore
|
|
3430
|
-
let value = null;
|
|
3431
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
3432
|
-
if (tokens[i].typ == 'Comment') {
|
|
3433
|
-
continue;
|
|
3434
|
-
}
|
|
3435
|
-
if (tokens[i].typ == 'Colon') {
|
|
3436
|
-
name = tokens.slice(0, i);
|
|
3437
|
-
value = parseTokens(tokens.slice(i + 1), 'Declaration', {
|
|
3438
|
-
parseColor: true,
|
|
3439
|
-
src: options.src,
|
|
3440
|
-
resolveUrls: options.resolveUrls,
|
|
3441
|
-
resolve: options.resolve,
|
|
3442
|
-
cwd: options.cwd
|
|
3443
|
-
});
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
|
-
if (name == null) {
|
|
3447
|
-
name = tokens;
|
|
3448
|
-
}
|
|
3449
|
-
const position = map.get(name[0]);
|
|
3450
|
-
if (name.length > 0) {
|
|
3451
|
-
for (let i = 1; i < name.length; i++) {
|
|
3452
|
-
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
3453
|
-
errors.push({
|
|
3454
|
-
action: 'drop',
|
|
3455
|
-
message: 'invalid declaration',
|
|
3456
|
-
location: { src, ...position }
|
|
3457
|
-
});
|
|
3458
|
-
return null;
|
|
3459
|
-
}
|
|
3460
|
-
}
|
|
3461
|
-
}
|
|
3462
|
-
if (value == null) {
|
|
3463
|
-
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
3464
|
-
return null;
|
|
3465
|
-
}
|
|
3466
|
-
if (value.length == 0) {
|
|
3467
|
-
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
3468
|
-
return null;
|
|
3469
|
-
}
|
|
3470
|
-
const node = {
|
|
3471
|
-
typ: 'Declaration',
|
|
3472
|
-
// @ts-ignore
|
|
3473
|
-
nam: renderToken(name.shift(), { removeComments: true }),
|
|
3474
|
-
// @ts-ignore
|
|
3475
|
-
val: value
|
|
3476
|
-
};
|
|
3477
|
-
while (node.val[0]?.typ == 'Whitespace') {
|
|
3478
|
-
node.val.shift();
|
|
3479
|
-
}
|
|
3480
|
-
if (node.val.length == 0) {
|
|
3481
|
-
errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
|
|
3482
|
-
return null;
|
|
3483
|
-
}
|
|
3484
|
-
// @ts-ignore
|
|
3485
|
-
context.chi.push(node);
|
|
3486
|
-
return null;
|
|
3487
|
-
}
|
|
3488
|
-
}
|
|
3489
|
-
}
|
|
3490
|
-
function peek(count = 1) {
|
|
3491
|
-
if (count == 1) {
|
|
3492
|
-
return iterator.charAt(ind + 1);
|
|
3493
|
-
}
|
|
3494
|
-
return iterator.slice(ind + 1, ind + count + 1);
|
|
3495
|
-
}
|
|
3496
|
-
function prev(count = 1) {
|
|
3497
|
-
if (count == 1) {
|
|
3498
|
-
return ind == 0 ? '' : iterator.charAt(ind - 1);
|
|
3499
|
-
}
|
|
3500
|
-
return iterator.slice(ind - 1 - count, ind - 1);
|
|
3501
|
-
}
|
|
3502
|
-
function next(count = 1) {
|
|
3503
|
-
let char = '';
|
|
3504
|
-
while (count-- > 0 && ind < total) {
|
|
3505
|
-
const codepoint = iterator.charCodeAt(++ind);
|
|
3506
|
-
if (isNaN(codepoint)) {
|
|
3507
|
-
return char;
|
|
3508
|
-
}
|
|
3509
|
-
char += iterator.charAt(ind);
|
|
3510
|
-
if (isNewLine(codepoint)) {
|
|
3511
|
-
lin++;
|
|
3512
|
-
col = 0;
|
|
3513
|
-
}
|
|
3514
|
-
else {
|
|
3515
|
-
col++;
|
|
3516
|
-
}
|
|
3517
|
-
}
|
|
3518
|
-
return char;
|
|
3519
|
-
}
|
|
3520
|
-
function pushToken(token) {
|
|
3521
|
-
tokens.push(token);
|
|
3522
|
-
map.set(token, { ...position });
|
|
3523
|
-
position.ind = ind;
|
|
3524
|
-
position.lin = lin;
|
|
3525
|
-
position.col = col == 0 ? 1 : col;
|
|
3526
|
-
}
|
|
3527
|
-
function consumeWhiteSpace() {
|
|
3528
|
-
let count = 0;
|
|
3529
|
-
while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
|
|
3530
|
-
count++;
|
|
3531
|
-
}
|
|
3532
|
-
next(count);
|
|
3533
|
-
return count;
|
|
3534
|
-
}
|
|
3535
|
-
function consumeString(quoteStr) {
|
|
3536
|
-
const quote = quoteStr;
|
|
3537
|
-
let value;
|
|
3538
|
-
let hasNewLine = false;
|
|
3539
|
-
if (buffer.length > 0) {
|
|
3540
|
-
pushToken(getType(buffer));
|
|
3541
|
-
buffer = '';
|
|
3542
|
-
}
|
|
3543
|
-
buffer += quoteStr;
|
|
3544
|
-
while (ind < total) {
|
|
3545
|
-
value = peek();
|
|
3546
|
-
if (ind >= total) {
|
|
3547
|
-
pushToken({ typ: hasNewLine ? 'Bad-string' : 'Unclosed-string', val: buffer });
|
|
3548
|
-
break;
|
|
3549
|
-
}
|
|
3550
|
-
if (value == '\\') {
|
|
3551
|
-
const sequence = peek(6);
|
|
3552
|
-
let escapeSequence = '';
|
|
3553
|
-
let codepoint;
|
|
3554
|
-
let i;
|
|
3555
|
-
for (i = 1; i < sequence.length; i++) {
|
|
3556
|
-
codepoint = sequence.charCodeAt(i);
|
|
3557
|
-
if (codepoint == 0x20 ||
|
|
3558
|
-
(codepoint >= 0x61 && codepoint <= 0x66) ||
|
|
3559
|
-
(codepoint >= 0x41 && codepoint <= 0x46) ||
|
|
3560
|
-
(codepoint >= 0x30 && codepoint <= 0x39)) {
|
|
3561
|
-
escapeSequence += sequence[i];
|
|
3562
|
-
if (codepoint == 0x20) {
|
|
3563
|
-
break;
|
|
3564
|
-
}
|
|
3565
|
-
continue;
|
|
3566
|
-
}
|
|
3567
|
-
break;
|
|
3568
|
-
}
|
|
3569
|
-
// not hex or new line
|
|
3570
|
-
// @ts-ignore
|
|
3571
|
-
if (i == 1 && !isNewLine(codepoint)) {
|
|
3572
|
-
buffer += sequence[i];
|
|
3573
|
-
next(2);
|
|
3574
|
-
continue;
|
|
3575
|
-
}
|
|
3576
|
-
if (escapeSequence.trimEnd().length > 0) {
|
|
3577
|
-
const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
|
|
3578
|
-
if (codepoint == 0 ||
|
|
3579
|
-
// leading surrogate
|
|
3580
|
-
(0xD800 <= codepoint && codepoint <= 0xDBFF) ||
|
|
3581
|
-
// trailing surrogate
|
|
3582
|
-
(0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
|
|
3583
|
-
buffer += String.fromCodePoint(0xFFFD);
|
|
3584
|
-
}
|
|
3585
|
-
else {
|
|
3586
|
-
buffer += String.fromCodePoint(codepoint);
|
|
3587
|
-
}
|
|
3588
|
-
next(escapeSequence.length + 1);
|
|
3589
|
-
continue;
|
|
3590
|
-
}
|
|
3591
|
-
// buffer += value;
|
|
3592
|
-
if (ind >= total) {
|
|
3593
|
-
// drop '\\' at the end
|
|
3594
|
-
pushToken(getType(buffer));
|
|
3595
|
-
break;
|
|
3596
|
-
}
|
|
3597
|
-
buffer += next(2);
|
|
3598
|
-
continue;
|
|
3599
|
-
}
|
|
3600
|
-
if (value == quote) {
|
|
3601
|
-
buffer += value;
|
|
3602
|
-
pushToken({ typ: hasNewLine ? 'Bad-string' : 'String', val: buffer });
|
|
3603
|
-
next();
|
|
3604
|
-
// i += value.length;
|
|
3605
|
-
buffer = '';
|
|
3606
|
-
break;
|
|
3607
|
-
}
|
|
3608
|
-
if (isNewLine(value.charCodeAt(0))) {
|
|
3609
|
-
hasNewLine = true;
|
|
3610
|
-
}
|
|
3611
|
-
if (hasNewLine && value == ';') {
|
|
3612
|
-
pushToken({ typ: 'Bad-string', val: buffer });
|
|
3613
|
-
buffer = '';
|
|
3614
|
-
break;
|
|
3615
|
-
}
|
|
3616
|
-
buffer += value;
|
|
3617
|
-
// i += value.length;
|
|
3618
|
-
next();
|
|
3619
|
-
}
|
|
3620
|
-
}
|
|
3621
|
-
while (ind < total) {
|
|
3622
|
-
value = next();
|
|
3623
|
-
if (ind >= total) {
|
|
3624
|
-
if (buffer.length > 0) {
|
|
3625
|
-
pushToken(getType(buffer));
|
|
3626
|
-
buffer = '';
|
|
3627
|
-
}
|
|
3628
|
-
break;
|
|
3629
|
-
}
|
|
3630
|
-
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
3631
|
-
if (buffer.length > 0) {
|
|
3632
|
-
pushToken(getType(buffer));
|
|
3633
|
-
buffer = '';
|
|
3634
|
-
}
|
|
3635
|
-
while (ind < total) {
|
|
3636
|
-
value = next();
|
|
3637
|
-
if (ind >= total) {
|
|
3638
|
-
break;
|
|
3639
|
-
}
|
|
3640
|
-
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
3641
|
-
break;
|
|
3642
|
-
}
|
|
3643
|
-
}
|
|
3644
|
-
pushToken({ typ: 'Whitespace' });
|
|
3645
|
-
buffer = '';
|
|
3646
|
-
if (ind >= total) {
|
|
3647
|
-
break;
|
|
3648
|
-
}
|
|
3649
|
-
}
|
|
3650
|
-
switch (value) {
|
|
3651
|
-
case '/':
|
|
3652
|
-
if (buffer.length > 0 && tokens.at(-1)?.typ == 'Whitespace') {
|
|
3653
|
-
pushToken(getType(buffer));
|
|
3654
|
-
buffer = '';
|
|
3655
|
-
if (peek() != '*') {
|
|
3656
|
-
pushToken(getType(value));
|
|
3657
|
-
break;
|
|
3658
|
-
}
|
|
3659
|
-
}
|
|
3660
|
-
buffer += value;
|
|
3661
|
-
if (peek() == '*') {
|
|
3662
|
-
buffer += '*';
|
|
3663
|
-
// i++;
|
|
3664
|
-
next();
|
|
3665
|
-
while (ind < total) {
|
|
3666
|
-
value = next();
|
|
3667
|
-
if (ind >= total) {
|
|
3668
|
-
pushToken({
|
|
3669
|
-
typ: 'Bad-comment', val: buffer
|
|
3670
|
-
});
|
|
3671
|
-
break;
|
|
3672
|
-
}
|
|
3673
|
-
if (value == '\\') {
|
|
3674
|
-
buffer += value;
|
|
3675
|
-
value = next();
|
|
3676
|
-
if (ind >= total) {
|
|
3677
|
-
pushToken({
|
|
3678
|
-
typ: 'Bad-comment',
|
|
3679
|
-
val: buffer
|
|
3680
|
-
});
|
|
3681
|
-
break;
|
|
3682
|
-
}
|
|
3683
|
-
buffer += value;
|
|
3684
|
-
continue;
|
|
3685
|
-
}
|
|
3686
|
-
if (value == '*') {
|
|
3687
|
-
buffer += value;
|
|
3688
|
-
value = next();
|
|
3689
|
-
if (ind >= total) {
|
|
3690
|
-
pushToken({
|
|
3691
|
-
typ: 'Bad-comment', val: buffer
|
|
3692
|
-
});
|
|
3693
|
-
break;
|
|
3694
|
-
}
|
|
3695
|
-
buffer += value;
|
|
3696
|
-
if (value == '/') {
|
|
3697
|
-
pushToken({ typ: 'Comment', val: buffer });
|
|
3698
|
-
buffer = '';
|
|
3699
|
-
break;
|
|
3700
|
-
}
|
|
3701
|
-
}
|
|
3702
|
-
else {
|
|
3703
|
-
buffer += value;
|
|
3704
|
-
}
|
|
3705
|
-
}
|
|
3706
|
-
}
|
|
3707
|
-
break;
|
|
3708
|
-
case '<':
|
|
3709
|
-
if (buffer.length > 0) {
|
|
3710
|
-
pushToken(getType(buffer));
|
|
3711
|
-
buffer = '';
|
|
3712
|
-
}
|
|
3713
|
-
buffer += value;
|
|
3714
|
-
value = next();
|
|
3715
|
-
if (ind >= total) {
|
|
3716
|
-
break;
|
|
3717
|
-
}
|
|
3718
|
-
if (peek(3) == '!--') {
|
|
3719
|
-
while (ind < total) {
|
|
3720
|
-
value = next();
|
|
3721
|
-
if (ind >= total) {
|
|
3722
|
-
break;
|
|
3723
|
-
}
|
|
3724
|
-
buffer += value;
|
|
3725
|
-
if (value == '>' && prev(2) == '--') {
|
|
3726
|
-
pushToken({
|
|
3727
|
-
typ: 'CDOCOMM',
|
|
3728
|
-
val: buffer
|
|
3729
|
-
});
|
|
3730
|
-
buffer = '';
|
|
3731
|
-
break;
|
|
3732
|
-
}
|
|
3733
|
-
}
|
|
3734
|
-
}
|
|
3735
|
-
if (ind >= total) {
|
|
3736
|
-
pushToken({ typ: 'BADCDO', val: buffer });
|
|
3737
|
-
buffer = '';
|
|
3738
|
-
}
|
|
3739
|
-
break;
|
|
3740
|
-
case '\\':
|
|
3741
|
-
value = next();
|
|
3742
|
-
// EOF
|
|
3743
|
-
if (ind + 1 >= total) {
|
|
3744
|
-
// end of stream ignore \\
|
|
3745
|
-
pushToken(getType(buffer));
|
|
3746
|
-
buffer = '';
|
|
3747
|
-
break;
|
|
3748
|
-
}
|
|
3749
|
-
buffer += value;
|
|
3750
|
-
break;
|
|
3751
|
-
case '"':
|
|
3752
|
-
case "'":
|
|
3753
|
-
consumeString(value);
|
|
3754
|
-
break;
|
|
3755
|
-
case '~':
|
|
3756
|
-
case '|':
|
|
3757
|
-
if (tokens.at(-1)?.typ == 'Whitespace') {
|
|
3758
|
-
tokens.pop();
|
|
3759
|
-
}
|
|
3760
|
-
if (buffer.length > 0) {
|
|
3761
|
-
pushToken(getType(buffer));
|
|
3762
|
-
buffer = '';
|
|
3763
|
-
}
|
|
3764
|
-
buffer += value;
|
|
3765
|
-
value = next();
|
|
3766
|
-
if (ind >= total) {
|
|
3767
|
-
pushToken(getType(buffer));
|
|
3768
|
-
buffer = '';
|
|
3769
|
-
break;
|
|
3770
|
-
}
|
|
3771
|
-
if (value == '=') {
|
|
3772
|
-
buffer += value;
|
|
3773
|
-
pushToken({
|
|
3774
|
-
typ: buffer[0] == '~' ? 'Includes' : 'Dash-matches',
|
|
3775
|
-
val: buffer
|
|
3776
|
-
});
|
|
3777
|
-
buffer = '';
|
|
3778
|
-
break;
|
|
3779
|
-
}
|
|
3780
|
-
pushToken(getType(buffer));
|
|
3781
|
-
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
3782
|
-
value = next();
|
|
3783
|
-
}
|
|
3784
|
-
buffer = value;
|
|
3785
|
-
break;
|
|
3786
|
-
case '>':
|
|
3787
|
-
if (buffer !== '') {
|
|
3788
|
-
pushToken(getType(buffer));
|
|
3789
|
-
buffer = '';
|
|
3790
|
-
}
|
|
3791
|
-
if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
|
|
3792
|
-
tokens.pop();
|
|
3793
|
-
}
|
|
3794
|
-
pushToken({ typ: 'Gt' });
|
|
3795
|
-
consumeWhiteSpace();
|
|
3796
|
-
break;
|
|
3797
|
-
case '.':
|
|
3798
|
-
const codepoint = peek().charCodeAt(0);
|
|
3799
|
-
if (!isDigit(codepoint) && buffer !== '') {
|
|
3800
|
-
pushToken(getType(buffer));
|
|
3801
|
-
buffer = value;
|
|
3802
|
-
break;
|
|
3803
|
-
}
|
|
3804
|
-
buffer += value;
|
|
3805
|
-
break;
|
|
3806
|
-
case '+':
|
|
3807
|
-
case ':':
|
|
3808
|
-
case ',':
|
|
3809
|
-
case '=':
|
|
3810
|
-
if (buffer.length > 0) {
|
|
3811
|
-
pushToken(getType(buffer));
|
|
3812
|
-
buffer = '';
|
|
3813
|
-
}
|
|
3814
|
-
if (value == ':' && ':' == peek()) {
|
|
3815
|
-
buffer += value + next();
|
|
3816
|
-
break;
|
|
3817
|
-
}
|
|
3818
|
-
pushToken(getType(value));
|
|
3819
|
-
buffer = '';
|
|
3820
|
-
if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
|
|
3821
|
-
pushToken(getType(next()));
|
|
3822
|
-
}
|
|
3823
|
-
while (isWhiteSpace(peek().charCodeAt(0))) {
|
|
3824
|
-
next();
|
|
3943
|
+
let raw = [...uniq.values()];
|
|
3944
|
+
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
3945
|
+
loc = {
|
|
3946
|
+
sta: position,
|
|
3947
|
+
src
|
|
3948
|
+
};
|
|
3949
|
+
if (options.sourcemap) {
|
|
3950
|
+
node.loc = loc;
|
|
3825
3951
|
}
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3952
|
+
// @ts-ignore
|
|
3953
|
+
context.chi.push(node);
|
|
3954
|
+
return node;
|
|
3955
|
+
}
|
|
3956
|
+
else {
|
|
3957
|
+
// declaration
|
|
3958
|
+
// @ts-ignore
|
|
3959
|
+
let name = null;
|
|
3960
|
+
// @ts-ignore
|
|
3961
|
+
let value = null;
|
|
3962
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
3963
|
+
if (tokens[i].typ == 'Comment') {
|
|
3964
|
+
continue;
|
|
3965
|
+
}
|
|
3966
|
+
if (tokens[i].typ == 'Colon') {
|
|
3967
|
+
name = tokens.slice(0, i);
|
|
3968
|
+
value = parseTokens(tokens.slice(i + 1), {
|
|
3969
|
+
parseColor: true,
|
|
3970
|
+
src: options.src,
|
|
3971
|
+
resolveUrls: options.resolveUrls,
|
|
3972
|
+
resolve: options.resolve,
|
|
3973
|
+
cwd: options.cwd
|
|
3974
|
+
});
|
|
3975
|
+
}
|
|
3831
3976
|
}
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
case '(':
|
|
3835
|
-
if (buffer.length == 0) {
|
|
3836
|
-
pushToken({ typ: 'Start-parens' });
|
|
3977
|
+
if (name == null) {
|
|
3978
|
+
name = tokens;
|
|
3837
3979
|
}
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
whitespace += value;
|
|
3849
|
-
}
|
|
3850
|
-
if (whitespace.length > 0) {
|
|
3851
|
-
next(whitespace.length);
|
|
3852
|
-
}
|
|
3853
|
-
value = peek();
|
|
3854
|
-
if (value == '"' || value == "'") {
|
|
3855
|
-
consumeString(next());
|
|
3856
|
-
let token = tokens[tokens.length - 1];
|
|
3857
|
-
if (['String', 'Literal'].includes(token.typ) && urlTokenMatcher.test(token.val)) {
|
|
3858
|
-
if (token.val.slice(1, 6) != 'data:') {
|
|
3859
|
-
if (token.typ == 'String') {
|
|
3860
|
-
token.val = token.val.slice(1, -1);
|
|
3861
|
-
}
|
|
3862
|
-
// @ts-ignore
|
|
3863
|
-
token.typ = 'Url-token';
|
|
3864
|
-
}
|
|
3865
|
-
}
|
|
3866
|
-
break;
|
|
3867
|
-
}
|
|
3868
|
-
else {
|
|
3869
|
-
buffer = '';
|
|
3870
|
-
do {
|
|
3871
|
-
let cp = value.charCodeAt(0);
|
|
3872
|
-
// EOF -
|
|
3873
|
-
if (cp == null) {
|
|
3874
|
-
pushToken({ typ: 'Bad-url-token', val: buffer });
|
|
3875
|
-
break;
|
|
3876
|
-
}
|
|
3877
|
-
// ')'
|
|
3878
|
-
if (cp == 0x29 || cp == null) {
|
|
3879
|
-
if (buffer.length == 0) {
|
|
3880
|
-
pushToken({ typ: 'Bad-url-token', val: '' });
|
|
3881
|
-
}
|
|
3882
|
-
else {
|
|
3883
|
-
pushToken({ typ: 'Url-token', val: buffer });
|
|
3884
|
-
}
|
|
3885
|
-
if (cp != null) {
|
|
3886
|
-
pushToken(getType(next()));
|
|
3887
|
-
}
|
|
3888
|
-
break;
|
|
3889
|
-
}
|
|
3890
|
-
if (isWhiteSpace(cp)) {
|
|
3891
|
-
whitespace = next();
|
|
3892
|
-
while (true) {
|
|
3893
|
-
value = peek();
|
|
3894
|
-
cp = value.charCodeAt(0);
|
|
3895
|
-
if (isWhiteSpace(cp)) {
|
|
3896
|
-
whitespace += value;
|
|
3897
|
-
continue;
|
|
3898
|
-
}
|
|
3899
|
-
break;
|
|
3900
|
-
}
|
|
3901
|
-
if (cp == null || cp == 0x29) {
|
|
3902
|
-
continue;
|
|
3903
|
-
}
|
|
3904
|
-
// bad url token
|
|
3905
|
-
buffer += next(whitespace.length);
|
|
3906
|
-
do {
|
|
3907
|
-
value = peek();
|
|
3908
|
-
cp = value.charCodeAt(0);
|
|
3909
|
-
if (cp == null || cp == 0x29) {
|
|
3910
|
-
break;
|
|
3911
|
-
}
|
|
3912
|
-
buffer += next();
|
|
3913
|
-
} while (true);
|
|
3914
|
-
pushToken({ typ: 'Bad-url-token', val: buffer });
|
|
3915
|
-
continue;
|
|
3916
|
-
}
|
|
3917
|
-
buffer += next();
|
|
3918
|
-
value = peek();
|
|
3919
|
-
} while (true);
|
|
3920
|
-
buffer = '';
|
|
3980
|
+
const position = map.get(name[0]);
|
|
3981
|
+
if (name.length > 0) {
|
|
3982
|
+
for (let i = 1; i < name.length; i++) {
|
|
3983
|
+
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
3984
|
+
errors.push({
|
|
3985
|
+
action: 'drop',
|
|
3986
|
+
message: 'invalid declaration',
|
|
3987
|
+
location: { src, ...position }
|
|
3988
|
+
});
|
|
3989
|
+
return null;
|
|
3921
3990
|
}
|
|
3922
3991
|
}
|
|
3923
3992
|
}
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
pushToken(getType(buffer));
|
|
3932
|
-
buffer = '';
|
|
3993
|
+
if (value == null) {
|
|
3994
|
+
errors.push({
|
|
3995
|
+
action: 'drop',
|
|
3996
|
+
message: 'invalid declaration',
|
|
3997
|
+
location: { src, ...position }
|
|
3998
|
+
});
|
|
3999
|
+
return null;
|
|
3933
4000
|
}
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
context = node;
|
|
3942
|
-
}
|
|
3943
|
-
else if (value == '{') {
|
|
3944
|
-
// node == null
|
|
3945
|
-
// consume and throw away until the closing '}' or EOF
|
|
3946
|
-
consume('{', '}');
|
|
3947
|
-
}
|
|
3948
|
-
tokens.length = 0;
|
|
3949
|
-
map.clear();
|
|
4001
|
+
if (value.length == 0) {
|
|
4002
|
+
errors.push({
|
|
4003
|
+
action: 'drop',
|
|
4004
|
+
message: 'invalid declaration',
|
|
4005
|
+
location: { src, ...position }
|
|
4006
|
+
});
|
|
4007
|
+
return null;
|
|
3950
4008
|
}
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
const previousNode = stack.pop();
|
|
4009
|
+
const node = {
|
|
4010
|
+
typ: 'Declaration',
|
|
3954
4011
|
// @ts-ignore
|
|
3955
|
-
|
|
4012
|
+
nam: renderToken(name.shift(), { removeComments: true }),
|
|
3956
4013
|
// @ts-ignore
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
map.clear();
|
|
3962
|
-
buffer = '';
|
|
3963
|
-
}
|
|
3964
|
-
break;
|
|
3965
|
-
case '!':
|
|
3966
|
-
if (buffer.length > 0) {
|
|
3967
|
-
pushToken(getType(buffer));
|
|
3968
|
-
buffer = '';
|
|
4014
|
+
val: value
|
|
4015
|
+
};
|
|
4016
|
+
while (node.val[0]?.typ == 'Whitespace') {
|
|
4017
|
+
node.val.shift();
|
|
3969
4018
|
}
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
buffer = '';
|
|
3978
|
-
break;
|
|
4019
|
+
if (node.val.length == 0) {
|
|
4020
|
+
errors.push({
|
|
4021
|
+
action: 'drop',
|
|
4022
|
+
message: 'invalid declaration',
|
|
4023
|
+
location: { src, ...position }
|
|
4024
|
+
});
|
|
4025
|
+
return null;
|
|
3979
4026
|
}
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
break;
|
|
4027
|
+
// @ts-ignore
|
|
4028
|
+
context.chi.push(node);
|
|
4029
|
+
return null;
|
|
4030
|
+
}
|
|
3985
4031
|
}
|
|
3986
4032
|
}
|
|
3987
|
-
|
|
3988
|
-
|
|
4033
|
+
function mapToken(token) {
|
|
4034
|
+
const node = getTokenType(token.token, token.hint);
|
|
4035
|
+
map.set(node, token.position);
|
|
4036
|
+
return node;
|
|
4037
|
+
}
|
|
4038
|
+
const iter = tokenize(iterator);
|
|
4039
|
+
let item;
|
|
4040
|
+
while (true) {
|
|
4041
|
+
item = iter.next().value;
|
|
4042
|
+
if (item == null) {
|
|
4043
|
+
break;
|
|
4044
|
+
}
|
|
4045
|
+
tokens.push(item);
|
|
4046
|
+
bytesIn = item.bytesIn;
|
|
4047
|
+
if (item.token == ';' || item.token == '{') {
|
|
4048
|
+
let node = await parseNode(tokens);
|
|
4049
|
+
if (node != null) {
|
|
4050
|
+
stack.push(node);
|
|
4051
|
+
// @ts-ignore
|
|
4052
|
+
context = node;
|
|
4053
|
+
}
|
|
4054
|
+
else if (item.token == '{') {
|
|
4055
|
+
// node == null
|
|
4056
|
+
// consume and throw away until the closing '}' or EOF
|
|
4057
|
+
let inBlock = 1;
|
|
4058
|
+
do {
|
|
4059
|
+
item = iter.next().value;
|
|
4060
|
+
if (item == null) {
|
|
4061
|
+
break;
|
|
4062
|
+
}
|
|
4063
|
+
if (item.token == '{') {
|
|
4064
|
+
inBlock++;
|
|
4065
|
+
}
|
|
4066
|
+
else if (item.token == '}') {
|
|
4067
|
+
inBlock--;
|
|
4068
|
+
}
|
|
4069
|
+
} while (inBlock != 0);
|
|
4070
|
+
}
|
|
4071
|
+
tokens = [];
|
|
4072
|
+
map = new Map;
|
|
4073
|
+
}
|
|
4074
|
+
else if (item.token == '}') {
|
|
4075
|
+
await parseNode(tokens);
|
|
4076
|
+
const previousNode = stack.pop();
|
|
4077
|
+
// @ts-ignore
|
|
4078
|
+
context = stack[stack.length - 1] || ast;
|
|
4079
|
+
// @ts-ignore
|
|
4080
|
+
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
4081
|
+
context.chi.pop();
|
|
4082
|
+
}
|
|
4083
|
+
tokens = [];
|
|
4084
|
+
map = new Map;
|
|
4085
|
+
}
|
|
3989
4086
|
}
|
|
3990
4087
|
if (tokens.length > 0) {
|
|
3991
4088
|
await parseNode(tokens);
|
|
3992
4089
|
}
|
|
3993
|
-
|
|
4090
|
+
const endParseTime = performance.now();
|
|
4091
|
+
if (options.minify) {
|
|
3994
4092
|
if (ast.chi.length > 0) {
|
|
3995
|
-
|
|
4093
|
+
minify(ast, options, true);
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
const endTime = performance.now();
|
|
4097
|
+
return {
|
|
4098
|
+
ast, errors, stats: {
|
|
4099
|
+
bytesIn,
|
|
4100
|
+
parse: `${(endParseTime - startTime).toFixed(2)}ms`,
|
|
4101
|
+
minify: `${(endTime - endParseTime).toFixed(2)}ms`,
|
|
4102
|
+
total: `${(endTime - startTime).toFixed(2)}ms`
|
|
4103
|
+
}
|
|
4104
|
+
};
|
|
4105
|
+
}
|
|
4106
|
+
function parseString(src, options = { location: false }) {
|
|
4107
|
+
return [...tokenize(src)].map(t => {
|
|
4108
|
+
const token = getTokenType(t.token, t.hint);
|
|
4109
|
+
if (options.location) {
|
|
4110
|
+
Object.assign(token, { loc: t.position });
|
|
3996
4111
|
}
|
|
4112
|
+
return token;
|
|
4113
|
+
});
|
|
4114
|
+
}
|
|
4115
|
+
function getTokenType(val, hint) {
|
|
4116
|
+
if (val === '' && hint == null) {
|
|
4117
|
+
throw new Error('empty string?');
|
|
4118
|
+
}
|
|
4119
|
+
if (hint != null) {
|
|
4120
|
+
return ([
|
|
4121
|
+
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
|
|
4122
|
+
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
|
|
4123
|
+
'Comma', 'Gt', 'Lt'
|
|
4124
|
+
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
4125
|
+
}
|
|
4126
|
+
if (val == ' ') {
|
|
4127
|
+
return { typ: 'Whitespace' };
|
|
4128
|
+
}
|
|
4129
|
+
if (val == ';') {
|
|
4130
|
+
return { typ: 'Semi-colon' };
|
|
4131
|
+
}
|
|
4132
|
+
if (val == '{') {
|
|
4133
|
+
return { typ: 'Block-start' };
|
|
4134
|
+
}
|
|
4135
|
+
if (val == '}') {
|
|
4136
|
+
return { typ: 'Block-end' };
|
|
4137
|
+
}
|
|
4138
|
+
if (val == '[') {
|
|
4139
|
+
return { typ: 'Attr-start' };
|
|
4140
|
+
}
|
|
4141
|
+
if (val == ']') {
|
|
4142
|
+
return { typ: 'Attr-end' };
|
|
4143
|
+
}
|
|
4144
|
+
if (val == ':') {
|
|
4145
|
+
return { typ: 'Colon' };
|
|
4146
|
+
}
|
|
4147
|
+
if (val == ')') {
|
|
4148
|
+
return { typ: 'End-parens' };
|
|
4149
|
+
}
|
|
4150
|
+
if (val == '(') {
|
|
4151
|
+
return { typ: 'Start-parens' };
|
|
4152
|
+
}
|
|
4153
|
+
if (val == '=') {
|
|
4154
|
+
return { typ: 'Delim', val };
|
|
4155
|
+
}
|
|
4156
|
+
if (val == ';') {
|
|
4157
|
+
return { typ: 'Semi-colon' };
|
|
4158
|
+
}
|
|
4159
|
+
if (val == ',') {
|
|
4160
|
+
return { typ: 'Comma' };
|
|
4161
|
+
}
|
|
4162
|
+
if (val == '<') {
|
|
4163
|
+
return { typ: 'Lt' };
|
|
4164
|
+
}
|
|
4165
|
+
if (val == '>') {
|
|
4166
|
+
return { typ: 'Gt' };
|
|
4167
|
+
}
|
|
4168
|
+
if (isPseudo(val)) {
|
|
4169
|
+
return val.endsWith('(') ? {
|
|
4170
|
+
typ: 'Pseudo-class-func',
|
|
4171
|
+
val: val.slice(0, -1),
|
|
4172
|
+
chi: []
|
|
4173
|
+
}
|
|
4174
|
+
: {
|
|
4175
|
+
typ: 'Pseudo-class',
|
|
4176
|
+
val
|
|
4177
|
+
};
|
|
4178
|
+
}
|
|
4179
|
+
if (isAtKeyword(val)) {
|
|
4180
|
+
return {
|
|
4181
|
+
typ: 'At-rule',
|
|
4182
|
+
val: val.slice(1)
|
|
4183
|
+
};
|
|
4184
|
+
}
|
|
4185
|
+
if (isFunction(val)) {
|
|
4186
|
+
val = val.slice(0, -1);
|
|
4187
|
+
return {
|
|
4188
|
+
typ: val == 'url' ? 'UrlFunc' : 'Func',
|
|
4189
|
+
val,
|
|
4190
|
+
chi: []
|
|
4191
|
+
};
|
|
4192
|
+
}
|
|
4193
|
+
if (isNumber(val)) {
|
|
4194
|
+
return {
|
|
4195
|
+
typ: 'Number',
|
|
4196
|
+
val
|
|
4197
|
+
};
|
|
4198
|
+
}
|
|
4199
|
+
if (isDimension(val)) {
|
|
4200
|
+
return parseDimension(val);
|
|
3997
4201
|
}
|
|
3998
|
-
|
|
4202
|
+
if (isPercentage(val)) {
|
|
4203
|
+
return {
|
|
4204
|
+
typ: 'Perc',
|
|
4205
|
+
val: val.slice(0, -1)
|
|
4206
|
+
};
|
|
4207
|
+
}
|
|
4208
|
+
const v = val.toLowerCase();
|
|
4209
|
+
if (v == 'currentcolor' || val == 'transparent' || v in COLORS_NAMES) {
|
|
4210
|
+
return {
|
|
4211
|
+
typ: 'Color',
|
|
4212
|
+
val,
|
|
4213
|
+
kin: 'lit'
|
|
4214
|
+
};
|
|
4215
|
+
}
|
|
4216
|
+
if (isIdent(val)) {
|
|
4217
|
+
return {
|
|
4218
|
+
typ: 'Iden',
|
|
4219
|
+
val
|
|
4220
|
+
};
|
|
4221
|
+
}
|
|
4222
|
+
if (val.charAt(0) == '#' && isHexColor(val)) {
|
|
4223
|
+
return {
|
|
4224
|
+
typ: 'Color',
|
|
4225
|
+
val,
|
|
4226
|
+
kin: 'hex'
|
|
4227
|
+
};
|
|
4228
|
+
}
|
|
4229
|
+
if (val.charAt(0) == '#' && isHash(val)) {
|
|
4230
|
+
return {
|
|
4231
|
+
typ: 'Hash',
|
|
4232
|
+
val
|
|
4233
|
+
};
|
|
4234
|
+
}
|
|
4235
|
+
if ('"\''.includes(val.charAt(0))) {
|
|
4236
|
+
return {
|
|
4237
|
+
typ: 'Unclosed-string',
|
|
4238
|
+
val
|
|
4239
|
+
};
|
|
4240
|
+
}
|
|
4241
|
+
return {
|
|
4242
|
+
typ: 'Literal',
|
|
4243
|
+
val
|
|
4244
|
+
};
|
|
3999
4245
|
}
|
|
4000
|
-
function parseTokens(tokens,
|
|
4246
|
+
function parseTokens(tokens, options = {}) {
|
|
4001
4247
|
for (let i = 0; i < tokens.length; i++) {
|
|
4002
4248
|
const t = tokens[i];
|
|
4003
4249
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
@@ -4051,7 +4297,7 @@ function parseTokens(tokens, nodeType, options = {}) {
|
|
|
4051
4297
|
if (t.chi.length > 1) {
|
|
4052
4298
|
/*(<AttrToken>t).chi =*/
|
|
4053
4299
|
// @ts-ignore
|
|
4054
|
-
parseTokens(t.chi, t.typ
|
|
4300
|
+
parseTokens(t.chi, t.typ);
|
|
4055
4301
|
}
|
|
4056
4302
|
// @ts-ignore
|
|
4057
4303
|
t.chi.forEach(val => {
|
|
@@ -4163,8 +4409,8 @@ function parseTokens(tokens, nodeType, options = {}) {
|
|
|
4163
4409
|
// @ts-ignore
|
|
4164
4410
|
if (t.chi.length > 0) {
|
|
4165
4411
|
// @ts-ignore
|
|
4166
|
-
parseTokens(t.chi, t.typ
|
|
4167
|
-
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.
|
|
4412
|
+
parseTokens(t.chi, t.typ);
|
|
4413
|
+
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.minify) {
|
|
4168
4414
|
//
|
|
4169
4415
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
4170
4416
|
if (count == 1 ||
|
|
@@ -4202,54 +4448,21 @@ function parseTokens(tokens, nodeType, options = {}) {
|
|
|
4202
4448
|
}
|
|
4203
4449
|
return tokens;
|
|
4204
4450
|
}
|
|
4205
|
-
function getBlockType(chr) {
|
|
4206
|
-
if (chr == ';') {
|
|
4207
|
-
return { typ: 'Semi-colon' };
|
|
4208
|
-
}
|
|
4209
|
-
if (chr == '{') {
|
|
4210
|
-
return { typ: 'Block-start' };
|
|
4211
|
-
}
|
|
4212
|
-
if (chr == '}') {
|
|
4213
|
-
return { typ: 'Block-end' };
|
|
4214
|
-
}
|
|
4215
|
-
if (chr == '[') {
|
|
4216
|
-
return { typ: 'Attr-start' };
|
|
4217
|
-
}
|
|
4218
|
-
if (chr == ']') {
|
|
4219
|
-
return { typ: 'Attr-end' };
|
|
4220
|
-
}
|
|
4221
|
-
throw new Error(`unhandled token: '${chr}'`);
|
|
4222
|
-
}
|
|
4223
|
-
|
|
4224
|
-
function* walk(node) {
|
|
4225
|
-
// @ts-ignore
|
|
4226
|
-
yield* doWalk(node, null, null);
|
|
4227
|
-
}
|
|
4228
|
-
function* doWalk(node, parent, root) {
|
|
4229
|
-
yield { node, parent, root };
|
|
4230
|
-
if ('chi' in node) {
|
|
4231
|
-
for (const child of node.chi) {
|
|
4232
|
-
yield* doWalk(child, node, (root ?? node));
|
|
4233
|
-
}
|
|
4234
|
-
}
|
|
4235
|
-
}
|
|
4236
4451
|
|
|
4237
4452
|
async function transform$1(css, options = {}) {
|
|
4238
|
-
options = {
|
|
4453
|
+
options = { minify: true, removeEmpty: true, ...options };
|
|
4239
4454
|
const startTime = performance.now();
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
}
|
|
4252
|
-
};
|
|
4455
|
+
return parse$1(css, options).then((parseResult) => {
|
|
4456
|
+
const rendered = render(parseResult.ast, options);
|
|
4457
|
+
return {
|
|
4458
|
+
...parseResult, ...rendered, stats: {
|
|
4459
|
+
bytesOut: rendered.code.length,
|
|
4460
|
+
...parseResult.stats,
|
|
4461
|
+
render: rendered.stats.total,
|
|
4462
|
+
total: `${(performance.now() - startTime).toFixed(2)}ms`
|
|
4463
|
+
}
|
|
4464
|
+
};
|
|
4465
|
+
});
|
|
4253
4466
|
}
|
|
4254
4467
|
|
|
4255
4468
|
const matchUrl = /^(https?:)?\/\//;
|
|
@@ -4369,16 +4582,42 @@ function transform(css, options = {}) {
|
|
|
4369
4582
|
return transform$1(css, Object.assign(options, { load, resolve, cwd: options.cwd ?? process.cwd() }));
|
|
4370
4583
|
}
|
|
4371
4584
|
|
|
4372
|
-
exports.
|
|
4373
|
-
exports.deduplicateRule = deduplicateRule;
|
|
4585
|
+
exports.combinators = combinators;
|
|
4374
4586
|
exports.dirname = dirname;
|
|
4587
|
+
exports.getConfig = getConfig;
|
|
4375
4588
|
exports.hasDeclaration = hasDeclaration;
|
|
4589
|
+
exports.isAngle = isAngle;
|
|
4590
|
+
exports.isAtKeyword = isAtKeyword;
|
|
4591
|
+
exports.isDigit = isDigit;
|
|
4592
|
+
exports.isDimension = isDimension;
|
|
4593
|
+
exports.isFrequency = isFrequency;
|
|
4594
|
+
exports.isFunction = isFunction;
|
|
4595
|
+
exports.isHash = isHash;
|
|
4596
|
+
exports.isHexColor = isHexColor;
|
|
4597
|
+
exports.isHexDigit = isHexDigit;
|
|
4598
|
+
exports.isIdent = isIdent;
|
|
4599
|
+
exports.isIdentCodepoint = isIdentCodepoint;
|
|
4600
|
+
exports.isIdentStart = isIdentStart;
|
|
4601
|
+
exports.isLength = isLength;
|
|
4602
|
+
exports.isNewLine = isNewLine;
|
|
4603
|
+
exports.isNumber = isNumber;
|
|
4604
|
+
exports.isPercentage = isPercentage;
|
|
4605
|
+
exports.isPseudo = isPseudo;
|
|
4606
|
+
exports.isResolution = isResolution;
|
|
4607
|
+
exports.isTime = isTime;
|
|
4608
|
+
exports.isWhiteSpace = isWhiteSpace;
|
|
4376
4609
|
exports.load = load;
|
|
4377
4610
|
exports.matchUrl = matchUrl;
|
|
4611
|
+
exports.minify = minify;
|
|
4612
|
+
exports.minifyRule = minifyRule;
|
|
4378
4613
|
exports.parse = parse;
|
|
4614
|
+
exports.parseDimension = parseDimension;
|
|
4615
|
+
exports.parseString = parseString;
|
|
4379
4616
|
exports.reduceSelector = reduceSelector;
|
|
4380
4617
|
exports.render = render;
|
|
4381
4618
|
exports.renderToken = renderToken;
|
|
4382
4619
|
exports.resolve = resolve;
|
|
4620
|
+
exports.tokenize = tokenize;
|
|
4383
4621
|
exports.transform = transform;
|
|
4622
|
+
exports.urlTokenMatcher = urlTokenMatcher;
|
|
4384
4623
|
exports.walk = walk;
|