@tbela99/css-parser 0.9.1 → 1.1.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 +265 -0
- package/LICENSE.md +1 -1
- package/README.md +29 -17
- package/dist/index-umd-web.js +7461 -4360
- package/dist/index.cjs +8608 -5507
- package/dist/index.d.ts +203 -61
- package/dist/lib/ast/expand.js +2 -1
- package/dist/lib/ast/features/calc.js +19 -11
- package/dist/lib/ast/features/index.js +1 -0
- package/dist/lib/ast/features/inlinecssvariables.js +47 -29
- package/dist/lib/ast/features/prefix.js +117 -91
- package/dist/lib/ast/features/shorthand.js +34 -14
- package/dist/lib/ast/features/transform.js +67 -0
- package/dist/lib/ast/features/type.js +7 -0
- package/dist/lib/ast/math/expression.js +20 -10
- package/dist/lib/ast/math/math.js +20 -2
- package/dist/lib/ast/minify.js +209 -80
- package/dist/lib/ast/transform/compute.js +337 -0
- package/dist/lib/ast/transform/convert.js +33 -0
- package/dist/lib/ast/transform/matrix.js +112 -0
- package/dist/lib/ast/transform/minify.js +296 -0
- package/dist/lib/ast/transform/perspective.js +10 -0
- package/dist/lib/ast/transform/rotate.js +40 -0
- package/dist/lib/ast/transform/scale.js +32 -0
- package/dist/lib/ast/transform/skew.js +23 -0
- package/dist/lib/ast/transform/translate.js +32 -0
- package/dist/lib/ast/transform/utils.js +198 -0
- package/dist/lib/ast/types.js +18 -15
- package/dist/lib/ast/walk.js +54 -22
- package/dist/lib/fs/resolve.js +10 -0
- package/dist/lib/parser/declaration/list.js +48 -45
- package/dist/lib/parser/declaration/map.js +1 -0
- package/dist/lib/parser/declaration/set.js +2 -1
- package/dist/lib/parser/parse.js +449 -340
- package/dist/lib/parser/tokenize.js +147 -72
- package/dist/lib/parser/utils/declaration.js +5 -4
- package/dist/lib/parser/utils/type.js +2 -1
- package/dist/lib/renderer/color/a98rgb.js +2 -1
- package/dist/lib/renderer/color/{colormix.js → color-mix.js} +16 -7
- package/dist/lib/renderer/color/color.js +264 -170
- package/dist/lib/renderer/color/hex.js +19 -8
- package/dist/lib/renderer/color/hsl.js +9 -3
- package/dist/lib/renderer/color/hwb.js +2 -1
- package/dist/lib/renderer/color/lab.js +10 -1
- package/dist/lib/renderer/color/lch.js +10 -1
- package/dist/lib/renderer/color/oklab.js +10 -1
- package/dist/lib/renderer/color/oklch.js +10 -1
- package/dist/lib/renderer/color/p3.js +2 -1
- package/dist/lib/renderer/color/rec2020.js +2 -1
- package/dist/lib/renderer/color/relativecolor.js +27 -32
- package/dist/lib/renderer/color/rgb.js +14 -10
- package/dist/lib/renderer/color/srgb.js +48 -23
- package/dist/lib/renderer/color/utils/components.js +18 -6
- package/dist/lib/renderer/color/utils/constants.js +47 -3
- package/dist/lib/renderer/color/xyz.js +2 -1
- package/dist/lib/renderer/color/xyzd50.js +2 -1
- package/dist/lib/renderer/render.js +108 -43
- package/dist/lib/syntax/syntax.js +267 -136
- package/dist/lib/validation/at-rules/container.js +81 -103
- package/dist/lib/validation/at-rules/counter-style.js +9 -8
- package/dist/lib/validation/at-rules/custom-media.js +13 -15
- package/dist/lib/validation/at-rules/document.js +22 -27
- package/dist/lib/validation/at-rules/font-feature-values.js +8 -8
- package/dist/lib/validation/at-rules/import.js +30 -81
- package/dist/lib/validation/at-rules/keyframes.js +19 -23
- package/dist/lib/validation/at-rules/layer.js +5 -5
- package/dist/lib/validation/at-rules/media.js +42 -53
- package/dist/lib/validation/at-rules/namespace.js +19 -23
- package/dist/lib/validation/at-rules/page-margin-box.js +15 -18
- package/dist/lib/validation/at-rules/page.js +8 -7
- package/dist/lib/validation/at-rules/supports.js +73 -82
- package/dist/lib/validation/at-rules/when.js +32 -36
- package/dist/lib/validation/atrule.js +15 -18
- package/dist/lib/validation/config.js +24 -1
- package/dist/lib/validation/config.json.js +563 -63
- package/dist/lib/validation/parser/parse.js +196 -185
- package/dist/lib/validation/parser/types.js +1 -1
- package/dist/lib/validation/selector.js +8 -5
- package/dist/lib/validation/syntax.js +724 -1405
- package/dist/lib/validation/syntaxes/complex-selector-list.js +10 -11
- package/dist/lib/validation/syntaxes/complex-selector.js +10 -11
- package/dist/lib/validation/syntaxes/compound-selector.js +40 -50
- package/dist/lib/validation/syntaxes/family-name.js +9 -8
- package/dist/lib/validation/syntaxes/keyframe-block-list.js +6 -5
- package/dist/lib/validation/syntaxes/keyframe-selector.js +23 -105
- package/dist/lib/validation/syntaxes/layer-name.js +6 -5
- package/dist/lib/validation/syntaxes/relative-selector-list.js +7 -6
- package/dist/lib/validation/syntaxes/relative-selector.js +17 -15
- package/dist/lib/validation/syntaxes/url.js +18 -22
- package/dist/lib/validation/utils/list.js +20 -2
- package/dist/lib/validation/utils/whitespace.js +2 -1
- package/dist/node/index.js +4 -2
- package/dist/node/load.js +6 -1
- package/dist/web/index.js +4 -2
- package/dist/web/load.js +5 -0
- package/package.json +16 -15
- package/dist/lib/renderer/color/prophotoRgb.js +0 -56
- package/dist/lib/validation/declaration.js +0 -94
- package/dist/lib/validation/syntaxes/image.js +0 -29
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isColor, parseColor, isIdent, mediaTypes, isDimension, parseDimension, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isHexColor, isHash, isIdentStart, isIdentColor, mathFuncs } from '../syntax/syntax.js';
|
|
2
2
|
import './utils/config.js';
|
|
3
|
-
import { EnumToken,
|
|
3
|
+
import { EnumToken, ValidationLevel, SyntaxValidationResult } from '../ast/types.js';
|
|
4
4
|
import { minify, definedPropertySettings, combinators } from '../ast/minify.js';
|
|
5
|
-
import { walkValues, walk } from '../ast/walk.js';
|
|
5
|
+
import { walkValues, walk, WalkerOptionEnum } from '../ast/walk.js';
|
|
6
6
|
import { expand } from '../ast/expand.js';
|
|
7
7
|
import { parseDeclarationNode } from './utils/declaration.js';
|
|
8
8
|
import { renderToken } from '../renderer/render.js';
|
|
9
|
-
import { COLORS_NAMES, systemColors, deprecatedSystemColors } from '../renderer/color/utils/constants.js';
|
|
9
|
+
import { funcLike, ColorKind, COLORS_NAMES, systemColors, deprecatedSystemColors, colorsFunc } from '../renderer/color/utils/constants.js';
|
|
10
|
+
import { buildExpression } from '../ast/math/expression.js';
|
|
10
11
|
import { tokenize } from './tokenize.js';
|
|
11
12
|
import '../validation/config.js';
|
|
12
13
|
import '../validation/parser/types.js';
|
|
13
14
|
import '../validation/parser/parse.js';
|
|
14
15
|
import { validateSelector } from '../validation/selector.js';
|
|
15
16
|
import { validateAtRule } from '../validation/atrule.js';
|
|
17
|
+
import { splitTokenList } from '../validation/utils/list.js';
|
|
16
18
|
import '../validation/syntaxes/complex-selector.js';
|
|
19
|
+
import { validateKeyframeSelector } from '../validation/syntaxes/keyframe-selector.js';
|
|
20
|
+
import { evaluateSyntax } from '../validation/syntax.js';
|
|
21
|
+
import { validateAtRuleKeyframes } from '../validation/at-rules/keyframes.js';
|
|
17
22
|
|
|
18
23
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
19
24
|
const trimWhiteSpace = [EnumToken.CommentTokenType, EnumToken.GtTokenType, EnumToken.GteTokenType, EnumToken.LtTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType];
|
|
@@ -48,21 +53,25 @@ async function doParse(iterator, options = {}) {
|
|
|
48
53
|
minify: true,
|
|
49
54
|
pass: 1,
|
|
50
55
|
parseColor: true,
|
|
51
|
-
nestingRules:
|
|
56
|
+
nestingRules: true,
|
|
52
57
|
resolveImport: false,
|
|
53
58
|
resolveUrls: false,
|
|
54
59
|
removeCharset: true,
|
|
55
60
|
removeEmpty: true,
|
|
56
61
|
removeDuplicateDeclarations: true,
|
|
62
|
+
computeTransform: true,
|
|
57
63
|
computeShorthand: true,
|
|
58
64
|
computeCalcExpression: true,
|
|
59
65
|
inlineCssVariables: false,
|
|
60
66
|
setParent: true,
|
|
61
67
|
removePrefix: false,
|
|
62
|
-
validation:
|
|
68
|
+
validation: ValidationLevel.Default,
|
|
63
69
|
lenient: true,
|
|
64
70
|
...options
|
|
65
71
|
};
|
|
72
|
+
if (typeof options.validation == 'boolean') {
|
|
73
|
+
options.validation = options.validation ? ValidationLevel.All : ValidationLevel.None;
|
|
74
|
+
}
|
|
66
75
|
if (options.expandNestingRules) {
|
|
67
76
|
options.nestingRules = false;
|
|
68
77
|
}
|
|
@@ -94,16 +103,22 @@ async function doParse(iterator, options = {}) {
|
|
|
94
103
|
lin: 1,
|
|
95
104
|
col: 1
|
|
96
105
|
},
|
|
106
|
+
end: {
|
|
107
|
+
ind: 0,
|
|
108
|
+
lin: 1,
|
|
109
|
+
col: 1
|
|
110
|
+
},
|
|
97
111
|
src: ''
|
|
98
112
|
};
|
|
99
113
|
}
|
|
100
114
|
const iter = tokenize(iterator);
|
|
101
115
|
let item;
|
|
116
|
+
let node;
|
|
102
117
|
const rawTokens = [];
|
|
118
|
+
const imports = [];
|
|
103
119
|
while (item = iter.next().value) {
|
|
104
120
|
stats.bytesIn = item.bytesIn;
|
|
105
121
|
rawTokens.push(item);
|
|
106
|
-
// doParse error
|
|
107
122
|
if (item.hint != null && BadTokensTypes.includes(item.hint)) {
|
|
108
123
|
// bad token
|
|
109
124
|
continue;
|
|
@@ -111,22 +126,33 @@ async function doParse(iterator, options = {}) {
|
|
|
111
126
|
if (item.hint != EnumToken.EOFTokenType) {
|
|
112
127
|
tokens.push(item);
|
|
113
128
|
}
|
|
129
|
+
else if (ast.loc != null) {
|
|
130
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
131
|
+
stack[i].loc.end = { ...item.end };
|
|
132
|
+
}
|
|
133
|
+
ast.loc.end = item.end;
|
|
134
|
+
}
|
|
114
135
|
if (item.token == ';' || item.token == '{') {
|
|
115
|
-
|
|
136
|
+
node = parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
116
137
|
rawTokens.length = 0;
|
|
117
138
|
if (node != null) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
139
|
+
if ('chi' in node) {
|
|
140
|
+
stack.push(node);
|
|
141
|
+
context = node;
|
|
142
|
+
}
|
|
143
|
+
else if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'import') {
|
|
144
|
+
imports.push(node);
|
|
145
|
+
}
|
|
122
146
|
}
|
|
123
147
|
else if (item.token == '{') {
|
|
124
148
|
let inBlock = 1;
|
|
149
|
+
tokens = [item];
|
|
125
150
|
do {
|
|
126
151
|
item = iter.next().value;
|
|
127
152
|
if (item == null) {
|
|
128
153
|
break;
|
|
129
154
|
}
|
|
155
|
+
tokens.push(item);
|
|
130
156
|
if (item.token == '{') {
|
|
131
157
|
inBlock++;
|
|
132
158
|
}
|
|
@@ -134,28 +160,32 @@ async function doParse(iterator, options = {}) {
|
|
|
134
160
|
inBlock--;
|
|
135
161
|
}
|
|
136
162
|
} while (inBlock != 0);
|
|
163
|
+
if (tokens.length > 0) {
|
|
164
|
+
errors.push({
|
|
165
|
+
action: 'drop',
|
|
166
|
+
message: 'invalid block',
|
|
167
|
+
rawTokens: tokens.slice()
|
|
168
|
+
});
|
|
169
|
+
}
|
|
137
170
|
}
|
|
138
171
|
tokens = [];
|
|
139
172
|
map = new Map;
|
|
140
173
|
}
|
|
141
174
|
else if (item.token == '}') {
|
|
142
|
-
|
|
175
|
+
parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
143
176
|
rawTokens.length = 0;
|
|
177
|
+
if (context.loc != null) {
|
|
178
|
+
context.loc.end = item.end;
|
|
179
|
+
}
|
|
144
180
|
const previousNode = stack.pop();
|
|
145
|
-
|
|
146
|
-
context = stack[stack.length - 1] ?? ast;
|
|
147
|
-
// @ts-ignore
|
|
181
|
+
context = (stack[stack.length - 1] ?? ast);
|
|
148
182
|
if (previousNode != null && previousNode.typ == EnumToken.InvalidRuleTokenType) {
|
|
149
|
-
// @ts-ignore
|
|
150
183
|
const index = context.chi.findIndex(node => node == previousNode);
|
|
151
184
|
if (index > -1) {
|
|
152
|
-
// @ts-ignore
|
|
153
185
|
context.chi.splice(index, 1);
|
|
154
186
|
}
|
|
155
187
|
}
|
|
156
|
-
// @ts-ignore
|
|
157
188
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
158
|
-
// @ts-ignore
|
|
159
189
|
context.chi.pop();
|
|
160
190
|
}
|
|
161
191
|
tokens = [];
|
|
@@ -163,23 +193,56 @@ async function doParse(iterator, options = {}) {
|
|
|
163
193
|
}
|
|
164
194
|
}
|
|
165
195
|
if (tokens.length > 0) {
|
|
166
|
-
|
|
196
|
+
node = parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
|
|
167
197
|
rawTokens.length = 0;
|
|
198
|
+
if (node != null) {
|
|
199
|
+
if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'import') {
|
|
200
|
+
imports.push(node);
|
|
201
|
+
}
|
|
202
|
+
else if ('chi' in node && node.typ != EnumToken.InvalidRuleTokenType) {
|
|
203
|
+
stack.push(node);
|
|
204
|
+
context = node;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
168
207
|
if (context != null && context.typ == EnumToken.InvalidRuleTokenType) {
|
|
208
|
+
// @ts-ignore
|
|
169
209
|
const index = context.chi.findIndex((node) => node == context);
|
|
170
210
|
if (index > -1) {
|
|
171
211
|
context.chi.splice(index, 1);
|
|
172
212
|
}
|
|
173
213
|
}
|
|
174
214
|
}
|
|
215
|
+
if (imports.length > 0 && options.resolveImport) {
|
|
216
|
+
await Promise.all(imports.map(async (node) => {
|
|
217
|
+
const token = node.tokens[0];
|
|
218
|
+
const url = token.typ == EnumToken.StringTokenType ? token.val.slice(1, -1) : token.val;
|
|
219
|
+
try {
|
|
220
|
+
const root = await options.load(url, options.src).then((src) => {
|
|
221
|
+
// console.error({url, src: options.src, resolved: options.resolve!(url, options.src as string)})
|
|
222
|
+
return doParse(src, Object.assign({}, options, {
|
|
223
|
+
minify: false,
|
|
224
|
+
setParent: false,
|
|
225
|
+
src: options.resolve(url, options.src).absolute
|
|
226
|
+
}));
|
|
227
|
+
});
|
|
228
|
+
stats.importedBytesIn += root.stats.bytesIn;
|
|
229
|
+
node.parent.chi.splice(node.parent.chi.indexOf(node), 1, ...root.ast.chi);
|
|
230
|
+
if (root.errors.length > 0) {
|
|
231
|
+
errors.push(...root.errors);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
// console.error(error);
|
|
236
|
+
// @ts-ignore
|
|
237
|
+
errors.push({ action: 'ignore', message: 'doParse: ' + error.message, error });
|
|
238
|
+
}
|
|
239
|
+
}));
|
|
240
|
+
}
|
|
175
241
|
while (stack.length > 0 && context != ast) {
|
|
176
242
|
const previousNode = stack.pop();
|
|
177
|
-
|
|
178
|
-
context = stack[stack.length - 1] ?? ast;
|
|
243
|
+
context = (stack[stack.length - 1] ?? ast);
|
|
179
244
|
// remove empty nodes
|
|
180
|
-
// @ts-ignore
|
|
181
245
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
182
|
-
// @ts-ignore
|
|
183
246
|
context.chi.pop();
|
|
184
247
|
continue;
|
|
185
248
|
}
|
|
@@ -192,14 +255,12 @@ async function doParse(iterator, options = {}) {
|
|
|
192
255
|
if (options.visitor != null) {
|
|
193
256
|
for (const result of walk(ast)) {
|
|
194
257
|
if (result.node.typ == EnumToken.DeclarationNodeType &&
|
|
195
|
-
// @ts-ignore
|
|
196
258
|
(typeof options.visitor.Declaration == 'function' || options.visitor.Declaration?.[result.node.nam] != null)) {
|
|
197
259
|
const callable = typeof options.visitor.Declaration == 'function' ? options.visitor.Declaration : options.visitor.Declaration[result.node.nam];
|
|
198
260
|
const results = await callable(result.node);
|
|
199
261
|
if (results == null || (Array.isArray(results) && results.length == 0)) {
|
|
200
262
|
continue;
|
|
201
263
|
}
|
|
202
|
-
// @ts-ignore
|
|
203
264
|
result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
|
|
204
265
|
}
|
|
205
266
|
else if (options.visitor.Rule != null && result.node.typ == EnumToken.RuleNodeType) {
|
|
@@ -207,7 +268,6 @@ async function doParse(iterator, options = {}) {
|
|
|
207
268
|
if (results == null || (Array.isArray(results) && results.length == 0)) {
|
|
208
269
|
continue;
|
|
209
270
|
}
|
|
210
|
-
// @ts-ignore
|
|
211
271
|
result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
|
|
212
272
|
}
|
|
213
273
|
else if (options.visitor.AtRule != null &&
|
|
@@ -219,7 +279,6 @@ async function doParse(iterator, options = {}) {
|
|
|
219
279
|
if (results == null || (Array.isArray(results) && results.length == 0)) {
|
|
220
280
|
continue;
|
|
221
281
|
}
|
|
222
|
-
// @ts-ignore
|
|
223
282
|
result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
|
|
224
283
|
}
|
|
225
284
|
}
|
|
@@ -258,30 +317,27 @@ function getLastNode(context) {
|
|
|
258
317
|
}
|
|
259
318
|
return null;
|
|
260
319
|
}
|
|
261
|
-
|
|
320
|
+
function parseNode(results, context, stats, options, errors, src, map, rawTokens) {
|
|
262
321
|
let tokens = [];
|
|
263
322
|
for (const t of results) {
|
|
264
323
|
const node = getTokenType(t.token, t.hint);
|
|
265
|
-
map.set(node, t.
|
|
324
|
+
map.set(node, { sta: t.sta, end: t.end, src });
|
|
266
325
|
tokens.push(node);
|
|
267
326
|
}
|
|
268
327
|
let i;
|
|
269
328
|
let loc;
|
|
270
329
|
for (i = 0; i < tokens.length; i++) {
|
|
271
330
|
if (tokens[i].typ == EnumToken.CommentTokenType || tokens[i].typ == EnumToken.CDOCOMMTokenType) {
|
|
272
|
-
const
|
|
331
|
+
const location = map.get(tokens[i]);
|
|
273
332
|
if (tokens[i].typ == EnumToken.CDOCOMMTokenType && context.typ != EnumToken.StyleSheetNodeType) {
|
|
274
333
|
errors.push({
|
|
275
334
|
action: 'drop',
|
|
276
335
|
message: `CDOCOMM not allowed here ${JSON.stringify(tokens[i], null, 1)}`,
|
|
277
|
-
location
|
|
336
|
+
location
|
|
278
337
|
});
|
|
279
338
|
continue;
|
|
280
339
|
}
|
|
281
|
-
loc =
|
|
282
|
-
sta: position,
|
|
283
|
-
src
|
|
284
|
-
};
|
|
340
|
+
loc = location;
|
|
285
341
|
// @ts-ignore
|
|
286
342
|
context.chi.push(tokens[i]);
|
|
287
343
|
if (options.sourcemap) {
|
|
@@ -300,10 +356,6 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
300
356
|
if (delim.typ == EnumToken.SemiColonTokenType || delim.typ == EnumToken.BlockStartTokenType || delim.typ == EnumToken.BlockEndTokenType) {
|
|
301
357
|
tokens.pop();
|
|
302
358
|
}
|
|
303
|
-
else {
|
|
304
|
-
delim = { typ: EnumToken.SemiColonTokenType };
|
|
305
|
-
}
|
|
306
|
-
// @ts-ignore
|
|
307
359
|
while ([EnumToken.WhitespaceTokenType, EnumToken.BadStringTokenType, EnumToken.BadCommentTokenType].includes(tokens.at(-1)?.typ)) {
|
|
308
360
|
tokens.pop();
|
|
309
361
|
}
|
|
@@ -312,11 +364,12 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
312
364
|
}
|
|
313
365
|
if (tokens[0]?.typ == EnumToken.AtRuleTokenType) {
|
|
314
366
|
const atRule = tokens.shift();
|
|
315
|
-
const
|
|
367
|
+
const location = map.get(atRule);
|
|
316
368
|
// @ts-ignore
|
|
317
369
|
while ([EnumToken.WhitespaceTokenType].includes(tokens[0]?.typ)) {
|
|
318
370
|
tokens.shift();
|
|
319
371
|
}
|
|
372
|
+
rawTokens.shift();
|
|
320
373
|
if (atRule.val == 'import') {
|
|
321
374
|
// only @charset and @layer are accepted before @import
|
|
322
375
|
// @ts-ignore
|
|
@@ -334,14 +387,14 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
334
387
|
if (!(type == EnumToken.InvalidAtRuleTokenType &&
|
|
335
388
|
// @ts-ignore
|
|
336
389
|
['charset', 'layer', 'import'].includes(context.chi[i].nam))) {
|
|
337
|
-
errors.push({ action: 'drop', message: 'invalid @import', location
|
|
390
|
+
errors.push({ action: 'drop', message: 'invalid @import', location });
|
|
338
391
|
return null;
|
|
339
392
|
}
|
|
340
393
|
}
|
|
341
394
|
// @ts-ignore
|
|
342
395
|
const name = context.chi[i].nam;
|
|
343
396
|
if (name != 'charset' && name != 'import' && name != 'layer') {
|
|
344
|
-
errors.push({ action: 'drop', message: 'invalid @import', location
|
|
397
|
+
errors.push({ action: 'drop', message: 'invalid @import', location });
|
|
345
398
|
return null;
|
|
346
399
|
}
|
|
347
400
|
break;
|
|
@@ -352,7 +405,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
352
405
|
errors.push({
|
|
353
406
|
action: 'drop',
|
|
354
407
|
message: 'doParse: invalid @import',
|
|
355
|
-
location
|
|
408
|
+
location
|
|
356
409
|
});
|
|
357
410
|
return null;
|
|
358
411
|
}
|
|
@@ -361,7 +414,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
361
414
|
errors.push({
|
|
362
415
|
action: 'drop',
|
|
363
416
|
message: 'doParse: invalid @import',
|
|
364
|
-
location
|
|
417
|
+
location
|
|
365
418
|
});
|
|
366
419
|
return null;
|
|
367
420
|
}
|
|
@@ -387,37 +440,6 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
387
440
|
}
|
|
388
441
|
}
|
|
389
442
|
}
|
|
390
|
-
// @ts-ignore
|
|
391
|
-
if (tokens[0].typ == EnumToken.StringTokenType) {
|
|
392
|
-
if (options.resolveImport) {
|
|
393
|
-
const url = tokens[0].val.slice(1, -1);
|
|
394
|
-
try {
|
|
395
|
-
// @ts-ignore
|
|
396
|
-
const root = await options.load(url, options.src).then((src) => {
|
|
397
|
-
return doParse(src, Object.assign({}, options, {
|
|
398
|
-
minify: false,
|
|
399
|
-
setParent: false,
|
|
400
|
-
// @ts-ignore
|
|
401
|
-
src: options.resolve(url, options.src).absolute
|
|
402
|
-
}));
|
|
403
|
-
});
|
|
404
|
-
stats.importedBytesIn += root.stats.bytesIn;
|
|
405
|
-
if (root.ast.chi.length > 0) {
|
|
406
|
-
// @todo - filter charset, layer and scope
|
|
407
|
-
// @ts-ignore
|
|
408
|
-
context.chi.push(...root.ast.chi);
|
|
409
|
-
}
|
|
410
|
-
if (root.errors.length > 0) {
|
|
411
|
-
errors.push(...root.errors);
|
|
412
|
-
}
|
|
413
|
-
return null;
|
|
414
|
-
}
|
|
415
|
-
catch (error) {
|
|
416
|
-
// @ts-ignore
|
|
417
|
-
errors.push({ action: 'ignore', message: 'doParse: ' + error.message, error });
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
443
|
}
|
|
422
444
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
423
445
|
// allowed nesting at-rules
|
|
@@ -425,7 +447,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
425
447
|
if (atRule.val == 'charset') {
|
|
426
448
|
let spaces = 0;
|
|
427
449
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/@charset
|
|
428
|
-
for (let k =
|
|
450
|
+
for (let k = 0; k < rawTokens.length; k++) {
|
|
429
451
|
if (rawTokens[k].hint == EnumToken.WhitespaceTokenType) {
|
|
430
452
|
spaces += rawTokens[k].len;
|
|
431
453
|
continue;
|
|
@@ -441,7 +463,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
441
463
|
action: 'drop',
|
|
442
464
|
message: '@charset must have only one space',
|
|
443
465
|
// @ts-ignore
|
|
444
|
-
location
|
|
466
|
+
location
|
|
445
467
|
});
|
|
446
468
|
return null;
|
|
447
469
|
}
|
|
@@ -449,8 +471,7 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
449
471
|
errors.push({
|
|
450
472
|
action: 'drop',
|
|
451
473
|
message: '@charset expects a "<charset>"',
|
|
452
|
-
|
|
453
|
-
location: { src, ...(map.get(atRule) ?? position) }
|
|
474
|
+
location
|
|
454
475
|
});
|
|
455
476
|
return null;
|
|
456
477
|
}
|
|
@@ -465,134 +486,127 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
465
486
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
466
487
|
return acc;
|
|
467
488
|
}, []);
|
|
489
|
+
const nam = renderToken(atRule, { removeComments: true });
|
|
490
|
+
// @ts-ignore
|
|
468
491
|
const node = {
|
|
469
|
-
typ: EnumToken.AtRuleNodeType,
|
|
470
|
-
nam
|
|
471
|
-
// tokens: t,
|
|
492
|
+
typ: /^(-[a-z]+-)?keyframes$/.test(nam) ? EnumToken.KeyframeAtRuleNodeType : EnumToken.AtRuleNodeType,
|
|
493
|
+
nam,
|
|
472
494
|
val: raw.join('')
|
|
473
495
|
};
|
|
474
496
|
Object.defineProperties(node, {
|
|
475
|
-
tokens: { ...definedPropertySettings, enumerable: false, value:
|
|
497
|
+
tokens: { ...definedPropertySettings, enumerable: false, value: t.slice() },
|
|
476
498
|
raw: { ...definedPropertySettings, value: raw }
|
|
477
499
|
});
|
|
478
500
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
479
501
|
node.chi = [];
|
|
480
502
|
}
|
|
481
|
-
loc =
|
|
482
|
-
sta: position,
|
|
483
|
-
src
|
|
484
|
-
};
|
|
503
|
+
loc = map.get(atRule);
|
|
485
504
|
if (options.sourcemap) {
|
|
486
505
|
node.loc = loc;
|
|
506
|
+
node.loc.end = { ...map.get(delim).end };
|
|
487
507
|
}
|
|
488
|
-
if (options.validation) {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
else {
|
|
498
|
-
isValid = false;
|
|
508
|
+
// if (options.validation) {
|
|
509
|
+
let isValid = true;
|
|
510
|
+
if (node.nam == 'else') {
|
|
511
|
+
const prev = getLastNode(context);
|
|
512
|
+
if (prev != null && prev.typ == EnumToken.AtRuleNodeType && ['when', 'else'].includes(prev.nam)) {
|
|
513
|
+
if (prev.nam == 'else') {
|
|
514
|
+
isValid = Array.isArray(prev.tokens) && prev.tokens.length > 0;
|
|
499
515
|
}
|
|
500
516
|
}
|
|
501
|
-
const valid = isValid ? validateAtRule(node, options, context) : {
|
|
502
|
-
valid: ValidationLevel.Drop,
|
|
503
|
-
node,
|
|
504
|
-
syntax: '@' + node.nam,
|
|
505
|
-
error: '@' + node.nam + ' not allowed here'};
|
|
506
|
-
if (valid.valid == ValidationLevel.Drop) {
|
|
507
|
-
errors.push({
|
|
508
|
-
action: 'drop',
|
|
509
|
-
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
510
|
-
// @ts-ignore
|
|
511
|
-
location: { src, ...(map.get(valid.node) ?? position) }
|
|
512
|
-
});
|
|
513
|
-
// @ts-ignore
|
|
514
|
-
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
515
|
-
}
|
|
516
517
|
else {
|
|
517
|
-
|
|
518
|
+
isValid = false;
|
|
518
519
|
}
|
|
519
520
|
}
|
|
520
521
|
// @ts-ignore
|
|
522
|
+
const valid = options.validation == ValidationLevel.None ? {
|
|
523
|
+
valid: SyntaxValidationResult.Valid,
|
|
524
|
+
error: '',
|
|
525
|
+
node,
|
|
526
|
+
syntax: '@' + node.nam
|
|
527
|
+
} : isValid ? (node.typ == EnumToken.KeyframeAtRuleNodeType ? validateAtRuleKeyframes(node) : validateAtRule(node, options, context)) : {
|
|
528
|
+
valid: SyntaxValidationResult.Drop,
|
|
529
|
+
node,
|
|
530
|
+
syntax: '@' + node.nam,
|
|
531
|
+
error: '@' + node.nam + ' not allowed here'};
|
|
532
|
+
if (valid.valid == SyntaxValidationResult.Drop) {
|
|
533
|
+
errors.push({
|
|
534
|
+
action: 'drop',
|
|
535
|
+
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
536
|
+
// @ts-ignore
|
|
537
|
+
location: { src, ...(map.get(valid.node) ?? location) }
|
|
538
|
+
});
|
|
539
|
+
// @ts-ignore
|
|
540
|
+
node.typ = EnumToken.InvalidAtRuleTokenType;
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr, {
|
|
544
|
+
minify: false,
|
|
545
|
+
removeComments: true
|
|
546
|
+
}), '');
|
|
547
|
+
}
|
|
548
|
+
// }
|
|
521
549
|
context.chi.push(node);
|
|
522
|
-
Object.
|
|
523
|
-
return
|
|
550
|
+
Object.defineProperties(node, { parent: { ...definedPropertySettings, value: context }, validSyntax: { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid } });
|
|
551
|
+
return node;
|
|
524
552
|
}
|
|
525
553
|
else {
|
|
526
554
|
// rule
|
|
527
555
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
528
|
-
const
|
|
556
|
+
const location = map.get(tokens[0]);
|
|
529
557
|
const uniq = new Map;
|
|
530
|
-
parseTokens(tokens, { minify: true })
|
|
531
|
-
|
|
532
|
-
return acc;
|
|
533
|
-
}
|
|
534
|
-
if (curr.typ == EnumToken.WhitespaceTokenType) {
|
|
535
|
-
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
536
|
-
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
537
|
-
combinators.includes(array[index - 1]?.val) ||
|
|
538
|
-
combinators.includes(array[index + 1]?.val)) {
|
|
539
|
-
return acc;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
let t = renderToken(curr, { minify: false });
|
|
543
|
-
if (t == ',') {
|
|
544
|
-
acc.push([]);
|
|
545
|
-
// uniqTokens.push([]);
|
|
546
|
-
}
|
|
547
|
-
else {
|
|
548
|
-
acc[acc.length - 1].push(t);
|
|
549
|
-
// uniqTokens[uniqTokens.length - 1].push(curr);
|
|
550
|
-
}
|
|
551
|
-
return acc;
|
|
552
|
-
}, [[]]).reduce((acc, curr) => {
|
|
553
|
-
let i = 0;
|
|
554
|
-
for (; i < curr.length; i++) {
|
|
555
|
-
if (i + 1 < curr.length && curr[i] == '*') {
|
|
556
|
-
if (curr[i] == '*') {
|
|
557
|
-
let index = curr[i + 1] == ' ' ? 2 : 1;
|
|
558
|
-
if (!['>', '~', '+'].includes(curr[index])) {
|
|
559
|
-
curr.splice(i, index);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
acc.set(curr.join(''), curr);
|
|
565
|
-
return acc;
|
|
566
|
-
}, uniq);
|
|
567
|
-
const ruleType = context.typ == EnumToken.AtRuleNodeType && context.nam == 'keyframes' ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType;
|
|
558
|
+
parseTokens(tokens, { minify: true });
|
|
559
|
+
const ruleType = context.typ == EnumToken.KeyframeAtRuleNodeType ? EnumToken.KeyFrameRuleNodeType : EnumToken.RuleNodeType;
|
|
568
560
|
if (ruleType == EnumToken.RuleNodeType) {
|
|
569
561
|
parseSelector(tokens);
|
|
570
|
-
if (options.validation) {
|
|
571
|
-
// @ts-ignore
|
|
572
|
-
const valid = validateSelector(tokens, options, context);
|
|
573
|
-
if (valid.valid != ValidationLevel.Valid) {
|
|
574
|
-
const node = {
|
|
575
|
-
typ: EnumToken.InvalidRuleTokenType,
|
|
576
|
-
// @ts-ignore
|
|
577
|
-
sel: tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), ''),
|
|
578
|
-
chi: []
|
|
579
|
-
};
|
|
580
|
-
errors.push({
|
|
581
|
-
action: 'drop',
|
|
582
|
-
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
583
|
-
// @ts-ignore
|
|
584
|
-
location: { src, ...(map.get(valid.node) ?? position) }
|
|
585
|
-
});
|
|
586
|
-
// @ts-ignore
|
|
587
|
-
context.chi.push(node);
|
|
588
|
-
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
589
|
-
return node;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
562
|
}
|
|
593
563
|
const node = {
|
|
594
564
|
typ: ruleType,
|
|
595
|
-
sel: [...
|
|
565
|
+
sel: [...tokens.reduce((acc, curr, index, array) => {
|
|
566
|
+
if (curr.typ == EnumToken.CommentTokenType) {
|
|
567
|
+
return acc;
|
|
568
|
+
}
|
|
569
|
+
if (curr.typ == EnumToken.WhitespaceTokenType) {
|
|
570
|
+
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
571
|
+
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
572
|
+
combinators.includes(array[index - 1]?.val) ||
|
|
573
|
+
combinators.includes(array[index + 1]?.val)) {
|
|
574
|
+
return acc;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (ruleType == EnumToken.KeyFrameRuleNodeType) {
|
|
578
|
+
if (curr.typ == EnumToken.IdenTokenType && curr.val == 'from') {
|
|
579
|
+
Object.assign(curr, { typ: EnumToken.PercentageTokenType, val: '0' });
|
|
580
|
+
}
|
|
581
|
+
else if (curr.typ == EnumToken.PercentageTokenType && curr.val == '100') {
|
|
582
|
+
Object.assign(curr, { typ: EnumToken.IdenTokenType, val: 'to' });
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
let t = renderToken(curr, { minify: false });
|
|
586
|
+
if (t == ',') {
|
|
587
|
+
acc.push([]);
|
|
588
|
+
// uniqTokens.push([]);
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
acc[acc.length - 1].push(t);
|
|
592
|
+
// uniqTokens[uniqTokens.length - 1].push(curr);
|
|
593
|
+
}
|
|
594
|
+
return acc;
|
|
595
|
+
}, [[]]).reduce((acc, curr) => {
|
|
596
|
+
let i = 0;
|
|
597
|
+
for (; i < curr.length; i++) {
|
|
598
|
+
if (i + 1 < curr.length && curr[i] == '*') {
|
|
599
|
+
if (curr[i] == '*') {
|
|
600
|
+
let index = curr[i + 1] == ' ' ? 2 : 1;
|
|
601
|
+
if (!['>', '~', '+'].includes(curr[index])) {
|
|
602
|
+
curr.splice(i, index);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
acc.set(curr.join(''), curr);
|
|
608
|
+
return acc;
|
|
609
|
+
}, uniq).keys()].join(','),
|
|
596
610
|
chi: []
|
|
597
611
|
};
|
|
598
612
|
Object.defineProperty(node, 'tokens', {
|
|
@@ -600,121 +614,203 @@ async function parseNode(results, context, stats, options, errors, src, map, raw
|
|
|
600
614
|
enumerable: false,
|
|
601
615
|
value: tokens.slice()
|
|
602
616
|
});
|
|
603
|
-
|
|
604
|
-
Object.defineProperty(node, 'raw', {
|
|
605
|
-
enumerable: false,
|
|
606
|
-
configurable: true,
|
|
607
|
-
writable: true,
|
|
608
|
-
value: raw
|
|
609
|
-
});
|
|
610
|
-
loc = {
|
|
611
|
-
sta: position,
|
|
612
|
-
src
|
|
613
|
-
};
|
|
617
|
+
loc = location;
|
|
614
618
|
if (options.sourcemap) {
|
|
615
619
|
node.loc = loc;
|
|
616
620
|
}
|
|
617
621
|
// @ts-ignore
|
|
618
622
|
context.chi.push(node);
|
|
619
623
|
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
|
|
624
|
+
// if (options.validation) {
|
|
625
|
+
// @ts-ignore
|
|
626
|
+
const valid = options.validation == ValidationLevel.None ? {
|
|
627
|
+
valid: SyntaxValidationResult.Valid,
|
|
628
|
+
error: null
|
|
629
|
+
} : ruleType == EnumToken.KeyFrameRuleNodeType ? validateKeyframeSelector(tokens) : validateSelector(tokens, options, context);
|
|
630
|
+
if (valid.valid != SyntaxValidationResult.Valid) {
|
|
631
|
+
// @ts-ignore
|
|
632
|
+
node.typ = EnumToken.InvalidRuleTokenType;
|
|
633
|
+
node.sel = tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '');
|
|
634
|
+
errors.push({
|
|
635
|
+
action: 'drop',
|
|
636
|
+
message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, { minify: false }), '') + '"',
|
|
637
|
+
// @ts-ignore
|
|
638
|
+
location
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
// } else {
|
|
642
|
+
//
|
|
643
|
+
// Object.defineProperty(node, 'tokens', {
|
|
644
|
+
// ...definedPropertySettings,
|
|
645
|
+
// enumerable: false,
|
|
646
|
+
// value: tokens.slice()
|
|
647
|
+
// });
|
|
648
|
+
//
|
|
649
|
+
// let raw: string[][] = [...uniq.values()];
|
|
650
|
+
//
|
|
651
|
+
// Object.defineProperty(node, 'raw', {
|
|
652
|
+
// enumerable: false,
|
|
653
|
+
// configurable: true,
|
|
654
|
+
// writable: true,
|
|
655
|
+
// value: raw
|
|
656
|
+
// });
|
|
657
|
+
// }
|
|
658
|
+
Object.defineProperty(node, 'validSyntax', { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid });
|
|
620
659
|
return node;
|
|
621
660
|
}
|
|
622
661
|
else {
|
|
623
662
|
let name = null;
|
|
624
663
|
let value = null;
|
|
625
|
-
|
|
664
|
+
let i = 0;
|
|
665
|
+
for (; i < tokens.length; i++) {
|
|
666
|
+
if (tokens[i].typ == EnumToken.LiteralTokenType && tokens[i].val.length > 1) {
|
|
667
|
+
const start = tokens[i].val.charAt(0);
|
|
668
|
+
const val = tokens[i].val.slice(1);
|
|
669
|
+
if (['/', '*'].includes(start) && isNumber(val)) {
|
|
670
|
+
tokens.splice(i, 1, {
|
|
671
|
+
typ: EnumToken.LiteralTokenType,
|
|
672
|
+
val: tokens[i].val.charAt(0)
|
|
673
|
+
}, {
|
|
674
|
+
typ: EnumToken.NumberTokenType,
|
|
675
|
+
val: tokens[i].val.slice(1)
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
else if (start == '/' && isFunction(val)) {
|
|
679
|
+
tokens.splice(i, 1, { typ: EnumToken.LiteralTokenType, val: '/' }, getTokenType(val));
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
parseTokens(tokens, { ...options, parseColor: true });
|
|
684
|
+
for (i = 0; i < tokens.length; i++) {
|
|
626
685
|
if (tokens[i].typ == EnumToken.CommentTokenType) {
|
|
627
686
|
continue;
|
|
628
687
|
}
|
|
629
688
|
if (name == null && [EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType].includes(tokens[i].typ)) {
|
|
630
689
|
name = tokens.slice(0, i + 1);
|
|
631
690
|
}
|
|
691
|
+
else if (name == null && tokens[i].typ == EnumToken.ColorTokenType && [ColorKind.SYS, ColorKind.DPSYS].includes(tokens[i].kin)) {
|
|
692
|
+
name = tokens.slice(0, i + 1);
|
|
693
|
+
tokens[i].typ = EnumToken.IdenTokenType;
|
|
694
|
+
}
|
|
632
695
|
else if (name != null && funcLike.concat([
|
|
633
696
|
EnumToken.LiteralTokenType,
|
|
634
697
|
EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType,
|
|
635
698
|
EnumToken.PseudoClassTokenType, EnumToken.PseudoClassFuncTokenType
|
|
636
699
|
]).includes(tokens[i].typ)) {
|
|
637
|
-
if (tokens[i].val
|
|
700
|
+
if (tokens[i].val?.charAt?.(0) == ':') {
|
|
638
701
|
Object.assign(tokens[i], getTokenType(tokens[i].val.slice(1)));
|
|
702
|
+
if ('chi' in tokens[i]) {
|
|
703
|
+
tokens[i].typ = EnumToken.FunctionTokenType;
|
|
704
|
+
if (colorsFunc.includes(tokens[i].val) && isColor(tokens[i])) {
|
|
705
|
+
parseColor(tokens[i]);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
tokens.splice(i, 0, { typ: EnumToken.ColonTokenType });
|
|
709
|
+
// i++;
|
|
710
|
+
i--;
|
|
711
|
+
continue;
|
|
639
712
|
}
|
|
640
713
|
if ('chi' in tokens[i]) {
|
|
641
714
|
tokens[i].typ = EnumToken.FunctionTokenType;
|
|
642
715
|
}
|
|
643
|
-
value =
|
|
644
|
-
parseColor: options.parseColor,
|
|
645
|
-
src: options.src,
|
|
646
|
-
resolveUrls: options.resolveUrls,
|
|
647
|
-
resolve: options.resolve,
|
|
648
|
-
cwd: options.cwd
|
|
649
|
-
});
|
|
650
|
-
break;
|
|
716
|
+
value = tokens.slice(i);
|
|
651
717
|
}
|
|
652
718
|
if (tokens[i].typ == EnumToken.ColonTokenType) {
|
|
653
719
|
name = tokens.slice(0, i);
|
|
654
|
-
value =
|
|
655
|
-
parseColor: options.parseColor,
|
|
656
|
-
src: options.src,
|
|
657
|
-
resolveUrls: options.resolveUrls,
|
|
658
|
-
resolve: options.resolve,
|
|
659
|
-
cwd: options.cwd
|
|
660
|
-
});
|
|
720
|
+
value = tokens.slice(i + 1);
|
|
661
721
|
break;
|
|
662
722
|
}
|
|
663
723
|
}
|
|
664
724
|
if (name == null) {
|
|
665
725
|
name = tokens;
|
|
666
726
|
}
|
|
667
|
-
const
|
|
727
|
+
const location = map.get(name[0]);
|
|
668
728
|
if (name.length > 0) {
|
|
669
729
|
for (let i = 1; i < name.length; i++) {
|
|
670
730
|
if (name[i].typ != EnumToken.WhitespaceTokenType && name[i].typ != EnumToken.CommentTokenType) {
|
|
671
731
|
errors.push({
|
|
672
732
|
action: 'drop',
|
|
673
733
|
message: 'doParse: invalid declaration',
|
|
674
|
-
location
|
|
734
|
+
location
|
|
675
735
|
});
|
|
676
736
|
return null;
|
|
677
737
|
}
|
|
678
738
|
}
|
|
679
739
|
}
|
|
680
|
-
|
|
740
|
+
const nam = renderToken(name.shift(), { removeComments: true });
|
|
741
|
+
if (value == null || (!nam.startsWith('--') && value.length == 0)) {
|
|
681
742
|
errors.push({
|
|
682
743
|
action: 'drop',
|
|
683
744
|
message: 'doParse: invalid declaration',
|
|
684
|
-
location
|
|
745
|
+
location
|
|
685
746
|
});
|
|
747
|
+
if (options.lenient) {
|
|
748
|
+
const node = {
|
|
749
|
+
typ: EnumToken.InvalidDeclarationNodeType,
|
|
750
|
+
nam,
|
|
751
|
+
val: []
|
|
752
|
+
};
|
|
753
|
+
if (options.sourcemap) {
|
|
754
|
+
node.loc = location;
|
|
755
|
+
node.loc.end = { ...map.get(delim).end };
|
|
756
|
+
}
|
|
757
|
+
context.chi.push(node);
|
|
758
|
+
}
|
|
686
759
|
return null;
|
|
687
760
|
}
|
|
761
|
+
for (const { value: token } of walkValues(value, null, {
|
|
762
|
+
fn: (node) => node.typ == EnumToken.FunctionTokenType && node.val == 'calc' ? WalkerOptionEnum.IgnoreChildren : null,
|
|
763
|
+
type: EnumToken.FunctionTokenType
|
|
764
|
+
})) {
|
|
765
|
+
if (token.typ == EnumToken.FunctionTokenType && token.val == 'calc') {
|
|
766
|
+
for (const { value: node, parent } of walkValues(token.chi, token)) {
|
|
767
|
+
// fix expressions starting with '/' or '*' such as '/4' in (1 + 1)/4
|
|
768
|
+
if (node.typ == EnumToken.LiteralTokenType && node.val.length > 0) {
|
|
769
|
+
if (node.val[0] == '/' || node.val[0] == '*') {
|
|
770
|
+
parent.chi.splice(parent.chi.indexOf(node), 1, { typ: node.val[0] == '/' ? EnumToken.Div : EnumToken.Mul }, ...parseString(node.val.slice(1)));
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
688
776
|
const node = {
|
|
689
777
|
typ: EnumToken.DeclarationNodeType,
|
|
690
|
-
|
|
691
|
-
nam: renderToken(name.shift(), { removeComments: true }),
|
|
692
|
-
// @ts-ignore
|
|
778
|
+
nam,
|
|
693
779
|
val: value
|
|
694
780
|
};
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
// // console.error({valid});
|
|
702
|
-
//
|
|
703
|
-
// if (valid.valid == ValidationLevel.Drop) {
|
|
704
|
-
//
|
|
705
|
-
// errors.push({
|
|
706
|
-
// action: 'drop',
|
|
707
|
-
// message: valid.error + ' - "' + tokens.reduce((acc, curr) => acc + renderToken(curr, {minify: false}), '') + '"',
|
|
708
|
-
// // @ts-ignore
|
|
709
|
-
// location: {src, ...(map.get(valid.node) ?? position)}
|
|
710
|
-
// });
|
|
711
|
-
//
|
|
712
|
-
// return null;
|
|
713
|
-
// }
|
|
714
|
-
// }
|
|
781
|
+
if (options.sourcemap) {
|
|
782
|
+
node.loc = location;
|
|
783
|
+
node.loc.end = { ...map.get(delim).end };
|
|
784
|
+
}
|
|
785
|
+
// do not allow declarations in style sheets
|
|
786
|
+
if (context.typ == EnumToken.StyleSheetNodeType && options.lenient) {
|
|
715
787
|
// @ts-ignore
|
|
788
|
+
node.typ = EnumToken.InvalidDeclarationNodeType;
|
|
789
|
+
context.chi.push(node);
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
const result = parseDeclarationNode(node, errors, location);
|
|
793
|
+
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
794
|
+
if (result != null) {
|
|
795
|
+
// console.error(doRender(result), result.val, location);
|
|
796
|
+
if (options.validation == ValidationLevel.All) {
|
|
797
|
+
const valid = evaluateSyntax(result, options);
|
|
798
|
+
Object.defineProperty(result, 'validSyntax', { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid });
|
|
799
|
+
if (valid.valid == SyntaxValidationResult.Drop) {
|
|
800
|
+
errors.push({
|
|
801
|
+
action: 'drop',
|
|
802
|
+
message: valid.error,
|
|
803
|
+
syntax: valid.syntax,
|
|
804
|
+
location: map.get(valid.node) ?? valid.node?.loc ?? result.loc ?? location
|
|
805
|
+
});
|
|
806
|
+
if (!options.lenient) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
// @ts-ignore
|
|
810
|
+
node.typ = EnumToken.InvalidDeclarationNodeType;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
716
813
|
context.chi.push(result);
|
|
717
|
-
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
|
|
718
814
|
}
|
|
719
815
|
return null;
|
|
720
816
|
}
|
|
@@ -733,6 +829,33 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
733
829
|
value.typ == EnumToken.CommaTokenType) {
|
|
734
830
|
continue;
|
|
735
831
|
}
|
|
832
|
+
if (value.typ == EnumToken.PseudoClassFuncTokenType || value.typ == EnumToken.PseudoClassTokenType) {
|
|
833
|
+
if (parent?.typ == EnumToken.ParensTokenType) {
|
|
834
|
+
const index = parent.chi.indexOf(value);
|
|
835
|
+
let i = index;
|
|
836
|
+
while (i--) {
|
|
837
|
+
if (parent.chi[i].typ == EnumToken.IdenTokenType || parent.chi[i].typ == EnumToken.DashedIdenTokenType) {
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
if (i >= 0) {
|
|
842
|
+
const token = getTokenType(parent.chi[index].val.slice(1) + (funcLike.includes(parent.chi[index].typ) ? '(' : ''));
|
|
843
|
+
parent.chi[index].val = token.val;
|
|
844
|
+
parent.chi[index].typ = token.typ;
|
|
845
|
+
if (parent.chi[index].typ == EnumToken.FunctionTokenType && isColor(parent.chi[index])) {
|
|
846
|
+
parseColor(parent.chi[index]);
|
|
847
|
+
}
|
|
848
|
+
parent.chi.splice(i, index - i + 1, {
|
|
849
|
+
typ: EnumToken.MediaQueryConditionTokenType,
|
|
850
|
+
l: parent.chi[i],
|
|
851
|
+
r: parent.chi.slice(index),
|
|
852
|
+
op: {
|
|
853
|
+
typ: EnumToken.ColonTokenType
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
736
859
|
if (atRule.val == 'page' && value.typ == EnumToken.PseudoClassTokenType) {
|
|
737
860
|
if ([':left', ':right', ':first', ':blank'].includes(value.val)) {
|
|
738
861
|
// @ts-ignore
|
|
@@ -793,9 +916,10 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
793
916
|
continue;
|
|
794
917
|
}
|
|
795
918
|
}
|
|
919
|
+
if (value.typ == EnumToken.FunctionTokenType && value.val == 'selector') {
|
|
920
|
+
parseSelector(value.chi);
|
|
921
|
+
}
|
|
796
922
|
if (value.typ == EnumToken.ParensTokenType || (value.typ == EnumToken.FunctionTokenType && ['media', 'supports', 'style', 'scroll-state'].includes(value.val))) {
|
|
797
|
-
// @todo parse range and declarations
|
|
798
|
-
// parseDeclaration(parent.chi);
|
|
799
923
|
let i;
|
|
800
924
|
let nameIndex = -1;
|
|
801
925
|
let valueIndex = -1;
|
|
@@ -816,6 +940,23 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
816
940
|
if (value.chi[i].typ == EnumToken.CommentTokenType || value.chi[i].typ == EnumToken.WhitespaceTokenType) {
|
|
817
941
|
continue;
|
|
818
942
|
}
|
|
943
|
+
if (value.chi[i].typ == EnumToken.LiteralTokenType && value.chi[i].val.startsWith(':') && isDimension(value.chi[i].val.slice(1))) {
|
|
944
|
+
value.chi.splice(i, 1, {
|
|
945
|
+
typ: EnumToken.ColonTokenType,
|
|
946
|
+
}, Object.assign(value.chi[i], parseDimension(value.chi[i].val.slice(1))));
|
|
947
|
+
i--;
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
if (nameIndex != -1 && value.chi[i].typ == EnumToken.PseudoClassTokenType) {
|
|
951
|
+
value.chi.splice(i, 1, {
|
|
952
|
+
typ: EnumToken.ColonTokenType,
|
|
953
|
+
}, Object.assign(value.chi[i], {
|
|
954
|
+
typ: EnumToken.IdenTokenType,
|
|
955
|
+
val: value.chi[i].val.slice(1)
|
|
956
|
+
}));
|
|
957
|
+
i--;
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
819
960
|
valueIndex = i;
|
|
820
961
|
break;
|
|
821
962
|
}
|
|
@@ -835,7 +976,7 @@ function parseAtRulePrelude(tokens, atRule) {
|
|
|
835
976
|
const node = value.chi.splice(nameIndex, 1)[0];
|
|
836
977
|
// 'background'
|
|
837
978
|
// @ts-ignore
|
|
838
|
-
if (node.typ == EnumToken.ColorTokenType && node.kin ==
|
|
979
|
+
if (node.typ == EnumToken.ColorTokenType && node.kin == ColorKind.DPSYS) {
|
|
839
980
|
// @ts-ignore
|
|
840
981
|
delete node.kin;
|
|
841
982
|
node.typ = EnumToken.IdenTokenType;
|
|
@@ -959,8 +1100,8 @@ function parseSelector(tokens) {
|
|
|
959
1100
|
}
|
|
960
1101
|
}
|
|
961
1102
|
else if (value.typ == EnumToken.ColorTokenType) {
|
|
962
|
-
if (value.kin ==
|
|
963
|
-
if (value.kin ==
|
|
1103
|
+
if (value.kin == ColorKind.LIT || value.kin == ColorKind.HEX || value.kin == ColorKind.SYS || value.kin == ColorKind.DPSYS) {
|
|
1104
|
+
if (value.kin == ColorKind.HEX) {
|
|
964
1105
|
if (!isIdent(value.val.slice(1))) {
|
|
965
1106
|
continue;
|
|
966
1107
|
}
|
|
@@ -1005,64 +1146,54 @@ function parseSelector(tokens) {
|
|
|
1005
1146
|
// return doParse(`.x{${src}`, options).then((result: ParseResult) => <AstDeclaration[]>(<AstRule>result.ast.chi[0]).chi.filter(t => t.typ == EnumToken.DeclarationNodeType));
|
|
1006
1147
|
// }
|
|
1007
1148
|
/**
|
|
1008
|
-
* parse string
|
|
1149
|
+
* parse css string
|
|
1009
1150
|
* @param src
|
|
1010
1151
|
* @param options
|
|
1011
1152
|
*/
|
|
1012
1153
|
function parseString(src, options = { location: false }) {
|
|
1013
|
-
return parseTokens([...tokenize(src)].
|
|
1154
|
+
return parseTokens([...tokenize(src)].reduce((acc, t) => {
|
|
1155
|
+
if (t.hint == EnumToken.EOFTokenType) {
|
|
1156
|
+
return acc;
|
|
1157
|
+
}
|
|
1014
1158
|
const token = getTokenType(t.token, t.hint);
|
|
1015
1159
|
if (options.location) {
|
|
1016
|
-
Object.assign(token, { loc: t.
|
|
1160
|
+
Object.assign(token, { loc: t.sta });
|
|
1017
1161
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1162
|
+
acc.push(token);
|
|
1163
|
+
return acc;
|
|
1164
|
+
}, []));
|
|
1020
1165
|
}
|
|
1021
1166
|
function getTokenType(val, hint) {
|
|
1022
1167
|
if (hint != null) {
|
|
1023
1168
|
return enumTokenHints.has(hint) ? { typ: hint } : { typ: hint, val };
|
|
1024
1169
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
if (val == '=') {
|
|
1053
|
-
return { typ: EnumToken.DelimTokenType };
|
|
1054
|
-
}
|
|
1055
|
-
if (val == ';') {
|
|
1056
|
-
return { typ: EnumToken.SemiColonTokenType };
|
|
1057
|
-
}
|
|
1058
|
-
if (val == ',') {
|
|
1059
|
-
return { typ: EnumToken.CommaTokenType };
|
|
1060
|
-
}
|
|
1061
|
-
if (val == '<') {
|
|
1062
|
-
return { typ: EnumToken.LtTokenType };
|
|
1063
|
-
}
|
|
1064
|
-
if (val == '>') {
|
|
1065
|
-
return { typ: EnumToken.GtTokenType };
|
|
1170
|
+
switch (val) {
|
|
1171
|
+
case ' ':
|
|
1172
|
+
return { typ: EnumToken.WhitespaceTokenType };
|
|
1173
|
+
case ';':
|
|
1174
|
+
return { typ: EnumToken.SemiColonTokenType };
|
|
1175
|
+
case '{':
|
|
1176
|
+
return { typ: EnumToken.BlockStartTokenType };
|
|
1177
|
+
case '}':
|
|
1178
|
+
return { typ: EnumToken.BlockEndTokenType };
|
|
1179
|
+
case '[':
|
|
1180
|
+
return { typ: EnumToken.AttrStartTokenType };
|
|
1181
|
+
case ']':
|
|
1182
|
+
return { typ: EnumToken.AttrEndTokenType };
|
|
1183
|
+
case ':':
|
|
1184
|
+
return { typ: EnumToken.ColonTokenType };
|
|
1185
|
+
case ')':
|
|
1186
|
+
return { typ: EnumToken.EndParensTokenType };
|
|
1187
|
+
case '(':
|
|
1188
|
+
return { typ: EnumToken.StartParensTokenType };
|
|
1189
|
+
case '=':
|
|
1190
|
+
return { typ: EnumToken.DelimTokenType };
|
|
1191
|
+
case ',':
|
|
1192
|
+
return { typ: EnumToken.CommaTokenType };
|
|
1193
|
+
case '<':
|
|
1194
|
+
return { typ: EnumToken.LtTokenType };
|
|
1195
|
+
case '>':
|
|
1196
|
+
return { typ: EnumToken.GtTokenType };
|
|
1066
1197
|
}
|
|
1067
1198
|
if (isPseudo(val)) {
|
|
1068
1199
|
return val.endsWith('(') ? {
|
|
@@ -1149,22 +1280,22 @@ function getTokenType(val, hint) {
|
|
|
1149
1280
|
return {
|
|
1150
1281
|
typ: EnumToken.ColorTokenType,
|
|
1151
1282
|
val: v,
|
|
1152
|
-
kin:
|
|
1283
|
+
kin: ColorKind.LIT
|
|
1153
1284
|
};
|
|
1154
1285
|
}
|
|
1155
1286
|
if (isIdent(val)) {
|
|
1156
|
-
if (systemColors.has(
|
|
1287
|
+
if (systemColors.has(v)) {
|
|
1157
1288
|
return {
|
|
1158
1289
|
typ: EnumToken.ColorTokenType,
|
|
1159
1290
|
val,
|
|
1160
|
-
kin:
|
|
1291
|
+
kin: ColorKind.SYS
|
|
1161
1292
|
};
|
|
1162
1293
|
}
|
|
1163
|
-
if (deprecatedSystemColors.has(
|
|
1294
|
+
if (deprecatedSystemColors.has(v)) {
|
|
1164
1295
|
return {
|
|
1165
1296
|
typ: EnumToken.ColorTokenType,
|
|
1166
1297
|
val,
|
|
1167
|
-
kin:
|
|
1298
|
+
kin: ColorKind.DPSYS
|
|
1168
1299
|
};
|
|
1169
1300
|
}
|
|
1170
1301
|
return {
|
|
@@ -1176,7 +1307,7 @@ function getTokenType(val, hint) {
|
|
|
1176
1307
|
return {
|
|
1177
1308
|
typ: EnumToken.ColorTokenType,
|
|
1178
1309
|
val,
|
|
1179
|
-
kin:
|
|
1310
|
+
kin: ColorKind.HEX
|
|
1180
1311
|
};
|
|
1181
1312
|
}
|
|
1182
1313
|
if (val.charAt(0) == '#' && isHash(val)) {
|
|
@@ -1197,23 +1328,13 @@ function getTokenType(val, hint) {
|
|
|
1197
1328
|
};
|
|
1198
1329
|
}
|
|
1199
1330
|
/**
|
|
1200
|
-
* parse token
|
|
1331
|
+
* parse token array into a tree structure
|
|
1201
1332
|
* @param tokens
|
|
1202
1333
|
* @param options
|
|
1203
1334
|
*/
|
|
1204
1335
|
function parseTokens(tokens, options = {}) {
|
|
1205
1336
|
for (let i = 0; i < tokens.length; i++) {
|
|
1206
1337
|
const t = tokens[i];
|
|
1207
|
-
if (t.typ == EnumToken.PseudoClassFuncTokenType) {
|
|
1208
|
-
if (t.val.slice(1) in webkitPseudoAliasMap) {
|
|
1209
|
-
t.val = ':' + webkitPseudoAliasMap[t.val.slice(1)];
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
else if (t.typ == EnumToken.PseudoClassTokenType) {
|
|
1213
|
-
if (t.val.slice(1) in webkitPseudoAliasMap) {
|
|
1214
|
-
t.val = ':' + webkitPseudoAliasMap[t.val.slice(1)];
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
1338
|
if (t.typ == EnumToken.WhitespaceTokenType && ((i == 0 ||
|
|
1218
1339
|
i + 1 == tokens.length ||
|
|
1219
1340
|
[EnumToken.CommaTokenType, EnumToken.GteTokenType, EnumToken.LteTokenType, EnumToken.ColumnCombinatorTokenType].includes(tokens[i + 1].typ)) ||
|
|
@@ -1225,13 +1346,9 @@ function parseTokens(tokens, options = {}) {
|
|
|
1225
1346
|
const typ = tokens[i + 1]?.typ;
|
|
1226
1347
|
if (typ != null) {
|
|
1227
1348
|
if (typ == EnumToken.FunctionTokenType) {
|
|
1228
|
-
tokens[i + 1].val = ':' + (tokens[i + 1].val in webkitPseudoAliasMap ? webkitPseudoAliasMap[tokens[i + 1].val] : tokens[i + 1].val);
|
|
1229
1349
|
tokens[i + 1].typ = EnumToken.PseudoClassFuncTokenType;
|
|
1230
1350
|
}
|
|
1231
1351
|
else if (typ == EnumToken.IdenTokenType) {
|
|
1232
|
-
if (tokens[i + 1].val in webkitPseudoAliasMap) {
|
|
1233
|
-
tokens[i + 1].val = webkitPseudoAliasMap[tokens[i + 1].val];
|
|
1234
|
-
}
|
|
1235
1352
|
tokens[i + 1].val = ':' + tokens[i + 1].val;
|
|
1236
1353
|
tokens[i + 1].typ = EnumToken.PseudoClassTokenType;
|
|
1237
1354
|
}
|
|
@@ -1351,6 +1468,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
1351
1468
|
l: t.chi[lower],
|
|
1352
1469
|
r: t.chi[upper]
|
|
1353
1470
|
};
|
|
1471
|
+
if (isIdentColor(t.chi[m].l)) {
|
|
1472
|
+
t.chi[m].l.typ = EnumToken.IdenTokenType;
|
|
1473
|
+
}
|
|
1474
|
+
if (isIdentColor(t.chi[m].r)) {
|
|
1475
|
+
t.chi[m].r.typ = EnumToken.IdenTokenType;
|
|
1476
|
+
}
|
|
1354
1477
|
t.chi.splice(upper, 1);
|
|
1355
1478
|
t.chi.splice(lower, 1);
|
|
1356
1479
|
upper = m;
|
|
@@ -1359,7 +1482,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1359
1482
|
upper++;
|
|
1360
1483
|
}
|
|
1361
1484
|
if (upper < t.chi.length &&
|
|
1362
|
-
t.chi[upper].typ == EnumToken.
|
|
1485
|
+
t.chi[upper].typ == EnumToken.IdenTokenType &&
|
|
1363
1486
|
['i', 's'].includes(t.chi[upper].val.toLowerCase())) {
|
|
1364
1487
|
t.chi[m].attr = t.chi[upper].val;
|
|
1365
1488
|
t.chi.splice(upper, 1);
|
|
@@ -1437,6 +1560,13 @@ function parseTokens(tokens, options = {}) {
|
|
|
1437
1560
|
delete value.val;
|
|
1438
1561
|
}
|
|
1439
1562
|
}
|
|
1563
|
+
t.chi = splitTokenList(t.chi).reduce((acc, t) => {
|
|
1564
|
+
if (acc.length > 0) {
|
|
1565
|
+
acc.push({ typ: EnumToken.CommaTokenType });
|
|
1566
|
+
}
|
|
1567
|
+
acc.push(buildExpression(t));
|
|
1568
|
+
return acc;
|
|
1569
|
+
}, []);
|
|
1440
1570
|
}
|
|
1441
1571
|
else if (t.typ == EnumToken.FunctionTokenType && ['minmax', 'fit-content', 'repeat'].includes(t.val)) {
|
|
1442
1572
|
// @ts-ignore
|
|
@@ -1448,34 +1578,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1448
1578
|
}
|
|
1449
1579
|
// @ts-ignore
|
|
1450
1580
|
if (options.parseColor && t.typ == EnumToken.FunctionTokenType && isColor(t)) {
|
|
1451
|
-
|
|
1452
|
-
t.typ = EnumToken.ColorTokenType;
|
|
1453
|
-
// @ts-ignore
|
|
1454
|
-
t.kin = t.val;
|
|
1455
|
-
// @ts-ignore
|
|
1456
|
-
if (t.chi[0].typ == EnumToken.IdenTokenType) {
|
|
1457
|
-
// @ts-ignore
|
|
1458
|
-
if (t.chi[0].val == 'from') {
|
|
1459
|
-
// @ts-ignore
|
|
1460
|
-
t.cal = 'rel';
|
|
1461
|
-
}
|
|
1462
|
-
// @ts-ignore
|
|
1463
|
-
else if (t.val == 'color-mix' && t.chi[0].val == 'in') {
|
|
1464
|
-
// @ts-ignore
|
|
1465
|
-
t.cal = 'mix';
|
|
1466
|
-
}
|
|
1467
|
-
else { // @ts-ignore
|
|
1468
|
-
if (t.val == 'color') {
|
|
1469
|
-
// @ts-ignore
|
|
1470
|
-
t.cal = 'col';
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
const filter = [EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType];
|
|
1475
|
-
if (t.val != 'light-dark') {
|
|
1476
|
-
filter.push(EnumToken.CommaTokenType);
|
|
1477
|
-
}
|
|
1478
|
-
t.chi = t.chi.filter((t) => !filter.includes(t.typ));
|
|
1581
|
+
parseColor(t);
|
|
1479
1582
|
continue;
|
|
1480
1583
|
}
|
|
1481
1584
|
if (t.typ == EnumToken.UrlFunctionTokenType) {
|
|
@@ -1487,6 +1590,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
1487
1590
|
if (t.chi[0].val.slice(1, 5) != 'data:' && urlTokenMatcher.test(value)) {
|
|
1488
1591
|
// @ts-ignore
|
|
1489
1592
|
t.chi[0].typ = EnumToken.UrlTokenTokenType;
|
|
1593
|
+
// console.error({t, v: t.chi[0], value,
|
|
1594
|
+
// src: options.src,
|
|
1595
|
+
// resolved: options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : null,
|
|
1596
|
+
// val2: options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : value});
|
|
1597
|
+
//
|
|
1598
|
+
// console.error(new Error('resolved'));
|
|
1490
1599
|
// @ts-ignore
|
|
1491
1600
|
t.chi[0].val = options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : value;
|
|
1492
1601
|
}
|
|
@@ -1522,7 +1631,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
1522
1631
|
Object.assign(t, {
|
|
1523
1632
|
typ: EnumToken.ColorTokenType,
|
|
1524
1633
|
val: COLORS_NAMES[value].length < value.length ? COLORS_NAMES[value] : value,
|
|
1525
|
-
kin:
|
|
1634
|
+
kin: ColorKind.HEX
|
|
1526
1635
|
});
|
|
1527
1636
|
}
|
|
1528
1637
|
continue;
|
|
@@ -1532,11 +1641,11 @@ function parseTokens(tokens, options = {}) {
|
|
|
1532
1641
|
// @ts-ignore
|
|
1533
1642
|
t.typ = EnumToken.ColorTokenType;
|
|
1534
1643
|
// @ts-ignore
|
|
1535
|
-
t.kin =
|
|
1644
|
+
t.kin = ColorKind.HEX;
|
|
1536
1645
|
}
|
|
1537
1646
|
}
|
|
1538
1647
|
}
|
|
1539
1648
|
return tokens;
|
|
1540
1649
|
}
|
|
1541
1650
|
|
|
1542
|
-
export { doParse, parseSelector, parseString, parseTokens, urlTokenMatcher };
|
|
1651
|
+
export { doParse, parseAtRulePrelude, parseSelector, parseString, parseTokens, urlTokenMatcher };
|