UNPKG

monaco-editor

Version:
108 lines (105 loc) 4.41 kB
import { isHTMLElement } from '../../../base/browser/dom.js'; import { isManagedHoverTooltipMarkdownString } from '../../../base/browser/ui/hover/hover.js'; import { CancellationTokenSource } from '../../../base/common/cancellation.js'; import { isMarkdownString } from '../../../base/common/htmlContent.js'; import { isString, isFunction } from '../../../base/common/types.js'; import { localize } from '../../../nls.js'; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ class ManagedHoverWidget { constructor(hoverDelegate, target, fadeInAnimation) { this.hoverDelegate = hoverDelegate; this.target = target; this.fadeInAnimation = fadeInAnimation; } async update(content, focus, options) { if (this._cancellationTokenSource) { // there's an computation ongoing, cancel it this._cancellationTokenSource.dispose(true); this._cancellationTokenSource = undefined; } if (this.isDisposed) { return; } let resolvedContent; if (isString(content) || isHTMLElement(content) || content === undefined) { resolvedContent = content; } else { // compute the content, potentially long-running this._cancellationTokenSource = new CancellationTokenSource(); const token = this._cancellationTokenSource.token; let managedContent; if (isManagedHoverTooltipMarkdownString(content)) { if (isFunction(content.markdown)) { managedContent = content.markdown(token).then(resolvedContent => resolvedContent ?? content.markdownNotSupportedFallback); } else { managedContent = content.markdown ?? content.markdownNotSupportedFallback; } } else { managedContent = content.element(token); } // compute the content if (managedContent instanceof Promise) { // show 'Loading' if no hover is up yet if (!this._hoverWidget) { this.show(localize(1700, "Loading..."), focus, options); } resolvedContent = await managedContent; } else { resolvedContent = managedContent; } if (this.isDisposed || token.isCancellationRequested) { // either the widget has been closed in the meantime // or there has been a new call to `update` return; } } this.show(resolvedContent, focus, options); } show(content, focus, options) { const oldHoverWidget = this._hoverWidget; if (this.hasContent(content)) { const hoverOptions = { content, target: this.target, actions: options?.actions, linkHandler: options?.linkHandler, trapFocus: options?.trapFocus, appearance: { showPointer: this.hoverDelegate.placement === 'element', skipFadeInAnimation: !this.fadeInAnimation || !!oldHoverWidget, // do not fade in if the hover is already showing showHoverHint: options?.appearance?.showHoverHint, }, position: { hoverPosition: 2 /* HoverPosition.BELOW */, }, }; this._hoverWidget = this.hoverDelegate.showHover(hoverOptions, focus); } oldHoverWidget?.dispose(); } hasContent(content) { if (!content) { return false; } if (isMarkdownString(content)) { return !!content.value; } return true; } get isDisposed() { return this._hoverWidget?.isDisposed; } dispose() { this._hoverWidget?.dispose(); this._cancellationTokenSource?.dispose(true); this._cancellationTokenSource = undefined; } } export { ManagedHoverWidget };