diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index 323f9e9db0e..222f5e17289 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -129,8 +129,8 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv this._revivers.delete(viewType); } - reviveWebview(webview: WebviewEditorInput) { - this._extensionService.activateByEvent(`onView:${webview.state.viewType}`).then(() => { + reviveWebview(webview: WebviewEditorInput): TPromise { + return this._extensionService.activateByEvent(`onView:${webview.state.viewType}`).then(() => { const handle = 'revival-' + MainThreadWebviews.revivalPool++; this._webviews.set(handle, webview); @@ -145,7 +145,8 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv } }; - this._proxy.$deserializeWebview(handle, webview.state.viewType, webview.state.state, webview.position, webview.options); + return this._proxy.$deserializeWebview(handle, webview.state.viewType, webview.state.state, webview.position, webview.options) + .then(() => { }); }); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 2a53c50b8ec..4c37176f89b 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -366,7 +366,7 @@ export interface ExtHostWebviewsShape { $onDidChangeActiveWeview(handle: WebviewHandle | undefined): void; $onDidDisposeWeview(handle: WebviewHandle): Thenable; $onDidChangePosition(handle: WebviewHandle, newPosition: EditorPosition): void; - $deserializeWebview(newWebviewHandle: WebviewHandle, viewType: string, state: any, position: EditorPosition, options: vscode.WebviewOptions): void; + $deserializeWebview(newWebviewHandle: WebviewHandle, viewType: string, state: any, position: EditorPosition, options: vscode.WebviewOptions): Thenable; $serializeWebview(webviewHandle: WebviewHandle): Thenable; } diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 5e3a1b38126..2312e863a41 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -237,15 +237,15 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { state: any, position: Position, options: vscode.WebviewOptions - ): void { + ): TPromise { const serializer = this._serializers.get(viewType); if (!serializer) { - return; + return TPromise.as(false); } const revivedWebview = new ExtHostWebview(webviewHandle, this._proxy, viewType, typeConverters.toViewColumn(position), options); this._webviews.set(webviewHandle, revivedWebview); - serializer.deserializeWebview(revivedWebview, state); + return serializer.deserializeWebview(revivedWebview, state); } $serializeWebview( diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts b/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts index bfc40a60fff..96b53745e4c 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewEditor.ts @@ -145,10 +145,10 @@ export class WebviewEditor extends BaseWebviewEditor { this._webview = undefined; this.webviewContent = undefined; } - await super.setInput(input, options); - input.onBecameActive(this.position); + await input.resolve(); + await input.onBecameActive(this.position); this.updateWebview(input); } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewInput.ts b/src/vs/workbench/parts/webview/electron-browser/webviewInput.ts index 1bd9535aeaf..10d3d0be8b4 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewInput.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewInput.ts @@ -141,6 +141,11 @@ export class WebviewEditorInput extends EditorInput { } public resolve(refresh?: boolean): TPromise { + if (this.reviver && !this._revived) { + this._revived = true; + return this.reviver.reviveWebview(this).then(() => new EditorModel()); + } + return TPromise.as(new EditorModel()); } @@ -221,16 +226,11 @@ export class WebviewEditorInput extends EditorInput { this._currentWebviewHtml = ''; } - public onBecameActive(position: Position) { + public onBecameActive(position: Position): void { this._position = position; if (this._events && this._events.onDidChangePosition) { this._events.onDidChangePosition(position); } - - if (this.reviver && !this._revived) { - this._revived = true; - this.reviver.reviveWebview(this); - } } } diff --git a/src/vs/workbench/parts/webview/electron-browser/webviewService.ts b/src/vs/workbench/parts/webview/electron-browser/webviewService.ts index c7b97ad1d1d..93cce4adeaa 100644 --- a/src/vs/workbench/parts/webview/electron-browser/webviewService.ts +++ b/src/vs/workbench/parts/webview/electron-browser/webviewService.ts @@ -10,6 +10,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; import * as vscode from 'vscode'; import { WebviewEditorInput } from './webviewInput'; +import { TPromise } from 'vs/base/common/winjs.base'; export const IWebviewService = createDecorator('webviewService'); @@ -55,7 +56,7 @@ export interface WebviewReviver { reviveWebview( webview: WebviewEditorInput - ): void; + ): TPromise; } export interface WebviewEvents { @@ -73,7 +74,7 @@ export class WebviewService implements IWebviewService { _serviceBrand: any; private readonly _revivers = new Map(); - private readonly _needingRevival = new Map(); + private _awaitingRevival: { input: WebviewEditorInput, resolve: (x: any) => void }[] = []; constructor( @IWorkbenchEditorService private readonly _editorService: IWorkbenchEditorService, @@ -120,12 +121,16 @@ export class WebviewService implements IWebviewService { canRevive: (webview) => { return true; }, - reviveWebview: (webview) => { - if (!this._needingRevival.has(viewType)) { - this._needingRevival.set(viewType, []); + reviveWebview: async (webview: WebviewEditorInput): TPromise => { + const didRevive = await this.tryRevive(webview); + if (didRevive) { + return; } - this._needingRevival.get(viewType).push(webviewInput); - this.tryRevive(viewType); + // A reviver may not be registered yet. Put into queue and resolve promise when can can revive + let resolve: (value: void) => void; + const promise = new TPromise(r => { resolve = r; }); + this._awaitingRevival.push({ input: webview, resolve }); + return promise; } }); @@ -141,7 +146,15 @@ export class WebviewService implements IWebviewService { } this._revivers.set(viewType, reviver); - this.tryRevive(viewType); + + // Resolve any pending views + + const toRevive = this._awaitingRevival.filter(x => x.input.viewType === viewType); + this._awaitingRevival = this._awaitingRevival.filter(x => x.input.viewType !== viewType); + + for (const input of toRevive) { + reviver.reviveWebview(input.input).then(() => input.resolve(void 0)); + } return toDisposable(() => { this._revivers.delete(viewType); @@ -156,20 +169,14 @@ export class WebviewService implements IWebviewService { } tryRevive( - viewType: string - ) { - const reviver = this._revivers.get(viewType); + webview: WebviewEditorInput + ): boolean { + const reviver = this._revivers.get(webview.viewType); if (!reviver) { - return; + return false; } - const toRevive = this._needingRevival.get(viewType); - if (!toRevive) { - return; - } - - for (const webview of toRevive) { - reviver.reviveWebview(webview); - } + reviver.reviveWebview(webview); + return true; } } \ No newline at end of file