Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for new HSL syntax along side legacy one #917

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/lib/colors/strategies/hsl-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import { DOT_VALUE, ALPHA, EOL } from '../../util/regexp';
import ColorStrategy from './__strategy-base';

const R_HUE = `\\d*${DOT_VALUE}?`;
const R_SATURATION = `(?:\\d{1,3}${DOT_VALUE}?|${DOT_VALUE})%`;
const R_SATURATION = `(?:\\d{1,3}${DOT_VALUE}?|${DOT_VALUE})`;
const R_LUMINANCE = R_SATURATION;
const R_ALPHA = `([ ,]\\s*${ALPHA}\\s*|\\s*\\/\\s*${R_SATURATION}%?\\s*)?`;

const HSL_NEW_SYNTAX = `hsla?\\(\\s*${R_HUE}(deg)?\\s*\\s*${R_SATURATION}%?\\s*\\s*${R_LUMINANCE}%?\\s*${R_ALPHA}\\)`;
const HSL_LEGACY_SYNTAX = `hsl\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}%\\s*,\\s*${R_LUMINANCE}%\\s*\\)`;
const HSLA_LEGACY_SYNTAX = `hsla\\(\\s*${R_HUE}\\s*,\\s*${R_SATURATION}%\\s*,\\s*${R_LUMINANCE}%\\s*,\\s*${ALPHA}\\s*\\)`;

export const REGEXP = new RegExp(
`((?: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}`,
`(${HSL_LEGACY_SYNTAX}|${HSLA_LEGACY_SYNTAX}|${HSL_NEW_SYNTAX})${EOL}`,
'gi',
);
export const REGEXP_ONE = new RegExp(
`^((?: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}`,
`^(${HSL_LEGACY_SYNTAX}|${HSLA_LEGACY_SYNTAX}|${HSL_NEW_SYNTAX})${EOL}`,
'i',
);
// 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;
Expand All @@ -30,7 +35,9 @@ function extractHSLValue(value: string) {
.replace(/hsl(a){0,1}\(/, '')
.replace(/\)/, '')
.replace(/%/g, '')
.split(/,/gi)
.replace(/deg/, '')
.replaceAll(',', ' ')
.split(/\s+/)
.map((c) => parseFloat(c));
return [h, s, l, a];
}
Expand Down
142 changes: 142 additions & 0 deletions test/unit/color-extractor-strategies/hsl-extractor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,36 @@ import { describe, it } from 'mocha';

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

describe('Test hsl(a) color Regex', () => {
it('Should match new hsl syntax', function () {
assert.equal(
regex_exec('hsl(120deg 75% 25%)', REGEXP)[1],
'hsl(120deg 75% 25%)',
);
assert.equal(
regex_exec('hsl(120 75 25)', REGEXP)[1],
'hsl(120 75 25)',
); /* deg and % units are optional */
assert.equal(
regex_exec('hsl(120deg 75% 25% / 60%)', REGEXP)[1],
'hsl(120deg 75% 25% / 60%)',
);
assert.equal(
regex_exec('hsl(120deg 75% 25)', REGEXP)[1],
'hsl(120deg 75% 25)',
);
assert.equal(
regex_exec('hsl(120deg 75 25%)', REGEXP)[1],
'hsl(120deg 75 25%)',
);
assert.equal(regex_exec('hsl(120 75% 25%)', REGEXP)[1], 'hsl(120 75% 25%)');
// assert.equal(
// regex_exec('hsl(none 75% 25%)', REGEXP)[1],
// 'hsl(120deg 75% 25% / 60%)',
// ); // Not supported yet
});
it('Should match a simple hsl color', function () {
assert.equal(
regex_exec('hsl(200, 10%, 10%)', REGEXP)[1],
Expand Down Expand Up @@ -135,3 +163,117 @@ describe('Test hsl(a) color Regex', () => {
);
});
});

describe('Extract color', () => {
it('Should match new hsl syntax', function () {
assert.deepEqual(
HSLStrategy.extractColor('hsl(120deg 75% 25%)')?.rgb,
[16, 112, 16],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(120 75 25)')?.rgb,
[16, 112, 16],
); /* deg and % units are optional */
assert.deepEqual(
HSLStrategy.extractColor('hsl(120deg 75% 25% / 60%)')?.rgb,
[16, 112, 16],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(120deg 75% 25)')?.rgb,
[16, 112, 16],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(120deg 75 25%)')?.rgb,
[16, 112, 16],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(120 75% 25%)')?.rgb,
[16, 112, 16],
);
// assert.equal(
// regex_exec('hsl(none 75% 25%)'),
// 'hsl(120deg 75% 25% / 60%)',
// ); // Not supported yet
});
it('Should match a simple hsl color', function () {
assert.deepEqual(
HSLStrategy.extractColor('hsl(200, 10%, 10%)')?.rgb,
[23, 26, 28],
);
});
it('Should match a simple hsla color', function () {
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10%, 0)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10%, 0.3)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10%, .3)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10%, 1)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10%, 1.0)')?.rgb,
[23, 26, 28],
);
});
it('Should accept dot values (hsl)', function () {
assert.deepEqual(
HSLStrategy.extractColor('hsl(200.1, 10%, 10%)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(200, 10.1%, 10%)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(200, 10%, 10.1%)')?.rgb,
[23, 27, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(200, 10%, 10.1111111%)')?.rgb,
[23, 27, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(200.1, 10.1%, 10.1%)')?.rgb,
[23, 27, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsl(.1, 10.1%, 10.1%)')?.rgb,
[28, 23, 23],
);
});

it('Should accept dot values (hsla)', function () {
assert.deepEqual(
HSLStrategy.extractColor('hsla(200.1, 10%, 10%, 1)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10.1%, 10%, 1)')?.rgb,
[23, 26, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10.1%, 1)')?.rgb,
[23, 27, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200, 10%, 10.1%, 1.0)')?.rgb,
[23, 27, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(200.1, 10.1%, 10.1%, 1)')?.rgb,
[23, 27, 28],
);
assert.deepEqual(
HSLStrategy.extractColor('hsla(.1, 10.1%, 10.1%, 1)')?.rgb,
[28, 23, 23],
);
});
});