mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 10:38:59 +01:00
Update css language service: Fixes #27590 & 4/8 digit hex colors
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument } from 'vscode';
|
||||
import * as parse from 'parse-color';
|
||||
import { window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument, DocumentColorProvider, Color, ColorFormat, ColorInfo } from 'vscode';
|
||||
|
||||
const MAX_DECORATORS = 500;
|
||||
|
||||
@@ -107,6 +108,12 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
|
||||
if (document && document.version === documentVersion && contentUri === document.uri.toString()) {
|
||||
let decorations = ranges.slice(0, MAX_DECORATORS).map(range => {
|
||||
let color = document.getText(range);
|
||||
if (color[0] === '#' && (color.length === 5 || color.length === 9)) {
|
||||
let c = Color.fromHex(color);
|
||||
if (c) {
|
||||
color = `rgba(${c.red}, ${c.green}, ${c.blue}, ${c.alpha})`;
|
||||
}
|
||||
}
|
||||
return <DecorationOptions>{
|
||||
range: range,
|
||||
renderOptions: {
|
||||
@@ -124,3 +131,53 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
|
||||
|
||||
return Disposable.from(...disposables);
|
||||
}
|
||||
|
||||
const CSSColorFormats = {
|
||||
Hex: '#{red:X}{green:X}{blue:X}',
|
||||
RGB: {
|
||||
opaque: 'rgb({red}, {green}, {blue})',
|
||||
transparent: 'rgba({red}, {green}, {blue}, {alpha:2f[0-1]})'
|
||||
},
|
||||
HSL: {
|
||||
opaque: 'hsl({hue:d[0-360]}, {saturation:d[0-100]}%, {luminosity:d[0-100]}%)',
|
||||
transparent: 'hsla({hue:d[0-360]}, {saturation:d[0-100]}%, {luminosity:d[0-100]}%, {alpha:2f[0-1]})'
|
||||
}
|
||||
};
|
||||
|
||||
function detectFormat(value: string): ColorFormat {
|
||||
if (/^rgb/i.test(value)) {
|
||||
return CSSColorFormats.RGB;
|
||||
} else if (/^hsl/i.test(value)) {
|
||||
return CSSColorFormats.HSL;
|
||||
} else {
|
||||
return CSSColorFormats.Hex;
|
||||
}
|
||||
}
|
||||
|
||||
export class ColorProvider implements DocumentColorProvider {
|
||||
|
||||
constructor(private decoratorProvider: (uri: string) => Thenable<Range[]>) { }
|
||||
|
||||
async provideDocumentColors(document: TextDocument): Promise<ColorInfo[]> {
|
||||
const ranges = await this.decoratorProvider(document.uri.toString());
|
||||
const result = [];
|
||||
for (let range of ranges) {
|
||||
let color;
|
||||
const value = document.getText(range);
|
||||
if (value[0] === '#') {
|
||||
color = Color.fromHex(value);
|
||||
} else {
|
||||
const parsedColor = parse(value);
|
||||
if (parsedColor && parsedColor.rgba) {
|
||||
const [red, green, blue, alpha] = parsedColor.rgba;
|
||||
color = new Color(red, green, blue, alpha);
|
||||
}
|
||||
}
|
||||
if (color) {
|
||||
const format = detectFormat(value);
|
||||
result.push(new ColorInfo(range, color, format, [CSSColorFormats.Hex, CSSColorFormats.RGB, CSSColorFormats.HSL]));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,10 @@
|
||||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as parse from 'parse-color';
|
||||
|
||||
import { languages, window, commands, workspace, ExtensionContext, DocumentColorProvider, Color, ColorFormat, CancellationToken, TextDocument, ColorInfo } from 'vscode';
|
||||
import { languages, window, commands, workspace, ExtensionContext } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, Range, TextEdit } from 'vscode-languageclient';
|
||||
import { activateColorDecorations } from './colorDecorators';
|
||||
import { activateColorDecorations, ColorProvider } from './colorDecorators';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
let localize = nls.loadMessageBundle();
|
||||
@@ -18,53 +17,6 @@ namespace ColorSymbolRequest {
|
||||
export const type: RequestType<string, Range[], any, any> = new RequestType('css/colorSymbols');
|
||||
}
|
||||
|
||||
const CSSColorFormats = {
|
||||
Hex: '#{red:X}{green:X}{blue:X}',
|
||||
RGB: {
|
||||
opaque: 'rgb({red}, {green}, {blue})',
|
||||
transparent: 'rgba({red}, {green}, {blue}, {alpha:2f[0-1]})'
|
||||
},
|
||||
HSL: {
|
||||
opaque: 'hsl({hue:d[0-360]}, {saturation:d[0-100]}%, {luminosity:d[0-100]}%)',
|
||||
transparent: 'hsla({hue:d[0-360]}, {saturation:d[0-100]}%, {luminosity:d[0-100]}%, {alpha:2f[0-1]})'
|
||||
}
|
||||
};
|
||||
|
||||
function detectFormat(value: string): ColorFormat {
|
||||
if (/^rgb/i.test(value)) {
|
||||
return CSSColorFormats.RGB;
|
||||
} else if (/^hsl/i.test(value)) {
|
||||
return CSSColorFormats.HSL;
|
||||
} else {
|
||||
return CSSColorFormats.Hex;
|
||||
}
|
||||
}
|
||||
|
||||
class ColorProvider implements DocumentColorProvider {
|
||||
|
||||
constructor(private client: LanguageClient) { }
|
||||
|
||||
async provideDocumentColors(document: TextDocument, token: CancellationToken): Promise<ColorInfo[]> {
|
||||
const ranges = await this.client.sendRequest(ColorSymbolRequest.type, document.uri.toString());
|
||||
|
||||
return ranges.reduce((result, r) => {
|
||||
const range = this.client.protocol2CodeConverter.asRange(r);
|
||||
const value = document.getText(range);
|
||||
const parsedColor = parse(value);
|
||||
|
||||
if (!parsedColor || !parsedColor.rgba) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const [red, green, blue, alpha] = parsedColor.rgba;
|
||||
const color = new Color(red, green, blue, alpha);
|
||||
const format = detectFormat(value);
|
||||
|
||||
return [...result, new ColorInfo(range, color, format, [CSSColorFormats.Hex, CSSColorFormats.RGB, CSSColorFormats.HSL])];
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
|
||||
// this method is called when vs code is activated
|
||||
export function activate(context: ExtensionContext) {
|
||||
|
||||
@@ -106,11 +58,8 @@ export function activate(context: ExtensionContext) {
|
||||
return workspace.getConfiguration().get<boolean>(languageId + '.colorDecorators.enable');
|
||||
};
|
||||
|
||||
const colorProvider = new ColorProvider(client);
|
||||
context.subscriptions.push(languages.registerColorProvider(['css', 'scss', 'less'], colorProvider));
|
||||
|
||||
disposable = activateColorDecorations(colorRequestor, { css: true, scss: true, less: true }, isDecoratorEnabled);
|
||||
context.subscriptions.push(disposable);
|
||||
context.subscriptions.push(languages.registerColorProvider(['css', 'scss', 'less'], new ColorProvider(colorRequestor)));
|
||||
context.subscriptions.push(activateColorDecorations(colorRequestor, { css: true, scss: true, less: true }, isDecoratorEnabled));
|
||||
});
|
||||
|
||||
let indentationRules = {
|
||||
|
||||
Reference in New Issue
Block a user