peekView.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. import * as dom from '../../../base/browser/dom.js';
  15. import { ActionBar } from '../../../base/browser/ui/actionbar/actionbar.js';
  16. import { Action } from '../../../base/common/actions.js';
  17. import { Codicon } from '../../../base/common/codicons.js';
  18. import { Color } from '../../../base/common/color.js';
  19. import { Emitter } from '../../../base/common/event.js';
  20. import * as objects from '../../../base/common/objects.js';
  21. import './media/peekViewWidget.css';
  22. import { registerEditorContribution } from '../../browser/editorExtensions.js';
  23. import { ICodeEditorService } from '../../browser/services/codeEditorService.js';
  24. import { EmbeddedCodeEditorWidget } from '../../browser/widget/embeddedCodeEditorWidget.js';
  25. import { ZoneWidget } from '../zoneWidget/zoneWidget.js';
  26. import * as nls from '../../../nls.js';
  27. import { createActionViewItem } from '../../../platform/actions/browser/menuEntryActionViewItem.js';
  28. import { IContextKeyService, RawContextKey } from '../../../platform/contextkey/common/contextkey.js';
  29. import { registerSingleton } from '../../../platform/instantiation/common/extensions.js';
  30. import { createDecorator, IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';
  31. import { activeContrastBorder, contrastBorder, editorInfoForeground, registerColor, transparent } from '../../../platform/theme/common/colorRegistry.js';
  32. export const IPeekViewService = createDecorator('IPeekViewService');
  33. registerSingleton(IPeekViewService, class {
  34. constructor() {
  35. this._widgets = new Map();
  36. }
  37. addExclusiveWidget(editor, widget) {
  38. const existing = this._widgets.get(editor);
  39. if (existing) {
  40. existing.listener.dispose();
  41. existing.widget.dispose();
  42. }
  43. const remove = () => {
  44. const data = this._widgets.get(editor);
  45. if (data && data.widget === widget) {
  46. data.listener.dispose();
  47. this._widgets.delete(editor);
  48. }
  49. };
  50. this._widgets.set(editor, { widget, listener: widget.onDidClose(remove) });
  51. }
  52. });
  53. export var PeekContext;
  54. (function (PeekContext) {
  55. PeekContext.inPeekEditor = new RawContextKey('inReferenceSearchEditor', true, nls.localize('inReferenceSearchEditor', "Whether the current code editor is embedded inside peek"));
  56. PeekContext.notInPeekEditor = PeekContext.inPeekEditor.toNegated();
  57. })(PeekContext || (PeekContext = {}));
  58. let PeekContextController = class PeekContextController {
  59. constructor(editor, contextKeyService) {
  60. if (editor instanceof EmbeddedCodeEditorWidget) {
  61. PeekContext.inPeekEditor.bindTo(contextKeyService);
  62. }
  63. }
  64. dispose() { }
  65. };
  66. PeekContextController.ID = 'editor.contrib.referenceController';
  67. PeekContextController = __decorate([
  68. __param(1, IContextKeyService)
  69. ], PeekContextController);
  70. registerEditorContribution(PeekContextController.ID, PeekContextController);
  71. export function getOuterEditor(accessor) {
  72. let editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
  73. if (editor instanceof EmbeddedCodeEditorWidget) {
  74. return editor.getParentEditor();
  75. }
  76. return editor;
  77. }
  78. const defaultOptions = {
  79. headerBackgroundColor: Color.white,
  80. primaryHeadingColor: Color.fromHex('#333333'),
  81. secondaryHeadingColor: Color.fromHex('#6c6c6cb3')
  82. };
  83. let PeekViewWidget = class PeekViewWidget extends ZoneWidget {
  84. constructor(editor, options, instantiationService) {
  85. super(editor, options);
  86. this.instantiationService = instantiationService;
  87. this._onDidClose = new Emitter();
  88. this.onDidClose = this._onDidClose.event;
  89. objects.mixin(this.options, defaultOptions, false);
  90. }
  91. dispose() {
  92. if (!this.disposed) {
  93. this.disposed = true; // prevent consumers who dispose on onDidClose from looping
  94. super.dispose();
  95. this._onDidClose.fire(this);
  96. }
  97. }
  98. style(styles) {
  99. let options = this.options;
  100. if (styles.headerBackgroundColor) {
  101. options.headerBackgroundColor = styles.headerBackgroundColor;
  102. }
  103. if (styles.primaryHeadingColor) {
  104. options.primaryHeadingColor = styles.primaryHeadingColor;
  105. }
  106. if (styles.secondaryHeadingColor) {
  107. options.secondaryHeadingColor = styles.secondaryHeadingColor;
  108. }
  109. super.style(styles);
  110. }
  111. _applyStyles() {
  112. super._applyStyles();
  113. let options = this.options;
  114. if (this._headElement && options.headerBackgroundColor) {
  115. this._headElement.style.backgroundColor = options.headerBackgroundColor.toString();
  116. }
  117. if (this._primaryHeading && options.primaryHeadingColor) {
  118. this._primaryHeading.style.color = options.primaryHeadingColor.toString();
  119. }
  120. if (this._secondaryHeading && options.secondaryHeadingColor) {
  121. this._secondaryHeading.style.color = options.secondaryHeadingColor.toString();
  122. }
  123. if (this._bodyElement && options.frameColor) {
  124. this._bodyElement.style.borderColor = options.frameColor.toString();
  125. }
  126. }
  127. _fillContainer(container) {
  128. this.setCssClass('peekview-widget');
  129. this._headElement = dom.$('.head');
  130. this._bodyElement = dom.$('.body');
  131. this._fillHead(this._headElement);
  132. this._fillBody(this._bodyElement);
  133. container.appendChild(this._headElement);
  134. container.appendChild(this._bodyElement);
  135. }
  136. _fillHead(container, noCloseAction) {
  137. const titleElement = dom.$('.peekview-title');
  138. if (this.options.supportOnTitleClick) {
  139. titleElement.classList.add('clickable');
  140. dom.addStandardDisposableListener(titleElement, 'click', event => this._onTitleClick(event));
  141. }
  142. dom.append(this._headElement, titleElement);
  143. this._fillTitleIcon(titleElement);
  144. this._primaryHeading = dom.$('span.filename');
  145. this._secondaryHeading = dom.$('span.dirname');
  146. this._metaHeading = dom.$('span.meta');
  147. dom.append(titleElement, this._primaryHeading, this._secondaryHeading, this._metaHeading);
  148. const actionsContainer = dom.$('.peekview-actions');
  149. dom.append(this._headElement, actionsContainer);
  150. const actionBarOptions = this._getActionBarOptions();
  151. this._actionbarWidget = new ActionBar(actionsContainer, actionBarOptions);
  152. this._disposables.add(this._actionbarWidget);
  153. if (!noCloseAction) {
  154. this._actionbarWidget.push(new Action('peekview.close', nls.localize('label.close', "Close"), Codicon.close.classNames, true, () => {
  155. this.dispose();
  156. return Promise.resolve();
  157. }), { label: false, icon: true });
  158. }
  159. }
  160. _fillTitleIcon(container) {
  161. }
  162. _getActionBarOptions() {
  163. return {
  164. actionViewItemProvider: createActionViewItem.bind(undefined, this.instantiationService),
  165. orientation: 0 /* HORIZONTAL */
  166. };
  167. }
  168. _onTitleClick(event) {
  169. // implement me if supportOnTitleClick option is set
  170. }
  171. setTitle(primaryHeading, secondaryHeading) {
  172. if (this._primaryHeading && this._secondaryHeading) {
  173. this._primaryHeading.innerText = primaryHeading;
  174. this._primaryHeading.setAttribute('title', primaryHeading);
  175. if (secondaryHeading) {
  176. this._secondaryHeading.innerText = secondaryHeading;
  177. }
  178. else {
  179. dom.clearNode(this._secondaryHeading);
  180. }
  181. }
  182. }
  183. setMetaTitle(value) {
  184. if (this._metaHeading) {
  185. if (value) {
  186. this._metaHeading.innerText = value;
  187. dom.show(this._metaHeading);
  188. }
  189. else {
  190. dom.hide(this._metaHeading);
  191. }
  192. }
  193. }
  194. _doLayout(heightInPixel, widthInPixel) {
  195. if (!this._isShowing && heightInPixel < 0) {
  196. // Looks like the view zone got folded away!
  197. this.dispose();
  198. return;
  199. }
  200. const headHeight = Math.ceil(this.editor.getOption(58 /* lineHeight */) * 1.2);
  201. const bodyHeight = Math.round(heightInPixel - (headHeight + 2 /* the border-top/bottom width*/));
  202. this._doLayoutHead(headHeight, widthInPixel);
  203. this._doLayoutBody(bodyHeight, widthInPixel);
  204. }
  205. _doLayoutHead(heightInPixel, widthInPixel) {
  206. if (this._headElement) {
  207. this._headElement.style.height = `${heightInPixel}px`;
  208. this._headElement.style.lineHeight = this._headElement.style.height;
  209. }
  210. }
  211. _doLayoutBody(heightInPixel, widthInPixel) {
  212. if (this._bodyElement) {
  213. this._bodyElement.style.height = `${heightInPixel}px`;
  214. }
  215. }
  216. };
  217. PeekViewWidget = __decorate([
  218. __param(2, IInstantiationService)
  219. ], PeekViewWidget);
  220. export { PeekViewWidget };
  221. export const peekViewTitleBackground = registerColor('peekViewTitle.background', { dark: transparent(editorInfoForeground, .1), light: transparent(editorInfoForeground, .1), hc: null }, nls.localize('peekViewTitleBackground', 'Background color of the peek view title area.'));
  222. export const peekViewTitleForeground = registerColor('peekViewTitleLabel.foreground', { dark: Color.white, light: Color.black, hc: Color.white }, nls.localize('peekViewTitleForeground', 'Color of the peek view title.'));
  223. export const peekViewTitleInfoForeground = registerColor('peekViewTitleDescription.foreground', { dark: '#ccccccb3', light: '#616161', hc: '#FFFFFF99' }, nls.localize('peekViewTitleInfoForeground', 'Color of the peek view title info.'));
  224. export const peekViewBorder = registerColor('peekView.border', { dark: editorInfoForeground, light: editorInfoForeground, hc: contrastBorder }, nls.localize('peekViewBorder', 'Color of the peek view borders and arrow.'));
  225. export const peekViewResultsBackground = registerColor('peekViewResult.background', { dark: '#252526', light: '#F3F3F3', hc: Color.black }, nls.localize('peekViewResultsBackground', 'Background color of the peek view result list.'));
  226. export const peekViewResultsMatchForeground = registerColor('peekViewResult.lineForeground', { dark: '#bbbbbb', light: '#646465', hc: Color.white }, nls.localize('peekViewResultsMatchForeground', 'Foreground color for line nodes in the peek view result list.'));
  227. export const peekViewResultsFileForeground = registerColor('peekViewResult.fileForeground', { dark: Color.white, light: '#1E1E1E', hc: Color.white }, nls.localize('peekViewResultsFileForeground', 'Foreground color for file nodes in the peek view result list.'));
  228. export const peekViewResultsSelectionBackground = registerColor('peekViewResult.selectionBackground', { dark: '#3399ff33', light: '#3399ff33', hc: null }, nls.localize('peekViewResultsSelectionBackground', 'Background color of the selected entry in the peek view result list.'));
  229. export const peekViewResultsSelectionForeground = registerColor('peekViewResult.selectionForeground', { dark: Color.white, light: '#6C6C6C', hc: Color.white }, nls.localize('peekViewResultsSelectionForeground', 'Foreground color of the selected entry in the peek view result list.'));
  230. export const peekViewEditorBackground = registerColor('peekViewEditor.background', { dark: '#001F33', light: '#F2F8FC', hc: Color.black }, nls.localize('peekViewEditorBackground', 'Background color of the peek view editor.'));
  231. export const peekViewEditorGutterBackground = registerColor('peekViewEditorGutter.background', { dark: peekViewEditorBackground, light: peekViewEditorBackground, hc: peekViewEditorBackground }, nls.localize('peekViewEditorGutterBackground', 'Background color of the gutter in the peek view editor.'));
  232. export const peekViewResultsMatchHighlight = registerColor('peekViewResult.matchHighlightBackground', { dark: '#ea5c004d', light: '#ea5c004d', hc: null }, nls.localize('peekViewResultsMatchHighlight', 'Match highlight color in the peek view result list.'));
  233. export const peekViewEditorMatchHighlight = registerColor('peekViewEditor.matchHighlightBackground', { dark: '#ff8f0099', light: '#f5d802de', hc: null }, nls.localize('peekViewEditorMatchHighlight', 'Match highlight color in the peek view editor.'));
  234. export const peekViewEditorMatchHighlightBorder = registerColor('peekViewEditor.matchHighlightBorder', { dark: null, light: null, hc: activeContrastBorder }, nls.localize('peekViewEditorMatchHighlightBorder', 'Match highlight border in the peek view editor.'));