Clean up markdown preview messaging (#176458)

- Add properties directly to message
- Add `ImageInfo` type
- Don't use state to pass around imageInfo
This commit is contained in:
Matt Bierner 2023-03-07 17:28:13 -08:00 committed by GitHub
parent 2fffa58906
commit 3ca5284e44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 35 deletions

View file

@ -22,14 +22,14 @@ let documentResource = settings.settings.source;
const vscode = acquireVsCodeApi();
const originalState = vscode.getState();
const originalState = vscode.getState() ?? {} as any;
const state = {
...(typeof originalState === 'object' ? originalState : {}),
originalState,
...getData<any>('data-state')
};
if (originalState.resource !== state.resource) {
if (originalState?.resource !== state.resource) {
state.scrollProgress = undefined;
}

View file

@ -25,7 +25,7 @@ export const createPosterForVsCode = (vscode: any, settingsManager: SettingsMana
vscode.postMessage({
type,
source: settingsManager.settings!.source,
body
...body
});
}
};

View file

@ -33,6 +33,11 @@ export interface MarkdownContentProviderOutput {
containingImages: Set<string>;
}
export interface ImageInfo {
readonly id: string;
readonly width: number;
readonly height: number;
}
export class MdDocumentRenderer {
constructor(
@ -57,6 +62,7 @@ export class MdDocumentRenderer {
initialLine: number | undefined,
selectedLine: number | undefined,
state: any | undefined,
imageInfo: readonly ImageInfo[],
token: vscode.CancellationToken
): Promise<MarkdownContentProviderOutput> {
const sourceUri = markdownDocument.uri;
@ -94,7 +100,7 @@ export class MdDocumentRenderer {
data-strings="${escapeAttribute(JSON.stringify(previewStrings))}"
data-state="${escapeAttribute(JSON.stringify(state || {}))}">
<script src="${this._extensionResourcePath(resourceProvider, 'pre.js')}" nonce="${nonce}"></script>
${this._getStyles(resourceProvider, sourceUri, config, state)}
${this._getStyles(resourceProvider, sourceUri, config, imageInfo)}
<base href="${resourceProvider.asWebviewUri(markdownDocument.uri)}">
</head>
<body class="vscode-body ${config.scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${config.wordWrap ? 'wordWrap' : ''} ${config.markEditorSelection ? 'showEditorSelection' : ''}">
@ -180,22 +186,24 @@ export class MdDocumentRenderer {
].join(' ');
}
private _getImageStabilizerStyles(state?: any) {
private _getImageStabilizerStyles(imageInfo: readonly ImageInfo[]): string {
if (!imageInfo.length) {
return '';
}
let ret = '<style>\n';
if (state && state.imageInfo) {
state.imageInfo.forEach((imgInfo: any) => {
ret += `#${imgInfo.id}.loading {
for (const imgInfo of imageInfo) {
ret += `#${imgInfo.id}.loading {
height: ${imgInfo.height}px;
width: ${imgInfo.width}px;
}\n`;
});
}
ret += '</style>\n';
return ret;
}
private _getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, state?: any): string {
private _getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, imageInfo: readonly ImageInfo[]): string {
const baseStyles: string[] = [];
for (const resource of this._contributionProvider.contributions.previewStyles) {
baseStyles.push(`<link rel="stylesheet" type="text/css" href="${escapeAttribute(resourceProvider.asWebviewUri(resource))}">`);
@ -203,7 +211,7 @@ export class MdDocumentRenderer {
return `${baseStyles.join('\n')}
${this._computeCustomStyleSheetIncludes(resourceProvider, resource, config)}
${this._getImageStabilizerStyles(state)}`;
${this._getImageStabilizerStyles(imageInfo)}`;
}
private _getScripts(resourceProvider: WebviewResourceProvider, nonce: string): string {

View file

@ -12,7 +12,7 @@ import { isMarkdownFile } from '../util/file';
import { MdLinkOpener } from '../util/openDocumentLink';
import { WebviewResourceProvider } from '../util/resources';
import { urlToUri } from '../util/url';
import { MdDocumentRenderer } from './documentRenderer';
import { ImageInfo, MdDocumentRenderer } from './documentRenderer';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling';
import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor';
@ -40,7 +40,6 @@ interface MarkdownPreviewDelegate {
openPreviewLinkToMarkdownFile(markdownLink: vscode.Uri, fragment: string): void;
}
class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private static readonly _unwatchedImageSchemes = new Set(['https', 'http', 'data']);
@ -59,7 +58,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private _currentVersion?: PreviewDocumentVersion;
private _isScrolling = false;
private _imageInfo: { readonly id: string; readonly width: number; readonly height: number }[] = [];
private _imageInfo: readonly ImageInfo[] = [];
private readonly _fileWatchersBySrc = new Map</* src: */ string, vscode.FileSystemWatcher>();
private readonly _onScrollEmitter = this._register(new vscode.EventEmitter<LastScrollLocation>());
@ -128,19 +127,19 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
switch (e.type) {
case 'cacheImageSizes':
this._imageInfo = e.body;
this._imageInfo = e.imageData;
break;
case 'revealLine':
this._onDidScrollPreview(e.body.line);
this._onDidScrollPreview(e.line);
break;
case 'didClick':
this._onDidClickPreview(e.body.line);
this._onDidClickPreview(e.line);
break;
case 'openLink':
this._onDidClickPreviewLink(e.body.href);
this._onDidClickPreviewLink(e.href);
break;
case 'showPreviewSecuritySelector':
@ -149,7 +148,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
case 'previewStyleLoadError':
vscode.window.showWarningMessage(
vscode.l10n.t("Could not load 'markdown.styles': {0}", e.body.unloadedStyles.join(', ')));
vscode.l10n.t("Could not load 'markdown.styles': {0}", e.unloadedStyles.join(', ')));
break;
}
}));
@ -179,7 +178,6 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
return {
resource: this._resource.toString(),
line: this._line,
imageInfo: this._imageInfo,
fragment: this._scrollToFragment,
...this._delegate.getAdditionalState(),
};
@ -274,7 +272,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
}
const content = await (shouldReloadPage
? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this._line, selectedLine, this.state, this._disposeCts.token)
? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this._line, selectedLine, this.state, this._imageInfo, this._disposeCts.token)
: this._contentProvider.renderBody(document, this));
// Another call to `doUpdate` may have happened.

View file

@ -11,28 +11,22 @@ export namespace FromWebviewMessage {
export interface CacheImageSizes extends BaseMessage {
readonly type: 'cacheImageSizes';
readonly body: { id: string; width: number; height: number }[];
readonly imageData: ReadonlyArray<{ id: string; width: number; height: number }>;
}
export interface RevealLine extends BaseMessage {
readonly type: 'revealLine';
readonly body: {
readonly line: number;
};
readonly line: number;
}
export interface DidClick extends BaseMessage {
readonly type: 'didClick';
readonly body: {
readonly line: number;
};
readonly line: number;
}
export interface ClickLink extends BaseMessage {
readonly type: 'openLink';
readonly body: {
readonly href: string;
};
readonly href: string;
}
export interface ShowPreviewSecuritySelector extends BaseMessage {
@ -41,9 +35,7 @@ export namespace FromWebviewMessage {
export interface PreviewStyleLoadError extends BaseMessage {
readonly type: 'previewStyleLoadError';
readonly body: {
readonly unloadedStyles: string[];
};
readonly unloadedStyles: readonly string[];
}
export type Type =