diff --git a/.vscodeignore b/.vscodeignore index 412af25..c73cef7 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -5,3 +5,24 @@ test/** jsconfig.json vsc-extension-quickstart.md .eslintrc + +# Ignore the source code +src +*.ts +*.map +*.js +*.js.map + +# Ignore node_modules +node_modules + +# Ignore test and other files +test +tests +.vscode +.npmignore +*.log +*.zip +.DS_Store +.gitignore +.vscodeignore diff --git a/CHANGELOG.md b/CHANGELOG.md index b47159d..284ec26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,24 @@ ## [Unreleased] +## [2.10.0] + +- Add support for hsl without function + +## [2.9.3] + +- Bugfix + +## [2.9.0] + +- Do dynamic contrast for hsl as well + +## [2.8.0] + +### Added + +- Support for hsl colors with decimal percentages + ## [2.6.0] ### Added diff --git a/package-lock.json b/package-lock.json index 92b31cb..ff10436 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "color-highlight", - "version": "2.5.0", + "name": "color-highlight-decimals", + "version": "2.10.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "color-highlight", - "version": "2.5.0", + "name": "color-highlight-decimals", + "version": "2.10.0", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { @@ -4616,7 +4616,7 @@ "node_modules/vscode": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/vscode/-/vscode-0.9.9.tgz", - "integrity": "sha1-qpoWeCHg0g1AWfoBj9hA2+BSILM=", + "integrity": "sha512-FK4eqMbskoWAQS8XVB7eXwFSLviY4MOWPAk2lfEwR7FbMBXKEw4E2IHG5MsWTWPnj+CmHfSco/ofkxaolhS5Rg==", "deprecated": "This package is deprecated in favor of @types/vscode and vscode-test. For more information please read: https://code.visualstudio.com/updates/v1_36#_splitting-vscode-package-into-typesvscode-and-vscodetest", "dev": true, "dependencies": { @@ -8730,7 +8730,7 @@ "vscode": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/vscode/-/vscode-0.9.9.tgz", - "integrity": "sha1-qpoWeCHg0g1AWfoBj9hA2+BSILM=", + "integrity": "sha512-FK4eqMbskoWAQS8XVB7eXwFSLviY4MOWPAk2lfEwR7FbMBXKEw4E2IHG5MsWTWPnj+CmHfSco/ofkxaolhS5Rg==", "dev": true, "requires": { "typescript": "^1.6.2" diff --git a/package.json b/package.json index 04510ed..29a26f1 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "color-highlight", - "displayName": "Color Highlight", + "name": "color-highlight-decimals", + "displayName": "Color Highlight with decimals", "description": "Highlight web colors in your editor", - "version": "2.6.0", - "publisher": "naumovs", + "version": "2.10.0", + "publisher": "ps-george", "license": "GPL-3.0", "engines": { "vscode": "^1.57.0" @@ -21,7 +21,9 @@ }, "scripts": { "build": "webpack --mode development", - "vscode:prepublish": "webpack --mode production", + "package": "vsce package", + "prepublish": "webpack --mode production", + "publish": "vsce publish", "dev": "webpack --mode development -w", "postinstall": "node ./node_modules/vscode/bin/install", "force-resolutions": "npx npm-force-resolutions", diff --git a/src/lib/dynamic-contrast.js b/src/lib/dynamic-contrast.js index 1109d01..1835fdf 100644 --- a/src/lib/dynamic-contrast.js +++ b/src/lib/dynamic-contrast.js @@ -11,12 +11,32 @@ // @return string of the form #RRGGBB import webColors from 'color-name'; +/** + * s and l are percentages, h is an angle in degrees out of 360. + * @param {int} h + * @param {float} s + * @param {float} l + * @returns {Array} + */ +function hsl2rgb(h, s, l) { + s /= 100; + l /= 100; + const k = n => (n + h / 30) % 12; + const a = s * Math.min(l, 1 - l); + const f = n => + l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1))); + return [Math.round(255 * f(0)), Math.round(255 * f(8)), Math.round(255 * f(4))]; +}; + export function getColorContrast(color) { const rgbExp = /^rgba?[\s+]?\(\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*(?:,\s*([\d.]+)\s*)?\)/im, - hexExp = /^(?:#)|([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$/igm; + hexExp = /^(?:#)|([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$/igm, + hslExp = /^(?:hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*(?:,\s*([\d.]+)\s*)?\)|([\d.]+)\s+([\d.]+)%\s+([\d.]+)%)/im; let rgb = color.match(rgbExp), hex = color.match(hexExp), + hsl = color.match(hslExp), r, g, b; + if (rgb) { r = parseInt(rgb[1], 10); g = parseInt(rgb[2], 10); @@ -33,6 +53,20 @@ export function getColorContrast(color) { r = parseInt(hex.substr(0, 2), 16); g = parseInt(hex.substr(2, 2), 16); b = parseInt(hex.substr(4, 2), 16); + } else if (hsl) { + let h, s, l; + if (hsl[1]) { + // HSL(A) function notation + h = parseFloat(hsl[1]); + s = parseFloat(hsl[2]); + l = parseFloat(hsl[3]); + } else { + // Space-separated HSL values + h = parseFloat(hsl[5]); + s = parseFloat(hsl[6]); + l = parseFloat(hsl[7]); + } + [r, g, b] = hsl2rgb(h, s, l); } else { rgb = webColors[color.toLowerCase()]; if (rgb) { diff --git a/src/strategies/functions.js b/src/strategies/functions.js index ea8f1fd..84bef2a 100644 --- a/src/strategies/functions.js +++ b/src/strategies/functions.js @@ -1,4 +1,5 @@ -const colorFunctions = /((rgb|hsl)a?\(\s*[\d]{1,3}%?\s*(?\s|,)\s*[\d]{1,3}%?\s*\k\s*[\d]{1,3}%?(\s*(\k|\/)\s*\d?\.?\d+%?)?\s*\))/gi; +const colorFunctions = /((rgb|hsl)a?\(\s*[\d.]+%?\s*(?\s|,)\s*[\d.]+%?\s*\k\s*[\d.]+%?(\s*(\k|\/)\s*\d?\.?\d+%?)?\s*\))/gi; +const colorWithoutFunctions = /([\d.]+\s+[\d.]+%\s+[\d.]+%\s*)/gi; /** * @export @@ -11,20 +12,36 @@ const colorFunctions = /((rgb|hsl)a?\(\s*[\d]{1,3}%?\s*(?\s|,)\s*[ */ export async function findFn(text) { let match = colorFunctions.exec(text); + let match2 = colorWithoutFunctions.exec(text); let result = []; - while (match !== null) { - const start = match.index; - const end = colorFunctions.lastIndex; - const color = match[0]; + while (match !== null || match2 !== null) { + if (match !== null) { + const start = match.index; + const end = colorFunctions.lastIndex; + const color = match[0]; - result.push({ - start, - end, - color - }); + result.push({ + start, + end, + color + }); + } + + if (match2 !== null) { + const start = match2.index; + const end = colorWithoutFunctions.lastIndex; + const color = `hsl(${match2[0]})`; + + result.push({ + start, + end, + color + }); + } match = colorFunctions.exec(text); + match2 = colorWithoutFunctions.exec(text); } return result; diff --git a/src/strategies/hsla.js b/src/strategies/hsla.js deleted file mode 100644 index 9134de9..0000000 --- a/src/strategies/hsla.js +++ /dev/null @@ -1,31 +0,0 @@ -const colorHsla = /(hsla?\([\d]{1,3},\s*[\d]{1,3}%,\s*[\d]{1,3}%(,\s*\d?\.?\d+)?\))/gi; - -/** - * @export - * @param {string} text - * @returns {{ - * start: number, - * end: number, - * color: string - * }} - */ -export async function findHsla(text) { - let match = colorHsla.exec(text); - let result = []; - - while (match !== null) { - const start = match.index; - const end = colorHsla.lastIndex; - const color = match[0]; - - result.push({ - start, - end, - color - }); - - match = colorHsla.exec(text); - } - - return result; -} \ No newline at end of file