@tbela99/css-parser 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +28 -10
- package/dist/index-umd-web.js +1610 -1170
- package/dist/index.cjs +1699 -1168
- package/dist/index.d.ts +1834 -71
- package/dist/lib/ast/expand.js +4 -65
- package/dist/lib/ast/features/calc.js +2 -2
- package/dist/lib/ast/features/inlinecssvariables.js +2 -2
- package/dist/lib/ast/features/prefix.js +2 -1
- package/dist/lib/ast/features/transform.js +2 -1
- package/dist/lib/ast/features/type.js +9 -0
- package/dist/lib/ast/math/math.js +1 -1
- package/dist/lib/ast/minify.js +82 -171
- package/dist/lib/ast/types.js +369 -4
- package/dist/lib/ast/walk.js +18 -0
- package/dist/lib/fs/resolve.js +11 -3
- package/dist/lib/parser/declaration/map.js +1 -0
- package/dist/lib/parser/parse.js +106 -21
- package/dist/lib/parser/tokenize.js +40 -80
- package/dist/lib/renderer/render.js +25 -3
- package/dist/lib/renderer/sourcemap/sourcemap.js +34 -0
- package/dist/lib/syntax/color/color.js +7 -0
- package/dist/lib/syntax/color/utils/distance.js +5 -1
- package/dist/lib/syntax/syntax.js +10 -0
- package/dist/lib/validation/config.json.js +33 -30
- package/dist/lib/validation/syntax.js +3 -1
- package/dist/node.js +229 -0
- package/dist/web.js +158 -0
- package/package.json +14 -11
- package/dist/node/index.js +0 -57
- package/dist/node/load.js +0 -20
- package/dist/web/index.js +0 -66
- package/dist/web/load.js +0 -31
|
@@ -303,10 +303,10 @@ var declarations = {
|
|
|
303
303
|
syntax: "normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>"
|
|
304
304
|
},
|
|
305
305
|
"align-items": {
|
|
306
|
-
syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]"
|
|
306
|
+
syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ] | anchor-center"
|
|
307
307
|
},
|
|
308
308
|
"align-self": {
|
|
309
|
-
syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>"
|
|
309
|
+
syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position> | anchor-center"
|
|
310
310
|
},
|
|
311
311
|
"align-tracks": {
|
|
312
312
|
syntax: "[ normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position> ]#"
|
|
@@ -366,7 +366,7 @@ var declarations = {
|
|
|
366
366
|
syntax: "<easing-function>#"
|
|
367
367
|
},
|
|
368
368
|
appearance: {
|
|
369
|
-
syntax: "none | auto |
|
|
369
|
+
syntax: "none | auto | <compat-auto> | <compat-special>"
|
|
370
370
|
},
|
|
371
371
|
"aspect-ratio": {
|
|
372
372
|
syntax: "auto || <ratio>"
|
|
@@ -378,7 +378,7 @@ var declarations = {
|
|
|
378
378
|
syntax: "visible | hidden"
|
|
379
379
|
},
|
|
380
380
|
background: {
|
|
381
|
-
syntax: "
|
|
381
|
+
syntax: "<bg-layer>#? , <final-bg-layer>"
|
|
382
382
|
},
|
|
383
383
|
"background-attachment": {
|
|
384
384
|
syntax: "<attachment>#"
|
|
@@ -465,10 +465,10 @@ var declarations = {
|
|
|
465
465
|
syntax: "<'border-top-color'>"
|
|
466
466
|
},
|
|
467
467
|
"border-bottom-left-radius": {
|
|
468
|
-
syntax: "<length-percentage>{1,2}"
|
|
468
|
+
syntax: "<length-percentage [0,∞]>{1,2}"
|
|
469
469
|
},
|
|
470
470
|
"border-bottom-right-radius": {
|
|
471
|
-
syntax: "<length-percentage>{1,2}"
|
|
471
|
+
syntax: "<length-percentage [0,∞]>{1,2}"
|
|
472
472
|
},
|
|
473
473
|
"border-bottom-style": {
|
|
474
474
|
syntax: "<line-style>"
|
|
@@ -477,7 +477,7 @@ var declarations = {
|
|
|
477
477
|
syntax: "<line-width>"
|
|
478
478
|
},
|
|
479
479
|
"border-collapse": {
|
|
480
|
-
syntax: "
|
|
480
|
+
syntax: "separate | collapse"
|
|
481
481
|
},
|
|
482
482
|
"border-color": {
|
|
483
483
|
syntax: "<color>{1,4}"
|
|
@@ -492,19 +492,19 @@ var declarations = {
|
|
|
492
492
|
syntax: "<'border-image-source'> || <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]? || <'border-image-repeat'>"
|
|
493
493
|
},
|
|
494
494
|
"border-image-outset": {
|
|
495
|
-
syntax: "[ <length> | <number> ]{1,4}"
|
|
495
|
+
syntax: "[ <length [0,∞]> | <number [0,∞]> ]{1,4} "
|
|
496
496
|
},
|
|
497
497
|
"border-image-repeat": {
|
|
498
498
|
syntax: "[ stretch | repeat | round | space ]{1,2}"
|
|
499
499
|
},
|
|
500
500
|
"border-image-slice": {
|
|
501
|
-
syntax: "<number
|
|
501
|
+
syntax: "[ <number [0,∞]> | <percentage [0,∞]> ]{1,4} && fill?"
|
|
502
502
|
},
|
|
503
503
|
"border-image-source": {
|
|
504
504
|
syntax: "none | <image>"
|
|
505
505
|
},
|
|
506
506
|
"border-image-width": {
|
|
507
|
-
syntax: "[ <length-percentage> | <number> | auto ]{1,4}"
|
|
507
|
+
syntax: "[ <length-percentage [0,∞]> | <number [0,∞]> | auto ]{1,4}"
|
|
508
508
|
},
|
|
509
509
|
"border-inline": {
|
|
510
510
|
syntax: "<'border-block-start'>"
|
|
@@ -555,7 +555,7 @@ var declarations = {
|
|
|
555
555
|
syntax: "<line-width>"
|
|
556
556
|
},
|
|
557
557
|
"border-radius": {
|
|
558
|
-
syntax: "<length-percentage>{1,4} [ / <length-percentage>{1,4} ]?"
|
|
558
|
+
syntax: "<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?"
|
|
559
559
|
},
|
|
560
560
|
"border-right": {
|
|
561
561
|
syntax: "<line-width> || <line-style> || <color>"
|
|
@@ -570,7 +570,7 @@ var declarations = {
|
|
|
570
570
|
syntax: "<line-width>"
|
|
571
571
|
},
|
|
572
572
|
"border-spacing": {
|
|
573
|
-
syntax: "<length>
|
|
573
|
+
syntax: "<length>{1,2}"
|
|
574
574
|
},
|
|
575
575
|
"border-start-end-radius": {
|
|
576
576
|
syntax: "<'border-top-left-radius'>"
|
|
@@ -588,10 +588,10 @@ var declarations = {
|
|
|
588
588
|
syntax: "<color>"
|
|
589
589
|
},
|
|
590
590
|
"border-top-left-radius": {
|
|
591
|
-
syntax: "<length-percentage>{1,2}"
|
|
591
|
+
syntax: "<length-percentage [0,∞]>{1,2}"
|
|
592
592
|
},
|
|
593
593
|
"border-top-right-radius": {
|
|
594
|
-
syntax: "<length-percentage>{1,2}"
|
|
594
|
+
syntax: "<length-percentage [0,∞]>{1,2}"
|
|
595
595
|
},
|
|
596
596
|
"border-top-style": {
|
|
597
597
|
syntax: "<line-style>"
|
|
@@ -603,7 +603,7 @@ var declarations = {
|
|
|
603
603
|
syntax: "<line-width>{1,4}"
|
|
604
604
|
},
|
|
605
605
|
bottom: {
|
|
606
|
-
syntax: "<length> | <
|
|
606
|
+
syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
|
|
607
607
|
},
|
|
608
608
|
"box-align": {
|
|
609
609
|
syntax: "start | center | end | baseline | stretch"
|
|
@@ -738,7 +738,7 @@ var declarations = {
|
|
|
738
738
|
syntax: "normal | [ [ size | inline-size ] || scroll-state ]"
|
|
739
739
|
},
|
|
740
740
|
content: {
|
|
741
|
-
syntax: "normal | none | [ <content-replacement> | <content-list> ] [/ [ <string> | <counter> ]+ ]?"
|
|
741
|
+
syntax: "normal | none | [ <content-replacement> | <content-list> ] [ / [ <string> | <counter> | <attr()> ]+ ]?"
|
|
742
742
|
},
|
|
743
743
|
"content-visibility": {
|
|
744
744
|
syntax: "visible | auto | hidden"
|
|
@@ -1032,16 +1032,16 @@ var declarations = {
|
|
|
1032
1032
|
syntax: "normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]"
|
|
1033
1033
|
},
|
|
1034
1034
|
"justify-items": {
|
|
1035
|
-
syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ]"
|
|
1035
|
+
syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center"
|
|
1036
1036
|
},
|
|
1037
1037
|
"justify-self": {
|
|
1038
|
-
syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ]"
|
|
1038
|
+
syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center"
|
|
1039
1039
|
},
|
|
1040
1040
|
"justify-tracks": {
|
|
1041
1041
|
syntax: "[ normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ] ]#"
|
|
1042
1042
|
},
|
|
1043
1043
|
left: {
|
|
1044
|
-
syntax: "<length> | <
|
|
1044
|
+
syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
|
|
1045
1045
|
},
|
|
1046
1046
|
"letter-spacing": {
|
|
1047
1047
|
syntax: "normal | <length> normal | <length-percentage>"
|
|
@@ -1086,7 +1086,7 @@ var declarations = {
|
|
|
1086
1086
|
syntax: "<'margin-top'>"
|
|
1087
1087
|
},
|
|
1088
1088
|
"margin-bottom": {
|
|
1089
|
-
syntax: "<length-percentage> | auto"
|
|
1089
|
+
syntax: "<length-percentage> | auto | <anchor-size()>"
|
|
1090
1090
|
},
|
|
1091
1091
|
"margin-inline": {
|
|
1092
1092
|
syntax: "<'margin-top'>{1,2}"
|
|
@@ -1098,13 +1098,13 @@ var declarations = {
|
|
|
1098
1098
|
syntax: "<'margin-top'>"
|
|
1099
1099
|
},
|
|
1100
1100
|
"margin-left": {
|
|
1101
|
-
syntax: "<length-percentage> | auto"
|
|
1101
|
+
syntax: "<length-percentage> | auto | <anchor-size()>"
|
|
1102
1102
|
},
|
|
1103
1103
|
"margin-right": {
|
|
1104
|
-
syntax: "<length-percentage> | auto"
|
|
1104
|
+
syntax: "<length-percentage> | auto | <anchor-size()>"
|
|
1105
1105
|
},
|
|
1106
1106
|
"margin-top": {
|
|
1107
|
-
syntax: "<length-percentage> | auto"
|
|
1107
|
+
syntax: "<length-percentage> | auto | <anchor-size()>"
|
|
1108
1108
|
},
|
|
1109
1109
|
"margin-trim": {
|
|
1110
1110
|
syntax: "none | in-flow | all"
|
|
@@ -1212,7 +1212,7 @@ var declarations = {
|
|
|
1212
1212
|
syntax: "auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()> | stretch | <-non-standard-size>"
|
|
1213
1213
|
},
|
|
1214
1214
|
"mix-blend-mode": {
|
|
1215
|
-
syntax: "<blend-mode> | plus-lighter"
|
|
1215
|
+
syntax: "<blend-mode> | plus-darker | plus-lighter"
|
|
1216
1216
|
},
|
|
1217
1217
|
"object-fit": {
|
|
1218
1218
|
syntax: "fill | contain | cover | none | scale-down"
|
|
@@ -1410,7 +1410,7 @@ var declarations = {
|
|
|
1410
1410
|
syntax: "none | both | horizontal | vertical | block | inline"
|
|
1411
1411
|
},
|
|
1412
1412
|
right: {
|
|
1413
|
-
syntax: "<length> | <
|
|
1413
|
+
syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
|
|
1414
1414
|
},
|
|
1415
1415
|
rotate: {
|
|
1416
1416
|
syntax: "none | <angle> | [ x | y | z | <number>{3} ] && <angle>"
|
|
@@ -1710,7 +1710,7 @@ var declarations = {
|
|
|
1710
1710
|
syntax: "none | <dashed-ident>#"
|
|
1711
1711
|
},
|
|
1712
1712
|
top: {
|
|
1713
|
-
syntax: "<length> | <
|
|
1713
|
+
syntax: "auto | <length-percentage> | <anchor()> | <anchor-size()>"
|
|
1714
1714
|
},
|
|
1715
1715
|
"touch-action": {
|
|
1716
1716
|
syntax: "auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] || pinch-zoom ] | manipulation"
|
|
@@ -2389,7 +2389,7 @@ var syntaxes = {
|
|
|
2389
2389
|
syntax: "<visual-box> | border-area | text"
|
|
2390
2390
|
},
|
|
2391
2391
|
"bg-image": {
|
|
2392
|
-
syntax: "
|
|
2392
|
+
syntax: "<image> | none"
|
|
2393
2393
|
},
|
|
2394
2394
|
"bg-layer": {
|
|
2395
2395
|
syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box>"
|
|
@@ -2398,7 +2398,7 @@ var syntaxes = {
|
|
|
2398
2398
|
syntax: "[ [ left | center | right | top | bottom | <length-percentage> ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | [ center | [ left | right ] <length-percentage>? ] && [ center | [ top | bottom ] <length-percentage>? ] ]"
|
|
2399
2399
|
},
|
|
2400
2400
|
"bg-size": {
|
|
2401
|
-
syntax: "[ <length-percentage> | auto ]{1,2} | cover | contain"
|
|
2401
|
+
syntax: "[ <length-percentage [0,∞]> | auto ]{1,2} | cover | contain"
|
|
2402
2402
|
},
|
|
2403
2403
|
"blend-mode": {
|
|
2404
2404
|
syntax: "normal | multiply | screen | overlay | darken | lighten | color-dodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity"
|
|
@@ -2488,7 +2488,10 @@ var syntaxes = {
|
|
|
2488
2488
|
syntax: "[ common-ligatures | no-common-ligatures ]"
|
|
2489
2489
|
},
|
|
2490
2490
|
"compat-auto": {
|
|
2491
|
-
syntax: "searchfield | textarea |
|
|
2491
|
+
syntax: "searchfield | textarea | checkbox | radio | menulist | listbox | meter | progress-bar | button"
|
|
2492
|
+
},
|
|
2493
|
+
"compat-special": {
|
|
2494
|
+
syntax: "textfield | menulist-button"
|
|
2492
2495
|
},
|
|
2493
2496
|
"complex-selector": {
|
|
2494
2497
|
syntax: "<complex-selector-unit> [ <combinator>? <complex-selector-unit> ]*"
|
|
@@ -2668,7 +2671,7 @@ var syntaxes = {
|
|
|
2668
2671
|
syntax: "[ <filter-function> | <url> ]+"
|
|
2669
2672
|
},
|
|
2670
2673
|
"final-bg-layer": {
|
|
2671
|
-
syntax: "<
|
|
2674
|
+
syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box> || <'background-color'>"
|
|
2672
2675
|
},
|
|
2673
2676
|
"fit-content()": {
|
|
2674
2677
|
syntax: "fit-content( <length-percentage [0,∞]> )"
|
|
@@ -8,9 +8,11 @@ import '../parser/tokenize.js';
|
|
|
8
8
|
import '../parser/utils/config.js';
|
|
9
9
|
import { wildCardFuncs, isIdentColor, mathFuncs } from '../syntax/syntax.js';
|
|
10
10
|
import { renderToken } from '../renderer/render.js';
|
|
11
|
-
import
|
|
11
|
+
import '../renderer/sourcemap/lib/encode.js';
|
|
12
12
|
import { getSyntaxConfig, getParsedSyntax, getSyntax } from './config.js';
|
|
13
13
|
import './syntaxes/complex-selector.js';
|
|
14
|
+
import { funcLike, colorsFunc } from '../syntax/color/utils/constants.js';
|
|
15
|
+
import '../ast/features/type.js';
|
|
14
16
|
|
|
15
17
|
const config = getSyntaxConfig();
|
|
16
18
|
// @ts-ignore
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
export { ColorType, EnumToken, ValidationLevel } from './lib/ast/types.js';
|
|
3
|
+
export { minify } from './lib/ast/minify.js';
|
|
4
|
+
export { WalkerOptionEnum, WalkerValueEvent, walk, walkValues } from './lib/ast/walk.js';
|
|
5
|
+
export { expand } from './lib/ast/expand.js';
|
|
6
|
+
import { doRender } from './lib/renderer/render.js';
|
|
7
|
+
export { renderToken } from './lib/renderer/render.js';
|
|
8
|
+
export { SourceMap } from './lib/renderer/sourcemap/sourcemap.js';
|
|
9
|
+
import { doParse } from './lib/parser/parse.js';
|
|
10
|
+
export { parseDeclarations, parseString, parseTokens } from './lib/parser/parse.js';
|
|
11
|
+
import { tokenizeStream, tokenize } from './lib/parser/tokenize.js';
|
|
12
|
+
import './lib/parser/utils/config.js';
|
|
13
|
+
export { convertColor } from './lib/syntax/color/color.js';
|
|
14
|
+
import './lib/syntax/color/utils/constants.js';
|
|
15
|
+
export { isOkLabClose, okLabDistance } from './lib/syntax/color/utils/distance.js';
|
|
16
|
+
import './lib/validation/config.js';
|
|
17
|
+
import './lib/validation/parser/types.js';
|
|
18
|
+
import './lib/validation/parser/parse.js';
|
|
19
|
+
import './lib/validation/syntaxes/complex-selector.js';
|
|
20
|
+
import './lib/validation/syntax.js';
|
|
21
|
+
import { resolve, matchUrl, dirname } from './lib/fs/resolve.js';
|
|
22
|
+
import { Readable } from 'node:stream';
|
|
23
|
+
import { createReadStream } from 'node:fs';
|
|
24
|
+
export { FeatureWalkMode } from './lib/ast/features/type.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* node module entry point
|
|
28
|
+
* @module node
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* load file or url as stream
|
|
32
|
+
* @param url
|
|
33
|
+
* @param currentFile
|
|
34
|
+
*
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
async function getStream(url, currentFile = '.') {
|
|
38
|
+
const resolved = resolve(url, currentFile);
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
return matchUrl.test(resolved.absolute) ? fetch(resolved.absolute).then((response) => {
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error(`${response.status} ${response.statusText} ${response.url}`);
|
|
43
|
+
}
|
|
44
|
+
return response.body;
|
|
45
|
+
}) : Readable.toWeb(createReadStream(resolved.absolute));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* render ast tree
|
|
49
|
+
* @param data
|
|
50
|
+
* @param options
|
|
51
|
+
*
|
|
52
|
+
* Example:
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
*
|
|
56
|
+
* import {render, ColorType} from '@tbela99/css-parser';
|
|
57
|
+
*
|
|
58
|
+
* // remote file
|
|
59
|
+
* let result = render(ast);
|
|
60
|
+
* console.log(result.code);
|
|
61
|
+
*
|
|
62
|
+
* // local file
|
|
63
|
+
* result = await parseFile(ast, {beatify: true, convertColor: ColorType.SRGB});
|
|
64
|
+
* console.log(result.code);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
function render(data, options = {}) {
|
|
68
|
+
return doRender(data, Object.assign(options, { getStream, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* parse css file
|
|
72
|
+
* @param file url or path
|
|
73
|
+
* @param options
|
|
74
|
+
*
|
|
75
|
+
* Example:
|
|
76
|
+
*
|
|
77
|
+
* ```ts
|
|
78
|
+
*
|
|
79
|
+
* import {parseFile} from '@tbela99/css-parser';
|
|
80
|
+
*
|
|
81
|
+
* // remote file
|
|
82
|
+
* let result = await parseFile('https://docs.deno.com/styles.css');
|
|
83
|
+
* console.log(result.ast);
|
|
84
|
+
*
|
|
85
|
+
* // local file
|
|
86
|
+
* result = await parseFile('./css/styles.css');
|
|
87
|
+
* console.log(result.ast);
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
async function parseFile(file, options = {}) {
|
|
91
|
+
return getStream(file).then(stream => parse(stream, { src: file, ...options }));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* parse css
|
|
95
|
+
* @param stream
|
|
96
|
+
* @param opt
|
|
97
|
+
*
|
|
98
|
+
* Example:
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
*
|
|
102
|
+
* import {transform} from '@tbela99/css-parser';
|
|
103
|
+
*
|
|
104
|
+
* // css string
|
|
105
|
+
* let result = await transform(css);
|
|
106
|
+
* console.log(result.code);
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* Example using stream
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
*
|
|
113
|
+
* import {parse} from '@tbela99/css-parser';
|
|
114
|
+
* import {Readable} from "node:stream";
|
|
115
|
+
*
|
|
116
|
+
* // usage: node index.ts < styles.css or cat styles.css | node index.ts
|
|
117
|
+
*
|
|
118
|
+
* const readableStream = Readable.toWeb(process.stdin);
|
|
119
|
+
* const result = await parse(readableStream, {beautify: true});
|
|
120
|
+
*
|
|
121
|
+
* console.log(result.ast);
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* Example using fetch
|
|
125
|
+
*
|
|
126
|
+
* ```ts
|
|
127
|
+
*
|
|
128
|
+
* import {parse} from '@tbela99/css-parser';
|
|
129
|
+
*
|
|
130
|
+
* const response = await fetch('https://docs.deno.com/styles.css');
|
|
131
|
+
* result = await parse(response.body, {beautify: true});
|
|
132
|
+
*
|
|
133
|
+
* console.log(result.ast);
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
async function parse(stream, opt = {}) {
|
|
137
|
+
return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize({
|
|
138
|
+
stream,
|
|
139
|
+
buffer: '',
|
|
140
|
+
position: { ind: 0, lin: 1, col: 1 },
|
|
141
|
+
currentPosition: { ind: -1, lin: 1, col: 0 }
|
|
142
|
+
}), Object.assign(opt, { getStream, resolve, dirname, cwd: opt.cwd ?? process.cwd() }));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* transform css file
|
|
146
|
+
* @param file url or path
|
|
147
|
+
* @param options
|
|
148
|
+
*
|
|
149
|
+
* Example:
|
|
150
|
+
*
|
|
151
|
+
* ```ts
|
|
152
|
+
*
|
|
153
|
+
* import {transformFile} from '@tbela99/css-parser';
|
|
154
|
+
*
|
|
155
|
+
* // remote file
|
|
156
|
+
* let result = await transformFile('https://docs.deno.com/styles.css');
|
|
157
|
+
* console.log(result.code);
|
|
158
|
+
*
|
|
159
|
+
* // local file
|
|
160
|
+
* result = await transformFile('./css/styles.css');
|
|
161
|
+
* console.log(result.code);
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
async function transformFile(file, options = {}) {
|
|
165
|
+
return getStream(file).then(stream => transform(stream, { src: file, ...options }));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* transform css
|
|
169
|
+
* @param css
|
|
170
|
+
* @param options
|
|
171
|
+
*
|
|
172
|
+
* Example:
|
|
173
|
+
*
|
|
174
|
+
* ```ts
|
|
175
|
+
*
|
|
176
|
+
* import {transform} from '@tbela99/css-parser';
|
|
177
|
+
*
|
|
178
|
+
* // css string
|
|
179
|
+
* let result = await transform(css);
|
|
180
|
+
* console.log(result.code);
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* Example using stream
|
|
184
|
+
*
|
|
185
|
+
* ```ts
|
|
186
|
+
*
|
|
187
|
+
* import {transform} from '@tbela99/css-parser';
|
|
188
|
+
* import {Readable} from "node:stream";
|
|
189
|
+
*
|
|
190
|
+
* // usage: node index.ts < styles.css or cat styles.css | node index.ts
|
|
191
|
+
*
|
|
192
|
+
* const readableStream = Readable.toWeb(process.stdin);
|
|
193
|
+
* const result = await transform(readableStream, {beautify: true});
|
|
194
|
+
*
|
|
195
|
+
* console.log(result.code);
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* Example using fetch
|
|
199
|
+
*
|
|
200
|
+
* ```ts
|
|
201
|
+
*
|
|
202
|
+
* import {transform} from '@tbela99/css-parser';
|
|
203
|
+
*
|
|
204
|
+
* const response = await fetch('https://docs.deno.com/styles.css');
|
|
205
|
+
* result = await transform(response.body, {beautify: true});
|
|
206
|
+
*
|
|
207
|
+
* console.log(result.code);
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
async function transform(css, options = {}) {
|
|
211
|
+
options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
|
|
212
|
+
const startTime = performance.now();
|
|
213
|
+
return parse(css, options).then((parseResult) => {
|
|
214
|
+
const rendered = render(parseResult.ast, options);
|
|
215
|
+
return {
|
|
216
|
+
...parseResult,
|
|
217
|
+
...rendered,
|
|
218
|
+
errors: parseResult.errors.concat(rendered.errors),
|
|
219
|
+
stats: {
|
|
220
|
+
bytesOut: rendered.code.length,
|
|
221
|
+
...parseResult.stats,
|
|
222
|
+
render: rendered.stats.total,
|
|
223
|
+
total: `${(performance.now() - startTime).toFixed(2)}ms`
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { dirname, getStream, parse, parseFile, render, resolve, transform, transformFile };
|
package/dist/web.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export { ColorType, EnumToken, ValidationLevel } from './lib/ast/types.js';
|
|
2
|
+
export { minify } from './lib/ast/minify.js';
|
|
3
|
+
export { WalkerOptionEnum, WalkerValueEvent, walk, walkValues } from './lib/ast/walk.js';
|
|
4
|
+
export { expand } from './lib/ast/expand.js';
|
|
5
|
+
import { doRender } from './lib/renderer/render.js';
|
|
6
|
+
export { renderToken } from './lib/renderer/render.js';
|
|
7
|
+
export { SourceMap } from './lib/renderer/sourcemap/sourcemap.js';
|
|
8
|
+
import { doParse } from './lib/parser/parse.js';
|
|
9
|
+
export { parseDeclarations, parseString, parseTokens } from './lib/parser/parse.js';
|
|
10
|
+
import { tokenizeStream, tokenize } from './lib/parser/tokenize.js';
|
|
11
|
+
import './lib/parser/utils/config.js';
|
|
12
|
+
export { convertColor } from './lib/syntax/color/color.js';
|
|
13
|
+
import './lib/syntax/color/utils/constants.js';
|
|
14
|
+
export { isOkLabClose, okLabDistance } from './lib/syntax/color/utils/distance.js';
|
|
15
|
+
import './lib/validation/config.js';
|
|
16
|
+
import './lib/validation/parser/types.js';
|
|
17
|
+
import './lib/validation/parser/parse.js';
|
|
18
|
+
import './lib/validation/syntaxes/complex-selector.js';
|
|
19
|
+
import './lib/validation/syntax.js';
|
|
20
|
+
import { matchUrl, resolve, dirname } from './lib/fs/resolve.js';
|
|
21
|
+
export { FeatureWalkMode } from './lib/ast/features/type.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* web module entry point
|
|
25
|
+
* @module web
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* load file or url as stream
|
|
29
|
+
* @param url
|
|
30
|
+
* @param currentFile
|
|
31
|
+
*
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
async function getStream(url, currentFile = '.') {
|
|
35
|
+
let t;
|
|
36
|
+
if (matchUrl.test(url)) {
|
|
37
|
+
t = new URL(url);
|
|
38
|
+
}
|
|
39
|
+
else if (currentFile != null && matchUrl.test(currentFile)) {
|
|
40
|
+
t = new URL(url, currentFile);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const path = resolve(url, currentFile).absolute;
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
t = new URL(path, self.origin);
|
|
46
|
+
}
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
return fetch(t, t.origin != self.origin ? { mode: 'cors' } : {}).then((response) => {
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new Error(`${response.status} ${response.statusText} ${response.url}`);
|
|
51
|
+
}
|
|
52
|
+
return response.body;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* render ast node
|
|
57
|
+
* @param data
|
|
58
|
+
* @param options
|
|
59
|
+
*/
|
|
60
|
+
function render(data, options = {}) {
|
|
61
|
+
return doRender(data, Object.assign(options, {
|
|
62
|
+
getStream,
|
|
63
|
+
resolve,
|
|
64
|
+
dirname,
|
|
65
|
+
cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* parse css file
|
|
70
|
+
* @param file url or path
|
|
71
|
+
* @param options
|
|
72
|
+
*/
|
|
73
|
+
async function parseFile(file, options = {}) {
|
|
74
|
+
return getStream(file).then(stream => parse(stream, { src: file, ...options }));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* parse css
|
|
78
|
+
* @param stream
|
|
79
|
+
* @param opt
|
|
80
|
+
*/
|
|
81
|
+
async function parse(stream, opt = {}) {
|
|
82
|
+
return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize({
|
|
83
|
+
stream,
|
|
84
|
+
buffer: '',
|
|
85
|
+
position: { ind: 0, lin: 1, col: 1 },
|
|
86
|
+
currentPosition: { ind: -1, lin: 1, col: 0 }
|
|
87
|
+
}), Object.assign(opt, {
|
|
88
|
+
getStream,
|
|
89
|
+
resolve,
|
|
90
|
+
dirname,
|
|
91
|
+
cwd: opt.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* transform css file
|
|
96
|
+
* @param file url or path
|
|
97
|
+
* @param options
|
|
98
|
+
*
|
|
99
|
+
* Example:
|
|
100
|
+
*
|
|
101
|
+
* ```ts
|
|
102
|
+
*
|
|
103
|
+
* import {transformFile} from '@tbela99/css-parser/web';
|
|
104
|
+
*
|
|
105
|
+
* // remote file
|
|
106
|
+
* let result = await transformFile('https://docs.deno.com/styles.css');
|
|
107
|
+
* console.log(result.code);
|
|
108
|
+
*
|
|
109
|
+
* // local file
|
|
110
|
+
* result = await transformFile('./css/styles.css');
|
|
111
|
+
* console.log(result.code);
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
async function transformFile(file, options = {}) {
|
|
115
|
+
return getStream(file).then(stream => transform(stream, { src: file, ...options }));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* transform css
|
|
119
|
+
* @param css
|
|
120
|
+
* @param options
|
|
121
|
+
*
|
|
122
|
+
* Example:
|
|
123
|
+
*
|
|
124
|
+
* ```ts
|
|
125
|
+
*
|
|
126
|
+
* import {transform} from '@tbela99/css-parser/web';
|
|
127
|
+
*
|
|
128
|
+
* // css string
|
|
129
|
+
* let result = await transform(css);
|
|
130
|
+
* console.log(result.code);
|
|
131
|
+
*
|
|
132
|
+
* // using readable stream
|
|
133
|
+
* const response = await fetch('https://docs.deno.com/styles.css');
|
|
134
|
+
* result = await transform(response.body, {beautify: true});
|
|
135
|
+
*
|
|
136
|
+
* console.log(result.code);
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
async function transform(css, options = {}) {
|
|
140
|
+
options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
|
|
141
|
+
const startTime = performance.now();
|
|
142
|
+
return parse(css, options).then((parseResult) => {
|
|
143
|
+
const rendered = render(parseResult.ast, options);
|
|
144
|
+
return {
|
|
145
|
+
...parseResult,
|
|
146
|
+
...rendered,
|
|
147
|
+
errors: parseResult.errors.concat(rendered.errors),
|
|
148
|
+
stats: {
|
|
149
|
+
bytesOut: rendered.code.length,
|
|
150
|
+
...parseResult.stats,
|
|
151
|
+
render: rendered.stats.total,
|
|
152
|
+
total: `${(performance.now() - startTime).toFixed(2)}ms`
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export { dirname, getStream, parse, parseFile, render, resolve, transform, transformFile };
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tbela99/css-parser",
|
|
3
3
|
"description": "CSS parser for node and the browser",
|
|
4
|
-
"version": "v1.3.
|
|
4
|
+
"version": "v1.3.1",
|
|
5
5
|
"exports": {
|
|
6
|
-
".": "./dist/node
|
|
7
|
-
"./node": "./dist/node
|
|
6
|
+
".": "./dist/node.js",
|
|
7
|
+
"./node": "./dist/node.js",
|
|
8
8
|
"./umd": "./dist/index-umd-web.js",
|
|
9
|
-
"./web": "./dist/web
|
|
9
|
+
"./web": "./dist/web.js",
|
|
10
10
|
"./cjs": "./dist/index.cjs"
|
|
11
11
|
},
|
|
12
12
|
"type": "module",
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
"test": "test"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
+
"doc": "typedoc --tsconfig typedoc-tsconfig.jsonc",
|
|
18
19
|
"build": "rollup -c;./build.sh dist/index.d.ts 'declare interface' 'declare type'",
|
|
19
|
-
"test": "web-test-runner \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=.; mocha --reporter-options='maxDiffSize=1801920' --timeout=10000 \"test/**/node.spec.js\"",
|
|
20
|
-
"test:web": "web-test-runner \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=.",
|
|
21
|
-
"test:node": "mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"",
|
|
20
|
+
"test": "web-test-runner \"test/**/web.spec.js\" --timeout=10000 --node-resolve --playwright --browsers chromium firefox webkit --root-dir=.; mocha --reporter-options='maxDiffSize=1801920' --timeout=10000 \"test/**/node.spec.js\"",
|
|
21
|
+
"test:web": "web-test-runner \"test/**/web.spec.js\" --timeout 30000 --node-resolve --playwright --browsers chromium firefox webkit --root-dir=.",
|
|
22
|
+
"test:node": "mocha -p --reporter-options='maxDiffSize=1801920' --timeout=10000 \"test/**/node.spec.js\"",
|
|
22
23
|
"test:cov": "c8 -x 'test/specs/**/*.js' --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' --timeout=10000 \"test/**/node.spec.js\"",
|
|
23
24
|
"test:web-cov": "web-test-runner -x 'test/specs/**/*.js' \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=. --coverage",
|
|
24
25
|
"profile": "node --enable-source-maps --inspect-brk test/inspect.js",
|
|
@@ -65,9 +66,11 @@
|
|
|
65
66
|
"c8": "^10.1.3",
|
|
66
67
|
"esno": "^4.8.0",
|
|
67
68
|
"mocha": "^11.7.1",
|
|
68
|
-
"playwright": "^1.
|
|
69
|
-
"rollup": "^4.
|
|
69
|
+
"playwright": "^1.55.0",
|
|
70
|
+
"rollup": "^4.48.0",
|
|
70
71
|
"rollup-plugin-dts": "^6.2.1",
|
|
71
|
-
"tslib": "^2.8.1"
|
|
72
|
+
"tslib": "^2.8.1",
|
|
73
|
+
"typedoc": "^0.28.10",
|
|
74
|
+
"typedoc-material-theme": "^1.4.0"
|
|
72
75
|
}
|
|
73
|
-
}
|
|
76
|
+
}
|