Skip to content

Commit 726e09b

Browse files
authored
Merge pull request #917 from KamiKillertO/hsl_new_syntax
feat: Add support for new HSL syntax along side legacy one
2 parents e7663b5 + 96bfb41 commit 726e09b

File tree

2 files changed

+153
-4
lines changed

2 files changed

+153
-4
lines changed

src/lib/colors/strategies/hsl-strategy.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@ import { DOT_VALUE, ALPHA, EOL } from '../../util/regexp';
55
import ColorStrategy from './__strategy-base';
66

77
const R_HUE = `\\d*${DOT_VALUE}?`;
8-
const R_SATURATION = `(?:\\d{1,3}${DOT_VALUE}?|${DOT_VALUE})%`;
8+
const R_SATURATION = `(?:\\d{1,3}${DOT_VALUE}?|${DOT_VALUE})`;
99
const R_LUMINANCE = R_SATURATION;
10+
const R_ALPHA = `([ ,]\\s*${ALPHA}\\s*|\\s*\\/\\s*${R_SATURATION}%?\\s*)?`;
11+
12+
const HSL_NEW_SYNTAX = `hsla?\\(\\s*${R_HUE}(deg)?\\s*\\s*${R_SATURATION}%?\\s*\\s*${R_LUMINANCE}%?\\s*${R_ALPHA}\\)`;
13+
const HSL_LEGACY_SYNTAX = `hsl\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}%\\s*,\\s*${R_LUMINANCE}%\\s*\\)`;
14+
const HSLA_LEGACY_SYNTAX = `hsla\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}%\\s*,\\s*${R_LUMINANCE}%\\s*,\\s*${ALPHA}\\s*\\)`;
1015

1116
export const REGEXP = new RegExp(
12-
`((?:hsl\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}\\s*,\\s*${R_LUMINANCE}\\s*\\))|(?:hsla\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}\\s*,\\s*${R_LUMINANCE}\\s*,\\s*${ALPHA}\\s*\\)))${EOL}`,
17+
`(${HSL_LEGACY_SYNTAX}|${HSLA_LEGACY_SYNTAX}|${HSL_NEW_SYNTAX})${EOL}`,
1318
'gi',
1419
);
1520
export const REGEXP_ONE = new RegExp(
16-
`^((?:hsl\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}\\s*,\\s*${R_LUMINANCE}\\s*\\))|(?:hsla\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}\\s*,\\s*${R_LUMINANCE}\\s*,\\s*${ALPHA}\\s*\\)))${EOL}`,
21+
`^(${HSL_LEGACY_SYNTAX}|${HSLA_LEGACY_SYNTAX}|${HSL_NEW_SYNTAX})${EOL}`,
1722
'i',
1823
);
1924
// export const REGEXP_ONE = /^((?:hsl\(\d*\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\))|(?:hsla\(\d*\s*,\s*(?:\d{1,3}%\s*,\s*){2}(?:[0-1]|1\.0|[0](?:\.\d+){0,1}|(?:\.\d+))\)))(?:$|"|'|,| |;|\)|\r|\n)/i;
@@ -30,7 +35,9 @@ function extractHSLValue(value: string) {
3035
.replace(/hsl(a){0,1}\(/, '')
3136
.replace(/\)/, '')
3237
.replace(/%/g, '')
33-
.split(/,/gi)
38+
.replace(/deg/, '')
39+
.replaceAll(',', ' ')
40+
.split(/\s+/)
3441
.map((c) => parseFloat(c));
3542
return [h, s, l, a];
3643
}

test/unit/color-extractor-strategies/hsl-extractor.test.ts

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,36 @@ import { describe, it } from 'mocha';
33

44
import { REGEXP } from '../../../src/lib/colors/strategies/hsl-strategy';
55
import { regex_exec } from '../../test-util';
6+
import HSLStrategy from '../../../src/lib/colors/strategies/hsl-strategy';
67

78
describe('Test hsl(a) color Regex', () => {
9+
it('Should match new hsl syntax', function () {
10+
assert.equal(
11+
regex_exec('hsl(120deg 75% 25%)', REGEXP)[1],
12+
'hsl(120deg 75% 25%)',
13+
);
14+
assert.equal(
15+
regex_exec('hsl(120 75 25)', REGEXP)[1],
16+
'hsl(120 75 25)',
17+
); /* deg and % units are optional */
18+
assert.equal(
19+
regex_exec('hsl(120deg 75% 25% / 60%)', REGEXP)[1],
20+
'hsl(120deg 75% 25% / 60%)',
21+
);
22+
assert.equal(
23+
regex_exec('hsl(120deg 75% 25)', REGEXP)[1],
24+
'hsl(120deg 75% 25)',
25+
);
26+
assert.equal(
27+
regex_exec('hsl(120deg 75 25%)', REGEXP)[1],
28+
'hsl(120deg 75 25%)',
29+
);
30+
assert.equal(regex_exec('hsl(120 75% 25%)', REGEXP)[1], 'hsl(120 75% 25%)');
31+
// assert.equal(
32+
// regex_exec('hsl(none 75% 25%)', REGEXP)[1],
33+
// 'hsl(120deg 75% 25% / 60%)',
34+
// ); // Not supported yet
35+
});
836
it('Should match a simple hsl color', function () {
937
assert.equal(
1038
regex_exec('hsl(200, 10%, 10%)', REGEXP)[1],
@@ -135,3 +163,117 @@ describe('Test hsl(a) color Regex', () => {
135163
);
136164
});
137165
});
166+
167+
describe('Extract color', () => {
168+
it('Should match new hsl syntax', function () {
169+
assert.deepEqual(
170+
HSLStrategy.extractColor('hsl(120deg 75% 25%)')?.rgb,
171+
[16, 112, 16],
172+
);
173+
assert.deepEqual(
174+
HSLStrategy.extractColor('hsl(120 75 25)')?.rgb,
175+
[16, 112, 16],
176+
); /* deg and % units are optional */
177+
assert.deepEqual(
178+
HSLStrategy.extractColor('hsl(120deg 75% 25% / 60%)')?.rgb,
179+
[16, 112, 16],
180+
);
181+
assert.deepEqual(
182+
HSLStrategy.extractColor('hsl(120deg 75% 25)')?.rgb,
183+
[16, 112, 16],
184+
);
185+
assert.deepEqual(
186+
HSLStrategy.extractColor('hsl(120deg 75 25%)')?.rgb,
187+
[16, 112, 16],
188+
);
189+
assert.deepEqual(
190+
HSLStrategy.extractColor('hsl(120 75% 25%)')?.rgb,
191+
[16, 112, 16],
192+
);
193+
// assert.equal(
194+
// regex_exec('hsl(none 75% 25%)'),
195+
// 'hsl(120deg 75% 25% / 60%)',
196+
// ); // Not supported yet
197+
});
198+
it('Should match a simple hsl color', function () {
199+
assert.deepEqual(
200+
HSLStrategy.extractColor('hsl(200, 10%, 10%)')?.rgb,
201+
[23, 26, 28],
202+
);
203+
});
204+
it('Should match a simple hsla color', function () {
205+
assert.deepEqual(
206+
HSLStrategy.extractColor('hsla(200, 10%, 10%, 0)')?.rgb,
207+
[23, 26, 28],
208+
);
209+
assert.deepEqual(
210+
HSLStrategy.extractColor('hsla(200, 10%, 10%, 0.3)')?.rgb,
211+
[23, 26, 28],
212+
);
213+
assert.deepEqual(
214+
HSLStrategy.extractColor('hsla(200, 10%, 10%, .3)')?.rgb,
215+
[23, 26, 28],
216+
);
217+
assert.deepEqual(
218+
HSLStrategy.extractColor('hsla(200, 10%, 10%, 1)')?.rgb,
219+
[23, 26, 28],
220+
);
221+
assert.deepEqual(
222+
HSLStrategy.extractColor('hsla(200, 10%, 10%, 1.0)')?.rgb,
223+
[23, 26, 28],
224+
);
225+
});
226+
it('Should accept dot values (hsl)', function () {
227+
assert.deepEqual(
228+
HSLStrategy.extractColor('hsl(200.1, 10%, 10%)')?.rgb,
229+
[23, 26, 28],
230+
);
231+
assert.deepEqual(
232+
HSLStrategy.extractColor('hsl(200, 10.1%, 10%)')?.rgb,
233+
[23, 26, 28],
234+
);
235+
assert.deepEqual(
236+
HSLStrategy.extractColor('hsl(200, 10%, 10.1%)')?.rgb,
237+
[23, 27, 28],
238+
);
239+
assert.deepEqual(
240+
HSLStrategy.extractColor('hsl(200, 10%, 10.1111111%)')?.rgb,
241+
[23, 27, 28],
242+
);
243+
assert.deepEqual(
244+
HSLStrategy.extractColor('hsl(200.1, 10.1%, 10.1%)')?.rgb,
245+
[23, 27, 28],
246+
);
247+
assert.deepEqual(
248+
HSLStrategy.extractColor('hsl(.1, 10.1%, 10.1%)')?.rgb,
249+
[28, 23, 23],
250+
);
251+
});
252+
253+
it('Should accept dot values (hsla)', function () {
254+
assert.deepEqual(
255+
HSLStrategy.extractColor('hsla(200.1, 10%, 10%, 1)')?.rgb,
256+
[23, 26, 28],
257+
);
258+
assert.deepEqual(
259+
HSLStrategy.extractColor('hsla(200, 10.1%, 10%, 1)')?.rgb,
260+
[23, 26, 28],
261+
);
262+
assert.deepEqual(
263+
HSLStrategy.extractColor('hsla(200, 10%, 10.1%, 1)')?.rgb,
264+
[23, 27, 28],
265+
);
266+
assert.deepEqual(
267+
HSLStrategy.extractColor('hsla(200, 10%, 10.1%, 1.0)')?.rgb,
268+
[23, 27, 28],
269+
);
270+
assert.deepEqual(
271+
HSLStrategy.extractColor('hsla(200.1, 10.1%, 10.1%, 1)')?.rgb,
272+
[23, 27, 28],
273+
);
274+
assert.deepEqual(
275+
HSLStrategy.extractColor('hsla(.1, 10.1%, 10.1%, 1)')?.rgb,
276+
[28, 23, 23],
277+
);
278+
});
279+
});

0 commit comments

Comments
 (0)