0524342108c29facede6db0fb51f5d12c5bf9dda337ab7652d012cbce7a2c20874abcf3058373e7571c41f946054d5e445adf92abe57dbab991107157e1f03 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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 { alert } from '../../../../base/browser/ui/aria/aria.js';
  15. import { TimeoutTimer } from '../../../../base/common/async.js';
  16. import { DisposableStore, MutableDisposable } from '../../../../base/common/lifecycle.js';
  17. import './messageController.css';
  18. import { EditorCommand, registerEditorCommand, registerEditorContribution } from '../../../browser/editorExtensions.js';
  19. import { Range } from '../../../common/core/range.js';
  20. import * as nls from '../../../../nls.js';
  21. import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
  22. let MessageController = class MessageController {
  23. constructor(editor, contextKeyService) {
  24. this._messageWidget = new MutableDisposable();
  25. this._messageListeners = new DisposableStore();
  26. this._editor = editor;
  27. this._visible = MessageController.MESSAGE_VISIBLE.bindTo(contextKeyService);
  28. }
  29. static get(editor) {
  30. return editor.getContribution(MessageController.ID);
  31. }
  32. dispose() {
  33. this._messageListeners.dispose();
  34. this._messageWidget.dispose();
  35. this._visible.reset();
  36. }
  37. showMessage(message, position) {
  38. alert(message);
  39. this._visible.set(true);
  40. this._messageWidget.clear();
  41. this._messageListeners.clear();
  42. this._messageWidget.value = new MessageWidget(this._editor, position, message);
  43. // close on blur, cursor, model change, dispose
  44. this._messageListeners.add(this._editor.onDidBlurEditorText(() => this.closeMessage()));
  45. this._messageListeners.add(this._editor.onDidChangeCursorPosition(() => this.closeMessage()));
  46. this._messageListeners.add(this._editor.onDidDispose(() => this.closeMessage()));
  47. this._messageListeners.add(this._editor.onDidChangeModel(() => this.closeMessage()));
  48. // 3sec
  49. this._messageListeners.add(new TimeoutTimer(() => this.closeMessage(), 3000));
  50. // close on mouse move
  51. let bounds;
  52. this._messageListeners.add(this._editor.onMouseMove(e => {
  53. // outside the text area
  54. if (!e.target.position) {
  55. return;
  56. }
  57. if (!bounds) {
  58. // define bounding box around position and first mouse occurance
  59. bounds = new Range(position.lineNumber - 3, 1, e.target.position.lineNumber + 3, 1);
  60. }
  61. else if (!bounds.containsPosition(e.target.position)) {
  62. // check if position is still in bounds
  63. this.closeMessage();
  64. }
  65. }));
  66. }
  67. closeMessage() {
  68. this._visible.reset();
  69. this._messageListeners.clear();
  70. if (this._messageWidget.value) {
  71. this._messageListeners.add(MessageWidget.fadeOut(this._messageWidget.value));
  72. }
  73. }
  74. };
  75. MessageController.ID = 'editor.contrib.messageController';
  76. MessageController.MESSAGE_VISIBLE = new RawContextKey('messageVisible', false, nls.localize('messageVisible', 'Whether the editor is currently showing an inline message'));
  77. MessageController = __decorate([
  78. __param(1, IContextKeyService)
  79. ], MessageController);
  80. export { MessageController };
  81. const MessageCommand = EditorCommand.bindToContribution(MessageController.get);
  82. registerEditorCommand(new MessageCommand({
  83. id: 'leaveEditorMessage',
  84. precondition: MessageController.MESSAGE_VISIBLE,
  85. handler: c => c.closeMessage(),
  86. kbOpts: {
  87. weight: 100 /* KeybindingWeight.EditorContrib */ + 30,
  88. primary: 9 /* KeyCode.Escape */
  89. }
  90. }));
  91. class MessageWidget {
  92. constructor(editor, { lineNumber, column }, text) {
  93. // Editor.IContentWidget.allowEditorOverflow
  94. this.allowEditorOverflow = true;
  95. this.suppressMouseDown = false;
  96. this._editor = editor;
  97. this._editor.revealLinesInCenterIfOutsideViewport(lineNumber, lineNumber, 0 /* ScrollType.Smooth */);
  98. this._position = { lineNumber, column };
  99. this._domNode = document.createElement('div');
  100. this._domNode.classList.add('monaco-editor-overlaymessage');
  101. this._domNode.style.marginLeft = '-6px';
  102. const anchorTop = document.createElement('div');
  103. anchorTop.classList.add('anchor', 'top');
  104. this._domNode.appendChild(anchorTop);
  105. const message = document.createElement('div');
  106. message.classList.add('message');
  107. message.textContent = text;
  108. this._domNode.appendChild(message);
  109. const anchorBottom = document.createElement('div');
  110. anchorBottom.classList.add('anchor', 'below');
  111. this._domNode.appendChild(anchorBottom);
  112. this._editor.addContentWidget(this);
  113. this._domNode.classList.add('fadeIn');
  114. }
  115. static fadeOut(messageWidget) {
  116. const dispose = () => {
  117. messageWidget.dispose();
  118. clearTimeout(handle);
  119. messageWidget.getDomNode().removeEventListener('animationend', dispose);
  120. };
  121. const handle = setTimeout(dispose, 110);
  122. messageWidget.getDomNode().addEventListener('animationend', dispose);
  123. messageWidget.getDomNode().classList.add('fadeOut');
  124. return { dispose };
  125. }
  126. dispose() {
  127. this._editor.removeContentWidget(this);
  128. }
  129. getId() {
  130. return 'messageoverlay';
  131. }
  132. getDomNode() {
  133. return this._domNode;
  134. }
  135. getPosition() {
  136. return {
  137. position: this._position,
  138. preference: [
  139. 1 /* ContentWidgetPositionPreference.ABOVE */,
  140. 2 /* ContentWidgetPositionPreference.BELOW */,
  141. ],
  142. positionAffinity: 1 /* PositionAffinity.Right */,
  143. };
  144. }
  145. afterRender(position) {
  146. this._domNode.classList.toggle('below', position === 2 /* ContentWidgetPositionPreference.BELOW */);
  147. }
  148. }
  149. registerEditorContribution(MessageController.ID, MessageController);