Skip to content

Commit 21ee81c

Browse files
committed
Working on webview persistence API
microsoft#49022
1 parent 7042689 commit 21ee81c

13 files changed

Lines changed: 69 additions & 97 deletions

File tree

extensions/markdown-language-features/media/index.js

Lines changed: 18 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/markdown-language-features/media/pre.js

Lines changed: 15 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/markdown-language-features/preview-src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ActiveLineMarker } from './activeLineMarker';
77
import { onceDocumentLoaded } from './events';
88
import { createPosterForVsCode } from './messaging';
99
import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine } from './scroll-sync';
10-
import { getSettings } from './settings';
10+
import { getSettings, getData } from './settings';
1111
import throttle = require('lodash.throttle');
1212

1313
declare var acquireVsCodeApi: any;
@@ -17,7 +17,10 @@ const marker = new ActiveLineMarker();
1717
const settings = getSettings();
1818

1919
const vscode = acquireVsCodeApi();
20-
vscode.postMessage({});
20+
21+
// Set VS Code state
22+
const state = getData('data-state');
23+
vscode.setState(state);
2124

2225
const messaging = createPosterForVsCode(vscode);
2326

extensions/markdown-language-features/preview-src/settings.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,26 @@ export interface PreviewSettings {
1515

1616
let cachedSettings: PreviewSettings | undefined = undefined;
1717

18+
export function getData(key: string): PreviewSettings {
19+
const element = document.getElementById('vscode-markdown-preview-data');
20+
if (element) {
21+
const data = element.getAttribute(key);
22+
if (data) {
23+
return JSON.parse(data);
24+
}
25+
}
26+
27+
throw new Error(`Could not load data for ${key}`);
28+
}
29+
1830
export function getSettings(): PreviewSettings {
1931
if (cachedSettings) {
2032
return cachedSettings;
2133
}
2234

23-
const element = document.getElementById('vscode-markdown-preview-data');
24-
if (element) {
25-
const data = element.getAttribute('data-settings');
26-
if (data) {
27-
cachedSettings = JSON.parse(data);
28-
return cachedSettings!;
29-
}
35+
cachedSettings = getData('data-settings');
36+
if (cachedSettings) {
37+
return cachedSettings;
3038
}
3139

3240
throw new Error('Could not load settings');

extensions/markdown-language-features/src/features/preview.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ export class MarkdownPreview {
325325
this.forceUpdate = false;
326326

327327
this.currentVersion = { resource, version: document.version };
328-
const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line);
328+
const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line, this.state);
329329
if (this._resource === resource) {
330330
this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked);
331331
this.editor.webview.html = content;

extensions/markdown-language-features/src/features/previewContentProvider.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ export class MarkdownContentProvider {
4747
public async provideTextDocumentContent(
4848
markdownDocument: vscode.TextDocument,
4949
previewConfigurations: MarkdownPreviewConfigurationManager,
50-
initialLine: number | undefined = undefined
50+
initialLine: number | undefined = undefined,
51+
state?: any
5152
): Promise<string> {
5253
const sourceUri = markdownDocument.uri;
5354
const config = previewConfigurations.loadAndCacheConfiguration(sourceUri);
@@ -73,7 +74,10 @@ export class MarkdownContentProvider {
7374
<head>
7475
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
7576
${csp}
76-
<meta id="vscode-markdown-preview-data" data-settings="${JSON.stringify(initialData).replace(/"/g, '&quot;')}" data-strings="${JSON.stringify(previewStrings).replace(/"/g, '&quot;')}">
77+
<meta id="vscode-markdown-preview-data"
78+
data-settings="${JSON.stringify(initialData).replace(/"/g, '&quot;')}"
79+
data-strings="${JSON.stringify(previewStrings).replace(/"/g, '&quot;')}"
80+
data-state="${JSON.stringify(state || {}).replace(/"/g, '&quot;')}">
7781
<script src="${this.extensionResourcePath('pre.js')}" nonce="${nonce}"></script>
7882
${this.getStyles(sourceUri, nonce, config)}
7983
<base href="${markdownDocument.uri.with({ scheme: 'vscode-resource' }).toString(true)}">

extensions/markdown-language-features/src/features/previewManager.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,6 @@ export class MarkdownPreviewManager implements vscode.WebviewPanelSerializer {
9494
this.registerPreview(preview);
9595
}
9696

97-
public async serializeWebviewPanel(
98-
webview: vscode.WebviewPanel,
99-
): Promise<any> {
100-
const preview = this.previews.find(preview => preview.isWebviewOf(webview));
101-
return preview ? preview.state : undefined;
102-
}
103-
10497
private getExistingPreview(
10598
resource: vscode.Uri,
10699
previewSettings: PreviewSettings

extensions/typescript-language-features/src/languageProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ export default class LanguageProvider {
263263
}
264264

265265
public diagnosticsReceived(diagnosticsKind: DiagnosticKind, file: Uri, diagnostics: (Diagnostic & { reportUnnecessary: any })[]): void {
266-
const config = workspace.getConfiguration(this.id);
266+
const config = workspace.getConfiguration(this.id, file);
267267
const reportUnnecessary = config.get<boolean>('showUnused.enabled', true);
268268
if (diagnosticsKind === DiagnosticKind.Suggestion) {
269269
this.ununsedHighlighter.diagnosticsReceived(file, diagnostics.filter(diag => diag.reportUnnecessary));

src/vs/vscode.proposed.d.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -299,21 +299,9 @@ declare module 'vscode' {
299299
//#region Matt: WebView Serializer
300300

301301
/**
302-
* Save and restore webview panels that have been persisted when vscode shuts down.
302+
* Restore webview panels that have been persisted when vscode shuts down.
303303
*/
304304
interface WebviewPanelSerializer {
305-
/**
306-
* Save a webview panel's `state`.
307-
*
308-
* Called before shutdown. Extensions have a 250ms timeframe to return a state. If serialization
309-
* takes longer than 250ms, the panel will not be serialized.
310-
*
311-
* @param webviewPanel webview Panel to serialize. May or may not be visible.
312-
*
313-
* @returns JSON serializable state blob.
314-
*/
315-
serializeWebviewPanel(webviewPanel: WebviewPanel): Thenable<any>;
316-
317305
/**
318306
* Restore a webview panel from its seriailzed `state`.
319307
*

src/vs/workbench/api/electron-browser/mainThreadWebview.ts

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ import { extHostNamedCustomer } from './extHostCustomers';
2323
@extHostNamedCustomer(MainContext.MainThreadWebviews)
2424
export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviver {
2525

26-
private static readonly serializeTimeout = 500; // ms
27-
2826
private static readonly viewType = 'mainThreadWebview';
2927

3028
private static readonly standardSupportedLinkSchemes = ['http', 'https', 'mailto'];
@@ -136,7 +134,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
136134
this._webviews.set(handle, webview);
137135
webview._events = this.createWebviewEventDelegate(handle);
138136

139-
return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), webview.state.state, webview.position, webview.options)
137+
return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), JSON.parse(webview.state.state), webview.position, webview.options)
140138
.then(undefined, () => {
141139
webview.html = MainThreadWebviews.getDeserializationFailedContents(viewType);
142140
});
@@ -152,34 +150,14 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
152150
}
153151

154152
private _onWillShutdown(): TPromise<boolean> {
155-
const toRevive: WebviewPanelHandle[] = [];
156-
this._webviews.forEach((view, key) => {
153+
this._webviews.forEach((view) => {
157154
if (this.canRevive(view)) {
158-
toRevive.push(key);
155+
view.state.state = view.webviewState;
159156
}
160157
});
161158

162-
const reviveResponses = toRevive.map(handle =>
163-
TPromise.any([
164-
this._proxy.$serializeWebviewPanel(handle).then(
165-
state => ({ handle, state }),
166-
() => ({ handle, state: null })),
167-
TPromise.timeout(MainThreadWebviews.serializeTimeout).then(() => ({ handle, state: null }))
168-
]).then(x => x.value));
169-
170-
return TPromise.join(reviveResponses).then(results => {
171-
for (const result of results) {
172-
const view = this._webviews.get(result.handle);
173-
if (view) {
174-
if (result.state) {
175-
view.state.state = result.state;
176-
} else {
177-
view.state = null;
178-
}
179-
}
180-
}
181-
return false; // Don't veto shutdown
182-
});
159+
return TPromise.as(false); // Don't veto shutdown
160+
183161
}
184162

185163
private createWebviewEventDelegate(handle: WebviewPanelHandle) {

0 commit comments

Comments
 (0)