Merge from vscode merge-base (#22780)

* Revert "Revert "Merge from vscode merge-base (#22769)" (#22779)"

This reverts commit 47a1745180.

* Fix notebook download task

* Remove done call from extensions-ci
This commit is contained in:
Karl Burtram
2023-04-19 21:48:46 -07:00
committed by GitHub
parent decbe8dded
commit e7d3d047ec
2389 changed files with 92155 additions and 42602 deletions

View File

@@ -6,9 +6,10 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import * as uri from 'vscode-uri';
import { Logger } from '../logger';
import { MarkdownEngine } from '../markdownEngine';
import { ILogger } from '../logging';
import { MarkdownItEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { escapeAttribute, getNonce } from '../util/dom';
import { WebviewResourceProvider } from '../util/resources';
import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig';
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from './security';
@@ -35,23 +36,19 @@ const previewStrings = {
'Content Disabled Security Warning')
};
function escapeAttribute(value: string | vscode.Uri): string {
return value.toString().replace(/"/g, '"');
}
export interface MarkdownContentProviderOutput {
html: string;
containingImages: { src: string }[];
}
export class MarkdownContentProvider {
export class MdDocumentRenderer {
constructor(
private readonly engine: MarkdownEngine,
private readonly engine: MarkdownItEngine,
private readonly context: vscode.ExtensionContext,
private readonly cspArbiter: ContentSecurityPolicyArbiter,
private readonly contributionProvider: MarkdownContributionProvider,
private readonly logger: Logger
private readonly logger: ILogger
) {
this.iconPath = {
dark: vscode.Uri.joinPath(this.context.extensionUri, 'media', 'preview-dark.svg'),
@@ -61,12 +58,13 @@ export class MarkdownContentProvider {
public readonly iconPath: { light: vscode.Uri; dark: vscode.Uri };
public async provideTextDocumentContent(
public async renderDocument(
markdownDocument: vscode.TextDocument,
resourceProvider: WebviewResourceProvider,
previewConfigurations: MarkdownPreviewConfigurationManager,
initialLine: number | undefined = undefined,
state?: any
state: any | undefined,
token: vscode.CancellationToken
): Promise<MarkdownContentProviderOutput> {
const sourceUri = markdownDocument.uri;
const config = previewConfigurations.loadAndCacheConfiguration(sourceUri);
@@ -82,13 +80,17 @@ export class MarkdownContentProvider {
webviewResourceRoot: resourceProvider.asWebviewUri(markdownDocument.uri).toString(),
};
this.logger.log('provideTextDocumentContent', initialData);
this.logger.verbose('DocumentRenderer', `provideTextDocumentContent - ${markdownDocument.uri}`, initialData);
// Content Security Policy
const nonce = getNonce();
const csp = this.getCsp(resourceProvider, sourceUri, nonce);
const body = await this.markdownBody(markdownDocument, resourceProvider);
const body = await this.renderBody(markdownDocument, resourceProvider);
if (token.isCancellationRequested) {
return { html: '', containingImages: [] };
}
const html = `<!DOCTYPE html>
<html style="${escapeAttribute(this.getSettingsOverrideStyles(config))}">
<head>
@@ -113,7 +115,7 @@ export class MarkdownContentProvider {
};
}
public async markdownBody(
public async renderBody(
markdownDocument: vscode.TextDocument,
resourceProvider: WebviewResourceProvider,
): Promise<MarkdownContentProviderOutput> {
@@ -125,9 +127,7 @@ export class MarkdownContentProvider {
};
}
public provideFileNotFoundContent(
resource: vscode.Uri,
): string {
public renderFileNotFoundDocument(resource: vscode.Uri): string {
const resourcePath = uri.Utils.basename(resource);
const body = localize('preview.notFound', '{0} cannot be found', resourcePath);
return `<!DOCTYPE html>
@@ -246,12 +246,3 @@ export class MarkdownContentProvider {
}
}
}
function getNonce() {
let text = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 64; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}

View File

@@ -6,16 +6,17 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import * as uri from 'vscode-uri';
import { Logger } from '../logger';
import { MarkdownEngine } from '../markdownEngine';
import { ILogger } from '../logging';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { MdTableOfContentsProvider } from '../tableOfContents';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { openDocumentLink, resolveDocumentLink, resolveUriToMarkdownFile } from '../util/openDocumentLink';
import { WebviewResourceProvider } from '../util/resources';
import { urlToUri } from '../util/url';
import { IMdWorkspace } from '../workspace';
import { MdDocumentRenderer } from './documentRenderer';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider } from './previewContentProvider';
import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling';
import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor';
@@ -109,16 +110,19 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private readonly _onScrollEmitter = this._register(new vscode.EventEmitter<LastScrollLocation>());
public readonly onScroll = this._onScrollEmitter.event;
private readonly _disposeCts = this._register(new vscode.CancellationTokenSource());
constructor(
webview: vscode.WebviewPanel,
resource: vscode.Uri,
startingScroll: StartingScrollLocation | undefined,
private readonly delegate: MarkdownPreviewDelegate,
private readonly engine: MarkdownEngine,
private readonly _contentProvider: MarkdownContentProvider,
private readonly _contentProvider: MdDocumentRenderer,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
private readonly _logger: Logger,
private readonly _workspace: IMdWorkspace,
private readonly _logger: ILogger,
private readonly _contributionProvider: MarkdownContributionProvider,
private readonly _tocProvider: MdTableOfContentsProvider,
) {
super();
@@ -202,6 +206,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
}
override dispose() {
this._disposeCts.cancel();
super.dispose();
this._disposed = true;
@@ -265,7 +271,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
return;
}
this._logger.log('updateForView', { markdownFile: this._resource });
this._logger.verbose('MarkdownPreview', 'updateForView', { markdownFile: this._resource });
this.line = topLine;
this.postMessage({
type: 'updateView',
@@ -286,7 +292,9 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
try {
document = await vscode.workspace.openTextDocument(this._resource);
} catch {
await this.showFileNotFoundError();
if (!this._disposed) {
await this.showFileNotFoundError();
}
return;
}
@@ -306,8 +314,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
this.currentVersion = pendingVersion;
const content = await (shouldReloadPage
? this._contentProvider.provideTextDocumentContent(document, this, this._previewConfigurations, this.line, this.state)
: this._contentProvider.markdownBody(document, this));
? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this.line, this.state, this._disposeCts.token)
: this._contentProvider.renderBody(document, this));
// Another call to `doUpdate` may have happened.
// Make sure we are still updating for the correct document
@@ -364,7 +372,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
}
private async showFileNotFoundError() {
this._webviewPanel.webview.html = this._contentProvider.provideFileNotFoundContent(this._resource);
this._webviewPanel.webview.html = this._contentProvider.renderFileNotFoundDocument(this._resource);
}
private updateWebviewContent(html: string, reloadPage: boolean): void {
@@ -443,14 +451,14 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
const config = vscode.workspace.getConfiguration('markdown', this.resource);
const openLinks = config.get<string>('preview.openMarkdownLinks', 'inPreview');
if (openLinks === 'inPreview') {
const linkedDoc = await resolveUriToMarkdownFile(targetResource);
const linkedDoc = await resolveUriToMarkdownFile(this._workspace, targetResource);
if (linkedDoc) {
this.delegate.openPreviewLinkToMarkdownFile(linkedDoc.uri, targetResource.fragment);
return;
}
}
return openDocumentLink(this.engine, targetResource, this.resource);
return openDocumentLink(this._tocProvider, targetResource, this.resource);
}
//#region WebviewResourceProvider
@@ -466,7 +474,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
//#endregion
}
export interface ManagedMarkdownPreview {
export interface IManagedMarkdownPreview {
readonly resource: vscode.Uri;
readonly resourceColumn: vscode.ViewColumn;
@@ -486,22 +494,23 @@ export interface ManagedMarkdownPreview {
): boolean;
}
export class StaticMarkdownPreview extends Disposable implements ManagedMarkdownPreview {
export class StaticMarkdownPreview extends Disposable implements IManagedMarkdownPreview {
public static readonly customEditorViewType = 'vscode.markdown.preview.editor';
public static revive(
resource: vscode.Uri,
webview: vscode.WebviewPanel,
contentProvider: MarkdownContentProvider,
contentProvider: MdDocumentRenderer,
previewConfigurations: MarkdownPreviewConfigurationManager,
topmostLineMonitor: TopmostLineMonitor,
logger: Logger,
workspace: IMdWorkspace,
logger: ILogger,
contributionProvider: MarkdownContributionProvider,
engine: MarkdownEngine,
tocProvider: MdTableOfContentsProvider,
scrollLine?: number,
): StaticMarkdownPreview {
return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, topmostLineMonitor, logger, contributionProvider, engine, scrollLine);
return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, topmostLineMonitor, workspace, logger, contributionProvider, tocProvider, scrollLine);
}
private readonly preview: MarkdownPreview;
@@ -509,12 +518,13 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
private constructor(
private readonly _webviewPanel: vscode.WebviewPanel,
resource: vscode.Uri,
contentProvider: MarkdownContentProvider,
contentProvider: MdDocumentRenderer,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
topmostLineMonitor: TopmostLineMonitor,
logger: Logger,
workspace: IMdWorkspace,
logger: ILogger,
contributionProvider: MarkdownContributionProvider,
engine: MarkdownEngine,
tocProvider: MdTableOfContentsProvider,
scrollLine?: number,
) {
super();
@@ -526,7 +536,7 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
fragment
}), StaticMarkdownPreview.customEditorViewType, this._webviewPanel.viewColumn);
}
}, engine, contentProvider, _previewConfigurations, logger, contributionProvider));
}, contentProvider, _previewConfigurations, workspace, logger, contributionProvider, tocProvider));
this._register(this._webviewPanel.onDidDispose(() => {
this.dispose();
@@ -592,7 +602,7 @@ interface DynamicPreviewInput {
readonly line?: number;
}
export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdownPreview {
export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdownPreview {
public static readonly viewType = 'markdown.preview';
@@ -605,28 +615,30 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
public static revive(
input: DynamicPreviewInput,
webview: vscode.WebviewPanel,
contentProvider: MarkdownContentProvider,
contentProvider: MdDocumentRenderer,
previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger,
workspace: IMdWorkspace,
logger: ILogger,
topmostLineMonitor: TopmostLineMonitor,
contributionProvider: MarkdownContributionProvider,
engine: MarkdownEngine,
tocProvider: MdTableOfContentsProvider,
): DynamicMarkdownPreview {
webview.iconPath = contentProvider.iconPath;
return new DynamicMarkdownPreview(webview, input,
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine);
contentProvider, previewConfigurations, workspace, logger, topmostLineMonitor, contributionProvider, tocProvider);
}
public static create(
input: DynamicPreviewInput,
previewColumn: vscode.ViewColumn,
contentProvider: MarkdownContentProvider,
contentProvider: MdDocumentRenderer,
previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger,
workspace: IMdWorkspace,
logger: ILogger,
topmostLineMonitor: TopmostLineMonitor,
contributionProvider: MarkdownContributionProvider,
engine: MarkdownEngine,
tocProvider: MdTableOfContentsProvider,
): DynamicMarkdownPreview {
const webview = vscode.window.createWebviewPanel(
DynamicMarkdownPreview.viewType,
@@ -636,18 +648,19 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
webview.iconPath = contentProvider.iconPath;
return new DynamicMarkdownPreview(webview, input,
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine);
contentProvider, previewConfigurations, workspace, logger, topmostLineMonitor, contributionProvider, tocProvider);
}
private constructor(
webview: vscode.WebviewPanel,
input: DynamicPreviewInput,
private readonly _contentProvider: MarkdownContentProvider,
private readonly _contentProvider: MdDocumentRenderer,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
private readonly _logger: Logger,
private readonly _workspace: IMdWorkspace,
private readonly _logger: ILogger,
private readonly _topmostLineMonitor: TopmostLineMonitor,
private readonly _contributionProvider: MarkdownContributionProvider,
private readonly _engine: MarkdownEngine,
private readonly _tocProvider: MdTableOfContentsProvider,
) {
super();
@@ -799,10 +812,11 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
this.update(link, fragment ? new StartingScrollFragment(fragment) : undefined);
}
},
this._engine,
this._contentProvider,
this._previewConfigurations,
this._workspace,
this._logger,
this._contributionProvider);
this._contributionProvider,
this._tocProvider);
}
}

View File

@@ -4,14 +4,15 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Logger } from '../logger';
import { MarkdownEngine } from '../markdownEngine';
import { ILogger } from '../logging';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { MdTableOfContentsProvider } from '../tableOfContents';
import { Disposable, disposeAll } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { DynamicMarkdownPreview, ManagedMarkdownPreview, StaticMarkdownPreview } from './preview';
import { IMdWorkspace } from '../workspace';
import { MdDocumentRenderer } from './documentRenderer';
import { DynamicMarkdownPreview, IManagedMarkdownPreview, StaticMarkdownPreview } from './preview';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider } from './previewContentProvider';
import { scrollEditorToLine, StartingScrollFragment } from './scrolling';
import { TopmostLineMonitor } from './topmostLineMonitor';
@@ -21,7 +22,7 @@ export interface DynamicPreviewSettings {
readonly locked: boolean;
}
class PreviewStore<T extends ManagedMarkdownPreview> extends Disposable {
class PreviewStore<T extends IManagedMarkdownPreview> extends Disposable {
private readonly _previews = new Set<T>();
@@ -65,13 +66,14 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
private readonly _dynamicPreviews = this._register(new PreviewStore<DynamicMarkdownPreview>());
private readonly _staticPreviews = this._register(new PreviewStore<StaticMarkdownPreview>());
private _activePreview: ManagedMarkdownPreview | undefined = undefined;
private _activePreview: IManagedMarkdownPreview | undefined = undefined;
public constructor(
private readonly _contentProvider: MarkdownContentProvider,
private readonly _logger: Logger,
private readonly _contentProvider: MdDocumentRenderer,
private readonly _workspace: IMdWorkspace,
private readonly _logger: ILogger,
private readonly _contributions: MarkdownContributionProvider,
private readonly _engine: MarkdownEngine,
private readonly _tocProvider: MdTableOfContentsProvider,
) {
super();
@@ -163,10 +165,11 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
webview,
this._contentProvider,
this._previewConfigurations,
this._workspace,
this._logger,
this._topmostLineMonitor,
this._contributions,
this._engine);
this._tocProvider);
this.registerDynamicPreview(preview);
}
@@ -182,9 +185,10 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
this._contentProvider,
this._previewConfigurations,
this._topmostLineMonitor,
this._workspace,
this._logger,
this._contributions,
this._engine,
this._tocProvider,
lineNumber
);
this.registerStaticPreview(preview);
@@ -206,10 +210,11 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
previewSettings.previewColumn,
this._contentProvider,
this._previewConfigurations,
this._workspace,
this._logger,
this._topmostLineMonitor,
this._contributions,
this._engine);
this._tocProvider);
this.setPreviewActiveContext(true);
this._activePreview = preview;
@@ -243,7 +248,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
return preview;
}
private trackActive(preview: ManagedMarkdownPreview): void {
private trackActive(preview: IManagedMarkdownPreview): void {
preview.onDidChangeViewState(({ webviewPanel }) => {
this.setPreviewActiveContext(webviewPanel.active);
this._activePreview = webviewPanel.active ? preview : undefined;

View File

@@ -6,6 +6,7 @@
import * as vscode from 'vscode';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { ResourceMap } from '../util/resourceMap';
export interface LastScrollLocation {
readonly line: number;
@@ -14,10 +15,10 @@ export interface LastScrollLocation {
export class TopmostLineMonitor extends Disposable {
private readonly pendingUpdates = new Map<string, number>();
private readonly pendingUpdates = new ResourceMap<number>();
private readonly throttle = 50;
private previousTextEditorInfo = new Map<string, LastScrollLocation>();
private previousStaticEditorInfo = new Map<string, LastScrollLocation>();
private previousTextEditorInfo = new ResourceMap<LastScrollLocation>();
private previousStaticEditorInfo = new ResourceMap<LastScrollLocation>();
constructor() {
super();
@@ -42,28 +43,28 @@ export class TopmostLineMonitor extends Disposable {
public readonly onDidChanged = this._onChanged.event;
public setPreviousStaticEditorLine(scrollLocation: LastScrollLocation): void {
this.previousStaticEditorInfo.set(scrollLocation.uri.toString(), scrollLocation);
this.previousStaticEditorInfo.set(scrollLocation.uri, scrollLocation);
}
public getPreviousStaticEditorLineByUri(resource: vscode.Uri): number | undefined {
const scrollLoc = this.previousStaticEditorInfo.get(resource.toString());
this.previousStaticEditorInfo.delete(resource.toString());
const scrollLoc = this.previousStaticEditorInfo.get(resource);
this.previousStaticEditorInfo.delete(resource);
return scrollLoc?.line;
}
public setPreviousTextEditorLine(scrollLocation: LastScrollLocation): void {
this.previousTextEditorInfo.set(scrollLocation.uri.toString(), scrollLocation);
this.previousTextEditorInfo.set(scrollLocation.uri, scrollLocation);
}
public getPreviousTextEditorLineByUri(resource: vscode.Uri): number | undefined {
const scrollLoc = this.previousTextEditorInfo.get(resource.toString());
this.previousTextEditorInfo.delete(resource.toString());
const scrollLoc = this.previousTextEditorInfo.get(resource);
this.previousTextEditorInfo.delete(resource);
return scrollLoc?.line;
}
public getPreviousStaticTextEditorLineByUri(resource: vscode.Uri): number | undefined {
const state = this.previousStaticEditorInfo.get(resource.toString());
const state = this.previousStaticEditorInfo.get(resource);
return state?.line;
}
@@ -71,21 +72,20 @@ export class TopmostLineMonitor extends Disposable {
resource: vscode.Uri,
line: number
) {
const key = resource.toString();
if (!this.pendingUpdates.has(key)) {
if (!this.pendingUpdates.has(resource)) {
// schedule update
setTimeout(() => {
if (this.pendingUpdates.has(key)) {
if (this.pendingUpdates.has(resource)) {
this._onChanged.fire({
resource,
line: this.pendingUpdates.get(key) as number
line: this.pendingUpdates.get(resource) as number
});
this.pendingUpdates.delete(key);
this.pendingUpdates.delete(resource);
}
}, this.throttle);
}
this.pendingUpdates.set(key, line);
this.pendingUpdates.set(resource, line);
}
}