@tbela99/css-parser 0.4.0 → 0.5.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/README.md +69 -12
- package/dist/config.json.js +9 -9
- package/dist/index-umd-web.js +382 -340
- package/dist/index.cjs +379 -339
- 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 +200 -175
- 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/quickjs.sh +0 -1
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++) {
|
|
@@ -327,6 +362,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
327
362
|
const root = await options.load(url, options.src).then((src) => {
|
|
328
363
|
return doParse(src, Object.assign({}, options, {
|
|
329
364
|
minify: false,
|
|
365
|
+
setParent: false,
|
|
330
366
|
// @ts-ignore
|
|
331
367
|
src: options.resolve(url, options.src).absolute
|
|
332
368
|
}));
|
|
@@ -360,7 +396,7 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
360
396
|
nam: renderToken(atRule, { removeComments: true }),
|
|
361
397
|
val: raw.join('')
|
|
362
398
|
};
|
|
363
|
-
Object.defineProperty(node, 'raw', {
|
|
399
|
+
Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
|
|
364
400
|
if (delim.typ == EnumToken.BlockStartTokenType) {
|
|
365
401
|
node.chi = [];
|
|
366
402
|
}
|
|
@@ -486,11 +522,6 @@ async function parseNode(results, context, stats, options, errors, src, map) {
|
|
|
486
522
|
}
|
|
487
523
|
}
|
|
488
524
|
}
|
|
489
|
-
function mapToken(token, map) {
|
|
490
|
-
const node = getTokenType(token.token, token.hint);
|
|
491
|
-
map.set(node, token.position);
|
|
492
|
-
return node;
|
|
493
|
-
}
|
|
494
525
|
function parseString(src, options = { location: false }) {
|
|
495
526
|
return parseTokens([...tokenize(src)].map(t => {
|
|
496
527
|
const token = getTokenType(t.token, t.hint);
|
|
@@ -505,13 +536,7 @@ function getTokenType(val, hint) {
|
|
|
505
536
|
throw new Error('empty string?');
|
|
506
537
|
}
|
|
507
538
|
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 });
|
|
539
|
+
return enumTokenHints.has(hint) ? { typ: hint } : { typ: hint, val };
|
|
515
540
|
}
|
|
516
541
|
if (val == ' ') {
|
|
517
542
|
return { typ: EnumToken.WhitespaceTokenType };
|
|
@@ -630,10 +655,10 @@ function getTokenType(val, hint) {
|
|
|
630
655
|
return parseDimension(val);
|
|
631
656
|
}
|
|
632
657
|
const v = val.toLowerCase();
|
|
633
|
-
if (v == 'currentcolor' ||
|
|
658
|
+
if (v == 'currentcolor' || v == 'transparent' || v in COLORS_NAMES) {
|
|
634
659
|
return {
|
|
635
660
|
typ: EnumToken.ColorTokenType,
|
|
636
|
-
val,
|
|
661
|
+
val: v,
|
|
637
662
|
kin: 'lit'
|
|
638
663
|
};
|
|
639
664
|
}
|
|
@@ -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
|
}
|
|
@@ -6,13 +6,12 @@ import { EnumToken } from '../../ast/types.js';
|
|
|
6
6
|
import '../../ast/minify.js';
|
|
7
7
|
import '../../parser/parse.js';
|
|
8
8
|
import { lab2srgb, lch2srgb, oklab2srgb, oklch2srgb } from './srgb.js';
|
|
9
|
-
import { eq } from '../../parser/utils/eq.js';
|
|
10
9
|
import '../sourcemap/lib/encode.js';
|
|
11
10
|
|
|
12
11
|
function rgb2hwb(token) {
|
|
13
12
|
// @ts-ignore
|
|
14
13
|
return srgb2hwb(...getComponents(token).map((t, index) => {
|
|
15
|
-
if (index == 3 &&
|
|
14
|
+
if (index == 3 && t.typ == EnumToken.IdenTokenType && t.val == 'none') {
|
|
16
15
|
return 1;
|
|
17
16
|
}
|
|
18
17
|
return getNumber(t) / 255;
|
|
@@ -21,7 +20,7 @@ function rgb2hwb(token) {
|
|
|
21
20
|
function hsl2hwb(token) {
|
|
22
21
|
// @ts-ignore
|
|
23
22
|
return hsl2hwbvalues(...getComponents(token).map((t, index) => {
|
|
24
|
-
if (index == 3 &&
|
|
23
|
+
if (index == 3 && (t.typ == EnumToken.IdenTokenType && t.val == 'none')) {
|
|
25
24
|
return 1;
|
|
26
25
|
}
|
|
27
26
|
if (index == 0) {
|