123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
- 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;
- return c > 3 && r && Object.defineProperty(target, key, r), r;
- };
- var __param = (this && this.__param) || function (paramIndex, decorator) {
- return function (target, key) { decorator(target, key, paramIndex); }
- };
- import * as dom from '../../../base/browser/dom.js';
- import { asArray } from '../../../base/common/arrays.js';
- import { AsyncIterableObject } from '../../../base/common/async.js';
- import { isEmptyMarkdownString, MarkdownString } from '../../../base/common/htmlContent.js';
- import { DisposableStore } from '../../../base/common/lifecycle.js';
- import { MarkdownRenderer } from '../../browser/core/markdownRenderer.js';
- import { Position } from '../../common/core/position.js';
- import { Range } from '../../common/core/range.js';
- import { HoverProviderRegistry } from '../../common/modes.js';
- import { IModeService } from '../../common/services/modeService.js';
- import { getHover } from './getHover.js';
- import * as nls from '../../../nls.js';
- import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
- import { IOpenerService } from '../../../platform/opener/common/opener.js';
- const $ = dom.$;
- export class MarkdownHover {
- constructor(owner, range, contents, ordinal) {
- this.owner = owner;
- this.range = range;
- this.contents = contents;
- this.ordinal = ordinal;
- }
- isValidForHoverAnchor(anchor) {
- return (anchor.type === 1 /* Range */
- && this.range.startColumn <= anchor.range.startColumn
- && this.range.endColumn >= anchor.range.endColumn);
- }
- }
- let MarkdownHoverParticipant = class MarkdownHoverParticipant {
- constructor(_editor, _hover, _modeService, _openerService, _configurationService) {
- this._editor = _editor;
- this._hover = _hover;
- this._modeService = _modeService;
- this._openerService = _openerService;
- this._configurationService = _configurationService;
- }
- createLoadingMessage(anchor) {
- return new MarkdownHover(this, anchor.range, [new MarkdownString().appendText(nls.localize('modesContentHover.loading', "Loading..."))], 2000);
- }
- computeSync(anchor, lineDecorations) {
- if (!this._editor.hasModel() || anchor.type !== 1 /* Range */) {
- return [];
- }
- const model = this._editor.getModel();
- const lineNumber = anchor.range.startLineNumber;
- const maxColumn = model.getLineMaxColumn(lineNumber);
- const result = [];
- let index = 1000;
- const lineLength = model.getLineLength(lineNumber);
- const languageId = model.getLanguageIdAtPosition(anchor.range.startLineNumber, anchor.range.startColumn);
- const maxTokenizationLineLength = this._configurationService.getValue('editor.maxTokenizationLineLength', {
- overrideIdentifier: languageId
- });
- if (typeof maxTokenizationLineLength === 'number' && lineLength >= maxTokenizationLineLength) {
- result.push(new MarkdownHover(this, anchor.range, [{
- value: nls.localize('too many characters', "Tokenization is skipped for long lines for performance reasons. This can be configured via `editor.maxTokenizationLineLength`.")
- }], index++));
- }
- for (const d of lineDecorations) {
- const startColumn = (d.range.startLineNumber === lineNumber) ? d.range.startColumn : 1;
- const endColumn = (d.range.endLineNumber === lineNumber) ? d.range.endColumn : maxColumn;
- const hoverMessage = d.options.hoverMessage;
- if (!hoverMessage || isEmptyMarkdownString(hoverMessage)) {
- continue;
- }
- const range = new Range(anchor.range.startLineNumber, startColumn, anchor.range.startLineNumber, endColumn);
- result.push(new MarkdownHover(this, range, asArray(hoverMessage), index++));
- }
- return result;
- }
- computeAsync(anchor, lineDecorations, token) {
- if (!this._editor.hasModel() || anchor.type !== 1 /* Range */) {
- return AsyncIterableObject.EMPTY;
- }
- const model = this._editor.getModel();
- if (!HoverProviderRegistry.has(model)) {
- return AsyncIterableObject.EMPTY;
- }
- const position = new Position(anchor.range.startLineNumber, anchor.range.startColumn);
- return getHover(model, position, token)
- .filter(item => !isEmptyMarkdownString(item.hover.contents))
- .map(item => {
- const rng = item.hover.range ? Range.lift(item.hover.range) : anchor.range;
- return new MarkdownHover(this, rng, item.hover.contents, item.ordinal);
- });
- }
- renderHoverParts(hoverParts, fragment, statusBar) {
- return renderMarkdownHovers(hoverParts, fragment, this._editor, this._hover, this._modeService, this._openerService);
- }
- };
- MarkdownHoverParticipant = __decorate([
- __param(2, IModeService),
- __param(3, IOpenerService),
- __param(4, IConfigurationService)
- ], MarkdownHoverParticipant);
- export { MarkdownHoverParticipant };
- export function renderMarkdownHovers(hoverParts, fragment, editor, hover, modeService, openerService) {
- // Sort hover parts to keep them stable since they might come in async, out-of-order
- hoverParts.sort((a, b) => a.ordinal - b.ordinal);
- const disposables = new DisposableStore();
- for (const hoverPart of hoverParts) {
- for (const contents of hoverPart.contents) {
- if (isEmptyMarkdownString(contents)) {
- continue;
- }
- const markdownHoverElement = $('div.hover-row.markdown-hover');
- const hoverContentsElement = dom.append(markdownHoverElement, $('div.hover-contents'));
- const renderer = disposables.add(new MarkdownRenderer({ editor }, modeService, openerService));
- disposables.add(renderer.onDidRenderAsync(() => {
- hoverContentsElement.className = 'hover-contents code-hover-contents';
- hover.onContentsChanged();
- }));
- const renderedContents = disposables.add(renderer.render(contents));
- hoverContentsElement.appendChild(renderedContents.element);
- fragment.appendChild(markdownHoverElement);
- }
- }
- return disposables;
- }
|