renameInputField.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 { DisposableStore } from '../../../base/common/lifecycle.js';
  15. import './renameInputField.css';
  16. import { Position } from '../../common/core/position.js';
  17. import { localize } from '../../../nls.js';
  18. import { IContextKeyService, RawContextKey } from '../../../platform/contextkey/common/contextkey.js';
  19. import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js';
  20. import { editorWidgetBackground, inputBackground, inputBorder, inputForeground, widgetShadow } from '../../../platform/theme/common/colorRegistry.js';
  21. import { IThemeService } from '../../../platform/theme/common/themeService.js';
  22. export const CONTEXT_RENAME_INPUT_VISIBLE = new RawContextKey('renameInputVisible', false, localize('renameInputVisible', "Whether the rename input widget is visible"));
  23. let RenameInputField = class RenameInputField {
  24. constructor(_editor, _acceptKeybindings, _themeService, _keybindingService, contextKeyService) {
  25. this._editor = _editor;
  26. this._acceptKeybindings = _acceptKeybindings;
  27. this._themeService = _themeService;
  28. this._keybindingService = _keybindingService;
  29. this._disposables = new DisposableStore();
  30. this.allowEditorOverflow = true;
  31. this._visibleContextKey = CONTEXT_RENAME_INPUT_VISIBLE.bindTo(contextKeyService);
  32. this._editor.addContentWidget(this);
  33. this._disposables.add(this._editor.onDidChangeConfiguration(e => {
  34. if (e.hasChanged(43 /* fontInfo */)) {
  35. this._updateFont();
  36. }
  37. }));
  38. this._disposables.add(_themeService.onDidColorThemeChange(this._updateStyles, this));
  39. }
  40. dispose() {
  41. this._disposables.dispose();
  42. this._editor.removeContentWidget(this);
  43. }
  44. getId() {
  45. return '__renameInputWidget';
  46. }
  47. getDomNode() {
  48. if (!this._domNode) {
  49. this._domNode = document.createElement('div');
  50. this._domNode.className = 'monaco-editor rename-box';
  51. this._input = document.createElement('input');
  52. this._input.className = 'rename-input';
  53. this._input.type = 'text';
  54. this._input.setAttribute('aria-label', localize('renameAriaLabel', "Rename input. Type new name and press Enter to commit."));
  55. this._domNode.appendChild(this._input);
  56. this._label = document.createElement('div');
  57. this._label.className = 'rename-label';
  58. this._domNode.appendChild(this._label);
  59. const updateLabel = () => {
  60. var _a, _b;
  61. const [accept, preview] = this._acceptKeybindings;
  62. this._keybindingService.lookupKeybinding(accept);
  63. this._label.innerText = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Rename, Shift+F2 to Preview"'] }, "{0} to Rename, {1} to Preview", (_a = this._keybindingService.lookupKeybinding(accept)) === null || _a === void 0 ? void 0 : _a.getLabel(), (_b = this._keybindingService.lookupKeybinding(preview)) === null || _b === void 0 ? void 0 : _b.getLabel());
  64. };
  65. updateLabel();
  66. this._disposables.add(this._keybindingService.onDidUpdateKeybindings(updateLabel));
  67. this._updateFont();
  68. this._updateStyles(this._themeService.getColorTheme());
  69. }
  70. return this._domNode;
  71. }
  72. _updateStyles(theme) {
  73. var _a, _b, _c, _d;
  74. if (!this._input || !this._domNode) {
  75. return;
  76. }
  77. const widgetShadowColor = theme.getColor(widgetShadow);
  78. this._domNode.style.backgroundColor = String((_a = theme.getColor(editorWidgetBackground)) !== null && _a !== void 0 ? _a : '');
  79. this._domNode.style.boxShadow = widgetShadowColor ? ` 0 0 8px 2px ${widgetShadowColor}` : '';
  80. this._domNode.style.color = String((_b = theme.getColor(inputForeground)) !== null && _b !== void 0 ? _b : '');
  81. this._input.style.backgroundColor = String((_c = theme.getColor(inputBackground)) !== null && _c !== void 0 ? _c : '');
  82. // this._input.style.color = String(theme.getColor(inputForeground) ?? '');
  83. const border = theme.getColor(inputBorder);
  84. this._input.style.borderWidth = border ? '1px' : '0px';
  85. this._input.style.borderStyle = border ? 'solid' : 'none';
  86. this._input.style.borderColor = (_d = border === null || border === void 0 ? void 0 : border.toString()) !== null && _d !== void 0 ? _d : 'none';
  87. }
  88. _updateFont() {
  89. if (!this._input || !this._label) {
  90. return;
  91. }
  92. const fontInfo = this._editor.getOption(43 /* fontInfo */);
  93. this._input.style.fontFamily = fontInfo.fontFamily;
  94. this._input.style.fontWeight = fontInfo.fontWeight;
  95. this._input.style.fontSize = `${fontInfo.fontSize}px`;
  96. this._label.style.fontSize = `${fontInfo.fontSize * 0.8}px`;
  97. }
  98. getPosition() {
  99. if (!this._visible) {
  100. return null;
  101. }
  102. return {
  103. position: this._position,
  104. preference: [2 /* BELOW */, 1 /* ABOVE */]
  105. };
  106. }
  107. afterRender(position) {
  108. if (!position) {
  109. // cancel rename when input widget isn't rendered anymore
  110. this.cancelInput(true);
  111. }
  112. }
  113. acceptInput(wantsPreview) {
  114. if (this._currentAcceptInput) {
  115. this._currentAcceptInput(wantsPreview);
  116. }
  117. }
  118. cancelInput(focusEditor) {
  119. if (this._currentCancelInput) {
  120. this._currentCancelInput(focusEditor);
  121. }
  122. }
  123. getInput(where, value, selectionStart, selectionEnd, supportPreview, token) {
  124. this._domNode.classList.toggle('preview', supportPreview);
  125. this._position = new Position(where.startLineNumber, where.startColumn);
  126. this._input.value = value;
  127. this._input.setAttribute('selectionStart', selectionStart.toString());
  128. this._input.setAttribute('selectionEnd', selectionEnd.toString());
  129. this._input.size = Math.max((where.endColumn - where.startColumn) * 1.1, 20);
  130. const disposeOnDone = new DisposableStore();
  131. return new Promise(resolve => {
  132. this._currentCancelInput = (focusEditor) => {
  133. this._currentAcceptInput = undefined;
  134. this._currentCancelInput = undefined;
  135. resolve(focusEditor);
  136. return true;
  137. };
  138. this._currentAcceptInput = (wantsPreview) => {
  139. if (this._input.value.trim().length === 0 || this._input.value === value) {
  140. // empty or whitespace only or not changed
  141. this.cancelInput(true);
  142. return;
  143. }
  144. this._currentAcceptInput = undefined;
  145. this._currentCancelInput = undefined;
  146. resolve({
  147. newName: this._input.value,
  148. wantsPreview: supportPreview && wantsPreview
  149. });
  150. };
  151. token.onCancellationRequested(() => this.cancelInput(true));
  152. disposeOnDone.add(this._editor.onDidBlurEditorWidget(() => this.cancelInput(false)));
  153. this._show();
  154. }).finally(() => {
  155. disposeOnDone.dispose();
  156. this._hide();
  157. });
  158. }
  159. _show() {
  160. this._editor.revealLineInCenterIfOutsideViewport(this._position.lineNumber, 0 /* Smooth */);
  161. this._visible = true;
  162. this._visibleContextKey.set(true);
  163. this._editor.layoutContentWidget(this);
  164. setTimeout(() => {
  165. this._input.focus();
  166. this._input.setSelectionRange(parseInt(this._input.getAttribute('selectionStart')), parseInt(this._input.getAttribute('selectionEnd')));
  167. }, 100);
  168. }
  169. _hide() {
  170. this._visible = false;
  171. this._visibleContextKey.reset();
  172. this._editor.layoutContentWidget(this);
  173. }
  174. };
  175. RenameInputField = __decorate([
  176. __param(2, IThemeService),
  177. __param(3, IKeybindingService),
  178. __param(4, IContextKeyService)
  179. ], RenameInputField);
  180. export { RenameInputField };