@tbela99/css-parser 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -12
- package/dist/config.json.js +9 -9
- package/dist/index-umd-web.js +392 -346
- package/dist/index.cjs +389 -345
- package/dist/index.d.ts +33 -20
- package/dist/lib/ast/features/calc.js +2 -4
- package/dist/lib/ast/features/inlinecssvariables.js +5 -4
- package/dist/lib/ast/features/shorthand.js +2 -3
- package/dist/lib/ast/minify.js +2 -2
- package/dist/lib/ast/walk.js +10 -12
- package/dist/lib/iterable/weakset.js +31 -21
- package/dist/lib/parser/declaration/list.js +1 -6
- package/dist/lib/parser/declaration/map.js +35 -11
- package/dist/lib/parser/declaration/set.js +2 -0
- package/dist/lib/parser/parse.js +210 -181
- package/dist/lib/parser/utils/eq.js +1 -1
- package/dist/lib/parser/utils/syntax.js +9 -5
- package/dist/lib/renderer/color/color.js +38 -1
- package/dist/lib/renderer/color/colormix.js +5 -6
- package/dist/lib/renderer/color/hsl.js +1 -2
- package/dist/lib/renderer/color/hwb.js +2 -3
- package/dist/lib/renderer/color/oklab.js +2 -3
- package/dist/lib/renderer/color/oklch.js +2 -3
- package/dist/lib/renderer/color/relativecolor.js +2 -6
- package/dist/lib/renderer/color/srgb.js +1 -5
- package/dist/lib/renderer/color/utils/constants.js +2 -2
- package/dist/lib/renderer/render.js +16 -3
- package/dist/web/load.js +3 -1
- package/package.json +3 -2
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isPseudo, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isIdent, isHexColor, isHash, isIdentStart, isColor } from './utils/syntax.js';
|
|
2
2
|
import { EnumToken, funcLike } from '../ast/types.js';
|
|
3
|
-
import { minify, combinators } from '../ast/minify.js';
|
|
3
|
+
import { minify, definedPropertySettings, combinators } from '../ast/minify.js';
|
|
4
4
|
import { walkValues, walk } from '../ast/walk.js';
|
|
5
5
|
import { expand } from '../ast/expand.js';
|
|
6
6
|
import { parseDeclaration } from './utils/declaration.js';
|
|
@@ -16,194 +16,229 @@ const BadTokensTypes = [
|
|
|
16
16
|
EnumToken.BadUrlTokenType,
|
|
17
17
|
EnumToken.BadStringTokenType
|
|
18
18
|
];
|
|
19
|
+
const enumTokenHints = new Set([
|
|
20
|
+
EnumToken.WhitespaceTokenType, EnumToken.SemiColonTokenType, EnumToken.ColonTokenType, EnumToken.BlockStartTokenType,
|
|
21
|
+
EnumToken.BlockStartTokenType, EnumToken.AttrStartTokenType, EnumToken.AttrEndTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType,
|
|
22
|
+
EnumToken.CommaTokenType, EnumToken.GtTokenType, EnumToken.LtTokenType, EnumToken.GteTokenType, EnumToken.LteTokenType, EnumToken.CommaTokenType,
|
|
23
|
+
EnumToken.StartMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DashMatchTokenType, EnumToken.ContainMatchTokenType,
|
|
24
|
+
EnumToken.EOFTokenType
|
|
25
|
+
]);
|
|
19
26
|
const webkitPseudoAliasMap = {
|
|
20
27
|
'-webkit-autofill': 'autofill'
|
|
21
28
|
};
|
|
29
|
+
function reject(reason) {
|
|
30
|
+
throw new Error(reason ?? 'Parsing aborted');
|
|
31
|
+
}
|
|
22
32
|
async function doParse(iterator, options = {}) {
|
|
23
|
-
return new Promise(async (resolve, reject) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
// return new Promise(async (resolve, reject) => {
|
|
34
|
+
if (options.signal != null) {
|
|
35
|
+
options.signal.addEventListener('abort', reject);
|
|
36
|
+
}
|
|
37
|
+
options = {
|
|
38
|
+
src: '',
|
|
39
|
+
sourcemap: false,
|
|
40
|
+
minify: true,
|
|
41
|
+
parseColor: true,
|
|
42
|
+
nestingRules: false,
|
|
43
|
+
resolveImport: false,
|
|
44
|
+
resolveUrls: false,
|
|
45
|
+
removeCharset: true,
|
|
46
|
+
removeEmpty: true,
|
|
47
|
+
removeDuplicateDeclarations: true,
|
|
48
|
+
computeShorthand: true,
|
|
49
|
+
computeCalcExpression: true,
|
|
50
|
+
inlineCssVariables: false,
|
|
51
|
+
setParent: true,
|
|
52
|
+
...options
|
|
53
|
+
};
|
|
54
|
+
if (options.expandNestingRules) {
|
|
55
|
+
options.nestingRules = false;
|
|
56
|
+
}
|
|
57
|
+
if (options.resolveImport) {
|
|
58
|
+
options.resolveUrls = true;
|
|
59
|
+
}
|
|
60
|
+
const startTime = performance.now();
|
|
61
|
+
const errors = [];
|
|
62
|
+
const src = options.src;
|
|
63
|
+
const stack = [];
|
|
64
|
+
const stats = {
|
|
65
|
+
bytesIn: 0,
|
|
66
|
+
importedBytesIn: 0,
|
|
67
|
+
parse: `0ms`,
|
|
68
|
+
minify: `0ms`,
|
|
69
|
+
total: `0ms`
|
|
70
|
+
};
|
|
71
|
+
let ast = {
|
|
72
|
+
typ: EnumToken.StyleSheetNodeType,
|
|
73
|
+
chi: []
|
|
74
|
+
};
|
|
75
|
+
let tokens = [];
|
|
76
|
+
let map = new Map;
|
|
77
|
+
let context = ast;
|
|
78
|
+
if (options.sourcemap) {
|
|
79
|
+
ast.loc = {
|
|
80
|
+
sta: {
|
|
81
|
+
ind: 0,
|
|
82
|
+
lin: 1,
|
|
83
|
+
col: 1
|
|
84
|
+
},
|
|
85
|
+
src: ''
|
|
42
86
|
};
|
|
43
|
-
|
|
44
|
-
|
|
87
|
+
}
|
|
88
|
+
const iter = tokenize(iterator);
|
|
89
|
+
let item;
|
|
90
|
+
while (item = iter.next().value) {
|
|
91
|
+
stats.bytesIn = item.bytesIn;
|
|
92
|
+
//
|
|
93
|
+
// doParse error
|
|
94
|
+
if (item.hint != null && BadTokensTypes.includes(item.hint)) {
|
|
95
|
+
// bad token
|
|
96
|
+
continue;
|
|
45
97
|
}
|
|
46
|
-
if (
|
|
47
|
-
|
|
98
|
+
if (item.hint != EnumToken.EOFTokenType) {
|
|
99
|
+
tokens.push(item);
|
|
48
100
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const stats = {
|
|
54
|
-
bytesIn: 0,
|
|
55
|
-
importedBytesIn: 0,
|
|
56
|
-
parse: `0ms`,
|
|
57
|
-
minify: `0ms`,
|
|
58
|
-
total: `0ms`
|
|
59
|
-
};
|
|
60
|
-
let ast = {
|
|
61
|
-
typ: EnumToken.StyleSheetNodeType,
|
|
62
|
-
chi: []
|
|
63
|
-
};
|
|
64
|
-
let tokens = [];
|
|
65
|
-
let map = new Map;
|
|
66
|
-
let context = ast;
|
|
67
|
-
if (options.sourcemap) {
|
|
68
|
-
ast.loc = {
|
|
69
|
-
sta: {
|
|
70
|
-
ind: 0,
|
|
71
|
-
lin: 1,
|
|
72
|
-
col: 1
|
|
73
|
-
},
|
|
74
|
-
src: ''
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
const iter = tokenize(iterator);
|
|
78
|
-
let item;
|
|
79
|
-
while (item = iter.next().value) {
|
|
80
|
-
stats.bytesIn = item.bytesIn;
|
|
81
|
-
//
|
|
82
|
-
// doParse error
|
|
83
|
-
if (item.hint != null && BadTokensTypes.includes(item.hint)) {
|
|
84
|
-
// bad token
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
if (item.hint != EnumToken.EOFTokenType) {
|
|
88
|
-
tokens.push(item);
|
|
89
|
-
}
|
|
90
|
-
if (item.token == ';' || item.token == '{') {
|
|
91
|
-
let node = await parseNode(tokens, context, stats, options, errors, src, map);
|
|
92
|
-
if (node != null) {
|
|
93
|
-
stack.push(node);
|
|
94
|
-
// @ts-ignore
|
|
95
|
-
context = node;
|
|
96
|
-
}
|
|
97
|
-
else if (item.token == '{') {
|
|
98
|
-
// node == null
|
|
99
|
-
// consume and throw away until the closing '}' or EOF
|
|
100
|
-
let inBlock = 1;
|
|
101
|
-
do {
|
|
102
|
-
item = iter.next().value;
|
|
103
|
-
if (item == null) {
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
if (item.token == '{') {
|
|
107
|
-
inBlock++;
|
|
108
|
-
}
|
|
109
|
-
else if (item.token == '}') {
|
|
110
|
-
inBlock--;
|
|
111
|
-
}
|
|
112
|
-
} while (inBlock != 0);
|
|
113
|
-
}
|
|
114
|
-
tokens = [];
|
|
115
|
-
map = new Map;
|
|
116
|
-
}
|
|
117
|
-
else if (item.token == '}') {
|
|
118
|
-
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
119
|
-
const previousNode = stack.pop();
|
|
120
|
-
// @ts-ignore
|
|
121
|
-
context = stack[stack.length - 1] || ast;
|
|
101
|
+
if (item.token == ';' || item.token == '{') {
|
|
102
|
+
let node = await parseNode(tokens, context, stats, options, errors, src, map);
|
|
103
|
+
if (node != null) {
|
|
104
|
+
stack.push(node);
|
|
122
105
|
// @ts-ignore
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
106
|
+
context = node;
|
|
107
|
+
}
|
|
108
|
+
else if (item.token == '{') {
|
|
109
|
+
// node == null
|
|
110
|
+
// consume and throw away until the closing '}' or EOF
|
|
111
|
+
let inBlock = 1;
|
|
112
|
+
do {
|
|
113
|
+
item = iter.next().value;
|
|
114
|
+
if (item == null) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
if (item.token == '{') {
|
|
118
|
+
inBlock++;
|
|
119
|
+
}
|
|
120
|
+
else if (item.token == '}') {
|
|
121
|
+
inBlock--;
|
|
122
|
+
}
|
|
123
|
+
} while (inBlock != 0);
|
|
128
124
|
}
|
|
125
|
+
tokens = [];
|
|
126
|
+
map = new Map;
|
|
129
127
|
}
|
|
130
|
-
if (
|
|
128
|
+
else if (item.token == '}') {
|
|
131
129
|
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
132
|
-
}
|
|
133
|
-
while (stack.length > 0 && context != ast) {
|
|
134
130
|
const previousNode = stack.pop();
|
|
135
131
|
// @ts-ignore
|
|
136
|
-
context = stack[stack.length - 1]
|
|
132
|
+
context = stack[stack.length - 1] || ast;
|
|
137
133
|
// @ts-ignore
|
|
138
134
|
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
139
135
|
context.chi.pop();
|
|
140
|
-
continue;
|
|
141
136
|
}
|
|
142
|
-
|
|
137
|
+
tokens = [];
|
|
138
|
+
map = new Map;
|
|
143
139
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
140
|
+
}
|
|
141
|
+
if (tokens.length > 0) {
|
|
142
|
+
await parseNode(tokens, context, stats, options, errors, src, map);
|
|
143
|
+
}
|
|
144
|
+
while (stack.length > 0 && context != ast) {
|
|
145
|
+
const previousNode = stack.pop();
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
context = stack[stack.length - 1] ?? ast;
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
150
|
+
context.chi.pop();
|
|
151
|
+
continue;
|
|
147
152
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
const endParseTime = performance.now();
|
|
156
|
+
if (options.expandNestingRules) {
|
|
157
|
+
ast = expand(ast);
|
|
158
|
+
}
|
|
159
|
+
if (options.visitor != null) {
|
|
160
|
+
for (const result of walk(ast)) {
|
|
161
|
+
if (result.node.typ == EnumToken.DeclarationNodeType &&
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
(typeof options.visitor.Declaration == 'function' || options.visitor.Declaration?.[result.node.nam] != null)) {
|
|
164
|
+
const callable = typeof options.visitor.Declaration == 'function' ? options.visitor.Declaration : options.visitor.Declaration[result.node.nam];
|
|
165
|
+
const results = await callable(result.node);
|
|
166
|
+
if (results == null || (Array.isArray(results) && results.length == 0)) {
|
|
167
|
+
continue;
|
|
160
168
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
|
|
171
|
+
}
|
|
172
|
+
else if (options.visitor.Rule != null && result.node.typ == EnumToken.RuleNodeType) {
|
|
173
|
+
const results = await options.visitor.Rule(result.node);
|
|
174
|
+
if (results == null || (Array.isArray(results) && results.length == 0)) {
|
|
175
|
+
continue;
|
|
168
176
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
// @ts-ignore
|
|
178
|
+
result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
|
|
179
|
+
}
|
|
180
|
+
else if (options.visitor.AtRule != null &&
|
|
181
|
+
result.node.typ == EnumToken.AtRuleNodeType &&
|
|
182
|
+
// @ts-ignore
|
|
183
|
+
(typeof options.visitor.AtRule == 'function' || options.visitor.AtRule?.[result.node.nam] != null)) {
|
|
184
|
+
const callable = typeof options.visitor.AtRule == 'function' ? options.visitor.AtRule : options.visitor.AtRule[result.node.nam];
|
|
185
|
+
const results = await callable(result.node);
|
|
186
|
+
if (results == null || (Array.isArray(results) && results.length == 0)) {
|
|
187
|
+
continue;
|
|
180
188
|
}
|
|
189
|
+
// @ts-ignore
|
|
190
|
+
result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
|
|
181
191
|
}
|
|
182
192
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
}
|
|
194
|
+
if (options.minify) {
|
|
195
|
+
if (ast.chi.length > 0) {
|
|
196
|
+
minify(ast, options, true, errors, false);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (options.setParent) {
|
|
200
|
+
const nodes = [ast];
|
|
201
|
+
let node;
|
|
202
|
+
while ((node = nodes.shift())) {
|
|
203
|
+
// @ts-ignore
|
|
204
|
+
if (node.chi.length > 0) {
|
|
205
|
+
// @ts-ignore
|
|
206
|
+
for (const child of node.chi) {
|
|
207
|
+
if (child.parent != node) {
|
|
208
|
+
Object.defineProperty(child, 'parent', { ...definedPropertySettings, value: node });
|
|
209
|
+
}
|
|
210
|
+
if ('chi' in child && child.chi.length > 0) {
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
nodes.push(child);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
186
215
|
}
|
|
187
216
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
217
|
+
}
|
|
218
|
+
const endTime = performance.now();
|
|
219
|
+
if (options.signal != null) {
|
|
220
|
+
options.signal.removeEventListener('abort', reject);
|
|
221
|
+
}
|
|
222
|
+
stats.bytesIn += stats.importedBytesIn;
|
|
223
|
+
return {
|
|
224
|
+
ast,
|
|
225
|
+
errors,
|
|
226
|
+
stats: {
|
|
227
|
+
...stats,
|
|
228
|
+
parse: `${(endParseTime - startTime).toFixed(2)}ms`,
|
|
229
|
+
minify: `${(endTime - endParseTime).toFixed(2)}ms`,
|
|
230
|
+
total: `${(endTime - startTime).toFixed(2)}ms`
|
|
191
231
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
ast,
|
|
195
|
-
errors,
|
|
196
|
-
stats: {
|
|
197
|
-
...stats,
|
|
198
|
-
parse: `${(endParseTime - startTime).toFixed(2)}ms`,
|
|
199
|
-
minify: `${(endTime - endParseTime).toFixed(2)}ms`,
|
|
200
|
-
total: `${(endTime - startTime).toFixed(2)}ms`
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
});
|
|
232
|
+
};
|
|
233
|
+
// });
|
|
204
234
|
}
|
|
205
235
|
async function parseNode(results, context, stats, options, errors, src, map) {
|
|
206
|
-
let tokens =
|
|
236
|
+
let tokens = [];
|
|
237
|
+
for (const t of results) {
|
|
238
|
+
const node = getTokenType(t.token, t.hint);
|
|
239
|
+
map.set(node, t.position);
|
|
240
|
+
tokens.push(node);
|
|
241
|
+
}
|
|
207
242
|
let i;
|
|
208
243
|
let loc;
|
|
209
244
|
for (i = 0; i < tokens.length; i++) {
|
|
@@ -311,12 +346,16 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
311
346
|
}
|
|
312
347
|
if (atRule.val == 'import') {
|
|
313
348
|
// @ts-ignore
|
|
314
|
-
if (tokens[0].typ == EnumToken.UrlFunctionTokenType
|
|
315
|
-
tokens.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
349
|
+
if (tokens[0].typ == EnumToken.UrlFunctionTokenType) {
|
|
350
|
+
if (tokens[1].typ == EnumToken.UrlTokenTokenType || tokens[1].typ == EnumToken.StringTokenType) {
|
|
351
|
+
tokens.shift();
|
|
352
|
+
if (tokens[1].typ == EnumToken.UrlTokenTokenType) {
|
|
353
|
+
// @ts-ignore
|
|
354
|
+
tokens[0].typ = EnumToken.StringTokenType;
|
|
355
|
+
// @ts-ignore
|
|
356
|
+
tokens[0].val = `"${tokens[0].val}"`;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
320
359
|
}
|
|
321
360
|
// @ts-ignore
|
|
322
361
|
if (tokens[0].typ == EnumToken.StringTokenType) {
|
|
@@ -327,6 +366,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
327
366
|
const root = await options.load(url, options.src).then((src) => {
|
|
328
367
|
return doParse(src, Object.assign({}, options, {
|
|
329
368
|
minify: false,
|
|
369
|
+
setParent: false,
|
|
330
370
|
// @ts-ignore
|
|
331
371
|
src: options.resolve(url, options.src).absolute
|
|
332
372
|
}));
|
|
@@ -360,7 +400,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
360
400
|
nam: renderToken(atRule, { removeComments: true }),
|
|
361
401
|
val: raw.join('')
|
|
362
402
|
};
|
|
363
|
-
Object.defineProperty(node, 'raw', {
|
|
403
|
+
Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
|
|
364
404
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
365
405
|
node.chi = [];
|
|
366
406
|
}
|
|
@@ -486,11 +526,6 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
486
526
|
}
|
|
487
527
|
}
|
|
488
528
|
}
|
|
489
|
-
function mapToken(token, map) {
|
|
490
|
-
const node = getTokenType(token.token, token.hint);
|
|
491
|
-
map.set(node, token.position);
|
|
492
|
-
return node;
|
|
493
|
-
}
|
|
494
529
|
function parseString(src, options = { location: false }) {
|
|
495
530
|
return parseTokens([...tokenize(src)].map(t => {
|
|
496
531
|
const token = getTokenType(t.token, t.hint);
|
|
@@ -505,13 +540,7 @@ function getTokenType(val, hint) {
|
|
|
505
540
|
throw new Error('empty string?');
|
|
506
541
|
}
|
|
507
542
|
if (hint != null) {
|
|
508
|
-
return (
|
|
509
|
-
EnumToken.WhitespaceTokenType, EnumToken.SemiColonTokenType, EnumToken.ColonTokenType, EnumToken.BlockStartTokenType,
|
|
510
|
-
EnumToken.BlockStartTokenType, EnumToken.AttrStartTokenType, EnumToken.AttrEndTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType,
|
|
511
|
-
EnumToken.CommaTokenType, EnumToken.GtTokenType, EnumToken.LtTokenType, EnumToken.GteTokenType, EnumToken.LteTokenType, EnumToken.CommaTokenType,
|
|
512
|
-
EnumToken.StartMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DashMatchTokenType, EnumToken.ContainMatchTokenType,
|
|
513
|
-
EnumToken.EOFTokenType
|
|
514
|
-
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
543
|
+
return enumTokenHints.has(hint) ? { typ: hint } : { typ: hint, val };
|
|
515
544
|
}
|
|
516
545
|
if (val == ' ') {
|
|
517
546
|
return { typ: EnumToken.WhitespaceTokenType };
|
|
@@ -630,10 +659,10 @@ function getTokenType(val, hint) {
|
|
|
630
659
|
return parseDimension(val);
|
|
631
660
|
}
|
|
632
661
|
const v = val.toLowerCase();
|
|
633
|
-
if (v == 'currentcolor' ||
|
|
662
|
+
if (v == 'currentcolor' || v == 'transparent' || v in COLORS_NAMES) {
|
|
634
663
|
return {
|
|
635
664
|
typ: EnumToken.ColorTokenType,
|
|
636
|
-
val,
|
|
665
|
+
val: v,
|
|
637
666
|
kin: 'lit'
|
|
638
667
|
};
|
|
639
668
|
}
|
|
@@ -8,14 +8,14 @@ import { COLORS_NAMES } from '../../renderer/color/utils/constants.js';
|
|
|
8
8
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
9
9
|
// '\\'
|
|
10
10
|
const REVERSE_SOLIDUS = 0x5c;
|
|
11
|
-
const dimensionUnits = [
|
|
11
|
+
const dimensionUnits = new Set([
|
|
12
12
|
'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
|
|
13
13
|
'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
|
|
14
14
|
'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
|
|
15
15
|
'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
|
|
16
|
-
];
|
|
16
|
+
]);
|
|
17
17
|
function isLength(dimension) {
|
|
18
|
-
return 'unit' in dimension && dimensionUnits.
|
|
18
|
+
return 'unit' in dimension && dimensionUnits.has(dimension.unit.toLowerCase());
|
|
19
19
|
}
|
|
20
20
|
function isResolution(dimension) {
|
|
21
21
|
return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
|
|
@@ -75,7 +75,7 @@ function isColor(token) {
|
|
|
75
75
|
for (let i = 1; i < children.length - 2; i++) {
|
|
76
76
|
if (children[i].typ == EnumToken.IdenTokenType) {
|
|
77
77
|
if (children[i].val != 'none' &&
|
|
78
|
-
!(isRelative && ['alpha', 'r', 'g', 'b'].includes(children[i].val) || isColorspace(children[i]))) {
|
|
78
|
+
!(isRelative && ['alpha', 'r', 'g', 'b', 'x', 'y', 'z'].includes(children[i].val) || isColorspace(children[i]))) {
|
|
79
79
|
return false;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -83,10 +83,14 @@ function isColor(token) {
|
|
|
83
83
|
return false;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
if (children.length == 4 || (isRelative && children.length == 6)) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
86
89
|
if (children.length == 8 || children.length == 6) {
|
|
87
90
|
const sep = children.at(-2);
|
|
88
91
|
const alpha = children.at(-1);
|
|
89
|
-
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
if ((children.length > 6 || !isRelative) && sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
|
|
90
94
|
return false;
|
|
91
95
|
}
|
|
92
96
|
if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
|
|
@@ -328,10 +328,47 @@ function convert(token, to) {
|
|
|
328
328
|
case 'lch':
|
|
329
329
|
values.push(...lch2srgb(token));
|
|
330
330
|
break;
|
|
331
|
-
case '
|
|
331
|
+
case 'oklch':
|
|
332
332
|
// @ts-ignore
|
|
333
333
|
values.push(...srgb2oklch(...color2srgbvalues(token)));
|
|
334
334
|
break;
|
|
335
|
+
case 'color':
|
|
336
|
+
const val = color2srgbvalues(token);
|
|
337
|
+
switch (to) {
|
|
338
|
+
case 'srgb':
|
|
339
|
+
values.push(...val);
|
|
340
|
+
break;
|
|
341
|
+
case 'srgb-linear':
|
|
342
|
+
// @ts-ignore
|
|
343
|
+
values.push(...srgb2lsrgbvalues(...val));
|
|
344
|
+
break;
|
|
345
|
+
case 'display-p3':
|
|
346
|
+
// @ts-ignore
|
|
347
|
+
values.push(...srgb2p3values(...val));
|
|
348
|
+
break;
|
|
349
|
+
case 'prophoto-rgb':
|
|
350
|
+
// @ts-ignore
|
|
351
|
+
values.push(...srgb2prophotorgbvalues(...val));
|
|
352
|
+
break;
|
|
353
|
+
case 'a98-rgb':
|
|
354
|
+
// @ts-ignore
|
|
355
|
+
values.push(...srgb2a98values(...val));
|
|
356
|
+
break;
|
|
357
|
+
case 'rec2020':
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
values.push(...srgb2rec2020values(...val));
|
|
360
|
+
break;
|
|
361
|
+
case 'xyz':
|
|
362
|
+
case 'xyz-d65':
|
|
363
|
+
// @ts-ignore
|
|
364
|
+
values.push(...srgb2xyz(...val));
|
|
365
|
+
break;
|
|
366
|
+
case 'xyz-d50':
|
|
367
|
+
// @ts-ignore
|
|
368
|
+
values.push(...(XYZ_D65_to_D50(...srgb2xyz(...val))));
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
335
372
|
}
|
|
336
373
|
if (values.length > 0) {
|
|
337
374
|
return values2colortoken(values, to);
|
|
@@ -4,7 +4,7 @@ import { EnumToken } from '../../ast/types.js';
|
|
|
4
4
|
import '../../ast/minify.js';
|
|
5
5
|
import { getNumber } from './color.js';
|
|
6
6
|
import { srgb2rgb } from './rgb.js';
|
|
7
|
-
import
|
|
7
|
+
import './utils/constants.js';
|
|
8
8
|
import { getComponents } from './utils/components.js';
|
|
9
9
|
import { srgb2hwb } from './hwb.js';
|
|
10
10
|
import { srgb2hsl } from './hsl.js';
|
|
@@ -12,7 +12,6 @@ import { srgbvalues, srgb2lsrgbvalues } from './srgb.js';
|
|
|
12
12
|
import { srgb2lch, xyz2lchvalues } from './lch.js';
|
|
13
13
|
import { srgb2lab } from './lab.js';
|
|
14
14
|
import { srgb2p3values } from './p3.js';
|
|
15
|
-
import { eq } from '../../parser/utils/eq.js';
|
|
16
15
|
import { srgb2oklch } from './oklch.js';
|
|
17
16
|
import { srgb2oklab } from './oklab.js';
|
|
18
17
|
import { srgb2a98values } from './a98rgb.js';
|
|
@@ -109,10 +108,10 @@ function colorMix(colorSpace, hueInterpolationMethod, color1, percentage1, color
|
|
|
109
108
|
}
|
|
110
109
|
const components1 = getComponents(color1);
|
|
111
110
|
const components2 = getComponents(color2);
|
|
112
|
-
if (
|
|
111
|
+
if ((components1[3] != null && components1[3].typ == EnumToken.IdenTokenType && components1[3].val == 'none') && values2.length == 4) {
|
|
113
112
|
values1[3] = values2[3];
|
|
114
113
|
}
|
|
115
|
-
if (
|
|
114
|
+
if ((components2[3] != null && components2[3].typ == EnumToken.IdenTokenType && components2[3].val == 'none') && values1.length == 4) {
|
|
116
115
|
values2[3] = values1[3];
|
|
117
116
|
}
|
|
118
117
|
const p1 = getNumber(percentage1);
|
|
@@ -224,13 +223,13 @@ function colorMix(colorSpace, hueInterpolationMethod, color1, percentage1, color
|
|
|
224
223
|
const lchSpaces = ['lch', 'oklch'];
|
|
225
224
|
// powerless
|
|
226
225
|
if (lchSpaces.includes(color1.kin) || lchSpaces.includes(colorSpace.val)) {
|
|
227
|
-
if (
|
|
226
|
+
if ((components1[2].typ == EnumToken.IdenTokenType && components1[2].val == 'none') || values1[2] == 0) {
|
|
228
227
|
values1[2] = values2[2];
|
|
229
228
|
}
|
|
230
229
|
}
|
|
231
230
|
// powerless
|
|
232
231
|
if (lchSpaces.includes(color1.kin) || lchSpaces.includes(colorSpace.val)) {
|
|
233
|
-
if (
|
|
232
|
+
if ((components2[2].typ == EnumToken.IdenTokenType && components2[2].val == 'none') || values2[2] == 0) {
|
|
234
233
|
values2[2] = values1[2];
|
|
235
234
|
}
|
|
236
235
|
}
|
|
@@ -3,7 +3,6 @@ import { getNumber } from './color.js';
|
|
|
3
3
|
import { hex2rgb, lab2rgb, lch2rgb, oklab2rgb, oklch2rgb } from './rgb.js';
|
|
4
4
|
import './utils/constants.js';
|
|
5
5
|
import { getComponents } from './utils/components.js';
|
|
6
|
-
import { eq } from '../../parser/utils/eq.js';
|
|
7
6
|
import { EnumToken } from '../../ast/types.js';
|
|
8
7
|
import '../../ast/minify.js';
|
|
9
8
|
import '../../parser/parse.js';
|
|
@@ -32,7 +31,7 @@ function rgb2hsl(token) {
|
|
|
32
31
|
t = chi[3];
|
|
33
32
|
// @ts-ignore
|
|
34
33
|
let a = null;
|
|
35
|
-
if (t != null && !
|
|
34
|
+
if (t != null && !(t.typ == EnumToken.IdenTokenType && t.val == 'none')) {
|
|
36
35
|
// @ts-ignore
|
|
37
36
|
a = getNumber(t) / 255;
|
|
38
37
|
}
|