Skip to content

Commit

Permalink
Refactors color detector to use injected text.
Browse files Browse the repository at this point in the history
  • Loading branch information
hediet committed Nov 9, 2021
1 parent e7eb1fc commit 8b0ea7d
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 41 deletions.
71 changes: 31 additions & 40 deletions src/vs/editor/contrib/colorPicker/colorDetector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import { CancelablePromise, createCancelablePromise, TimeoutTimer } from 'vs/base/common/async';
import { RGBA } from 'vs/base/common/color';
import { onUnexpectedError } from 'vs/base/common/errors';
import { hash } from 'vs/base/common/hash';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { noBreakWhitespace } from 'vs/base/common/strings';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { DynamicCssRules } from 'vs/editor/browser/editorDom';
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
Expand All @@ -36,13 +36,14 @@ export class ColorDetector extends Disposable implements IEditorContribution {
private _decorationsIds: string[] = [];
private _colorDatas = new Map<string, IColorData>();

private _colorDecoratorIds: string[] = [];
private readonly _decorationsTypes = new Set<string>();
private _colorDecoratorIds: ReadonlySet<string> = new Set<string>();

private _isEnabled: boolean;

constructor(private readonly _editor: ICodeEditor,
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
private readonly _ruleFactory = new DynamicCssRules(this._editor);

constructor(
private readonly _editor: ICodeEditor,
@IConfigurationService private readonly _configurationService: IConfigurationService
) {
super();
Expand Down Expand Up @@ -166,63 +167,49 @@ export class ColorDetector extends Disposable implements IEditorContribution {
this._decorationsIds.forEach((id, i) => this._colorDatas.set(id, colorDatas[i]));
}

private _colorDecorationClassRefs = this._register(new DisposableStore());

private updateColorDecorators(colorData: IColorData[]): void {
this._colorDecorationClassRefs.clear();

let decorations: IModelDeltaDecoration[] = [];
let newDecorationsTypes: { [key: string]: boolean } = {};

for (let i = 0; i < colorData.length && decorations.length < MAX_DECORATORS; i++) {
const { red, green, blue, alpha } = colorData[i].colorInfo.color;
const rgba = new RGBA(Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255), alpha);
let subKey = hash(`rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a})`).toString(16);
let color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
let key = 'colorBox-' + subKey;

if (!this._decorationsTypes.has(key) && !newDecorationsTypes[key]) {
this._codeEditorService.registerDecorationType('color-detector-color', key, {
before: {
contentText: ' ',
border: 'solid 0.1em #000',
margin: '0.1em 0.2em 0 0.2em',
width: '0.8em',
height: '0.8em',
backgroundColor: color
},
dark: {
before: {
border: 'solid 0.1em #eee'
}
}
}, undefined, this._editor);
}
const ref = this._colorDecorationClassRefs.add(
this._ruleFactory.createClassNameRef({
backgroundColor: color
})
);

newDecorationsTypes[key] = true;
decorations.push({
range: {
startLineNumber: colorData[i].colorInfo.range.startLineNumber,
startColumn: colorData[i].colorInfo.range.startColumn,
endLineNumber: colorData[i].colorInfo.range.endLineNumber,
endColumn: colorData[i].colorInfo.range.endColumn
},
options: this._codeEditorService.resolveDecorationOptions(key, true)
options: {
description: 'colorDetector',
before: {
content: noBreakWhitespace,
inlineClassName: `${ref.className} colorpicker-color-decoration`,
inlineClassNameAffectsLetterSpacing: true,
}
}
});
}

this._decorationsTypes.forEach(subType => {
if (!newDecorationsTypes[subType]) {
this._codeEditorService.removeDecorationType(subType);
}
});

this._colorDecoratorIds = this._editor.deltaDecorations(this._colorDecoratorIds, decorations);
this._colorDecoratorIds = new Set(this._editor.deltaDecorations([...this._colorDecoratorIds], decorations));
}

private removeAllDecorations(): void {
this._decorationsIds = this._editor.deltaDecorations(this._decorationsIds, []);
this._colorDecoratorIds = this._editor.deltaDecorations(this._colorDecoratorIds, []);

this._decorationsTypes.forEach(subType => {
this._codeEditorService.removeDecorationType(subType);
});
this._colorDecoratorIds = new Set(this._editor.deltaDecorations([...this._colorDecoratorIds], []));
this._colorDecorationClassRefs.clear();
}

getColorData(position: Position): IColorData | null {
Expand All @@ -241,6 +228,10 @@ export class ColorDetector extends Disposable implements IEditorContribution {

return this._colorDatas.get(decorations[0].id)!;
}

isColorDecorationId(decorationId: string): boolean {
return this._colorDecoratorIds.has(decorationId);
}
}

registerEditorContribution(ColorDetector.ID, ColorDetector);
16 changes: 16 additions & 0 deletions src/vs/editor/contrib/colorPicker/colorPicker.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
outline: none;
}

/* Decoration */

.colorpicker-color-decoration {
border: solid 0.1em #000;
box-sizing: border-box;
margin: 0.1em 0.2em 0 0.2em;
width: 0.8em;
height: 0.8em;
line-height: 0.8em;
display: inline-block;
}

.hc-black .colorpicker-color-decoration,
.vs-dark .colorpicker-color-decoration {
border: solid 0.1em #eee;
}

/* Header */

Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/contrib/hover/colorHoverParticipant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class ColorHoverParticipant implements IEditorHoverParticipant<ColorHover
}
const colorDetector = ColorDetector.get(this._editor);
for (const d of lineDecorations) {
if (d.options.description !== 'color-detector-color') {
if (!colorDetector.isColorDecorationId(d.id)) {
continue;
}

Expand Down

0 comments on commit 8b0ea7d

Please sign in to comment.