9c44585348e8b8cf920032aa80721e4c8ec3d59890868e9b99c358735f4877cd02eb93f103de86df8858e40a8dcb1c8a3fa89514b9694b1fe81aee0d9dd663 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  6. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  7. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  8. 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;
  9. return c > 3 && r && Object.defineProperty(target, key, r), r;
  10. };
  11. var __param = (this && this.__param) || function (paramIndex, decorator) {
  12. return function (target, key) { decorator(target, key, paramIndex); }
  13. };
  14. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  15. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  16. return new (P || (P = Promise))(function (resolve, reject) {
  17. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  18. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  19. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  20. step((generator = generator.apply(thisArg, _arguments || [])).next());
  21. });
  22. };
  23. import { AsyncIterableObject } from '../../../../base/common/async.js';
  24. import { CancellationToken } from '../../../../base/common/cancellation.js';
  25. import { Color, RGBA } from '../../../../base/common/color.js';
  26. import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
  27. import { Range } from '../../../common/core/range.js';
  28. import { getColorPresentations } from './color.js';
  29. import { ColorDetector } from './colorDetector.js';
  30. import { ColorPickerModel } from './colorPickerModel.js';
  31. import { ColorPickerWidget } from './colorPickerWidget.js';
  32. import { IThemeService } from '../../../../platform/theme/common/themeService.js';
  33. export class ColorHover {
  34. constructor(owner, range, model, provider) {
  35. this.owner = owner;
  36. this.range = range;
  37. this.model = model;
  38. this.provider = provider;
  39. /**
  40. * Force the hover to always be rendered at this specific range,
  41. * even in the case of multiple hover parts.
  42. */
  43. this.forceShowAtRange = true;
  44. }
  45. isValidForHoverAnchor(anchor) {
  46. return (anchor.type === 1 /* HoverAnchorType.Range */
  47. && this.range.startColumn <= anchor.range.startColumn
  48. && this.range.endColumn >= anchor.range.endColumn);
  49. }
  50. }
  51. let ColorHoverParticipant = class ColorHoverParticipant {
  52. constructor(_editor, _themeService) {
  53. this._editor = _editor;
  54. this._themeService = _themeService;
  55. this.hoverOrdinal = 1;
  56. }
  57. computeSync(anchor, lineDecorations) {
  58. return [];
  59. }
  60. computeAsync(anchor, lineDecorations, token) {
  61. return AsyncIterableObject.fromPromise(this._computeAsync(anchor, lineDecorations, token));
  62. }
  63. _computeAsync(anchor, lineDecorations, token) {
  64. return __awaiter(this, void 0, void 0, function* () {
  65. if (!this._editor.hasModel()) {
  66. return [];
  67. }
  68. const colorDetector = ColorDetector.get(this._editor);
  69. if (!colorDetector) {
  70. return [];
  71. }
  72. for (const d of lineDecorations) {
  73. if (!colorDetector.isColorDecoration(d)) {
  74. continue;
  75. }
  76. const colorData = colorDetector.getColorData(d.range.getStartPosition());
  77. if (colorData) {
  78. const colorHover = yield this._createColorHover(this._editor.getModel(), colorData.colorInfo, colorData.provider);
  79. return [colorHover];
  80. }
  81. }
  82. return [];
  83. });
  84. }
  85. _createColorHover(editorModel, colorInfo, provider) {
  86. return __awaiter(this, void 0, void 0, function* () {
  87. const originalText = editorModel.getValueInRange(colorInfo.range);
  88. const { red, green, blue, alpha } = colorInfo.color;
  89. const rgba = new RGBA(Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255), alpha);
  90. const color = new Color(rgba);
  91. const colorPresentations = yield getColorPresentations(editorModel, colorInfo, provider, CancellationToken.None);
  92. const model = new ColorPickerModel(color, [], 0);
  93. model.colorPresentations = colorPresentations || [];
  94. model.guessColorPresentation(color, originalText);
  95. return new ColorHover(this, Range.lift(colorInfo.range), model, provider);
  96. });
  97. }
  98. renderHoverParts(context, hoverParts) {
  99. if (hoverParts.length === 0 || !this._editor.hasModel()) {
  100. return Disposable.None;
  101. }
  102. const disposables = new DisposableStore();
  103. const colorHover = hoverParts[0];
  104. const editorModel = this._editor.getModel();
  105. const model = colorHover.model;
  106. const widget = disposables.add(new ColorPickerWidget(context.fragment, model, this._editor.getOption(131 /* EditorOption.pixelRatio */), this._themeService));
  107. context.setColorPicker(widget);
  108. let range = new Range(colorHover.range.startLineNumber, colorHover.range.startColumn, colorHover.range.endLineNumber, colorHover.range.endColumn);
  109. const updateEditorModel = () => {
  110. let textEdits;
  111. let newRange;
  112. if (model.presentation.textEdit) {
  113. textEdits = [model.presentation.textEdit];
  114. newRange = new Range(model.presentation.textEdit.range.startLineNumber, model.presentation.textEdit.range.startColumn, model.presentation.textEdit.range.endLineNumber, model.presentation.textEdit.range.endColumn);
  115. const trackedRange = this._editor.getModel()._setTrackedRange(null, newRange, 3 /* TrackedRangeStickiness.GrowsOnlyWhenTypingAfter */);
  116. this._editor.pushUndoStop();
  117. this._editor.executeEdits('colorpicker', textEdits);
  118. newRange = this._editor.getModel()._getTrackedRange(trackedRange) || newRange;
  119. }
  120. else {
  121. textEdits = [{ range, text: model.presentation.label, forceMoveMarkers: false }];
  122. newRange = range.setEndPosition(range.endLineNumber, range.startColumn + model.presentation.label.length);
  123. this._editor.pushUndoStop();
  124. this._editor.executeEdits('colorpicker', textEdits);
  125. }
  126. if (model.presentation.additionalTextEdits) {
  127. textEdits = [...model.presentation.additionalTextEdits];
  128. this._editor.executeEdits('colorpicker', textEdits);
  129. context.hide();
  130. }
  131. this._editor.pushUndoStop();
  132. range = newRange;
  133. };
  134. const updateColorPresentations = (color) => {
  135. return getColorPresentations(editorModel, {
  136. range: range,
  137. color: {
  138. red: color.rgba.r / 255,
  139. green: color.rgba.g / 255,
  140. blue: color.rgba.b / 255,
  141. alpha: color.rgba.a
  142. }
  143. }, colorHover.provider, CancellationToken.None).then((colorPresentations) => {
  144. model.colorPresentations = colorPresentations || [];
  145. });
  146. };
  147. disposables.add(model.onColorFlushed((color) => {
  148. updateColorPresentations(color).then(updateEditorModel);
  149. }));
  150. disposables.add(model.onDidChangeColor(updateColorPresentations));
  151. return disposables;
  152. }
  153. };
  154. ColorHoverParticipant = __decorate([
  155. __param(1, IThemeService)
  156. ], ColorHoverParticipant);
  157. export { ColorHoverParticipant };