@tbela99/css-parser 0.8.0 → 0.9.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/.editorconfig +484 -0
- package/README.md +5 -3
- package/dist/index-umd-web.js +3272 -1898
- package/dist/index.cjs +3272 -1898
- package/dist/index.d.ts +48 -11
- package/dist/lib/ast/expand.js +14 -2
- package/dist/lib/ast/math/expression.js +1 -1
- package/dist/lib/ast/minify.js +30 -16
- package/dist/lib/ast/types.js +1 -0
- package/dist/lib/ast/walk.js +12 -0
- package/dist/lib/parser/declaration/map.js +59 -52
- package/dist/lib/parser/declaration/set.js +0 -12
- package/dist/lib/parser/parse.js +140 -101
- package/dist/lib/parser/tokenize.js +15 -3
- package/dist/lib/renderer/color/hex.js +1 -1
- package/dist/lib/renderer/color/hsl.js +1 -1
- package/dist/lib/renderer/color/hwb.js +2 -2
- package/dist/lib/renderer/color/lab.js +1 -1
- package/dist/lib/renderer/color/lch.js +1 -1
- package/dist/lib/renderer/color/oklab.js +2 -2
- package/dist/lib/renderer/color/oklch.js +1 -1
- package/dist/lib/renderer/color/p3.js +1 -1
- package/dist/lib/renderer/color/prophotoRgb.js +1 -1
- package/dist/lib/renderer/color/prophotorgb.js +1 -1
- package/dist/lib/renderer/color/rgb.js +1 -1
- package/dist/lib/renderer/color/srgb.js +2 -2
- package/dist/lib/renderer/color/utils/constants.js +1 -1
- package/dist/lib/renderer/color/xyz.js +1 -1
- package/dist/lib/renderer/render.js +34 -6
- package/dist/lib/syntax/syntax.js +336 -1
- package/dist/lib/validation/at-rules/container.js +353 -0
- package/dist/lib/validation/at-rules/counter-style.js +2 -2
- package/dist/lib/validation/at-rules/custom-media.js +52 -0
- package/dist/lib/validation/at-rules/else.js +5 -0
- package/dist/lib/validation/at-rules/font-feature-values.js +3 -0
- package/dist/lib/validation/at-rules/import.js +3 -0
- package/dist/lib/validation/at-rules/layer.js +3 -0
- package/dist/lib/validation/at-rules/media.js +117 -29
- package/dist/lib/validation/at-rules/supports.js +11 -11
- package/dist/lib/validation/at-rules/when.js +178 -0
- package/dist/lib/validation/atrule.js +25 -10
- package/dist/lib/validation/config.js +20 -15
- package/dist/lib/validation/config.json.js +162 -42
- package/dist/lib/validation/declaration.js +39 -9
- package/dist/lib/validation/parser/parse.js +91 -13
- package/dist/lib/validation/parser/types.js +1 -0
- package/dist/lib/validation/selector.js +6 -3
- package/dist/lib/validation/syntax.js +50 -4
- package/dist/lib/validation/syntaxes/complex-selector-list.js +16 -12
- package/dist/lib/validation/syntaxes/complex-selector.js +17 -247
- package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
- package/dist/lib/validation/syntaxes/image.js +29 -0
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +1 -1
- package/dist/lib/validation/syntaxes/keyframe-selector.js +1 -1
- package/dist/lib/validation/syntaxes/relative-selector-list.js +43 -13
- package/dist/lib/validation/utils/list.js +2 -2
- package/dist/node/index.js +1 -1
- package/dist/web/index.js +1 -1
- package/package.json +7 -7
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { webkitPseudoAliasMap, isIdentStart, isIdent, mathFuncs, isColor, isHexColor, isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isHash, mediaTypes } from '../syntax/syntax.js';
|
|
2
2
|
import './utils/config.js';
|
|
3
3
|
import { EnumToken, funcLike, ValidationLevel } from '../ast/types.js';
|
|
4
4
|
import { minify, definedPropertySettings, combinators } from '../ast/minify.js';
|
|
@@ -13,6 +13,7 @@ import '../validation/parser/types.js';
|
|
|
13
13
|
import '../validation/parser/parse.js';
|
|
14
14
|
import { validateSelector } from '../validation/selector.js';
|
|
15
15
|
import { validateAtRule } from '../validation/atrule.js';
|
|
16
|
+
import '../validation/syntaxes/complex-selector.js';
|
|
16
17
|
|
|
17
18
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
18
19
|
const trimWhiteSpace = [EnumToken.CommentTokenType, EnumToken.GtTokenType, EnumToken.GteTokenType, EnumToken.LtTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType];
|
|
@@ -29,51 +30,14 @@ const enumTokenHints = new Set([
|
|
|
29
30
|
EnumToken.StartMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DashMatchTokenType, EnumToken.ContainMatchTokenType,
|
|
30
31
|
EnumToken.EOFTokenType
|
|
31
32
|
]);
|
|
32
|
-
const webkitPseudoAliasMap = {
|
|
33
|
-
'-webkit-autofill': 'autofill',
|
|
34
|
-
'-webkit-any': 'is',
|
|
35
|
-
'-moz-any': 'is',
|
|
36
|
-
'-webkit-border-after': 'border-block-end',
|
|
37
|
-
'-webkit-border-after-color': 'border-block-end-color',
|
|
38
|
-
'-webkit-border-after-style': 'border-block-end-style',
|
|
39
|
-
'-webkit-border-after-width': 'border-block-end-width',
|
|
40
|
-
'-webkit-border-before': 'border-block-start',
|
|
41
|
-
'-webkit-border-before-color': 'border-block-start-color',
|
|
42
|
-
'-webkit-border-before-style': 'border-block-start-style',
|
|
43
|
-
'-webkit-border-before-width': 'border-block-start-width',
|
|
44
|
-
'-webkit-border-end': 'border-inline-end',
|
|
45
|
-
'-webkit-border-end-color': 'border-inline-end-color',
|
|
46
|
-
'-webkit-border-end-style': 'border-inline-end-style',
|
|
47
|
-
'-webkit-border-end-width': 'border-inline-end-width',
|
|
48
|
-
'-webkit-border-start': 'border-inline-start',
|
|
49
|
-
'-webkit-border-start-color': 'border-inline-start-color',
|
|
50
|
-
'-webkit-border-start-style': 'border-inline-start-style',
|
|
51
|
-
'-webkit-border-start-width': 'border-inline-start-width',
|
|
52
|
-
'-webkit-box-align': 'align-items',
|
|
53
|
-
'-webkit-box-direction': 'flex-direction',
|
|
54
|
-
'-webkit-box-flex': 'flex-grow',
|
|
55
|
-
'-webkit-box-lines': 'flex-flow',
|
|
56
|
-
'-webkit-box-ordinal-group': 'order',
|
|
57
|
-
'-webkit-box-orient': 'flex-direction',
|
|
58
|
-
'-webkit-box-pack': 'justify-content',
|
|
59
|
-
'-webkit-column-break-after': 'break-after',
|
|
60
|
-
'-webkit-column-break-before': 'break-before',
|
|
61
|
-
'-webkit-column-break-inside': 'break-inside',
|
|
62
|
-
'-webkit-font-feature-settings': 'font-feature-settings',
|
|
63
|
-
'-webkit-hyphenate-character': 'hyphenate-character',
|
|
64
|
-
'-webkit-initial-letter': 'initial-letter',
|
|
65
|
-
'-webkit-margin-end': 'margin-block-end',
|
|
66
|
-
'-webkit-margin-start': 'margin-block-start',
|
|
67
|
-
'-webkit-padding-after': 'padding-block-end',
|
|
68
|
-
'-webkit-padding-before': 'padding-block-start',
|
|
69
|
-
'-webkit-padding-end': 'padding-inline-end',
|
|
70
|
-
'-webkit-padding-start': 'padding-inline-start',
|
|
71
|
-
'-webkit-min-device-pixel-ratio': 'min-resolution',
|
|
72
|
-
'-webkit-max-device-pixel-ratio': 'max-resolution'
|
|
73
|
-
};
|
|
74
33
|
function reject(reason) {
|
|
75
34
|
throw new Error(reason ?? 'Parsing aborted');
|
|
76
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* parse css string
|
|
38
|
+
* @param iterator
|
|
39
|
+
* @param options
|
|
40
|
+
*/
|
|
77
41
|
async function doParse(iterator, options = {}) {
|
|
78
42
|
if (options.signal != null) {
|
|
79
43
|
options.signal.addEventListener('abort', reject);
|
|
@@ -95,6 +59,7 @@ async function doParse(iterator, options = {}) {
|
|
|
95
59
|
setParent: true,
|
|
96
60
|
removePrefix: false,
|
|
97
61
|
validation: true,
|
|
62
|
+
lenient: true,
|
|
98
63
|
...options
|
|
99
64
|
};
|
|
100
65
|
if (options.expandNestingRules) {
|
|
@@ -133,9 +98,10 @@ async function doParse(iterator, options = {}) {
|
|
|
133
98
|
}
|
|
134
99
|
const iter = tokenize(iterator);
|
|
135
100
|
let item;
|
|
101
|
+
const rawTokens = [];
|
|
136
102
|
while (item = iter.next().value) {
|
|
137
103
|
stats.bytesIn = item.bytesIn;
|
|
138
|
-
|
|
104
|
+
rawTokens.push(item);
|
|
139
105
|
// doParse error
|
|
140
106
|
if (item.hint != null && BadTokensTypes.includes(item.hint)) {
|
|
141
107
|
// bad token
|
|
@@ -145,7 +111,8 @@ async function doParse(iterator, options = {}) {
|
|
|
145
111
|
tokens.push(item);
|
|
146
112
|
}
|
|
147
113
|
if (item.token == ';' || item.token == '{') {
|
|
148
|
-
let node = await parseNode(tokens, context, stats, options, errors, src, map);
|
|
114
|
+
let node = await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
115
|
+
rawTokens.length = 0;
|
|
149
116
|
if (node != null) {
|
|
150
117
|
// @ts-ignore
|
|
151
118
|
stack.push(node);
|
|
@@ -171,7 +138,8 @@ async function doParse(iterator, options = {}) {
|
|
|
171
138
|
map = new Map;
|
|
172
139
|
}
|
|
173
140
|
else if (item.token == '}') {
|
|
174
|
-
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
141
|
+
await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
142
|
+
rawTokens.length = 0;
|
|
175
143
|
const previousNode = stack.pop();
|
|
176
144
|
// @ts-ignore
|
|
177
145
|
context = stack[stack.length - 1] ?? ast;
|
|
@@ -194,7 +162,8 @@ async function doParse(iterator, options = {}) {
|
|
|
194
162
|
}
|
|
195
163
|
}
|
|
196
164
|
if (tokens.length > 0) {
|
|
197
|
-
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
165
|
+
await parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
166
|
+
rawTokens.length = 0;
|
|
198
167
|
if (context != null && context.typ == EnumToken.InvalidRuleTokenType) {
|
|
199
168
|
const index = context.chi.findIndex(node => node == context);
|
|
200
169
|
if (index > -1) {
|
|
@@ -206,6 +175,7 @@ async function doParse(iterator, options = {}) {
|
|
|
206
175
|
const previousNode = stack.pop();
|
|
207
176
|
// @ts-ignore
|
|
208
177
|
context = stack[stack.length - 1] ?? ast;
|
|
178
|
+
// remove empty nodes
|
|
209
179
|
// @ts-ignore
|
|
210
180
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
211
181
|
// @ts-ignore
|
|
@@ -258,33 +228,6 @@ async function doParse(iterator, options = {}) {
|
|
|
258
228
|
minify(ast, options, true, errors, false);
|
|
259
229
|
}
|
|
260
230
|
}
|
|
261
|
-
// if (options.setParent) {
|
|
262
|
-
//
|
|
263
|
-
// const nodes: Array<AstRule | AstAtRule | AstRuleStyleSheet> = [ast];
|
|
264
|
-
// let node: AstNode;
|
|
265
|
-
//
|
|
266
|
-
// while ((node = nodes.shift()!)) {
|
|
267
|
-
//
|
|
268
|
-
// // @ts-ignore
|
|
269
|
-
// if (node.chi.length > 0) {
|
|
270
|
-
//
|
|
271
|
-
// // @ts-ignore
|
|
272
|
-
// for (const child of node.chi) {
|
|
273
|
-
//
|
|
274
|
-
// if (child.parent != node) {
|
|
275
|
-
//
|
|
276
|
-
// Object.defineProperty(child, 'parent', {...definedPropertySettings, value: node});
|
|
277
|
-
// }
|
|
278
|
-
//
|
|
279
|
-
// if ('chi' in child && child.chi.length > 0) {
|
|
280
|
-
//
|
|
281
|
-
// // @ts-ignore
|
|
282
|
-
// nodes.push(<AstRule | AstAtRule>child);
|
|
283
|
-
// }
|
|
284
|
-
// }
|
|
285
|
-
// }
|
|
286
|
-
// }
|
|
287
|
-
// }
|
|
288
231
|
const endTime = performance.now();
|
|
289
232
|
if (options.signal != null) {
|
|
290
233
|
options.signal.removeEventListener('abort', reject);
|
|
@@ -301,7 +244,17 @@ async function doParse(iterator, options = {}) {
|
|
|
301
244
|
}
|
|
302
245
|
};
|
|
303
246
|
}
|
|
304
|
-
|
|
247
|
+
function getLastNode(context) {
|
|
248
|
+
let i = context.chi.length;
|
|
249
|
+
while (i--) {
|
|
250
|
+
if ([EnumToken.CommentTokenType, EnumToken.CDOCOMMTokenType, EnumToken.WhitespaceTokenType].includes(context.chi[i].typ)) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
return context.chi[i];
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
async function parseNode(results, context, stats, options, errors, src, map, rawTokens) {
|
|
305
258
|
let tokens = [];
|
|
306
259
|
for (const t of results) {
|
|
307
260
|
const node = getTokenType(t.token, t.hint);
|
|
@@ -356,24 +309,6 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
356
309
|
if (tokens[0]?.typ == EnumToken.AtRuleTokenType) {
|
|
357
310
|
const atRule = tokens.shift();
|
|
358
311
|
const position = map.get(atRule);
|
|
359
|
-
// if (atRule.val == 'charset') {
|
|
360
|
-
//
|
|
361
|
-
// if (context.typ != EnumToken.StyleSheetNodeType || context.chi.some(t => t.typ != EnumToken.CDOCOMMTokenType && t.typ != EnumToken.CommentNodeType)) {
|
|
362
|
-
//
|
|
363
|
-
// errors.push({
|
|
364
|
-
// action: 'drop',
|
|
365
|
-
// message: 'doParse: invalid @charset',
|
|
366
|
-
// location: {src, ...position}
|
|
367
|
-
// });
|
|
368
|
-
//
|
|
369
|
-
// return null;
|
|
370
|
-
// }
|
|
371
|
-
//
|
|
372
|
-
// if (options.removeCharset) {
|
|
373
|
-
//
|
|
374
|
-
// return null;
|
|
375
|
-
// }
|
|
376
|
-
// }
|
|
377
312
|
// @ts-ignore
|
|
378
313
|
while ([EnumToken.WhitespaceTokenType].includes(tokens[0]?.typ)) {
|
|
379
314
|
tokens.shift();
|
|
@@ -470,8 +405,43 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
470
405
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
471
406
|
// allowed nesting at-rules
|
|
472
407
|
// there must be a top level rule in the stack
|
|
473
|
-
if (atRule.val == 'charset'
|
|
474
|
-
|
|
408
|
+
if (atRule.val == 'charset') {
|
|
409
|
+
let spaces = 0;
|
|
410
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/@charset
|
|
411
|
+
for (let k = 1; k < rawTokens.length; k++) {
|
|
412
|
+
if (rawTokens[k].hint == EnumToken.WhitespaceTokenType) {
|
|
413
|
+
spaces += rawTokens[k].len;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
if (rawTokens[k].hint == EnumToken.CommentTokenType) {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (rawTokens[k].hint == EnumToken.CDOCOMMTokenType) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (spaces > 1) {
|
|
423
|
+
errors.push({
|
|
424
|
+
action: 'drop',
|
|
425
|
+
message: '@charset must have only one space',
|
|
426
|
+
// @ts-ignore
|
|
427
|
+
location: { src, ...(map.get(atRule) ?? position) }
|
|
428
|
+
});
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
if (rawTokens[k].hint != EnumToken.StringTokenType || rawTokens[k].token[0] != '"') {
|
|
432
|
+
errors.push({
|
|
433
|
+
action: 'drop',
|
|
434
|
+
message: '@charset expects a "<charset>"',
|
|
435
|
+
// @ts-ignore
|
|
436
|
+
location: { src, ...(map.get(atRule) ?? position) }
|
|
437
|
+
});
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
if (options.removeCharset) {
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
475
445
|
}
|
|
476
446
|
const t = parseAtRulePrelude(parseTokens(tokens, { minify: options.minify }), atRule);
|
|
477
447
|
const raw = t.reduce((acc, curr) => {
|
|
@@ -499,11 +469,36 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
499
469
|
node.loc = loc;
|
|
500
470
|
}
|
|
501
471
|
if (options.validation) {
|
|
502
|
-
|
|
472
|
+
let isValid = true;
|
|
473
|
+
if (node.nam == 'else') {
|
|
474
|
+
const prev = getLastNode(context);
|
|
475
|
+
if (prev != null && prev.typ == EnumToken.AtRuleNodeType && ['when', 'else'].includes(prev.nam)) {
|
|
476
|
+
if (prev.nam == 'else') {
|
|
477
|
+
isValid = Array.isArray(prev.tokens) && prev.tokens.length > 0;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
isValid = false;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
const valid = isValid ? validateAtRule(node, options, context) : {
|
|
485
|
+
valid: ValidationLevel.Drop,
|
|
486
|
+
node,
|
|
487
|
+
syntax: '@' + node.nam,
|
|
488
|
+
error: '@' + node.nam + ' not allowed here'};
|
|
503
489
|
if (valid.valid == ValidationLevel.Drop) {
|
|
490
|
+
errors.push({
|
|
491
|
+
action: 'drop',
|
|
492
|
+
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
493
|
+
// @ts-ignore
|
|
494
|
+
location: { src, ...(map.get(valid.node) ?? position) }
|
|
495
|
+
});
|
|
504
496
|
// @ts-ignore
|
|
505
497
|
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
506
498
|
}
|
|
499
|
+
else {
|
|
500
|
+
node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false, removeComments: true }), '');
|
|
501
|
+
}
|
|
507
502
|
}
|
|
508
503
|
// @ts-ignore
|
|
509
504
|
context.chi.push(node);
|
|
@@ -682,7 +677,24 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
682
677
|
};
|
|
683
678
|
const result = parseDeclarationNode(node, errors, src, position);
|
|
684
679
|
if (result != null) {
|
|
685
|
-
if (options.validation)
|
|
680
|
+
// if (options.validation) {
|
|
681
|
+
//
|
|
682
|
+
// const valid: ValidationResult = validateDeclaration(result, options, context);
|
|
683
|
+
//
|
|
684
|
+
// console.error({valid});
|
|
685
|
+
//
|
|
686
|
+
// if (valid.valid == ValidationLevel.Drop) {
|
|
687
|
+
//
|
|
688
|
+
// errors.push({
|
|
689
|
+
// action: 'drop',
|
|
690
|
+
// message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, {minify: false}), '') + '"',
|
|
691
|
+
// // @ts-ignore
|
|
692
|
+
// location: {src, ...(map.get(valid.node) ?? position)}
|
|
693
|
+
// });
|
|
694
|
+
//
|
|
695
|
+
// return null;
|
|
696
|
+
// }
|
|
697
|
+
// }
|
|
686
698
|
// @ts-ignore
|
|
687
699
|
context.chi.push(result);
|
|
688
700
|
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
@@ -691,6 +703,11 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
691
703
|
}
|
|
692
704
|
}
|
|
693
705
|
}
|
|
706
|
+
/**
|
|
707
|
+
* parse at-rule prelude
|
|
708
|
+
* @param tokens
|
|
709
|
+
* @param atRule
|
|
710
|
+
*/
|
|
694
711
|
function parseAtRulePrelude(tokens, atRule) {
|
|
695
712
|
// @ts-ignore
|
|
696
713
|
for (const { value, parent } of walkValues(tokens, null, null, true)) {
|
|
@@ -759,17 +776,18 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
759
776
|
continue;
|
|
760
777
|
}
|
|
761
778
|
}
|
|
762
|
-
if (value.typ == EnumToken.ParensTokenType) {
|
|
779
|
+
if (value.typ == EnumToken.ParensTokenType || (value.typ == EnumToken.FunctionTokenType && ['media', 'supports', 'style', 'scroll-state'].includes(value.val))) {
|
|
763
780
|
// @todo parse range and declarations
|
|
764
781
|
// parseDeclaration(parent.chi);
|
|
765
782
|
let i;
|
|
766
783
|
let nameIndex = -1;
|
|
767
784
|
let valueIndex = -1;
|
|
785
|
+
const dashedIdent = value.typ == EnumToken.FunctionTokenType && value.val == 'style';
|
|
768
786
|
for (let i = 0; i < value.chi.length; i++) {
|
|
769
787
|
if (value.chi[i].typ == EnumToken.CommentTokenType || value.chi[i].typ == EnumToken.WhitespaceTokenType) {
|
|
770
788
|
continue;
|
|
771
789
|
}
|
|
772
|
-
if (value.chi[i].typ == EnumToken.IdenTokenType) {
|
|
790
|
+
if ((dashedIdent && value.chi[i].typ == EnumToken.DashedIdenTokenType) || value.chi[i].typ == EnumToken.IdenTokenType || value.chi[i].typ == EnumToken.FunctionTokenType || value.chi[i].typ == EnumToken.ColorTokenType) {
|
|
773
791
|
nameIndex = i;
|
|
774
792
|
}
|
|
775
793
|
break;
|
|
@@ -798,6 +816,13 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
798
816
|
].includes(value.chi[valueIndex].typ)) {
|
|
799
817
|
const val = value.chi.splice(valueIndex, 1)[0];
|
|
800
818
|
const node = value.chi.splice(nameIndex, 1)[0];
|
|
819
|
+
// 'background'
|
|
820
|
+
// @ts-ignore
|
|
821
|
+
if (node.typ == EnumToken.ColorTokenType && node.kin == 'dpsys') {
|
|
822
|
+
// @ts-ignore
|
|
823
|
+
delete node.kin;
|
|
824
|
+
node.typ = EnumToken.IdenTokenType;
|
|
825
|
+
}
|
|
801
826
|
while (value.chi[0]?.typ == EnumToken.WhitespaceTokenType) {
|
|
802
827
|
value.chi.shift();
|
|
803
828
|
}
|
|
@@ -815,6 +840,10 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
815
840
|
}
|
|
816
841
|
return tokens;
|
|
817
842
|
}
|
|
843
|
+
/**
|
|
844
|
+
* parse selector
|
|
845
|
+
* @param tokens
|
|
846
|
+
*/
|
|
818
847
|
function parseSelector(tokens) {
|
|
819
848
|
for (const { value, previousValue, nextValue, parent } of walkValues(tokens)) {
|
|
820
849
|
if (value.typ == EnumToken.CommentTokenType ||
|
|
@@ -958,6 +987,11 @@ function parseSelector(tokens) {
|
|
|
958
987
|
//
|
|
959
988
|
// return doParse(`.x{${src}`, options).then((result: ParseResult) => <AstDeclaration[]>(<AstRule>result.ast.chi[0]).chi.filter(t => t.typ == EnumToken.DeclarationNodeType));
|
|
960
989
|
// }
|
|
990
|
+
/**
|
|
991
|
+
* parse string
|
|
992
|
+
* @param src
|
|
993
|
+
* @param options
|
|
994
|
+
*/
|
|
961
995
|
function parseString(src, options = { location: false }) {
|
|
962
996
|
return parseTokens([...tokenize(src)].map(t => {
|
|
963
997
|
const token = getTokenType(t.token, t.hint);
|
|
@@ -1039,7 +1073,7 @@ function getTokenType(val, hint) {
|
|
|
1039
1073
|
chi: []
|
|
1040
1074
|
};
|
|
1041
1075
|
}
|
|
1042
|
-
if (['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'conic-gradient', 'image', 'image-set', 'element', 'cross-fade'].includes(val)) {
|
|
1076
|
+
if (['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'conic-gradient', 'image', 'image-set', 'element', 'cross-fade', 'paint'].includes(val)) {
|
|
1043
1077
|
return {
|
|
1044
1078
|
typ: EnumToken.ImageFunctionTokenType,
|
|
1045
1079
|
val,
|
|
@@ -1139,6 +1173,11 @@ function getTokenType(val, hint) {
|
|
|
1139
1173
|
val
|
|
1140
1174
|
};
|
|
1141
1175
|
}
|
|
1176
|
+
/**
|
|
1177
|
+
* parse token list
|
|
1178
|
+
* @param tokens
|
|
1179
|
+
* @param options
|
|
1180
|
+
*/
|
|
1142
1181
|
function parseTokens(tokens, options = {}) {
|
|
1143
1182
|
for (let i = 0; i < tokens.length; i++) {
|
|
1144
1183
|
const t = tokens[i];
|
|
@@ -1474,4 +1513,4 @@ function parseTokens(tokens, options = {}) {
|
|
|
1474
1513
|
return tokens;
|
|
1475
1514
|
}
|
|
1476
1515
|
|
|
1477
|
-
export { doParse,
|
|
1516
|
+
export { doParse, parseSelector, parseString, parseTokens, urlTokenMatcher };
|
|
@@ -16,7 +16,13 @@ function consumeWhiteSpace(parseInfo) {
|
|
|
16
16
|
return count;
|
|
17
17
|
}
|
|
18
18
|
function pushToken(token, parseInfo, hint) {
|
|
19
|
-
const result = {
|
|
19
|
+
const result = {
|
|
20
|
+
token,
|
|
21
|
+
len: parseInfo.currentPosition.ind - parseInfo.position.ind,
|
|
22
|
+
hint,
|
|
23
|
+
position: { ...parseInfo.position },
|
|
24
|
+
bytesIn: parseInfo.currentPosition.ind + 1
|
|
25
|
+
};
|
|
20
26
|
parseInfo.position.ind = parseInfo.currentPosition.ind;
|
|
21
27
|
parseInfo.position.lin = parseInfo.currentPosition.lin;
|
|
22
28
|
parseInfo.position.col = Math.max(parseInfo.currentPosition.col, 1);
|
|
@@ -136,6 +142,10 @@ function next(parseInfo, count = 1) {
|
|
|
136
142
|
}
|
|
137
143
|
return char;
|
|
138
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* tokenize css string
|
|
147
|
+
* @param stream
|
|
148
|
+
*/
|
|
139
149
|
function* tokenize(stream) {
|
|
140
150
|
const parseInfo = {
|
|
141
151
|
stream,
|
|
@@ -184,8 +194,10 @@ function* tokenize(stream) {
|
|
|
184
194
|
buffer += value;
|
|
185
195
|
}
|
|
186
196
|
}
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
if (buffer.length > 0) {
|
|
198
|
+
yield pushToken(buffer, parseInfo, EnumToken.BadCommentTokenType);
|
|
199
|
+
buffer = '';
|
|
200
|
+
}
|
|
189
201
|
}
|
|
190
202
|
break;
|
|
191
203
|
case '&':
|
|
@@ -2,7 +2,7 @@ import { EnumToken } from '../../ast/types.js';
|
|
|
2
2
|
import '../../ast/minify.js';
|
|
3
3
|
import '../../ast/walk.js';
|
|
4
4
|
import '../../parser/parse.js';
|
|
5
|
-
import {
|
|
5
|
+
import { minmax, getNumber } from './color.js';
|
|
6
6
|
import { hsl2rgb, hwb2rgb, cmyk2rgb, oklab2rgb, oklch2rgb, lab2rgb, lch2rgb } from './rgb.js';
|
|
7
7
|
import { NAMES_COLORS } from './utils/constants.js';
|
|
8
8
|
import { getComponents } from './utils/components.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { hwb2hsv } from './hsv.js';
|
|
2
2
|
import { getNumber } from './color.js';
|
|
3
|
-
import {
|
|
3
|
+
import { lch2rgb, lab2rgb, oklch2rgb, oklab2rgb, hex2rgb } from './rgb.js';
|
|
4
4
|
import './utils/constants.js';
|
|
5
5
|
import { getComponents } from './utils/components.js';
|
|
6
6
|
import { EnumToken } from '../../ast/types.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { hsl2hsv } from './hsv.js';
|
|
2
2
|
import './utils/constants.js';
|
|
3
3
|
import { getComponents } from './utils/components.js';
|
|
4
|
-
import {
|
|
4
|
+
import { getAngle, getNumber } from './color.js';
|
|
5
5
|
import { EnumToken } from '../../ast/types.js';
|
|
6
6
|
import '../../ast/minify.js';
|
|
7
7
|
import '../../ast/walk.js';
|
|
8
8
|
import '../../parser/parse.js';
|
|
9
|
-
import { lab2srgb,
|
|
9
|
+
import { lch2srgb, lab2srgb, oklch2srgb, oklab2srgb } from './srgb.js';
|
|
10
10
|
import '../sourcemap/lib/encode.js';
|
|
11
11
|
import '../../parser/utils/config.js';
|
|
12
12
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { e, k, D50 } from './utils/constants.js';
|
|
2
2
|
import { getComponents } from './utils/components.js';
|
|
3
3
|
import { srgb2xyz, xyzd502srgb } from './xyz.js';
|
|
4
|
-
import {
|
|
4
|
+
import { oklch2srgb, hwb2srgb, hsl2srgb, rgb2srgb, hex2srgb } from './srgb.js';
|
|
5
5
|
import { getLCHComponents } from './lch.js';
|
|
6
6
|
import { OKLab_to_XYZ, getOKLABComponents } from './oklab.js';
|
|
7
7
|
import { getNumber } from './color.js';
|
|
@@ -5,7 +5,7 @@ import { EnumToken } from '../../ast/types.js';
|
|
|
5
5
|
import '../../ast/minify.js';
|
|
6
6
|
import '../../ast/walk.js';
|
|
7
7
|
import '../../parser/parse.js';
|
|
8
|
-
import { srgb2lab, xyz2lab,
|
|
8
|
+
import { srgb2lab, xyz2lab, oklch2lab, oklab2lab, getLABComponents, hwb2lab, hsl2lab, rgb2lab, hex2lab } from './lab.js';
|
|
9
9
|
import '../sourcemap/lib/encode.js';
|
|
10
10
|
import '../../parser/utils/config.js';
|
|
11
11
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { multiplyMatrices } from './utils/matrix.js';
|
|
2
2
|
import './utils/constants.js';
|
|
3
3
|
import { getComponents } from './utils/components.js';
|
|
4
|
-
import { srgb2lsrgbvalues,
|
|
4
|
+
import { srgb2lsrgbvalues, lch2srgb, lab2srgb, hwb2srgb, hsl2srgb, rgb2srgb, hex2srgb, lsrgb2srgbvalues } from './srgb.js';
|
|
5
5
|
import { getNumber } from './color.js';
|
|
6
6
|
import { EnumToken } from '../../ast/types.js';
|
|
7
7
|
import '../../ast/minify.js';
|
|
@@ -106,7 +106,7 @@ function OKLab_to_sRGB(l, a, b) {
|
|
|
106
106
|
1.2914855378640917399 * b, 3);
|
|
107
107
|
return lsrgb2srgbvalues(
|
|
108
108
|
/* r: */
|
|
109
|
-
|
|
109
|
+
4.076741661347994 * L -
|
|
110
110
|
3.307711590408193 * M +
|
|
111
111
|
0.230969928729428 * S,
|
|
112
112
|
/* g: */
|
|
@@ -6,7 +6,7 @@ import '../../ast/minify.js';
|
|
|
6
6
|
import '../../ast/walk.js';
|
|
7
7
|
import '../../parser/parse.js';
|
|
8
8
|
import { lab2lchvalues } from './lch.js';
|
|
9
|
-
import { srgb2oklab,
|
|
9
|
+
import { srgb2oklab, lch2oklab, getOKLABComponents, lab2oklab, hwb2oklab, hsl2oklab, rgb2oklab, hex2oklab } from './oklab.js';
|
|
10
10
|
import '../sourcemap/lib/encode.js';
|
|
11
11
|
import '../../parser/utils/config.js';
|
|
12
12
|
|
|
@@ -5,7 +5,7 @@ import '../../ast/minify.js';
|
|
|
5
5
|
import '../../ast/walk.js';
|
|
6
6
|
import '../../parser/parse.js';
|
|
7
7
|
import { expandHexValue } from './hex.js';
|
|
8
|
-
import {
|
|
8
|
+
import { hslvalues, hsl2srgbvalues, hwb2srgb, cmyk2srgb, oklab2srgb, oklch2srgb, lab2srgb, lch2srgb } from './srgb.js';
|
|
9
9
|
import '../sourcemap/lib/encode.js';
|
|
10
10
|
import '../../parser/utils/config.js';
|
|
11
11
|
|
|
@@ -6,8 +6,8 @@ import '../../ast/minify.js';
|
|
|
6
6
|
import '../../ast/walk.js';
|
|
7
7
|
import '../../parser/parse.js';
|
|
8
8
|
import { expandHexValue } from './hex.js';
|
|
9
|
-
import { lch2labvalues,
|
|
10
|
-
import {
|
|
9
|
+
import { lch2labvalues, Lab_to_sRGB, getLABComponents } from './lab.js';
|
|
10
|
+
import { OKLab_to_sRGB, getOKLABComponents } from './oklab.js';
|
|
11
11
|
import { getLCHComponents } from './lch.js';
|
|
12
12
|
import { getOKLCHComponents } from './oklch.js';
|
|
13
13
|
import { XYZ_to_lin_sRGB } from './xyz.js';
|
|
@@ -28,7 +28,7 @@ const colorRange = {
|
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
const colorFuncColorSpace = ['srgb', 'srgb-linear', 'display-p3', 'prophoto-rgb', 'a98-rgb', 'rec2020', 'xyz', 'xyz-d65', 'xyz-d50'];
|
|
31
|
-
({ typ: EnumToken.IdenTokenType
|
|
31
|
+
({ typ: EnumToken.IdenTokenType});
|
|
32
32
|
const D50 = [0.3457 / 0.3585, 1.00000, (1.0 - 0.3457 - 0.3585) / 0.3585];
|
|
33
33
|
const k = Math.pow(29, 3) / Math.pow(3, 3);
|
|
34
34
|
const e = Math.pow(6, 3) / Math.pow(29, 3);
|
|
@@ -4,7 +4,7 @@ import '../../ast/types.js';
|
|
|
4
4
|
import '../../ast/minify.js';
|
|
5
5
|
import '../../ast/walk.js';
|
|
6
6
|
import '../../parser/parse.js';
|
|
7
|
-
import {
|
|
7
|
+
import { srgb2lsrgbvalues, lsrgb2srgbvalues } from './srgb.js';
|
|
8
8
|
import '../sourcemap/lib/encode.js';
|
|
9
9
|
import '../../parser/utils/config.js';
|
|
10
10
|
|
|
@@ -41,17 +41,27 @@ function update(position, str) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* render ast
|
|
46
|
+
* @param data
|
|
47
|
+
* @param options
|
|
48
|
+
*/
|
|
44
49
|
function doRender(data, options = {}) {
|
|
50
|
+
const minify = options.minify ?? true;
|
|
51
|
+
const beautify = options.beautify ?? !minify;
|
|
45
52
|
options = {
|
|
46
|
-
...(
|
|
53
|
+
...(beautify ? {
|
|
54
|
+
indent: ' ',
|
|
55
|
+
newLine: '\n',
|
|
56
|
+
} : {
|
|
47
57
|
indent: '',
|
|
48
58
|
newLine: '',
|
|
59
|
+
}),
|
|
60
|
+
...(minify ? {
|
|
49
61
|
removeEmpty: true,
|
|
50
62
|
removeComments: true
|
|
51
63
|
} : {
|
|
52
|
-
|
|
53
|
-
newLine: '\n',
|
|
54
|
-
compress: false,
|
|
64
|
+
removeEmpty: false,
|
|
55
65
|
removeComments: false,
|
|
56
66
|
}), sourcemap: false, convertColor: true, expandNestingRules: false, preserveLicense: false, ...options
|
|
57
67
|
};
|
|
@@ -119,7 +129,18 @@ function updateSourceMap(node, options, cache, sourcemap, position, str) {
|
|
|
119
129
|
}
|
|
120
130
|
update(position, str);
|
|
121
131
|
}
|
|
122
|
-
|
|
132
|
+
/**
|
|
133
|
+
* render ast node
|
|
134
|
+
* @param data
|
|
135
|
+
* @param options
|
|
136
|
+
* @param sourcemap
|
|
137
|
+
* @param position
|
|
138
|
+
* @param errors
|
|
139
|
+
* @param reducer
|
|
140
|
+
* @param cache
|
|
141
|
+
* @param level
|
|
142
|
+
* @param indents
|
|
143
|
+
*/
|
|
123
144
|
function renderAstNode(data, options, sourcemap, position, errors, reducer, cache, level = 0, indents = []) {
|
|
124
145
|
if (indents.length < level + 1) {
|
|
125
146
|
indents.push(options.indent.repeat(level));
|
|
@@ -212,8 +233,15 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
|
|
|
212
233
|
// return renderToken(data as Token, options, cache, reducer, errors);
|
|
213
234
|
throw new Error(`render: unexpected token ${JSON.stringify(data, null, 1)}`);
|
|
214
235
|
}
|
|
215
|
-
return '';
|
|
216
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* render ast token
|
|
239
|
+
* @param token
|
|
240
|
+
* @param options
|
|
241
|
+
* @param cache
|
|
242
|
+
* @param reducer
|
|
243
|
+
* @param errors
|
|
244
|
+
*/
|
|
217
245
|
function renderToken(token, options = {}, cache = Object.create(null), reducer, errors) {
|
|
218
246
|
if (reducer == null) {
|
|
219
247
|
reducer = function (acc, curr) {
|