@tbela99/css-parser 1.3.3 → 1.4.0
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 +44 -0
- package/README.md +64 -48
- package/dist/config.json.js +3 -0
- package/dist/index-umd-web.js +2266 -631
- package/dist/index.cjs +2271 -620
- package/dist/index.d.ts +522 -181
- package/dist/lib/ast/expand.js +5 -10
- package/dist/lib/ast/features/calc.js +3 -2
- package/dist/lib/ast/features/inlinecssvariables.js +5 -3
- package/dist/lib/ast/features/prefix.js +1 -1
- package/dist/lib/ast/features/shorthand.js +1 -0
- package/dist/lib/ast/features/transform.js +13 -19
- package/dist/lib/ast/features/type.js +1 -1
- package/dist/lib/ast/minify.js +6 -3
- package/dist/lib/ast/transform/compute.js +2 -4
- package/dist/lib/ast/transform/matrix.js +20 -20
- package/dist/lib/ast/transform/minify.js +105 -12
- package/dist/lib/ast/transform/rotate.js +11 -11
- package/dist/lib/ast/transform/scale.js +6 -6
- package/dist/lib/ast/transform/skew.js +4 -4
- package/dist/lib/ast/transform/translate.js +3 -3
- package/dist/lib/ast/transform/utils.js +30 -37
- package/dist/lib/ast/types.js +76 -5
- package/dist/lib/ast/walk.js +77 -58
- package/dist/lib/fs/resolve.js +69 -10
- package/dist/lib/parser/declaration/list.js +6 -1
- package/dist/lib/parser/parse.js +1169 -312
- package/dist/lib/parser/tokenize.js +33 -20
- package/dist/lib/parser/utils/declaration.js +54 -0
- package/dist/lib/parser/utils/hash.js +86 -0
- package/dist/lib/parser/utils/text.js +8 -0
- package/dist/lib/renderer/render.js +26 -7
- package/dist/lib/syntax/color/relativecolor.js +0 -3
- package/dist/lib/syntax/syntax.js +36 -18
- package/dist/lib/validation/at-rules/container.js +11 -0
- package/dist/lib/validation/at-rules/counter-style.js +11 -0
- package/dist/lib/validation/at-rules/font-feature-values.js +11 -0
- package/dist/lib/validation/at-rules/keyframes.js +11 -0
- package/dist/lib/validation/at-rules/layer.js +11 -0
- package/dist/lib/validation/at-rules/media.js +11 -0
- package/dist/lib/validation/at-rules/page-margin-box.js +11 -0
- package/dist/lib/validation/at-rules/page.js +11 -0
- package/dist/lib/validation/at-rules/supports.js +11 -0
- package/dist/lib/validation/at-rules/when.js +11 -0
- package/dist/lib/validation/config.js +0 -2
- package/dist/lib/validation/config.json.js +36 -4
- package/dist/lib/validation/parser/parse.js +53 -2
- package/dist/lib/validation/syntax.js +204 -36
- package/dist/lib/validation/syntaxes/compound-selector.js +1 -2
- package/dist/lib/validation/syntaxes/relative-selector-list.js +2 -5
- package/dist/node.js +60 -18
- package/dist/types.d.ts +17 -0
- package/dist/types.js +20 -0
- package/dist/web.js +43 -17
- package/package.json +20 -17
- package/dist/lib/validation/parser/types.js +0 -54
|
@@ -2,9 +2,6 @@ const epsilon = 1e-5;
|
|
|
2
2
|
function identity() {
|
|
3
3
|
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
4
4
|
}
|
|
5
|
-
function pLength(point) {
|
|
6
|
-
return Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
|
|
7
|
-
}
|
|
8
5
|
function normalize(point) {
|
|
9
6
|
const [x, y, z] = point;
|
|
10
7
|
const norm = Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
|
|
@@ -32,8 +29,14 @@ function multiply(matrixA, matrixB) {
|
|
|
32
29
|
function inverse(matrix) {
|
|
33
30
|
// Create augmented matrix [matrix | identity]
|
|
34
31
|
let augmented = [
|
|
35
|
-
|
|
36
|
-
1, 0, 0, 0,
|
|
32
|
+
...matrix.slice(0, 4),
|
|
33
|
+
1, 0, 0, 0,
|
|
34
|
+
...matrix.slice(4, 8),
|
|
35
|
+
0, 1, 0, 0,
|
|
36
|
+
...matrix.slice(8, 12),
|
|
37
|
+
0, 0, 1, 0,
|
|
38
|
+
...matrix.slice(12, 16),
|
|
39
|
+
0, 0, 0, 1
|
|
37
40
|
];
|
|
38
41
|
// Gaussian elimination with partial pivoting
|
|
39
42
|
for (let col = 0; col < 4; col++) {
|
|
@@ -73,24 +76,9 @@ function inverse(matrix) {
|
|
|
73
76
|
// Extract the inverse from the right side of the augmented matrix
|
|
74
77
|
return augmented.slice(0, 16);
|
|
75
78
|
}
|
|
76
|
-
// function transpose(matrix: Matrix): Matrix {
|
|
77
|
-
// // Crée une nouvelle matrice vide 4x4
|
|
78
|
-
// // @ts-ignore
|
|
79
|
-
// let transposed: Matrix = [[], [], [], []] as Matrix;
|
|
80
|
-
//
|
|
81
|
-
// // Parcourt chaque ligne et colonne pour transposer
|
|
82
|
-
// for (let i = 0; i < 4; i++) {
|
|
83
|
-
//
|
|
84
|
-
// for (let j = 0; j < 4; j++) {
|
|
85
|
-
//
|
|
86
|
-
// transposed[j][i] = matrix[i][j];
|
|
87
|
-
// }
|
|
88
|
-
// }
|
|
89
|
-
//
|
|
90
|
-
// return transposed;
|
|
91
|
-
// }
|
|
92
79
|
function round(number) {
|
|
93
|
-
|
|
80
|
+
const rounded = Math.round(number);
|
|
81
|
+
return Math.abs(rounded - number) <= epsilon ? rounded : +number.toPrecision(6);
|
|
94
82
|
}
|
|
95
83
|
// translate3d(25.9808px, 0, 15px ) rotateY(60deg) skewX(49.9999deg) scale(1, 1.2)
|
|
96
84
|
// translate → rotate → skew → scale
|
|
@@ -113,7 +101,7 @@ function decompose(original) {
|
|
|
113
101
|
perspectiveMatrix[15] = 1;
|
|
114
102
|
// @ts-ignore
|
|
115
103
|
const inverted = inverse(original.slice());
|
|
116
|
-
if (
|
|
104
|
+
if (inverted === null) {
|
|
117
105
|
return null;
|
|
118
106
|
}
|
|
119
107
|
const transposedInverse = transposeMatrix4(inverted);
|
|
@@ -134,8 +122,13 @@ function decompose(original) {
|
|
|
134
122
|
const row0 = [matrix[0], matrix[1], matrix[2]];
|
|
135
123
|
const row1 = [matrix[4], matrix[5], matrix[6]];
|
|
136
124
|
const row2 = [matrix[8], matrix[9], matrix[10]];
|
|
125
|
+
const cross = [
|
|
126
|
+
row1[1] * row2[2] - row1[2] * row2[1],
|
|
127
|
+
row1[2] * row2[0] - row1[0] * row2[2],
|
|
128
|
+
row1[0] * row2[1] - row1[1] * row2[0],
|
|
129
|
+
];
|
|
137
130
|
// Compute scale
|
|
138
|
-
const scaleX =
|
|
131
|
+
const scaleX = Math.hypot(...row0);
|
|
139
132
|
const row0Norm = normalize(row0);
|
|
140
133
|
const skewXY = dot(row0Norm, row1);
|
|
141
134
|
const row1Proj = [
|
|
@@ -143,7 +136,7 @@ function decompose(original) {
|
|
|
143
136
|
row1[1] - skewXY * row0Norm[1],
|
|
144
137
|
row1[2] - skewXY * row0Norm[2]
|
|
145
138
|
];
|
|
146
|
-
const scaleY =
|
|
139
|
+
const scaleY = Math.hypot(...row1Proj);
|
|
147
140
|
const row1Norm = normalize(row1Proj);
|
|
148
141
|
const skewXZ = dot(row0Norm, row2);
|
|
149
142
|
const skewYZ = dot(row1Norm, row2);
|
|
@@ -152,8 +145,9 @@ function decompose(original) {
|
|
|
152
145
|
row2[1] - skewXZ * row0Norm[1] - skewYZ * row1Norm[1],
|
|
153
146
|
row2[2] - skewXZ * row0Norm[2] - skewYZ * row1Norm[2]
|
|
154
147
|
];
|
|
155
|
-
const scaleZ = pLength(row2Proj);
|
|
156
148
|
const row2Norm = normalize(row2Proj);
|
|
149
|
+
const determinant = row0[0] * cross[0] + row0[1] * cross[1] + row0[2] * cross[2];
|
|
150
|
+
const scaleZ = Math.hypot(...row2Proj) * (determinant < 0 ? -1 : 1);
|
|
157
151
|
// Build rotation matrix from orthonormalized vectors
|
|
158
152
|
const r00 = row0Norm[0], r01 = row1Norm[0], r02 = row2Norm[0];
|
|
159
153
|
const r10 = row0Norm[1], r11 = row1Norm[1], r12 = row2Norm[1];
|
|
@@ -190,7 +184,6 @@ function decompose(original) {
|
|
|
190
184
|
qz = 0.25 * s;
|
|
191
185
|
}
|
|
192
186
|
[qx, qy, qz] = toZero([qx, qy, qz]);
|
|
193
|
-
// const q = gcd(qx, gcd(qy, qz));
|
|
194
187
|
let q = [Math.abs(qx), Math.abs(qy), Math.abs(qz)].reduce((acc, curr) => {
|
|
195
188
|
if (acc == 0 || (curr > 0 && curr < acc)) {
|
|
196
189
|
acc = curr;
|
|
@@ -235,16 +228,16 @@ function toZero(v) {
|
|
|
235
228
|
// https://drafts.csswg.org/css-transforms-1/#2d-matrix
|
|
236
229
|
function is2DMatrix(matrix) {
|
|
237
230
|
// m13,m14, m23, m24, m31, m32, m34, m43 are all 0
|
|
238
|
-
return matrix[
|
|
239
|
-
matrix[
|
|
240
|
-
matrix[
|
|
241
|
-
matrix[
|
|
242
|
-
matrix[
|
|
243
|
-
matrix[
|
|
244
|
-
matrix[
|
|
245
|
-
matrix[
|
|
246
|
-
matrix[
|
|
247
|
-
matrix[
|
|
231
|
+
return matrix[2] === 0 &&
|
|
232
|
+
matrix[3] === 0 &&
|
|
233
|
+
matrix[6] === 0 &&
|
|
234
|
+
matrix[7] === 0 &&
|
|
235
|
+
matrix[8] === 0 &&
|
|
236
|
+
matrix[9] === 0 &&
|
|
237
|
+
matrix[11] === 0 &&
|
|
238
|
+
matrix[14] === 0 &&
|
|
239
|
+
matrix[10] === 1 &&
|
|
240
|
+
matrix[15] === 1;
|
|
248
241
|
}
|
|
249
242
|
|
|
250
243
|
export { decompose, epsilon, identity, is2DMatrix, multiply, round, toZero };
|
package/dist/lib/ast/types.js
CHANGED
|
@@ -19,14 +19,26 @@ var ValidationLevel;
|
|
|
19
19
|
* disable validation
|
|
20
20
|
*/
|
|
21
21
|
ValidationLevel[ValidationLevel["None"] = 0] = "None";
|
|
22
|
+
/**
|
|
23
|
+
* validate selectors
|
|
24
|
+
*/
|
|
25
|
+
ValidationLevel[ValidationLevel["Selector"] = 1] = "Selector";
|
|
26
|
+
/**
|
|
27
|
+
* validate at-rules
|
|
28
|
+
*/
|
|
29
|
+
ValidationLevel[ValidationLevel["AtRule"] = 2] = "AtRule";
|
|
30
|
+
/**
|
|
31
|
+
* validate declarations
|
|
32
|
+
*/
|
|
33
|
+
ValidationLevel[ValidationLevel["Declaration"] = 4] = "Declaration";
|
|
22
34
|
/**
|
|
23
35
|
* validate selectors and at-rules
|
|
24
36
|
*/
|
|
25
|
-
ValidationLevel[ValidationLevel["Default"] =
|
|
37
|
+
ValidationLevel[ValidationLevel["Default"] = 3] = "Default";
|
|
26
38
|
/**
|
|
27
39
|
* validate selectors, at-rules and declarations
|
|
28
40
|
*/
|
|
29
|
-
ValidationLevel[ValidationLevel["All"] =
|
|
41
|
+
ValidationLevel[ValidationLevel["All"] = 7] = "All"; // selectors + at-rules + declarations
|
|
30
42
|
})(ValidationLevel || (ValidationLevel = {}));
|
|
31
43
|
/**
|
|
32
44
|
* enum of all token types
|
|
@@ -415,6 +427,23 @@ var EnumToken;
|
|
|
415
427
|
* invalid declaration node type
|
|
416
428
|
*/
|
|
417
429
|
EnumToken[EnumToken["InvalidDeclarationNodeType"] = 94] = "InvalidDeclarationNodeType";
|
|
430
|
+
/* css module nodes */
|
|
431
|
+
/**
|
|
432
|
+
* composes token node type
|
|
433
|
+
*/
|
|
434
|
+
EnumToken[EnumToken["ComposesSelectorNodeType"] = 95] = "ComposesSelectorNodeType";
|
|
435
|
+
/**
|
|
436
|
+
* css variable token type
|
|
437
|
+
*/
|
|
438
|
+
EnumToken[EnumToken["CssVariableTokenType"] = 96] = "CssVariableTokenType";
|
|
439
|
+
/**
|
|
440
|
+
* css variable import token type
|
|
441
|
+
*/
|
|
442
|
+
EnumToken[EnumToken["CssVariableImportTokenType"] = 97] = "CssVariableImportTokenType";
|
|
443
|
+
/**
|
|
444
|
+
* css variable declaration map token type
|
|
445
|
+
*/
|
|
446
|
+
EnumToken[EnumToken["CssVariableDeclarationMapTokenType"] = 98] = "CssVariableDeclarationMapTokenType";
|
|
418
447
|
/* aliases */
|
|
419
448
|
/**
|
|
420
449
|
* alias for time token type
|
|
@@ -531,7 +560,7 @@ var EnumToken;
|
|
|
531
560
|
var ColorType;
|
|
532
561
|
(function (ColorType) {
|
|
533
562
|
/**
|
|
534
|
-
* system colors
|
|
563
|
+
* deprecated system colors
|
|
535
564
|
*/
|
|
536
565
|
ColorType[ColorType["SYS"] = 0] = "SYS";
|
|
537
566
|
/**
|
|
@@ -539,7 +568,7 @@ var ColorType;
|
|
|
539
568
|
*/
|
|
540
569
|
ColorType[ColorType["DPSYS"] = 1] = "DPSYS";
|
|
541
570
|
/**
|
|
542
|
-
* colors
|
|
571
|
+
* named colors
|
|
543
572
|
*/
|
|
544
573
|
ColorType[ColorType["LIT"] = 2] = "LIT";
|
|
545
574
|
/**
|
|
@@ -639,5 +668,47 @@ var ColorType;
|
|
|
639
668
|
*/
|
|
640
669
|
ColorType[ColorType["DEVICE_CMYK"] = 7] = "DEVICE_CMYK";
|
|
641
670
|
})(ColorType || (ColorType = {}));
|
|
671
|
+
var ModuleCaseTransformEnum;
|
|
672
|
+
(function (ModuleCaseTransformEnum) {
|
|
673
|
+
/**
|
|
674
|
+
* export class names as-is
|
|
675
|
+
*/
|
|
676
|
+
ModuleCaseTransformEnum[ModuleCaseTransformEnum["IgnoreCase"] = 1] = "IgnoreCase";
|
|
677
|
+
/**
|
|
678
|
+
* transform mapping key name to camel case
|
|
679
|
+
*/
|
|
680
|
+
ModuleCaseTransformEnum[ModuleCaseTransformEnum["CamelCase"] = 2] = "CamelCase";
|
|
681
|
+
/**
|
|
682
|
+
* transform class names and mapping key name to camel case
|
|
683
|
+
*/
|
|
684
|
+
ModuleCaseTransformEnum[ModuleCaseTransformEnum["CamelCaseOnly"] = 4] = "CamelCaseOnly";
|
|
685
|
+
/**
|
|
686
|
+
* transform mapping key name to dash case
|
|
687
|
+
*/
|
|
688
|
+
ModuleCaseTransformEnum[ModuleCaseTransformEnum["DashCase"] = 8] = "DashCase";
|
|
689
|
+
/**
|
|
690
|
+
* transform class names and mapping key name to dash case
|
|
691
|
+
*/
|
|
692
|
+
ModuleCaseTransformEnum[ModuleCaseTransformEnum["DashCaseOnly"] = 16] = "DashCaseOnly";
|
|
693
|
+
})(ModuleCaseTransformEnum || (ModuleCaseTransformEnum = {}));
|
|
694
|
+
var ModuleScopeEnumOptions;
|
|
695
|
+
(function (ModuleScopeEnumOptions) {
|
|
696
|
+
/**
|
|
697
|
+
* use the global scope
|
|
698
|
+
*/
|
|
699
|
+
ModuleScopeEnumOptions[ModuleScopeEnumOptions["Global"] = 32] = "Global";
|
|
700
|
+
/**
|
|
701
|
+
* use the local scope
|
|
702
|
+
*/
|
|
703
|
+
ModuleScopeEnumOptions[ModuleScopeEnumOptions["Local"] = 64] = "Local";
|
|
704
|
+
/**
|
|
705
|
+
* do not allow selector without an id or class
|
|
706
|
+
*/
|
|
707
|
+
ModuleScopeEnumOptions[ModuleScopeEnumOptions["Pure"] = 128] = "Pure";
|
|
708
|
+
/**
|
|
709
|
+
* export using ICSS module format
|
|
710
|
+
*/
|
|
711
|
+
ModuleScopeEnumOptions[ModuleScopeEnumOptions["ICSS"] = 256] = "ICSS";
|
|
712
|
+
})(ModuleScopeEnumOptions || (ModuleScopeEnumOptions = {}));
|
|
642
713
|
|
|
643
|
-
export { ColorType, EnumToken, SyntaxValidationResult, ValidationLevel };
|
|
714
|
+
export { ColorType, EnumToken, ModuleCaseTransformEnum, ModuleScopeEnumOptions, SyntaxValidationResult, ValidationLevel };
|
package/dist/lib/ast/walk.js
CHANGED
|
@@ -12,28 +12,28 @@ var WalkerOptionEnum;
|
|
|
12
12
|
*/
|
|
13
13
|
WalkerOptionEnum[WalkerOptionEnum["Stop"] = 2] = "Stop";
|
|
14
14
|
/**
|
|
15
|
-
* ignore node and process children
|
|
15
|
+
* ignore the current node and process its children
|
|
16
16
|
*/
|
|
17
17
|
WalkerOptionEnum[WalkerOptionEnum["Children"] = 4] = "Children";
|
|
18
18
|
/**
|
|
19
|
-
* ignore children
|
|
19
|
+
* ignore the current node children
|
|
20
20
|
*/
|
|
21
21
|
WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] = 8] = "IgnoreChildren";
|
|
22
22
|
})(WalkerOptionEnum || (WalkerOptionEnum = {}));
|
|
23
23
|
/**
|
|
24
24
|
* event types for the walkValues function
|
|
25
25
|
*/
|
|
26
|
-
var
|
|
27
|
-
(function (
|
|
26
|
+
var WalkerEvent;
|
|
27
|
+
(function (WalkerEvent) {
|
|
28
28
|
/**
|
|
29
29
|
* enter node
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
WalkerEvent[WalkerEvent["Enter"] = 1] = "Enter";
|
|
32
32
|
/**
|
|
33
33
|
* leave node
|
|
34
34
|
*/
|
|
35
|
-
|
|
36
|
-
})(
|
|
35
|
+
WalkerEvent[WalkerEvent["Leave"] = 2] = "Leave";
|
|
36
|
+
})(WalkerEvent || (WalkerEvent = {}));
|
|
37
37
|
/**
|
|
38
38
|
* walk ast nodes
|
|
39
39
|
* @param node initial node
|
|
@@ -64,11 +64,10 @@ var WalkerValueEvent;
|
|
|
64
64
|
* }
|
|
65
65
|
* ```
|
|
66
66
|
*
|
|
67
|
-
* Using a filter to control the
|
|
67
|
+
* Using a {@link filter} function to control the ast traversal. the filter function returns a value of type {@link WalkerOption}.
|
|
68
68
|
*
|
|
69
69
|
* ```ts
|
|
70
|
-
*
|
|
71
|
-
* import {walk} from '@tbela99/css-parser';
|
|
70
|
+
* import {EnumToken, transform, walk, WalkerOptionEnum} from '@tbela99/css-parser';
|
|
72
71
|
*
|
|
73
72
|
* const css = `
|
|
74
73
|
* body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
|
|
@@ -84,17 +83,28 @@ var WalkerValueEvent;
|
|
|
84
83
|
* }
|
|
85
84
|
* `;
|
|
86
85
|
*
|
|
87
|
-
*
|
|
86
|
+
* function filter(node) {
|
|
88
87
|
*
|
|
89
88
|
* if (node.typ == EnumToken.AstRule && node.sel.includes('html')) {
|
|
90
89
|
*
|
|
91
90
|
* // skip the children of the current node
|
|
92
91
|
* return WalkerOptionEnum.IgnoreChildren;
|
|
93
92
|
* }
|
|
94
|
-
* }
|
|
93
|
+
* }
|
|
95
94
|
*
|
|
96
|
-
*
|
|
95
|
+
* const result = await transform(css);
|
|
96
|
+
* for (const {node} of walk(result.ast, filter)) {
|
|
97
|
+
*
|
|
98
|
+
* console.error([EnumToken[node.typ]]);
|
|
97
99
|
* }
|
|
100
|
+
*
|
|
101
|
+
* // [ "StyleSheetNodeType" ]
|
|
102
|
+
* // [ "RuleNodeType" ]
|
|
103
|
+
* // [ "DeclarationNodeType" ]
|
|
104
|
+
* // [ "RuleNodeType" ]
|
|
105
|
+
* // [ "DeclarationNodeType" ]
|
|
106
|
+
* // [ "RuleNodeType" ]
|
|
107
|
+
* // [ "DeclarationNodeType" ]
|
|
98
108
|
* ```
|
|
99
109
|
*/
|
|
100
110
|
function* walk(node, filter, reverse) {
|
|
@@ -102,7 +112,8 @@ function* walk(node, filter, reverse) {
|
|
|
102
112
|
const root = node;
|
|
103
113
|
const map = new Map;
|
|
104
114
|
let isNumeric = false;
|
|
105
|
-
|
|
115
|
+
let i = 0;
|
|
116
|
+
while ((node = parents[i++])) {
|
|
106
117
|
let option = null;
|
|
107
118
|
if (filter != null) {
|
|
108
119
|
option = filter(node);
|
|
@@ -121,8 +132,8 @@ function* walk(node, filter, reverse) {
|
|
|
121
132
|
yield { node, parent: map.get(node), root };
|
|
122
133
|
}
|
|
123
134
|
if ('chi' in node && (!isNumeric || ((option & WalkerOptionEnum.IgnoreChildren) === 0))) {
|
|
124
|
-
parents.
|
|
125
|
-
for (const child of node.chi
|
|
135
|
+
parents.splice(i, 0, ...node.chi[reverse ? 'reverse' : 'slice']());
|
|
136
|
+
for (const child of node.chi) {
|
|
126
137
|
map.set(child, node);
|
|
127
138
|
}
|
|
128
139
|
}
|
|
@@ -139,55 +150,68 @@ function* walk(node, filter, reverse) {
|
|
|
139
150
|
*
|
|
140
151
|
* ```ts
|
|
141
152
|
*
|
|
142
|
-
* import {EnumToken,
|
|
153
|
+
* import {AstDeclaration, EnumToken, transform, walkValues} from '@tbela99/css-parser';
|
|
143
154
|
*
|
|
144
155
|
* const css = `
|
|
145
156
|
* body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
|
|
146
|
-
*
|
|
147
|
-
* html,
|
|
148
|
-
* body {
|
|
149
|
-
* line-height: 1.474;
|
|
150
|
-
* }
|
|
151
|
-
*
|
|
152
|
-
* .ruler {
|
|
153
|
-
*
|
|
154
|
-
* height: 10px;
|
|
155
|
-
* }
|
|
156
157
|
* `;
|
|
157
158
|
*
|
|
158
|
-
*
|
|
159
|
+
* const result = await transform(css);
|
|
160
|
+
* const declaration = result.ast.chi[0].chi[0] as AstDeclaration;
|
|
161
|
+
*
|
|
162
|
+
* // walk the node attribute's tokens in reverse order
|
|
163
|
+
* for (const {value} of walkValues(declaration.val, null, null,true)) {
|
|
159
164
|
*
|
|
160
165
|
* console.error([EnumToken[value.typ], value.val]);
|
|
161
166
|
* }
|
|
162
167
|
*
|
|
168
|
+
* // [ "Color", "color" ]
|
|
169
|
+
* // [ "FunctionTokenType", "calc" ]
|
|
170
|
+
* // [ "Number", 0.15 ]
|
|
171
|
+
* // [ "Add", undefined ]
|
|
172
|
+
* // [ "Iden", "b" ]
|
|
173
|
+
* // [ "Whitespace", undefined ]
|
|
174
|
+
* // [ "FunctionTokenType", "calc" ]
|
|
175
|
+
* // [ "Number", 0.24 ]
|
|
176
|
+
* // [ "Add", undefined ]
|
|
177
|
+
* // [ "Iden", "g" ]
|
|
178
|
+
* // [ "Whitespace", undefined ]
|
|
179
|
+
* // [ "Iden", "r" ]
|
|
180
|
+
* // [ "Whitespace", undefined ]
|
|
181
|
+
* // [ "Iden", "display-p3" ]
|
|
182
|
+
* // [ "Whitespace", undefined ]
|
|
183
|
+
* // [ "FunctionTokenType", "var" ]
|
|
184
|
+
* // [ "DashedIden", "--base-color" ]
|
|
185
|
+
* // [ "Whitespace", undefined ]
|
|
186
|
+
* // [ "Iden", "from" ]
|
|
187
|
+
* ```
|
|
163
188
|
*/
|
|
164
189
|
function* walkValues(values, root = null, filter, reverse) {
|
|
165
|
-
// const set = new Set<Token>();
|
|
166
190
|
const stack = values.slice();
|
|
167
191
|
const map = new Map;
|
|
168
192
|
let previous = null;
|
|
169
193
|
if (filter != null && typeof filter == 'function') {
|
|
170
194
|
filter = {
|
|
171
|
-
event:
|
|
195
|
+
event: WalkerEvent.Enter,
|
|
172
196
|
fn: filter
|
|
173
197
|
};
|
|
174
198
|
}
|
|
175
199
|
else if (filter == null) {
|
|
176
200
|
filter = {
|
|
177
|
-
event:
|
|
201
|
+
event: WalkerEvent.Enter
|
|
178
202
|
};
|
|
179
203
|
}
|
|
180
204
|
let isNumeric = false;
|
|
181
|
-
const eventType = filter.event ??
|
|
205
|
+
const eventType = filter.event ?? WalkerEvent.Enter;
|
|
182
206
|
while (stack.length > 0) {
|
|
183
207
|
let value = reverse ? stack.pop() : stack.shift();
|
|
184
208
|
let option = null;
|
|
185
|
-
if (filter.fn != null && (eventType &
|
|
209
|
+
if (filter.fn != null && (eventType & WalkerEvent.Enter)) {
|
|
186
210
|
const isValid = filter.type == null || value.typ == filter.type ||
|
|
187
211
|
(Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
|
|
188
212
|
(typeof filter.type == 'function' && filter.type(value));
|
|
189
213
|
if (isValid) {
|
|
190
|
-
option = filter.fn(value, map.get(value) ?? root,
|
|
214
|
+
option = filter.fn(value, map.get(value) ?? root, WalkerEvent.Enter);
|
|
191
215
|
isNumeric = typeof option == 'number';
|
|
192
216
|
if (isNumeric && (option & WalkerOptionEnum.Stop)) {
|
|
193
217
|
return;
|
|
@@ -196,12 +220,15 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
196
220
|
continue;
|
|
197
221
|
}
|
|
198
222
|
// @ts-ignore
|
|
199
|
-
if (option != null && typeof option == 'object' && 'typ' in option) {
|
|
200
|
-
|
|
223
|
+
if (option != null && typeof option == 'object' && ('typ' in option || Array.isArray(option))) {
|
|
224
|
+
const op = Array.isArray(option) ? option : [option];
|
|
225
|
+
for (const o of op) {
|
|
226
|
+
map.set(o, map.get(value) ?? root);
|
|
227
|
+
}
|
|
228
|
+
stack[reverse ? 'push' : 'unshift'](...op);
|
|
201
229
|
}
|
|
202
230
|
}
|
|
203
231
|
}
|
|
204
|
-
// if ((eventType & WalkerValueEvent.Enter) && (!isNumeric || ((option as number) & WalkerOptionEnum.Children) === 0)) {
|
|
205
232
|
yield {
|
|
206
233
|
value,
|
|
207
234
|
parent: map.get(value) ?? root,
|
|
@@ -210,7 +237,6 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
210
237
|
// @ts-ignore
|
|
211
238
|
root: root ?? null
|
|
212
239
|
};
|
|
213
|
-
// }
|
|
214
240
|
if ('chi' in value && (!isNumeric || (option & WalkerOptionEnum.IgnoreChildren) === 0)) {
|
|
215
241
|
const sliced = value.chi.slice();
|
|
216
242
|
for (const child of sliced) {
|
|
@@ -222,12 +248,12 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
222
248
|
const values = [];
|
|
223
249
|
if ('l' in value && value.l != null) {
|
|
224
250
|
// @ts-ignore
|
|
225
|
-
values
|
|
251
|
+
values.push(value.l);
|
|
226
252
|
// @ts-ignore
|
|
227
253
|
map.set(value.l, value);
|
|
228
254
|
}
|
|
229
255
|
if ('op' in value && typeof value.op == 'object') {
|
|
230
|
-
values
|
|
256
|
+
values.push(value.op);
|
|
231
257
|
// @ts-ignore
|
|
232
258
|
map.set(value.op, value);
|
|
233
259
|
}
|
|
@@ -235,14 +261,14 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
235
261
|
if (Array.isArray(value.r)) {
|
|
236
262
|
for (const r of value.r) {
|
|
237
263
|
// @ts-ignore
|
|
238
|
-
values
|
|
264
|
+
values.push(r);
|
|
239
265
|
// @ts-ignore
|
|
240
266
|
map.set(r, value);
|
|
241
267
|
}
|
|
242
268
|
}
|
|
243
269
|
else {
|
|
244
270
|
// @ts-ignore
|
|
245
|
-
values
|
|
271
|
+
values.push(value.r);
|
|
246
272
|
// @ts-ignore
|
|
247
273
|
map.set(value.r, value);
|
|
248
274
|
}
|
|
@@ -251,31 +277,24 @@ function* walkValues(values, root = null, filter, reverse) {
|
|
|
251
277
|
stack[reverse ? 'push' : 'unshift'](...values);
|
|
252
278
|
}
|
|
253
279
|
}
|
|
254
|
-
if ((eventType &
|
|
280
|
+
if ((eventType & WalkerEvent.Leave) && filter.fn != null) {
|
|
255
281
|
const isValid = filter.type == null || value.typ == filter.type ||
|
|
256
282
|
(Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
|
|
257
283
|
(typeof filter.type == 'function' && filter.type(value));
|
|
258
284
|
if (isValid) {
|
|
259
|
-
option = filter.fn(value, map.get(value),
|
|
285
|
+
option = filter.fn(value, map.get(value), WalkerEvent.Leave);
|
|
260
286
|
// @ts-ignore
|
|
261
|
-
if (option != null && 'typ' in option) {
|
|
262
|
-
|
|
287
|
+
if (option != null && ('typ' in option || Array.isArray(option))) {
|
|
288
|
+
const op = Array.isArray(option) ? option : [option];
|
|
289
|
+
for (const o of op) {
|
|
290
|
+
map.set(o, map.get(value) ?? root);
|
|
291
|
+
}
|
|
292
|
+
stack[reverse ? 'push' : 'unshift'](...op);
|
|
263
293
|
}
|
|
264
294
|
}
|
|
265
295
|
}
|
|
266
|
-
// if ((eventType & WalkerValueEvent.Leave) && (!isNumeric && ((option as number) & WalkerOptionEnum.Children) === 0)) {
|
|
267
|
-
//
|
|
268
|
-
// yield {
|
|
269
|
-
// value,
|
|
270
|
-
// parent: <FunctionToken | ParensToken>map.get(value) ?? root,
|
|
271
|
-
// previousValue: previous,
|
|
272
|
-
// nextValue: <Token>stack[0] ?? null,
|
|
273
|
-
// // @ts-ignore
|
|
274
|
-
// root: root ?? null
|
|
275
|
-
// };
|
|
276
|
-
// }
|
|
277
296
|
previous = value;
|
|
278
297
|
}
|
|
279
298
|
}
|
|
280
299
|
|
|
281
|
-
export {
|
|
300
|
+
export { WalkerEvent, WalkerOptionEnum, walk, walkValues };
|
package/dist/lib/fs/resolve.js
CHANGED
|
@@ -10,6 +10,9 @@ function dirname(path) {
|
|
|
10
10
|
//
|
|
11
11
|
// return path;
|
|
12
12
|
// }
|
|
13
|
+
if (path === '') {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
13
16
|
let i = 0;
|
|
14
17
|
let parts = [''];
|
|
15
18
|
for (; i < path.length; i++) {
|
|
@@ -17,9 +20,10 @@ function dirname(path) {
|
|
|
17
20
|
if (chr == '/') {
|
|
18
21
|
parts.push('');
|
|
19
22
|
}
|
|
20
|
-
else if (chr == '?' || chr == '#') {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
// else if (chr == '?' || chr == '#') {
|
|
24
|
+
//
|
|
25
|
+
// break;
|
|
26
|
+
// }
|
|
23
27
|
else {
|
|
24
28
|
parts[parts.length - 1] += chr;
|
|
25
29
|
}
|
|
@@ -33,6 +37,12 @@ function dirname(path) {
|
|
|
33
37
|
* @private
|
|
34
38
|
*/
|
|
35
39
|
function splitPath(result) {
|
|
40
|
+
if (result.length == 0) {
|
|
41
|
+
return { parts: [], i: 0 };
|
|
42
|
+
}
|
|
43
|
+
if (result === '/') {
|
|
44
|
+
return { parts: ['/'], i: 0 };
|
|
45
|
+
}
|
|
36
46
|
const parts = [''];
|
|
37
47
|
let i = 0;
|
|
38
48
|
for (; i < result.length; i++) {
|
|
@@ -74,6 +84,23 @@ function resolve(url, currentDirectory, cwd) {
|
|
|
74
84
|
relative: url
|
|
75
85
|
};
|
|
76
86
|
}
|
|
87
|
+
cwd ??= '';
|
|
88
|
+
currentDirectory ??= '';
|
|
89
|
+
if (currentDirectory !== '' && url.startsWith(currentDirectory + '/')) {
|
|
90
|
+
return {
|
|
91
|
+
absolute: url,
|
|
92
|
+
relative: url.slice(currentDirectory.length + 1)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (currentDirectory === '' && cwd !== '' && url.startsWith(cwd == '/' ? cwd : cwd + '/')) {
|
|
96
|
+
cwd = normalize(cwd);
|
|
97
|
+
const absolute = normalize(url);
|
|
98
|
+
const prefix = cwd == '/' ? cwd : cwd + '/';
|
|
99
|
+
return {
|
|
100
|
+
absolute,
|
|
101
|
+
relative: absolute.startsWith(prefix) ? absolute.slice(prefix.length) : diff(absolute, cwd)
|
|
102
|
+
};
|
|
103
|
+
}
|
|
77
104
|
if (matchUrl.test(currentDirectory)) {
|
|
78
105
|
const path = new URL(url, currentDirectory).href;
|
|
79
106
|
return {
|
|
@@ -88,9 +115,15 @@ function resolve(url, currentDirectory, cwd) {
|
|
|
88
115
|
else if (currentDirectory.charAt(0) == '/') {
|
|
89
116
|
result = dirname(currentDirectory) + '/' + url;
|
|
90
117
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
118
|
+
const absolute = normalize(result);
|
|
119
|
+
return {
|
|
120
|
+
absolute,
|
|
121
|
+
relative: absolute === '' ? '' : diff(absolute, cwd ?? currentDirectory),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function diff(path1, path2) {
|
|
125
|
+
let { parts } = splitPath(path1);
|
|
126
|
+
const { parts: dirs } = splitPath(path2);
|
|
94
127
|
for (const p of dirs) {
|
|
95
128
|
if (parts[0] == p) {
|
|
96
129
|
parts.shift();
|
|
@@ -99,10 +132,36 @@ function resolve(url, currentDirectory, cwd) {
|
|
|
99
132
|
parts.unshift('..');
|
|
100
133
|
}
|
|
101
134
|
}
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
135
|
+
return parts.join('/');
|
|
136
|
+
}
|
|
137
|
+
function normalize(path) {
|
|
138
|
+
let parts = [];
|
|
139
|
+
let i = 0;
|
|
140
|
+
for (; i < path.length; i++) {
|
|
141
|
+
const chr = path.charAt(i);
|
|
142
|
+
if (chr == '/') {
|
|
143
|
+
if (parts.length == 0 || parts[parts.length - 1] !== '') {
|
|
144
|
+
parts.push('');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (chr == '?' || chr == '#') {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
parts[parts.length - 1] += chr;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
let k = -1;
|
|
155
|
+
while (++k < parts.length) {
|
|
156
|
+
if (parts[k] == '.') {
|
|
157
|
+
parts.splice(k--, 1);
|
|
158
|
+
}
|
|
159
|
+
else if (parts[k] == '..') {
|
|
160
|
+
parts.splice(k - 1, 2);
|
|
161
|
+
k -= 2;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return (path.charAt(0) == '/' ? '/' : '') + parts.join('/');
|
|
106
165
|
}
|
|
107
166
|
|
|
108
167
|
export { dirname, matchUrl, resolve };
|
|
@@ -25,8 +25,13 @@ class PropertyList {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
add(...declarations) {
|
|
28
|
+
let name;
|
|
28
29
|
for (const declaration of declarations) {
|
|
29
|
-
|
|
30
|
+
name = declaration.typ != EnumToken.DeclarationNodeType ? null : declaration.nam.toLowerCase();
|
|
31
|
+
if (declaration.typ != EnumToken.DeclarationNodeType ||
|
|
32
|
+
'composes' === name ||
|
|
33
|
+
(typeof this.options.removeDuplicateDeclarations === 'string' && this.options.removeDuplicateDeclarations === name) ||
|
|
34
|
+
(Array.isArray(this.options.removeDuplicateDeclarations) ? this.options.removeDuplicateDeclarations.includes(declaration.nam) : !this.options.removeDuplicateDeclarations)) {
|
|
30
35
|
this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
|
|
31
36
|
continue;
|
|
32
37
|
}
|