@tbela99/css-parser 0.3.0 → 0.4.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/{LICENSE → LICENSE.md} +1 -1
- package/README.md +191 -80
- package/dist/config.json.js +20 -1
- package/dist/index-umd-web.js +3210 -1352
- package/dist/index.cjs +3211 -1353
- package/dist/index.d.ts +910 -0
- package/dist/lib/ast/expand.js +1 -1
- package/dist/lib/ast/features/calc.js +1 -2
- package/dist/lib/ast/features/inlinecssvariables.js +1 -1
- package/dist/lib/ast/features/shorthand.js +1 -1
- package/dist/lib/ast/math/expression.js +38 -3
- package/dist/lib/ast/math/math.js +2 -2
- package/dist/lib/ast/minify.js +0 -1
- package/dist/lib/ast/types.js +1 -0
- package/dist/lib/ast/utils/minifyfeature.js +4 -3
- package/dist/lib/parser/declaration/list.js +1 -1
- package/dist/lib/parser/declaration/map.js +129 -26
- package/dist/lib/parser/declaration/set.js +1 -1
- package/dist/lib/parser/parse.js +325 -303
- package/dist/lib/parser/tokenize.js +220 -223
- package/dist/lib/parser/utils/declaration.js +1 -1
- package/dist/lib/parser/utils/syntax.js +159 -23
- package/dist/lib/parser/utils/type.js +2 -2
- package/dist/lib/renderer/color/a98rgb.js +64 -0
- package/dist/lib/renderer/color/color.js +521 -0
- package/dist/lib/renderer/color/colormix.js +337 -0
- package/dist/lib/renderer/color/hex.js +92 -0
- package/dist/lib/renderer/color/hsl.js +118 -0
- package/dist/lib/renderer/color/hsv.js +20 -0
- package/dist/lib/renderer/color/hwb.js +101 -0
- package/dist/lib/renderer/color/lab.js +136 -0
- package/dist/lib/renderer/color/lch.js +79 -0
- package/dist/lib/renderer/color/oklab.js +121 -0
- package/dist/lib/renderer/color/oklch.js +65 -0
- package/dist/lib/renderer/color/p3.js +57 -0
- package/dist/lib/renderer/color/prophotorgb.js +56 -0
- package/dist/lib/renderer/color/rec2020.js +70 -0
- package/dist/lib/renderer/color/relativecolor.js +152 -0
- package/dist/lib/renderer/color/rgb.js +44 -0
- package/dist/lib/renderer/color/srgb.js +261 -0
- package/dist/lib/renderer/color/utils/components.js +20 -0
- package/dist/lib/renderer/color/utils/constants.js +191 -0
- package/dist/lib/renderer/color/utils/matrix.js +35 -0
- package/dist/lib/renderer/color/xyz.js +64 -0
- package/dist/lib/renderer/color/xyzd50.js +33 -0
- package/dist/lib/renderer/render.js +61 -32
- package/dist/node/index.js +1 -1
- package/dist/node/load.js +1 -1
- package/dist/web/index.js +1 -1
- package/package.json +15 -14
- package/dist/lib/ast/features/utils/math.js +0 -95
- package/dist/lib/iterable/set.js +0 -48
- package/dist/lib/iterable/weakmap.js +0 -53
- package/dist/lib/renderer/utils/calccolor.js +0 -238
- package/dist/lib/renderer/utils/color.js +0 -371
- package/dist/lib/renderer/utils/hex.js +0 -124
- package/dist/lib/renderer/utils/hsl.js +0 -49
- package/dist/lib/renderer/utils/hsv.js +0 -15
- package/dist/lib/renderer/utils/hwb.js +0 -50
- package/dist/lib/renderer/utils/rgb.js +0 -66
|
@@ -3,7 +3,7 @@ import '../../ast/minify.js';
|
|
|
3
3
|
import { walkValues } from '../../ast/walk.js';
|
|
4
4
|
import '../parse.js';
|
|
5
5
|
import { isWhiteSpace } from './syntax.js';
|
|
6
|
-
import '../../renderer/utils/
|
|
6
|
+
import '../../renderer/color/utils/constants.js';
|
|
7
7
|
import '../../renderer/sourcemap/lib/encode.js';
|
|
8
8
|
|
|
9
9
|
function parseDeclaration(node, errors, src, position) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { colorsFunc } from '../../renderer/render.js';
|
|
2
|
-
import { COLORS_NAMES } from '../../renderer/utils/color.js';
|
|
3
2
|
import { EnumToken } from '../../ast/types.js';
|
|
4
3
|
import '../../ast/minify.js';
|
|
5
4
|
import '../parse.js';
|
|
5
|
+
import { COLORS_NAMES } from '../../renderer/color/utils/constants.js';
|
|
6
6
|
|
|
7
7
|
// https://www.w3.org/TR/CSS21/syndata.html#syntax
|
|
8
8
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
@@ -29,6 +29,30 @@ function isTime(dimension) {
|
|
|
29
29
|
function isFrequency(dimension) {
|
|
30
30
|
return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
|
|
31
31
|
}
|
|
32
|
+
function isColorspace(token) {
|
|
33
|
+
if (token.typ != EnumToken.IdenTokenType) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return ['srgb', 'srgb-linear', 'lab', 'oklab', 'lch', 'oklch', 'xyz', 'xyz-d50', 'xyz-d65', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'rgb', 'hsl', 'hwb'].includes(token.val.toLowerCase());
|
|
37
|
+
}
|
|
38
|
+
function isRectangularOrthogonalColorspace(token) {
|
|
39
|
+
if (token.typ != EnumToken.IdenTokenType) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return ['srgb', 'srgb-linear', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'lab', 'oklab', 'xyz', 'xyz-d50', 'xyz-d65'].includes(token.val.toLowerCase());
|
|
43
|
+
}
|
|
44
|
+
function isPolarColorspace(token) {
|
|
45
|
+
if (token.typ != EnumToken.IdenTokenType) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return ['hsl', 'hwb', 'lch', 'oklch'].includes(token.val);
|
|
49
|
+
}
|
|
50
|
+
function isHueInterpolationMethod(token) {
|
|
51
|
+
if (token.typ != EnumToken.IdenTokenType) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return ['shorter', 'longer', 'increasing', 'decreasing'].includes(token.val);
|
|
55
|
+
}
|
|
32
56
|
function isColor(token) {
|
|
33
57
|
if (token.typ == EnumToken.ColorTokenType) {
|
|
34
58
|
return true;
|
|
@@ -39,36 +63,119 @@ function isColor(token) {
|
|
|
39
63
|
}
|
|
40
64
|
let isLegacySyntax = false;
|
|
41
65
|
if (token.typ == EnumToken.FunctionTokenType && token.chi.length > 0 && colorsFunc.includes(token.val)) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (v.typ == EnumToken.CommaTokenType) {
|
|
51
|
-
isLegacySyntax = true;
|
|
66
|
+
if (token.val == 'color') {
|
|
67
|
+
const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
|
|
68
|
+
const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
|
|
69
|
+
if (children.length < 4 || children.length > 8) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
if (!isRelative && !isColorspace(children[0])) {
|
|
73
|
+
return false;
|
|
52
74
|
}
|
|
53
|
-
|
|
54
|
-
if (
|
|
75
|
+
for (let i = 1; i < children.length - 2; i++) {
|
|
76
|
+
if (children[i].typ == EnumToken.IdenTokenType) {
|
|
77
|
+
if (children[i].val != 'none' &&
|
|
78
|
+
!(isRelative && ['alpha', 'r', 'g', 'b'].includes(children[i].val) || isColorspace(children[i]))) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (children[i].typ == EnumToken.FunctionTokenType && !['calc'].includes(children[i].val)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (children.length == 8 || children.length == 6) {
|
|
87
|
+
const sep = children.at(-2);
|
|
88
|
+
const alpha = children.at(-1);
|
|
89
|
+
if (sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
|
|
55
93
|
return false;
|
|
56
94
|
}
|
|
57
|
-
|
|
58
|
-
|
|
95
|
+
else {
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
if (alpha.typ == EnumToken.PercentageTokenType) {
|
|
98
|
+
if (+alpha.val < 0 || +alpha.val > 100) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (alpha.typ == EnumToken.NumberTokenType) {
|
|
103
|
+
if (+alpha.val < 0 || +alpha.val > 1) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
else if (token.val == 'color-mix') {
|
|
112
|
+
const children = token.chi.reduce((acc, t) => {
|
|
113
|
+
if (t.typ == EnumToken.CommaTokenType) {
|
|
114
|
+
acc.push([]);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
|
|
118
|
+
acc[acc.length - 1].push(t);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return acc;
|
|
122
|
+
}, [[]]);
|
|
123
|
+
if (children.length == 3) {
|
|
124
|
+
if (children[0].length > 3 ||
|
|
125
|
+
children[0][0].typ != EnumToken.IdenTokenType ||
|
|
126
|
+
children[0][0].val != 'in' ||
|
|
127
|
+
!isColorspace(children[0][1]) ||
|
|
128
|
+
(children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
|
|
129
|
+
children[1].length > 2 ||
|
|
130
|
+
children[1][0].typ != EnumToken.ColorTokenType ||
|
|
131
|
+
children[2].length > 2 ||
|
|
132
|
+
children[2][0].typ != EnumToken.ColorTokenType) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
if (children[1].length == 2) {
|
|
136
|
+
if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
|
|
59
137
|
return false;
|
|
60
138
|
}
|
|
61
|
-
|
|
139
|
+
}
|
|
140
|
+
if (children[2].length == 2) {
|
|
141
|
+
if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
|
|
62
142
|
return false;
|
|
63
143
|
}
|
|
64
144
|
}
|
|
65
|
-
|
|
145
|
+
return true;
|
|
66
146
|
}
|
|
67
|
-
|
|
68
|
-
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const keywords = ['from', 'none'];
|
|
151
|
+
if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
|
|
152
|
+
keywords.push('alpha', ...token.val.slice(-3).split(''));
|
|
69
153
|
}
|
|
70
|
-
|
|
71
|
-
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
for (const v of token.chi) {
|
|
156
|
+
if (v.typ == EnumToken.CommaTokenType) {
|
|
157
|
+
isLegacySyntax = true;
|
|
158
|
+
}
|
|
159
|
+
if (v.typ == EnumToken.IdenTokenType) {
|
|
160
|
+
if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (keywords.includes(v.val)) {
|
|
164
|
+
if (isLegacySyntax) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (v.typ == EnumToken.FunctionTokenType && (v.val == 'calc' || v.val == 'var' || colorsFunc.includes(v.val))) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
72
179
|
}
|
|
73
180
|
}
|
|
74
181
|
return true;
|
|
@@ -239,7 +346,11 @@ function parseDimension(name) {
|
|
|
239
346
|
index++;
|
|
240
347
|
break;
|
|
241
348
|
}
|
|
242
|
-
const dimension = {
|
|
349
|
+
const dimension = {
|
|
350
|
+
typ: EnumToken.DimensionTokenType,
|
|
351
|
+
val: name.slice(0, index),
|
|
352
|
+
unit: name.slice(index)
|
|
353
|
+
};
|
|
243
354
|
if (isAngle(dimension)) {
|
|
244
355
|
// @ts-ignore
|
|
245
356
|
dimension.typ = EnumToken.AngleTokenType;
|
|
@@ -281,6 +392,31 @@ function isHexColor(name) {
|
|
|
281
392
|
}
|
|
282
393
|
return true;
|
|
283
394
|
}
|
|
395
|
+
/*
|
|
396
|
+
export function isHexDigit(name: string): boolean {
|
|
397
|
+
|
|
398
|
+
if (name.length || name.length > 6) {
|
|
399
|
+
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
for (let chr of name) {
|
|
404
|
+
|
|
405
|
+
let codepoint = <number>chr.charCodeAt(0);
|
|
406
|
+
|
|
407
|
+
if (!isDigit(codepoint) &&
|
|
408
|
+
// A F
|
|
409
|
+
!(codepoint >= 0x41 && codepoint <= 0x46) &&
|
|
410
|
+
// a f
|
|
411
|
+
!(codepoint >= 0x61 && codepoint <= 0x66)) {
|
|
412
|
+
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
*/
|
|
284
420
|
function isFunction(name) {
|
|
285
421
|
return name.endsWith('(') && isIdent(name.slice(0, -1));
|
|
286
422
|
}
|
|
@@ -297,4 +433,4 @@ function isWhiteSpace(codepoint) {
|
|
|
297
433
|
codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
|
|
298
434
|
}
|
|
299
435
|
|
|
300
|
-
export { isAngle, isAtKeyword, isColor, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|
|
436
|
+
export { isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, parseDimension };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EnumToken } from '../../ast/types.js';
|
|
2
2
|
import '../../ast/minify.js';
|
|
3
3
|
import '../parse.js';
|
|
4
|
-
import '../../renderer/utils/
|
|
4
|
+
import '../../renderer/color/utils/constants.js';
|
|
5
5
|
import '../../renderer/sourcemap/lib/encode.js';
|
|
6
6
|
|
|
7
7
|
// https://www.w3.org/TR/css-values-4/#math-function
|
|
@@ -22,7 +22,7 @@ function matchType(val, properties) {
|
|
|
22
22
|
}
|
|
23
23
|
if (val.typ == EnumToken.FunctionTokenType) {
|
|
24
24
|
if (funcList.includes(val.val)) {
|
|
25
|
-
return val.chi.every((t => [EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType].includes(t.typ) || matchType(t, properties)));
|
|
25
|
+
return val.chi.every(((t) => [EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType].includes(t.typ) || matchType(t, properties)));
|
|
26
26
|
}
|
|
27
27
|
// match type defined like function 'symbols()', 'url()', 'attr()' etc.
|
|
28
28
|
// return properties.types.includes((<FunctionToken>val).val + '()')
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { xyz2srgb } from './srgb.js';
|
|
2
|
+
import { multiplyMatrices } from './utils/matrix.js';
|
|
3
|
+
import './utils/constants.js';
|
|
4
|
+
import '../../ast/types.js';
|
|
5
|
+
import '../../ast/minify.js';
|
|
6
|
+
import '../../parser/parse.js';
|
|
7
|
+
import { srgb2xyz } from './xyz.js';
|
|
8
|
+
import '../sourcemap/lib/encode.js';
|
|
9
|
+
|
|
10
|
+
function a98rgb2srgbvalues(r, g, b, a = null) {
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
return xyz2srgb(...la98rgb2xyz(...a98rgb2la98(r, g, b, a)));
|
|
13
|
+
}
|
|
14
|
+
function srgb2a98values(r, g, b, a = null) {
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
return la98rgb2a98rgb(xyz2la98rgb(...srgb2xyz(r, g, b, a)));
|
|
17
|
+
}
|
|
18
|
+
// a98-rgb functions
|
|
19
|
+
function a98rgb2la98(r, g, b, a = null) {
|
|
20
|
+
// convert an array of a98-rgb values in the range 0.0 - 1.0
|
|
21
|
+
// to linear light (un-companded) form.
|
|
22
|
+
// negative values are also now accepted
|
|
23
|
+
return [r, g, b].map(function (val) {
|
|
24
|
+
let sign = val < 0 ? -1 : 1;
|
|
25
|
+
let abs = Math.abs(val);
|
|
26
|
+
return sign * Math.pow(abs, 563 / 256);
|
|
27
|
+
}).concat(a == null || a == 1 ? [] : [a]);
|
|
28
|
+
}
|
|
29
|
+
function la98rgb2a98rgb(r, g, b, a = null) {
|
|
30
|
+
// convert an array of linear-light a98-rgb in the range 0.0-1.0
|
|
31
|
+
// to gamma corrected form
|
|
32
|
+
// negative values are also now accepted
|
|
33
|
+
return [r, b, g].map(function (val) {
|
|
34
|
+
let sign = val < 0 ? -1 : 1;
|
|
35
|
+
let abs = Math.abs(val);
|
|
36
|
+
return sign * Math.pow(abs, 256 / 563);
|
|
37
|
+
}).concat(a == null || a == 1 ? [] : [a]);
|
|
38
|
+
}
|
|
39
|
+
function la98rgb2xyz(r, g, b, a = null) {
|
|
40
|
+
// convert an array of linear-light a98-rgb values to CIE XYZ
|
|
41
|
+
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
42
|
+
// has greater numerical precision than section 4.3.5.3 of
|
|
43
|
+
// https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
|
|
44
|
+
// but the values below were calculated from first principles
|
|
45
|
+
// from the chromaticity coordinates of R G B W
|
|
46
|
+
// see matrixmaker.html
|
|
47
|
+
var M = [
|
|
48
|
+
[573536 / 994567, 263643 / 1420810, 187206 / 994567],
|
|
49
|
+
[591459 / 1989134, 6239551 / 9945670, 374412 / 4972835],
|
|
50
|
+
[53769 / 1989134, 351524 / 4972835, 4929758 / 4972835],
|
|
51
|
+
];
|
|
52
|
+
return multiplyMatrices(M, [r, g, b]).concat(a == null || a == 1 ? [] : [a]);
|
|
53
|
+
}
|
|
54
|
+
function xyz2la98rgb(x, y, z, a = null) {
|
|
55
|
+
// convert XYZ to linear-light a98-rgb
|
|
56
|
+
var M = [
|
|
57
|
+
[1829569 / 896150, -506331 / 896150, -308931 / 896150],
|
|
58
|
+
[-851781 / 878810, 1648619 / 878810, 36519 / 878810],
|
|
59
|
+
[16779 / 1248040, -147721 / 1248040, 1266979 / 1248040],
|
|
60
|
+
];
|
|
61
|
+
return multiplyMatrices(M, [x, y, z]).concat(a == null || a == 1 ? [] : [a]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { a98rgb2srgbvalues, srgb2a98values };
|