| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
- return c > 3 && r && Object.defineProperty(target, key, r), r;
- };
- var __param = (this && this.__param) || function (paramIndex, decorator) {
- return function (target, key) { decorator(target, key, paramIndex); }
- };
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
- import { createCancelablePromise, TimeoutTimer } from '../../../../base/common/async.js';
- import { RGBA } from '../../../../base/common/color.js';
- import { onUnexpectedError } from '../../../../base/common/errors.js';
- import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
- import { StopWatch } from '../../../../base/common/stopwatch.js';
- import { noBreakWhitespace } from '../../../../base/common/strings.js';
- import { DynamicCssRules } from '../../../browser/editorDom.js';
- import { registerEditorContribution } from '../../../browser/editorExtensions.js';
- import { Range } from '../../../common/core/range.js';
- import { ModelDecorationOptions } from '../../../common/model/textModel.js';
- import { ILanguageFeatureDebounceService } from '../../../common/services/languageFeatureDebounce.js';
- import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
- import { getColors } from './color.js';
- import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
- export const ColorDecorationInjectedTextMarker = Object.create({});
- const MAX_DECORATORS = 500;
- let ColorDetector = class ColorDetector extends Disposable {
- constructor(_editor, _configurationService, _languageFeaturesService, languageFeatureDebounceService) {
- super();
- this._editor = _editor;
- this._configurationService = _configurationService;
- this._languageFeaturesService = _languageFeaturesService;
- this._localToDispose = this._register(new DisposableStore());
- this._decorationsIds = [];
- this._colorDatas = new Map();
- this._colorDecoratorIds = this._editor.createDecorationsCollection();
- this._ruleFactory = new DynamicCssRules(this._editor);
- this._colorDecorationClassRefs = this._register(new DisposableStore());
- this._debounceInformation = languageFeatureDebounceService.for(_languageFeaturesService.colorProvider, 'Document Colors', { min: ColorDetector.RECOMPUTE_TIME });
- this._register(_editor.onDidChangeModel(() => {
- this._isEnabled = this.isEnabled();
- this.onModelChanged();
- }));
- this._register(_editor.onDidChangeModelLanguage(() => this.onModelChanged()));
- this._register(_languageFeaturesService.colorProvider.onDidChange(() => this.onModelChanged()));
- this._register(_editor.onDidChangeConfiguration(() => {
- const prevIsEnabled = this._isEnabled;
- this._isEnabled = this.isEnabled();
- if (prevIsEnabled !== this._isEnabled) {
- if (this._isEnabled) {
- this.onModelChanged();
- }
- else {
- this.removeAllDecorations();
- }
- }
- }));
- this._timeoutTimer = null;
- this._computePromise = null;
- this._isEnabled = this.isEnabled();
- this.onModelChanged();
- }
- isEnabled() {
- const model = this._editor.getModel();
- if (!model) {
- return false;
- }
- const languageId = model.getLanguageId();
- // handle deprecated settings. [languageId].colorDecorators.enable
- const deprecatedConfig = this._configurationService.getValue(languageId);
- if (deprecatedConfig && typeof deprecatedConfig === 'object') {
- const colorDecorators = deprecatedConfig['colorDecorators']; // deprecatedConfig.valueOf('.colorDecorators.enable');
- if (colorDecorators && colorDecorators['enable'] !== undefined && !colorDecorators['enable']) {
- return colorDecorators['enable'];
- }
- }
- return this._editor.getOption(17 /* EditorOption.colorDecorators */);
- }
- static get(editor) {
- return editor.getContribution(this.ID);
- }
- dispose() {
- this.stop();
- this.removeAllDecorations();
- super.dispose();
- }
- onModelChanged() {
- this.stop();
- if (!this._isEnabled) {
- return;
- }
- const model = this._editor.getModel();
- if (!model || !this._languageFeaturesService.colorProvider.has(model)) {
- return;
- }
- this._localToDispose.add(this._editor.onDidChangeModelContent(() => {
- if (!this._timeoutTimer) {
- this._timeoutTimer = new TimeoutTimer();
- this._timeoutTimer.cancelAndSet(() => {
- this._timeoutTimer = null;
- this.beginCompute();
- }, this._debounceInformation.get(model));
- }
- }));
- this.beginCompute();
- }
- beginCompute() {
- this._computePromise = createCancelablePromise((token) => __awaiter(this, void 0, void 0, function* () {
- const model = this._editor.getModel();
- if (!model) {
- return Promise.resolve([]);
- }
- const sw = new StopWatch(false);
- const colors = yield getColors(this._languageFeaturesService.colorProvider, model, token);
- this._debounceInformation.update(model, sw.elapsed());
- return colors;
- }));
- this._computePromise.then((colorInfos) => {
- this.updateDecorations(colorInfos);
- this.updateColorDecorators(colorInfos);
- this._computePromise = null;
- }, onUnexpectedError);
- }
- stop() {
- if (this._timeoutTimer) {
- this._timeoutTimer.cancel();
- this._timeoutTimer = null;
- }
- if (this._computePromise) {
- this._computePromise.cancel();
- this._computePromise = null;
- }
- this._localToDispose.clear();
- }
- updateDecorations(colorDatas) {
- const decorations = colorDatas.map(c => ({
- range: {
- startLineNumber: c.colorInfo.range.startLineNumber,
- startColumn: c.colorInfo.range.startColumn,
- endLineNumber: c.colorInfo.range.endLineNumber,
- endColumn: c.colorInfo.range.endColumn
- },
- options: ModelDecorationOptions.EMPTY
- }));
- this._editor.changeDecorations((changeAccessor) => {
- this._decorationsIds = changeAccessor.deltaDecorations(this._decorationsIds, decorations);
- this._colorDatas = new Map();
- this._decorationsIds.forEach((id, i) => this._colorDatas.set(id, colorDatas[i]));
- });
- }
- updateColorDecorators(colorData) {
- this._colorDecorationClassRefs.clear();
- const decorations = [];
- 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);
- const color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
- const ref = this._colorDecorationClassRefs.add(this._ruleFactory.createClassNameRef({
- backgroundColor: color
- }));
- 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: {
- description: 'colorDetector',
- before: {
- content: noBreakWhitespace,
- inlineClassName: `${ref.className} colorpicker-color-decoration`,
- inlineClassNameAffectsLetterSpacing: true,
- attachedData: ColorDecorationInjectedTextMarker
- }
- }
- });
- }
- this._colorDecoratorIds.set(decorations);
- }
- removeAllDecorations() {
- this._editor.removeDecorations(this._decorationsIds);
- this._decorationsIds = [];
- this._colorDecoratorIds.clear();
- this._colorDecorationClassRefs.clear();
- }
- getColorData(position) {
- const model = this._editor.getModel();
- if (!model) {
- return null;
- }
- const decorations = model
- .getDecorationsInRange(Range.fromPositions(position, position))
- .filter(d => this._colorDatas.has(d.id));
- if (decorations.length === 0) {
- return null;
- }
- return this._colorDatas.get(decorations[0].id);
- }
- isColorDecoration(decoration) {
- return this._colorDecoratorIds.has(decoration);
- }
- };
- ColorDetector.ID = 'editor.contrib.colorDetector';
- ColorDetector.RECOMPUTE_TIME = 1000; // ms
- ColorDetector = __decorate([
- __param(1, IConfigurationService),
- __param(2, ILanguageFeaturesService),
- __param(3, ILanguageFeatureDebounceService)
- ], ColorDetector);
- export { ColorDetector };
- registerEditorContribution(ColorDetector.ID, ColorDetector);
|