omgovich / colord

👑 A tiny yet powerful tool for high-performance color manipulations and conversions
https://colord.omgovich.ru
MIT License
1.67k stars 49 forks source link

HEX Simplifications #71

Closed lbragile closed 3 years ago

lbragile commented 3 years ago

Hi @omgovich,

In my opinion, the current hex matcher:

const hexMatcher = /^#([0-9a-f]{3,8})$/i;

is a little too generous.


Let's consider the following hex input that a user can provide: #abcde

This matcher will accept it, which is why lines 15-33 exist (to filter out such instances).

if (hex.length <= 4) {
    return {
      r: parseInt(hex[0] + hex[0], 16),
      g: parseInt(hex[1] + hex[1], 16),
      b: parseInt(hex[2] + hex[2], 16),
      a: hex.length === 4 ? round(parseInt(hex[3] + hex[3], 16) / 255, 2) : 1,
    };
}

if (hex.length === 6 || hex.length === 8) {
    return {
      r: parseInt(hex.substr(0, 2), 16),
      g: parseInt(hex.substr(2, 2), 16),
      b: parseInt(hex.substr(4, 2), 16),
      a: hex.length === 8 ? round(parseInt(hex.substr(6, 2), 16) / 255, 2) : 1,
    };
}

return null;

I propose adjusting the matcher to:

const hexMatcher = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;

as it is a more rigorous definition & will eliminate the need for an extra condition (one condition will do → is length > 5?)