@tbela99/css-parser 0.2.0 → 0.3.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 +62 -0
- package/dist/config.json.js +225 -0
- package/dist/index-umd-web.js +1404 -604
- package/dist/index.cjs +1404 -604
- package/dist/lib/ast/features/calc.js +30 -190
- package/dist/lib/ast/features/index.js +3 -3
- package/dist/lib/ast/features/inlinecssvariables.js +5 -5
- package/dist/lib/ast/features/shorthand.js +4 -5
- package/dist/lib/ast/math/expression.js +185 -0
- package/dist/lib/ast/math/math.js +95 -0
- package/dist/lib/ast/types.js +30 -13
- package/dist/lib/ast/walk.js +24 -4
- package/dist/lib/fs/resolve.js +4 -3
- package/dist/lib/iterable/weakset.js +48 -0
- package/dist/lib/parser/declaration/list.js +5 -1
- package/dist/lib/parser/declaration/map.js +44 -13
- package/dist/lib/parser/declaration/set.js +41 -21
- package/dist/lib/parser/parse.js +30 -56
- package/dist/lib/parser/utils/declaration.js +67 -0
- package/dist/lib/parser/utils/syntax.js +32 -2
- package/dist/lib/renderer/render.js +77 -8
- package/dist/lib/renderer/utils/calccolor.js +238 -0
- package/dist/lib/renderer/utils/color.js +36 -164
- package/dist/lib/renderer/utils/hex.js +124 -0
- package/dist/lib/renderer/utils/hsl.js +49 -0
- package/dist/lib/renderer/utils/hsv.js +15 -0
- package/dist/lib/renderer/utils/hwb.js +50 -0
- package/dist/lib/renderer/utils/rgb.js +66 -0
- package/package.json +5 -5
- package/dist/index.d.ts +0 -862
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { EnumToken } from '../../ast/types.js';
|
|
2
|
+
import '../../ast/minify.js';
|
|
3
|
+
import '../../parser/parse.js';
|
|
4
|
+
import { getNumber, getAngle } from './color.js';
|
|
5
|
+
import { hsl2rgb } from './rgb.js';
|
|
6
|
+
import '../sourcemap/lib/encode.js';
|
|
7
|
+
|
|
8
|
+
function rgb2Hex(token) {
|
|
9
|
+
let value = '#';
|
|
10
|
+
let t;
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
for (let i = 0; i < 3; i++) {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
t = token.chi[i];
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
value += (t.val == 'none' ? '0' : Math.round(t.typ == EnumToken.PercentageTokenType ? 255 * t.val / 100 : t.val)).toString(16).padStart(2, '0');
|
|
17
|
+
}
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
if (token.chi.length == 4) {
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
t = token.chi[3];
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
if ((t.typ == EnumToken.IdenTokenType && t.val == 'none') ||
|
|
24
|
+
(t.typ == EnumToken.NumberTokenType && +t.val < 1) ||
|
|
25
|
+
(t.typ == EnumToken.PercentageTokenType && +t.val < 100)) {
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
value += Math.round(255 * getNumber(t)).toString(16).padStart(2, '0');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function hsl2Hex(token) {
|
|
33
|
+
let t;
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
let h = getAngle(token.chi[0]);
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
t = token.chi[1];
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
let s = getNumber(t);
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
t = token.chi[2];
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
let l = getNumber(t);
|
|
44
|
+
let a = null;
|
|
45
|
+
if (token.chi?.length == 4) {
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
t = token.chi[3];
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
if ((t.typ == EnumToken.IdenTokenType && t.val == 'none') || (t.typ == EnumToken.PercentageTokenType && +t.val < 100) ||
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
(t.typ == EnumToken.NumberTokenType && t.val < 1)) {
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
a = getNumber(t);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return `#${hsl2rgb(h, s, l, a).reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
|
|
57
|
+
}
|
|
58
|
+
function hwb2hex(token) {
|
|
59
|
+
let t;
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
let h = getAngle(token.chi[0]);
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
t = token.chi[1];
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
let white = getNumber(t);
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
t = token.chi[2];
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
let black = getNumber(t);
|
|
70
|
+
let a = null;
|
|
71
|
+
if (token.chi?.length == 4) {
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
t = token.chi[3];
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
if ((t.typ == EnumToken.IdenTokenType && t.val == 'none') ||
|
|
76
|
+
(t.typ == EnumToken.PercentageTokenType && +t.val < 100) ||
|
|
77
|
+
(t.typ == EnumToken.NumberTokenType && +t.val < 1)) {
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
a = getNumber(t);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const rgb = hsl2rgb(h, 1, .5, a);
|
|
83
|
+
let value;
|
|
84
|
+
for (let i = 0; i < 3; i++) {
|
|
85
|
+
value = rgb[i] / 255;
|
|
86
|
+
value *= (1 - white - black);
|
|
87
|
+
value += white;
|
|
88
|
+
rgb[i] = Math.round(value * 255);
|
|
89
|
+
}
|
|
90
|
+
return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
|
|
91
|
+
}
|
|
92
|
+
function cmyk2hex(token) {
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
let t = token.chi[0];
|
|
95
|
+
// @ts-ignore
|
|
96
|
+
const c = getNumber(t);
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
t = token.chi[1];
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
const m = getNumber(t);
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
t = token.chi[2];
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
const y = getNumber(t);
|
|
105
|
+
// @ts-ignore
|
|
106
|
+
t = token.chi[3];
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
const k = getNumber(t);
|
|
109
|
+
const rgb = [
|
|
110
|
+
Math.round(255 * (1 - Math.min(1, c * (1 - k) + k))),
|
|
111
|
+
Math.round(255 * (1 - Math.min(1, m * (1 - k) + k))),
|
|
112
|
+
Math.round(255 * (1 - Math.min(1, y * (1 - k) + k)))
|
|
113
|
+
];
|
|
114
|
+
// @ts-ignore
|
|
115
|
+
if (token.chi.length >= 9) {
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
t = token.chi[8];
|
|
118
|
+
// @ts-ignore
|
|
119
|
+
rgb.push(Math.round(255 * getNumber(t)));
|
|
120
|
+
}
|
|
121
|
+
return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { cmyk2hex, hsl2Hex, hwb2hex, rgb2Hex };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { hwb2hsv } from './hsv.js';
|
|
2
|
+
|
|
3
|
+
function rgb2hsl(r, g, b, a) {
|
|
4
|
+
r /= 255;
|
|
5
|
+
g /= 255;
|
|
6
|
+
b /= 255;
|
|
7
|
+
let max = Math.max(r, g, b);
|
|
8
|
+
let min = Math.min(r, g, b);
|
|
9
|
+
let h = 0;
|
|
10
|
+
let s = 0;
|
|
11
|
+
let l = (max + min) / 2;
|
|
12
|
+
if (max != min) {
|
|
13
|
+
let d = max - min;
|
|
14
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
15
|
+
switch (max) {
|
|
16
|
+
case r:
|
|
17
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
18
|
+
break;
|
|
19
|
+
case g:
|
|
20
|
+
h = (b - r) / d + 2;
|
|
21
|
+
break;
|
|
22
|
+
case b:
|
|
23
|
+
h = (r - g) / d + 4;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
h /= 6;
|
|
27
|
+
}
|
|
28
|
+
return [h, s, l, a == 1 ? null : a ?? null];
|
|
29
|
+
}
|
|
30
|
+
// https://gist.github.com/defims/0ca2ef8832833186ed396a2f8a204117#file-annotated-js
|
|
31
|
+
function hsv2hsl(h, s, v) {
|
|
32
|
+
return [
|
|
33
|
+
//[hue, saturation, lightness]
|
|
34
|
+
//Range should be between 0 - 1
|
|
35
|
+
h,
|
|
36
|
+
//Saturation is very different between the two color spaces
|
|
37
|
+
//If (2-sat)*val < 1 set it to sat*val/((2-sat)*val)
|
|
38
|
+
//Otherwise sat*val/(2-(2-sat)*val)
|
|
39
|
+
//Conditional is not operating with hue, it is reassigned!
|
|
40
|
+
s * v / ((h = (2 - s) * v) < 1 ? h : 2 - h),
|
|
41
|
+
h / 2 //Lightness is (2-sat)*val/2
|
|
42
|
+
//See reassignment of hue above
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
function hwb2hsl(h, w, b) {
|
|
46
|
+
return hsv2hsl(...hwb2hsv(h, w, b));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { hsv2hsl, hwb2hsl, rgb2hsl };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function hwb2hsv(h, w, b) {
|
|
2
|
+
return [h, 1 - w / (1 - b), 1 - b];
|
|
3
|
+
}
|
|
4
|
+
// https://gist.github.com/defims/0ca2ef8832833186ed396a2f8a204117#file-annotated-js
|
|
5
|
+
function hsl2hsv(h, s, l) {
|
|
6
|
+
s *= l < .5 ? l : 1 - l;
|
|
7
|
+
return [
|
|
8
|
+
//Range should be between 0 - 1
|
|
9
|
+
h,
|
|
10
|
+
2 * s / (l + s),
|
|
11
|
+
l + s //Value
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { hsl2hsv, hwb2hsv };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { hsl2hsv } from './hsv.js';
|
|
2
|
+
|
|
3
|
+
function rgb2hue(r, g, b, fallback = 0) {
|
|
4
|
+
let value = rgb2value(r, g, b);
|
|
5
|
+
let whiteness = rgb2whiteness(r, g, b);
|
|
6
|
+
let delta = value - whiteness;
|
|
7
|
+
if (delta > 0) {
|
|
8
|
+
// calculate segment
|
|
9
|
+
let segment = value === r ? (g - b) / delta : (value === g
|
|
10
|
+
? (b - r) / delta
|
|
11
|
+
: (r - g) / delta);
|
|
12
|
+
// calculate shift
|
|
13
|
+
let shift = value === r ? segment < 0
|
|
14
|
+
? 360 / 60
|
|
15
|
+
: 0 / 60 : (value === g
|
|
16
|
+
? 120 / 60
|
|
17
|
+
: 240 / 60);
|
|
18
|
+
// calculate hue
|
|
19
|
+
return (segment + shift) * 60;
|
|
20
|
+
}
|
|
21
|
+
return fallback;
|
|
22
|
+
}
|
|
23
|
+
function rgb2value(r, g, b) {
|
|
24
|
+
return Math.max(r, g, b);
|
|
25
|
+
}
|
|
26
|
+
function rgb2whiteness(r, g, b) {
|
|
27
|
+
return Math.min(r, g, b);
|
|
28
|
+
}
|
|
29
|
+
function rgb2hwb(r, g, b, a = null, fallback = 0) {
|
|
30
|
+
r *= 100 / 255;
|
|
31
|
+
g *= 100 / 255;
|
|
32
|
+
b *= 100 / 255;
|
|
33
|
+
let hue = rgb2hue(r, g, b, fallback);
|
|
34
|
+
let whiteness = rgb2whiteness(r, g, b);
|
|
35
|
+
let value = Math.round(rgb2value(r, g, b));
|
|
36
|
+
let blackness = 100 - value;
|
|
37
|
+
const result = [hue / 360, whiteness / 100, blackness / 100];
|
|
38
|
+
if (a != null) {
|
|
39
|
+
result.push(a);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function hsv2hwb(h, s, v) {
|
|
44
|
+
return [h, (1 - s) * v, 1 - v];
|
|
45
|
+
}
|
|
46
|
+
function hsl2hwb(h, s, l) {
|
|
47
|
+
return hsv2hwb(...hsl2hsv(h, s, l));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { hsl2hwb, hsv2hwb, rgb2hwb };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
function hwb2rgb(hue, white, black, alpha = null) {
|
|
2
|
+
const rgb = hsl2rgb(hue, 1, .5);
|
|
3
|
+
for (let i = 0; i < 3; i++) {
|
|
4
|
+
rgb[i] *= (1 - white - black);
|
|
5
|
+
rgb[i] = Math.round(rgb[i] + white);
|
|
6
|
+
}
|
|
7
|
+
if (alpha != null && alpha != 1) {
|
|
8
|
+
rgb.push(alpha);
|
|
9
|
+
}
|
|
10
|
+
return rgb;
|
|
11
|
+
}
|
|
12
|
+
function hsl2rgb(h, s, l, a = null) {
|
|
13
|
+
let v = l <= .5 ? l * (1.0 + s) : l + s - l * s;
|
|
14
|
+
let r = l;
|
|
15
|
+
let g = l;
|
|
16
|
+
let b = l;
|
|
17
|
+
if (v > 0) {
|
|
18
|
+
let m = l + l - v;
|
|
19
|
+
let sv = (v - m) / v;
|
|
20
|
+
h *= 6.0;
|
|
21
|
+
let sextant = Math.floor(h);
|
|
22
|
+
let fract = h - sextant;
|
|
23
|
+
let vsf = v * sv * fract;
|
|
24
|
+
let mid1 = m + vsf;
|
|
25
|
+
let mid2 = v - vsf;
|
|
26
|
+
switch (sextant) {
|
|
27
|
+
case 0:
|
|
28
|
+
r = v;
|
|
29
|
+
g = mid1;
|
|
30
|
+
b = m;
|
|
31
|
+
break;
|
|
32
|
+
case 1:
|
|
33
|
+
r = mid2;
|
|
34
|
+
g = v;
|
|
35
|
+
b = m;
|
|
36
|
+
break;
|
|
37
|
+
case 2:
|
|
38
|
+
r = m;
|
|
39
|
+
g = v;
|
|
40
|
+
b = mid1;
|
|
41
|
+
break;
|
|
42
|
+
case 3:
|
|
43
|
+
r = m;
|
|
44
|
+
g = mid2;
|
|
45
|
+
b = v;
|
|
46
|
+
break;
|
|
47
|
+
case 4:
|
|
48
|
+
r = mid1;
|
|
49
|
+
g = m;
|
|
50
|
+
b = v;
|
|
51
|
+
break;
|
|
52
|
+
case 5:
|
|
53
|
+
r = v;
|
|
54
|
+
g = m;
|
|
55
|
+
b = mid2;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const values = [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
|
60
|
+
if (a != null && a != 1) {
|
|
61
|
+
values.push(Math.round(a * 255));
|
|
62
|
+
}
|
|
63
|
+
return values;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { hsl2rgb, hwb2rgb };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tbela99/css-parser",
|
|
3
3
|
"description": "CSS parser for node and the browser",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/node/index.js",
|
|
7
7
|
"./umd": "./dist/index-umd-web.js",
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
"typings": "dist/index.d.ts",
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "rollup -c;./build.sh dist/index.d.ts 'declare interface' 'declare type'",
|
|
15
|
-
"test": "web-test-runner \"test
|
|
16
|
-
"test:cov": "c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' \"test
|
|
17
|
-
"test:web-cov": "web-test-runner
|
|
15
|
+
"test": "web-test-runner \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=.; mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"",
|
|
16
|
+
"test:cov": "c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"",
|
|
17
|
+
"test:web-cov": "web-test-runner \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=. --coverage",
|
|
18
18
|
"profile": "node --inspect-brk test/inspect.mjs",
|
|
19
|
-
"debug": "web-test-runner \"test
|
|
19
|
+
"debug": "web-test-runner \"test/**/web.spec.js\" --manual --open --node-resolve --root-dir=."
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|