Skip to content
Open
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
2 changes: 1 addition & 1 deletion packages/css-color-parser/dist/index.mjs

Large diffs are not rendered by default.

30 changes: 28 additions & 2 deletions packages/css-color-parser/src/color-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,9 @@ export function colorDataTo(colorData: ColorData, toNotation: ColorNotation): Co
};

// Change any powerless components in src to missing components
colorData.channels = convertPowerlessComponentsToMissingComponents(colorData.channels, colorData.colorNotation);
Comment thread
romainmenke marked this conversation as resolved.
if (colorData.colorNotation !== toNotation) {
colorData.channels = convertPowerlessComponentsToMissingComponents(colorData.channels, colorData.colorNotation);
}

const outputColorData: ColorData = {
...colorData,
Expand Down Expand Up @@ -582,7 +584,9 @@ export function colorDataTo(colorData: ColorData, toNotation: ColorNotation): Co
}
}

outputColorData.channels = convertPowerlessComponentsToMissingComponents(outputColorData.channels, toNotation);
if (colorData.colorNotation !== toNotation) {
outputColorData.channels = convertPowerlessComponentsToMissingComponents(outputColorData.channels, toNotation);
}

return outputColorData;
}
Expand All @@ -594,24 +598,46 @@ function convertPowerlessComponentsToMissingComponents(a: Color, colorNotation:
case ColorNotation.HSL:
if ((Number.isNaN(out[1]) ? 0 : out[1]) <= 0.001) {
out[0] = Number.NaN;

if ((Number.isNaN(out[1]) ? 0 : out[1]) > 0 && !Number.isNaN(out[1])) {
out[1] = 0;
}
}

break;
case ColorNotation.HWB:
if ((Math.max(0, (Number.isNaN(out[1]) ? 0 : out[1])) + Math.max(0, (Number.isNaN(out[2]) ? 0 : out[2]))) >= 99.999) {
out[0] = Number.NaN;

if ((Math.max(0, (Number.isNaN(out[1]) ? 0 : out[1])) + Math.max(0, (Number.isNaN(out[2]) ? 0 : out[2]))) < 100) {
if (!Number.isNaN(out[1]) && !Number.isNaN(out[2])) {
out[2] = 100 - out[1];
} else if (!Number.isNaN(out[1])) {
out[1] = 100;
} else if (!Number.isNaN(out[2])) {
out[2] = 100;
}
}
}

break;
case ColorNotation.LCH:
if ((Number.isNaN(out[1]) ? 0 : out[1]) <= 0.0015) {
out[2] = Number.NaN;

if ((Number.isNaN(out[1]) ? 0 : out[1]) > 0 && !Number.isNaN(out[1])) {
out[1] = 0;
}
}

break;
case ColorNotation.OKLCH:
if ((Number.isNaN(out[1]) ? 0 : out[1]) <= 0.000004) {
out[2] = Number.NaN;

if ((Number.isNaN(out[1]) ? 0 : out[1]) > 0 && !Number.isNaN(out[1])) {
out[1] = 0;
}
}

break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { parse } from '../util/parse.mjs';
import { serialize_OKLCH_data } from '../util/serialize.mjs';

const tests = [
['color-mix(in oklch, oklch(100% 0% 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.1 0)'],
['color-mix(in oklch, oklch(100% 0% 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.1 30)'],
['color-mix(in oklch, rgb(255, 255, 255), rgb(180, 6, 95))', 'oklch(0.75031 0.10016 359.858)'],
['color-mix(in lch, oklch(75% 0% 60deg), oklch(75% 50% 0deg))', 'oklch(0.74979 0.09824 0.10588)'],
['color-mix(in oklch, oklch(100% 0% none), oklch(50% 50% 0deg))', 'oklch(0.75 0.1 0)'],
['color-mix(in oklch, oklch(100% none 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.2 0)'],
['color-mix(in oklch, oklch(100% none 60deg), oklch(50% 50% 0deg))', 'oklch(0.75 0.2 30)'],

// Analogous sets
['color-mix(in oklch, rgb(none none none), oklch(0.5 0.2 50))', 'oklch(0.5 0.2 50)'],
Expand Down
15 changes: 8 additions & 7 deletions packages/css-color-parser/test/basic/color-mix-function.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,10 @@ const tests = [
['color-mix(in hsl increasing hue, hsl(180deg 50% 50%), hsl(180deg 50% 50%))', canonicalize('hsl(180deg 50% 50%)')],
['color-mix(in hsl decreasing hue, hsl(180deg 50% 50%), hsl(180deg 50% 50%))', canonicalize('hsl(180deg 50% 50%)')],

['color-mix(in hsl, color-mix(in hsl longer hue, hsl(50deg 0% 50%), hsl(50deg 0% 50%)), hsl(180deg 100% 50%))', canonicalize('hsl(180deg 50% 50%)')],
['color-mix(in hsl longer hue, hsl(50deg 0% 50%), hsl(50deg 0% 50%))', canonicalize('hsl(230deg 0% 50%)')],
['color-mix(in hsl, color-mix(in hsl longer hue, hsl(50deg 0% 50%), hsl(50deg 0% 50%)), hsl(180deg 100% 50%))', canonicalize('hsl(205deg 50% 50%)')],

['color-mix(in hsl, hsl(30deg 40% 80% / 25%) 0%, hsl(90deg none none / none))', canonicalize('hsl(30deg 40% 80% / 25%)')],
['color-mix(in hsl, hsl(30deg 40% 80% / 25%) 0%, hsl(90deg none none / none))', canonicalize('hsl(90deg 40% 80% / 25%)')],
['color-mix(in hwb, hwb(30deg 30% 40% / 25%) 0%, hwb(90deg none none / 0.5))', canonicalize('hwb(90deg 30% 40% / 0.5)')],
['color-mix(in hsl, hsl(from hsl(none 50% 50%) h s l), hsl(from hsl(120deg 50% 50%) h s l))', canonicalize('hsl(120deg 50% 50%)')],
['color-mix(in hsl, hsl(from hsl(0deg 50% 50%) none s l), hsl(from hsl(120deg 50% 50%) h s l))', canonicalize('hsl(120deg 50% 50%)')],
Expand Down Expand Up @@ -223,7 +224,7 @@ assert.deepStrictEqual(
color(parse('color-mix(in lch, lch(100 0 40deg), lch(100 0 60deg))')),
{
colorNotation: 'lch',
channels: [100, 0, Number.NaN],
channels: [100, 0, 50],
alpha: 1,
syntaxFlags: new Set(['color-mix']),
},
Expand All @@ -233,7 +234,7 @@ assert.deepStrictEqual(
color(parse('oklch(from lch(100 0 0deg) l c h)')),
{
colorNotation: 'oklch',
channels: [1, 4.996003610813204e-16, Number.NaN],
channels: [1, 0, Number.NaN],
alpha: 1,
syntaxFlags: new Set(['relative-color-syntax', 'has-number-values']),
},
Expand All @@ -243,7 +244,7 @@ assert.deepStrictEqual(
color(parse('lch(from oklch(100 0 0deg) l c h)')),
{
colorNotation: 'lch',
channels: [100, 1.1102230246251565e-13, Number.NaN],
channels: [100, 0, Number.NaN],
alpha: 1,
syntaxFlags: new Set(['relative-color-syntax', 'has-number-values']),
},
Expand All @@ -253,7 +254,7 @@ assert.deepStrictEqual(
color(parse('color-mix(in oklch, lch(100 0 40deg), lch(100 0 60deg))')),
{
colorNotation: 'oklch',
channels: [1.0000000000000002, 4.996003610813204e-16, Number.NaN],
channels: [1.0000000000000002, 0, Number.NaN],
alpha: 1,
syntaxFlags: new Set(['color-mix']),
},
Expand Down Expand Up @@ -283,7 +284,7 @@ assert.deepStrictEqual(
color(parse('color-mix(in hsl, lch(none 0 30), hsl(50 0 none))')),
{
colorNotation: 'hsl',
channels: [Number.NaN, 0, Number.NaN],
channels: [50, 0, Number.NaN],
alpha: 1,
syntaxFlags: new Set(['color-mix']),
},
Expand Down
20 changes: 10 additions & 10 deletions packages/css-color-parser/test/basic/none-exhaustive.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ import { computedValue, reducePrecisionWholeValue } from '../util/serialize.mjs'
{
const tests = [
// https://github.com/w3c/csswg-drafts/issues/14095
['hsl(from hsl(180 none 50%) h s l)', 'hsl(none none 50%)'],
['hsl(from hsl(180 0 50%) h s l)', 'hsl(none 0% 50%)'],
['hsl(from hsl(180 none 50%) h s l)', 'hsl(180 none 50%)'],
['hsl(from hsl(180 0 50%) h s l)', 'color(srgb 0.5 0.5 0.5)'],
['hsl(from lch(20 none 180) h s l)', 'hsl(none none 18.93757452%)'],
['hsl(from lch(20 0 180) h s l)', 'hsl(none 0% 18.93757452%)'],

// https://github.com/w3c/csswg-drafts/issues/14100
['lch(from orchid l 0 h)', 'lch(62.75256542 0 326.96909222)'],
['lch(from lch(from orchid l 0 h) l c h)', 'lch(62.75256542 0 none)'],
['color-mix(in lch, lch(from orchid l 0 h))', 'lch(62.75256542 0 none)'],
['lch(from lch(from orchid l 0 h) l c h)', 'lch(62.75256542 0 326.96909222)'],
['color-mix(in lch, lch(from orchid l 0 h))', 'lch(62.75256542 0 326.96909222)'],

// exhaustive tests
// HSL
['hsl(from hsl(none 50% 50%) h s l)', 'hsl(none 50% 50%)'],
['hsl(from hsl(180 none 50%) h s l)', 'hsl(none none 50%)'],
['hsl(from hsl(180 none 50%) h s l)', 'hsl(180 none 50%)'],
['hsl(from hsl(180 50% none) h s l)', 'hsl(180 50% none)'],
['hsl(from hsl(none none 50%) h s l)', 'hsl(none none 50%)'],
['hsl(from hsl(180 none none) h s l)', 'hsl(none none none)'],
['hsl(from hsl(180 none none) h s l)', 'hsl(180 none none)'],
['hsl(from hsl(none 50% none) h s l)', 'hsl(none 50% none)'],
['hsl(from hsl(none none none) h s l)', 'hsl(none none none)'],

Expand Down Expand Up @@ -137,9 +137,9 @@ import { computedValue, reducePrecisionWholeValue } from '../util/serialize.mjs'
['lch(from hwb(none none none) l c h)', 'lch(none none none)'],

['lch(from lch(none 20 180) l c h)', 'lch(none 20 180)'],
['lch(from lch(20 none 180) l c h)', 'lch(20 none none)'],
['lch(from lch(20 none 180) l c h)', 'lch(20 none 180)'],
['lch(from lch(20 20 none) l c h)', 'lch(20 20 none)'],
['lch(from lch(none none 180) l c h)', 'lch(none none none)'],
['lch(from lch(none none 180) l c h)', 'lch(none none 180)'],
['lch(from lch(20 none none) l c h)', 'lch(20 none none)'],
['lch(from lch(none 20 none) l c h)', 'lch(none 20 none)'],
['lch(from lch(none none none) l c h)', 'lch(none none none)'],
Expand Down Expand Up @@ -197,9 +197,9 @@ import { computedValue, reducePrecisionWholeValue } from '../util/serialize.mjs'
['oklch(from lch(none none none) l c h)', 'oklch(none none none)'],

['oklch(from oklch(none 0.2 180) l c h)', 'oklch(none 0.2 180)'],
['oklch(from oklch(0.2 none 180) l c h)', 'oklch(0.2 none none)'],
['oklch(from oklch(0.2 none 180) l c h)', 'oklch(0.2 none 180)'],
['oklch(from oklch(0.2 0.2 none) l c h)', 'oklch(0.2 0.2 none)'],
['oklch(from oklch(none none 180) l c h)', 'oklch(none none none)'],
['oklch(from oklch(none none 180) l c h)', 'oklch(none none 180)'],
['oklch(from oklch(0.2 none none) l c h)', 'oklch(0.2 none none)'],
['oklch(from oklch(none 0.2 none) l c h)', 'oklch(none 0.2 none)'],
['oklch(from oklch(none none none) l c h)', 'oklch(none none none)'],
Expand Down
Loading
Loading