Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,10 @@ export default class CSSVariableManager {
},
};

if (isColor(decl.value)) {
const culoriColor = culori.parse(decl.value);
if (culoriColor) {
variable.color = culoriColorToVscodeColor(culoriColor);
}
const culoriColor = culori.parse(decl.value);

if (culoriColor) {
variable.color = culoriColorToVscodeColor(culoriColor);
}

// add to cache
Expand Down
7 changes: 6 additions & 1 deletion packages/css-variables-language-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { indexToPosition } from './utils/indexToPosition';
import { getCurrentWord } from './utils/getCurrentWord';
import { isInFunctionExpression } from './utils/isInFunctionExpression';
import CSSVariableManager, { CSSVariablesSettings, defaultSettings } from './CSSVariableManager';
import { formatHex } from 'culori';

// Create a connection for the server, using Node's IPC as a transport.
// Also include all preview / proposed LSP features.
Expand Down Expand Up @@ -199,6 +200,11 @@ connection.onCompletion(
sortText: 'z',
};

if (isColor(varSymbol.value)) {
// convert to hex code
completion.documentation = formatHex(varSymbol.value);
}

if (isFunctionCall) {
completion.detail = varSymbol.value;
}
Expand Down Expand Up @@ -278,7 +284,6 @@ connection.onHover((params) => {
if (cssVariable) {
return {
contents: cssVariable.symbol.value,
range: cssVariable.definition.range,
} as Hover;
}

Expand Down
214 changes: 3 additions & 211 deletions packages/css-variables-language-server/src/utils/isColor.ts
Original file line number Diff line number Diff line change
@@ -1,217 +1,9 @@
// borrow from https://github.com/princejwesley/is-css-color/blob/master/index.js
'use strict';

//every string I match against are lowercase
const HEX_PATTERN = /^#(?:[a-f0-9]{3})?(?:[a-f0-9]{3})$/;
// css color names + initial + inherit + currentColor + transparent
const CSS_COLOR_NAMES = [
'aliceblue',
'antiquewhite',
'aqua',
'aquamarine',
'azure',
'beige',
'bisque',
'black',
'blanchedalmond',
'blue',
'blueviolet',
'brown',
'burlywood',
'cadetblue',
'chartreuse',
'chocolate',
'coral',
'cornflowerblue',
'cornsilk',
'crimson',
'currentColor',
'cyan',
'darkblue',
'darkcyan',
'darkgoldenrod',
'darkgray',
'darkgreen',
'darkgrey',
'darkkhaki',
'darkmagenta',
'darkolivegreen',
'darkorange',
'darkorchid',
'darkred',
'darksalmon',
'darkseagreen',
'darkslateblue',
'darkslategray',
'darkslategrey',
'darkturquoise',
'darkviolet',
'deeppink',
'deepskyblue',
'dimgray',
'dimgrey',
'dodgerblue',
'firebrick',
'floralwhite',
'forestgreen',
'fuchsia',
'gainsboro',
'ghostwhite',
'gold',
'goldenrod',
'gray',
'green',
'greenyellow',
'grey',
'honeydew',
'hotpink',
'indianred',
'indigo',
'inherit',
'initial',
'ivory',
'khaki',
'lavender',
'lavenderblush',
'lawngreen',
'lemonchiffon',
'lightblue',
'lightcoral',
'lightcyan',
'lightgoldenrodyellow',
'lightgray',
'lightgreen',
'lightgrey',
'lightpink',
'lightsalmon',
'lightseagreen',
'lightskyblue',
'lightslategray',
'lightslategrey',
'lightsteelblue',
'lightyellow',
'lime',
'limegreen',
'linen',
'magenta',
'maroon',
'mediumaquamarine',
'mediumblue',
'mediumorchid',
'mediumpurple',
'mediumseagreen',
'mediumslateblue',
'mediumspringgreen',
'mediumturquoise',
'mediumvioletred',
'midnightblue',
'mintcream',
'mistyrose',
'moccasin',
'navajowhite',
'navy',
'oldlace',
'olive',
'olivedrab',
'orange',
'orangered',
'orchid',
'palegoldenrod',
'palegreen',
'paleturquoise',
'palevioletred',
'papayawhip',
'peachpuff',
'peru',
'pink',
'plum',
'powderblue',
'purple',
'rebeccapurple',
'red',
'rosybrown',
'royalblue',
'saddlebrown',
'salmon',
'sandybrown',
'seagreen',
'seashell',
'sienna',
'silver',
'skyblue',
'slateblue',
'slategray',
'slategrey',
'snow',
'springgreen',
'steelblue',
'tan',
'teal',
'thistle',
'tomato',
'transparent',
'turquoise',
'violet',
'wheat',
'white',
'whitesmoke',
'yellow',
'yellowgreen',
];

const PREFIX = '^(rgb|hsl)(a?)\\s*\\(';
const VALUE = '\\s*([-+]?\\d+%?)\\s*';
const ALPHA = '(?:,\\s*([-+]?(?:(?:\\d+(?:.\\d+)?)|(?:.\\d+))\\s*))?';
const SUFFIX = '\\)$';
const RGB_HSL_PATTERN = new RegExp(PREFIX + VALUE + ',' + VALUE + ',' + VALUE + ALPHA + SUFFIX);

const NUM_TYPE = 1;
const PERCENTAGE_TYPE = 2;
const ERROR_TYPE = NUM_TYPE & PERCENTAGE_TYPE;
import * as culori from 'culori';

const isColor = (str: string) => {
function getColorType(token: string) {
return token.indexOf('%') !== -1 ? PERCENTAGE_TYPE : NUM_TYPE;
}

if(!str || typeof str !== 'string') {
return false;
}

const color = str.replace(/^\s+|\s+$/g, '').toLocaleLowerCase();

// named colors or hex code
if((CSS_COLOR_NAMES.indexOf(color) !== -1) || HEX_PATTERN.test(color)) {
return true;
}

const result = color.match(RGB_HSL_PATTERN);
if(result) {
const flavor = result[1];
const alpha = result[2];
const rh = result[3];
const gs = result[4];
const bl = result[5];
const a = result[6];

// alpha test
if((alpha === 'a' && !a) || (a && alpha === '')) {
return false;
}

// hsl
if(flavor === 'hsl') {
if(getColorType(rh) !== NUM_TYPE) {
return false;
}
return (getColorType(gs) & getColorType(bl)) === PERCENTAGE_TYPE;
}

// rgb
return (getColorType(rh) & getColorType(gs) & getColorType(bl)) !== ERROR_TYPE;
}
const colorTemp = culori.parse(str);

return false;
return !!colorTemp;
};

export default isColor;