mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-24 09:35:37 -05:00
* Merge from vscode 504f934659740e9d41501cad9f162b54d7745ad9 * delete unused folders * distro * Bump build node version * update chokidar * FIx hygiene errors * distro * Fix extension lint issues * Remove strict-vscode * Add copyright header exemptions * Bump vscode-extension-telemetry to fix webpacking issue with zone.js * distro * Fix failing tests (revert marked.js back to current one until we decide to update) * Skip searchmodel test * Fix mac build * temp debug script loading * Try disabling coverage * log error too * Revert "log error too" This reverts commit af0183e5d4ab458fdf44b88fbfab9908d090526f. * Revert "temp debug script loading" This reverts commit 3d687d541c76db2c5b55626c78ae448d3c25089c. * Add comments explaining coverage disabling * Fix ansi_up loading issue * Merge latest from ads * Use newer option * Fix compile * add debug logging warn * Always log stack * log more * undo debug * Update to use correct base path (+cleanup) * distro * fix compile errors * Remove strict-vscode * Fix sql editors not showing * Show db dropdown input & fix styling * Fix more info in gallery * Fix gallery asset requests * Delete unused workflow * Fix tapable resolutions for smoke test compile error * Fix smoke compile * Disable crash reporting * Disable interactive Co-authored-by: ADS Merger <karlb@microsoft.com>
262 lines
7.9 KiB
TypeScript
262 lines
7.9 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as vscode from 'vscode';
|
|
import { Logger } from '../logger';
|
|
import { MarkdownEngine } from '../markdownEngine';
|
|
import { MarkdownContributionProvider } from '../markdownExtensions';
|
|
import { Disposable, disposeAll } from '../util/dispose';
|
|
import { isMarkdownFile } from '../util/file';
|
|
import { TopmostLineMonitor } from '../util/topmostLineMonitor';
|
|
import { DynamicMarkdownPreview, ManagedMarkdownPreview, scrollEditorToLine, StartingScrollFragment, StaticMarkdownPreview } from './preview';
|
|
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
|
import { MarkdownContentProvider } from './previewContentProvider';
|
|
|
|
export interface DynamicPreviewSettings {
|
|
readonly resourceColumn: vscode.ViewColumn;
|
|
readonly previewColumn: vscode.ViewColumn;
|
|
readonly locked: boolean;
|
|
}
|
|
|
|
class PreviewStore<T extends ManagedMarkdownPreview> extends Disposable {
|
|
|
|
private readonly _previews = new Set<T>();
|
|
|
|
public override dispose(): void {
|
|
super.dispose();
|
|
for (const preview of this._previews) {
|
|
preview.dispose();
|
|
}
|
|
this._previews.clear();
|
|
}
|
|
|
|
[Symbol.iterator](): Iterator<T> {
|
|
return this._previews[Symbol.iterator]();
|
|
}
|
|
|
|
public get(resource: vscode.Uri, previewSettings: DynamicPreviewSettings): T | undefined {
|
|
for (const preview of this._previews) {
|
|
if (preview.matchesResource(resource, previewSettings.previewColumn, previewSettings.locked)) {
|
|
return preview;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
public add(preview: T) {
|
|
this._previews.add(preview);
|
|
}
|
|
|
|
public delete(preview: T) {
|
|
this._previews.delete(preview);
|
|
}
|
|
}
|
|
|
|
export class MarkdownPreviewManager extends Disposable implements vscode.WebviewPanelSerializer, vscode.CustomTextEditorProvider {
|
|
private static readonly markdownPreviewActiveContextKey = 'markdownPreviewFocus';
|
|
|
|
private readonly _topmostLineMonitor = new TopmostLineMonitor();
|
|
private readonly _previewConfigurations = new MarkdownPreviewConfigurationManager();
|
|
|
|
private readonly _dynamicPreviews = this._register(new PreviewStore<DynamicMarkdownPreview>());
|
|
private readonly _staticPreviews = this._register(new PreviewStore<StaticMarkdownPreview>());
|
|
|
|
private _activePreview: ManagedMarkdownPreview | undefined = undefined;
|
|
|
|
private readonly customEditorViewType = 'vscode.markdown.preview.editor';
|
|
|
|
public constructor(
|
|
private readonly _contentProvider: MarkdownContentProvider,
|
|
private readonly _logger: Logger,
|
|
private readonly _contributions: MarkdownContributionProvider,
|
|
private readonly _engine: MarkdownEngine,
|
|
) {
|
|
super();
|
|
this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this));
|
|
this._register(vscode.window.registerCustomEditorProvider(this.customEditorViewType, this));
|
|
|
|
this._register(vscode.window.onDidChangeActiveTextEditor(textEditor => {
|
|
|
|
// When at a markdown file, apply existing scroll settings
|
|
if (textEditor && textEditor.document && isMarkdownFile(textEditor.document)) {
|
|
const line = this._topmostLineMonitor.getPreviousEditorLineByUri(textEditor.document.uri);
|
|
if (line) {
|
|
scrollEditorToLine(line, textEditor);
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
|
|
public refresh() {
|
|
for (const preview of this._dynamicPreviews) {
|
|
preview.refresh();
|
|
}
|
|
for (const preview of this._staticPreviews) {
|
|
preview.refresh();
|
|
}
|
|
}
|
|
|
|
public updateConfiguration() {
|
|
for (const preview of this._dynamicPreviews) {
|
|
preview.updateConfiguration();
|
|
}
|
|
for (const preview of this._staticPreviews) {
|
|
preview.updateConfiguration();
|
|
}
|
|
}
|
|
|
|
public openDynamicPreview(
|
|
resource: vscode.Uri,
|
|
settings: DynamicPreviewSettings
|
|
): void {
|
|
let preview = this._dynamicPreviews.get(resource, settings);
|
|
if (preview) {
|
|
preview.reveal(settings.previewColumn);
|
|
} else {
|
|
preview = this.createNewDynamicPreview(resource, settings);
|
|
}
|
|
|
|
preview.update(
|
|
resource,
|
|
resource.fragment ? new StartingScrollFragment(resource.fragment) : undefined
|
|
);
|
|
}
|
|
|
|
public get activePreviewResource() {
|
|
return this._activePreview?.resource;
|
|
}
|
|
|
|
public get activePreviewResourceColumn() {
|
|
return this._activePreview?.resourceColumn;
|
|
}
|
|
|
|
public toggleLock() {
|
|
const preview = this._activePreview;
|
|
if (preview instanceof DynamicMarkdownPreview) {
|
|
preview.toggleLock();
|
|
|
|
// Close any previews that are now redundant, such as having two dynamic previews in the same editor group
|
|
for (const otherPreview of this._dynamicPreviews) {
|
|
if (otherPreview !== preview && preview.matches(otherPreview)) {
|
|
otherPreview.dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public async deserializeWebviewPanel(
|
|
webview: vscode.WebviewPanel,
|
|
state: any
|
|
): Promise<void> {
|
|
const resource = vscode.Uri.parse(state.resource);
|
|
const locked = state.locked;
|
|
const line = state.line;
|
|
const resourceColumn = state.resourceColumn;
|
|
|
|
const preview = await DynamicMarkdownPreview.revive(
|
|
{ resource, locked, line, resourceColumn },
|
|
webview,
|
|
this._contentProvider,
|
|
this._previewConfigurations,
|
|
this._logger,
|
|
this._topmostLineMonitor,
|
|
this._contributions,
|
|
this._engine);
|
|
|
|
this.registerDynamicPreview(preview);
|
|
}
|
|
|
|
public async resolveCustomTextEditor(
|
|
document: vscode.TextDocument,
|
|
webview: vscode.WebviewPanel
|
|
): Promise<void> {
|
|
const lineNumber = this._topmostLineMonitor.getPreviousEditorLineByUri(document.uri);
|
|
const preview = StaticMarkdownPreview.revive(
|
|
document.uri,
|
|
webview,
|
|
this._contentProvider,
|
|
this._previewConfigurations,
|
|
this._topmostLineMonitor,
|
|
this._logger,
|
|
this._contributions,
|
|
this._engine,
|
|
lineNumber
|
|
);
|
|
this.registerStaticPreview(preview);
|
|
}
|
|
|
|
private createNewDynamicPreview(
|
|
resource: vscode.Uri,
|
|
previewSettings: DynamicPreviewSettings
|
|
): DynamicMarkdownPreview {
|
|
const activeTextEditorURI = vscode.window.activeTextEditor?.document.uri;
|
|
const scrollLine = (activeTextEditorURI?.toString() === resource.toString()) ? vscode.window.activeTextEditor?.visibleRanges[0].start.line : undefined;
|
|
const preview = DynamicMarkdownPreview.create(
|
|
{
|
|
resource,
|
|
resourceColumn: previewSettings.resourceColumn,
|
|
locked: previewSettings.locked,
|
|
line: scrollLine,
|
|
},
|
|
previewSettings.previewColumn,
|
|
this._contentProvider,
|
|
this._previewConfigurations,
|
|
this._logger,
|
|
this._topmostLineMonitor,
|
|
this._contributions,
|
|
this._engine);
|
|
|
|
this.setPreviewActiveContext(true);
|
|
this._activePreview = preview;
|
|
return this.registerDynamicPreview(preview);
|
|
}
|
|
|
|
private registerDynamicPreview(preview: DynamicMarkdownPreview): DynamicMarkdownPreview {
|
|
this._dynamicPreviews.add(preview);
|
|
|
|
preview.onDispose(() => {
|
|
this._dynamicPreviews.delete(preview);
|
|
});
|
|
|
|
this.trackActive(preview);
|
|
|
|
preview.onDidChangeViewState(() => {
|
|
// Remove other dynamic previews in our column
|
|
disposeAll(Array.from(this._dynamicPreviews).filter(otherPreview => preview !== otherPreview && preview.matches(otherPreview)));
|
|
});
|
|
return preview;
|
|
}
|
|
|
|
private registerStaticPreview(preview: StaticMarkdownPreview): StaticMarkdownPreview {
|
|
this._staticPreviews.add(preview);
|
|
|
|
preview.onDispose(() => {
|
|
this._staticPreviews.delete(preview);
|
|
});
|
|
|
|
this.trackActive(preview);
|
|
return preview;
|
|
}
|
|
|
|
private trackActive(preview: ManagedMarkdownPreview): void {
|
|
preview.onDidChangeViewState(({ webviewPanel }) => {
|
|
this.setPreviewActiveContext(webviewPanel.active);
|
|
this._activePreview = webviewPanel.active ? preview : undefined;
|
|
});
|
|
|
|
preview.onDispose(() => {
|
|
if (this._activePreview === preview) {
|
|
this.setPreviewActiveContext(false);
|
|
this._activePreview = undefined;
|
|
}
|
|
});
|
|
}
|
|
|
|
private setPreviewActiveContext(value: boolean) {
|
|
vscode.commands.executeCommand('setContext', MarkdownPreviewManager.markdownPreviewActiveContextKey, value);
|
|
}
|
|
}
|
|
|