Add suggestions & optimize code
This commit is contained in:
parent
d48fe130dc
commit
0e6b6adf7b
|
@ -1,5 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const hues = {
|
||||||
|
deg: 1,
|
||||||
|
grad: 360 / 400,
|
||||||
|
rad: 180 / Math.PI,
|
||||||
|
turn: 360
|
||||||
|
};
|
||||||
|
|
||||||
const colorConverter = (() => {
|
const colorConverter = (() => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -44,12 +51,9 @@ const colorConverter = (() => {
|
||||||
|
|
||||||
// Copied from _hexcolor() in parserlib.js
|
// Copied from _hexcolor() in parserlib.js
|
||||||
function validateHex(color) {
|
function validateHex(color) {
|
||||||
const len = color.length;
|
return (!/^#[a-f\d]+$/i.test(color) || [4, 5, 7, 9].every(n => color.length !== n))
|
||||||
if (len !== 4 && len !== 5 && len !== 7 && len !== 9 ||
|
? false
|
||||||
!/^#([a-f\d]{3}(?:[a-f\d](?:[a-f\d]{2}){0,2})?)$/i.test(color)) {
|
: color;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// % converted before function call
|
// % converted before function call
|
||||||
|
@ -72,6 +76,28 @@ const colorConverter = (() => {
|
||||||
return num >= 0 && num <= 1;
|
return num >= 0 && num <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseNumber(value) {
|
||||||
|
return /[^\d]/.test(value) ? -1 : parseFloat(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parsePercentage(value) {
|
||||||
|
const val = value.endsWith('%') && parseNumber(value.slice(0, -1));
|
||||||
|
return val >= 0 && val <= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHue(value) {
|
||||||
|
const raw = value.replace('.', '').replace(colorConverter.anglesRegexp, '');
|
||||||
|
let h = parseNumber(raw);
|
||||||
|
Object.keys(colorConverter.angles).some(angle => {
|
||||||
|
if (value.endsWith(angle)) {
|
||||||
|
h *= colorConverter.angles[angle];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return h < 0 ? h : h % 360;
|
||||||
|
}
|
||||||
|
|
||||||
function parse(str) {
|
function parse(str) {
|
||||||
if (typeof str !== 'string') return;
|
if (typeof str !== 'string') return;
|
||||||
str = str.trim();
|
str = str.trim();
|
||||||
|
@ -88,13 +114,12 @@ const colorConverter = (() => {
|
||||||
const [r, g, b, a = 255] = str.length <= 4 ?
|
const [r, g, b, a = 255] = str.length <= 4 ?
|
||||||
str.match(/(.)/g).map(c => parseInt(c + c, 16)) :
|
str.match(/(.)/g).map(c => parseInt(c + c, 16)) :
|
||||||
str.match(/(..)/g).map(c => parseInt(c, 16));
|
str.match(/(..)/g).map(c => parseInt(c, 16));
|
||||||
return validateRGB(r, g, b) ? {type: 'hex', r, g, b, a: a === 255 ? undefined : a / 255} : null;
|
return {type: 'hex', r, g, b, a: a === 255 ? undefined : a / 255};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [, type, value] = str.match(/^(rgb|hsl)a?\((.*?)\)|$/i);
|
const [, type, value] = str.match(/^(rgb|hsl)a?\((.*?)\)|$/i);
|
||||||
const nonDigit = /[^\d]/;
|
|
||||||
if (!type) return;
|
if (!type) return;
|
||||||
|
|
||||||
const comma = value.includes(',') && !value.includes('/');
|
const comma = value.includes(',') && !value.includes('/');
|
||||||
|
@ -103,25 +128,24 @@ const colorConverter = (() => {
|
||||||
|
|
||||||
let a = !num[3] ? 1 : parseFloat(num[3]) / (num[3].endsWith('%') ? 100 : 1);
|
let a = !num[3] ? 1 : parseFloat(num[3]) / (num[3].endsWith('%') ? 100 : 1);
|
||||||
if (isNaN(a)) a = 1;
|
if (isNaN(a)) a = 1;
|
||||||
|
if (!validateAlpha(a)) return null;
|
||||||
|
|
||||||
const first = num[0];
|
const first = num[0];
|
||||||
if (/rgb/i.test(type)) {
|
if (/rgb/i.test(type)) {
|
||||||
const k = first.endsWith('%') ? 2.55 : 1;
|
const isPercent = first.endsWith('%');
|
||||||
|
const k = isPercent ? 2.55 : 1;
|
||||||
|
const parser = isPercent ? parsePercentage : parseNumber;
|
||||||
const [r, g, b] = num.map(s => {
|
const [r, g, b] = num.map(s => {
|
||||||
const val = nonDigit.test(s.replace('%', '')) ? -1 : parseFloat(s) * k;
|
const val = parser(s) * k;
|
||||||
// Round the values when converting % to byte value or validation fails
|
// Round the values when converting % to byte value or validation fails
|
||||||
return k === 1 ? val : Math.round(val);
|
return isPercent ? Math.round(val) : val;
|
||||||
});
|
});
|
||||||
return validateRGB(r, g, b) && validateAlpha(a) ? {type: 'rgb', r, g, b, a} : null;
|
return validateRGB(r, g, b) ? {type: 'rgb', r, g, b, a} : null;
|
||||||
} else {
|
} else {
|
||||||
let h = nonDigit.test(first.replace('.', '').replace(/(deg|grad|rad|turn)/, '')) ? -1 : parseFloat(first);
|
const h = parseHue(first);
|
||||||
if (first.endsWith('grad')) h *= 360 / 400;
|
const s = parsePercentage(num[1]);
|
||||||
else if (first.endsWith('rad')) h *= 180 / Math.PI;
|
const l = parsePercentage(num[2]);
|
||||||
else if (first.endsWith('turn')) h *= 360;
|
return validateHSL(h, s, l) ? {type: 'hsl', h, s, l, a} : null;
|
||||||
h %= 360;
|
|
||||||
const s = num[1].includes('%') && parseFloat(num[1]);
|
|
||||||
const l = num[2].includes('%') && parseFloat(num[2]);
|
|
||||||
return validateHSL(h, s, l) && validateAlpha(a) ? {type: 'hsl', h, s, l, a} : null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +231,15 @@ const colorConverter = (() => {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
colorConverter.angles = {
|
||||||
|
deg: 1,
|
||||||
|
grad: 360 / 400,
|
||||||
|
rad: 180 / Math.PI,
|
||||||
|
turn: 360
|
||||||
|
};
|
||||||
|
|
||||||
|
colorConverter.anglesRegexp = new RegExp(Object.keys(colorConverter.angles).join('|'));
|
||||||
|
|
||||||
colorConverter.NAMED_COLORS = new Map([
|
colorConverter.NAMED_COLORS = new Map([
|
||||||
['transparent', 'rgba(0, 0, 0, 0)'],
|
['transparent', 'rgba(0, 0, 0, 0)'],
|
||||||
// CSS4 named colors
|
// CSS4 named colors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user