Undoing exthost side of the webview serializer split

This commit is contained in:
Matt Bierner
2020-08-26 16:46:25 -07:00
parent 51ba70d426
commit 79d7a9569d
6 changed files with 58 additions and 85 deletions
@@ -82,8 +82,7 @@ export class MainThreadWebviewPanelsAndViews extends Disposable implements extHo
private readonly webviewPanelViewType = new WebviewViewTypeTransformer('mainThreadWebview-');
private readonly _proxy: extHostProtocol.ExtHostWebviewsShape;
private readonly _proxyPanels: extHostProtocol.ExtHostWebviewPanelsShape;
private readonly _proxy: extHostProtocol.ExtHostWebviewPanelsShape;
private readonly _webviewInputs = new WebviewInputStore();
@@ -105,8 +104,7 @@ export class MainThreadWebviewPanelsAndViews extends Disposable implements extHo
) {
super();
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviews);
this._proxyPanels = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewPanels);
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewPanels);
this._mainThreadWebviews = this._instantiationService.createInstance(MainThreadWebviews, context);
context.set(extHostProtocol.MainContext.MainThreadWebviews, this._mainThreadWebviews);
@@ -258,7 +256,7 @@ export class MainThreadWebviewPanelsAndViews extends Disposable implements extHo
}
try {
await this._proxyPanels.$deserializeWebviewPanel(handle, viewType, webviewInput.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webviewInput.group || 0), webviewInput.webview.options);
await this._proxy.$deserializeWebviewPanel(handle, viewType, webviewInput.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webviewInput.group || 0), webviewInput.webview.options);
} catch (error) {
onUnexpectedError(error);
webviewInput.webview.html = this._mainThreadWebviews.getWebviewResolvedFailedContent(viewType);
@@ -78,7 +78,6 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa
import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer';
import { ExtHostWebviewViews } from 'vs/workbench/api/common/extHostWebviewView';
import { ExtHostCustomEditors } from 'vs/workbench/api/common/extHostCustomEditors';
import { ExtHostWebviewSerializer } from 'vs/workbench/api/common/extHostWebviewSerializer';
export interface IExtensionApiFactory {
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
@@ -145,7 +144,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol, extHostCommands));
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace, extHostLogService, extHostApiDeprecation));
const extHostWebviewSerializers = rpcProtocol.set(ExtHostContext.ExtHostWebviewPanels, new ExtHostWebviewSerializer(rpcProtocol, extHostWebviews));
rpcProtocol.set(ExtHostContext.ExtHostWebviewPanels, extHostWebviews);
const extHostCustomEditors = rpcProtocol.set(ExtHostContext.ExtHostCustomEditors, new ExtHostCustomEditors(rpcProtocol, extHostDocuments, extensionStoragePaths, extHostWebviews));
const extHostWebviewViews = rpcProtocol.set(ExtHostContext.ExtHostWebviewViews, new ExtHostWebviewViews(rpcProtocol, extHostWebviews));
@@ -595,7 +594,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostTreeViews.createTreeView(viewId, options, extension);
},
registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
return extHostWebviewSerializers.registerWebviewPanelSerializer(extension, viewType, serializer);
return extHostWebviews.registerWebviewPanelSerializer(extension, viewType, serializer);
},
registerCustomEditorProvider: (viewType: string, provider: vscode.CustomTextEditorProvider | vscode.CustomReadonlyEditorProvider, options: { webviewOptions?: vscode.WebviewPanelOptions, supportsMultipleEditorsPerDocument?: boolean } = {}) => {
return extHostCustomEditors.registerCustomEditorProvider(extension, viewType, provider, options);
@@ -652,11 +652,11 @@ export interface WebviewPanelViewStateData {
export interface ExtHostWebviewsShape {
$onMessage(handle: WebviewPanelHandle, message: any): void;
$onMissingCsp(handle: WebviewPanelHandle, extensionId: string): void;
$onDidChangeWebviewPanelViewStates(newState: WebviewPanelViewStateData): void;
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void>;
}
export interface ExtHostWebviewPanelsShape {
$onDidChangeWebviewPanelViewStates(newState: WebviewPanelViewStateData): void;
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void>;
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
}
+46 -1
View File
@@ -13,9 +13,11 @@ import { ILogService } from 'vs/platform/log/common/log';
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import type * as vscode from 'vscode';
import * as extHostProtocol from './extHost.protocol';
import * as extHostTypes from './extHostTypes';
export class ExtHostWebview implements vscode.Webview {
@@ -261,7 +263,7 @@ class ExtHostWebviewPanel extends Disposable implements vscode.WebviewPanel {
}
}
export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape, extHostProtocol.ExtHostWebviewPanelsShape {
private static newHandle(): extHostProtocol.WebviewPanelHandle {
return generateUuid();
@@ -273,6 +275,11 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
private readonly _webviews = new Map<extHostProtocol.WebviewPanelHandle, ExtHostWebview>();
private readonly _webviewPanels = new Map<extHostProtocol.WebviewPanelHandle, ExtHostWebviewPanel>();
private readonly _serializers = new Map<string, {
readonly serializer: vscode.WebviewPanelSerializer;
readonly extension: IExtensionDescription;
}>();
constructor(
mainContext: extHostProtocol.IMainContext,
private readonly initData: WebviewInitData,
@@ -364,6 +371,44 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
this._webviews.delete(handle);
}
public registerWebviewPanelSerializer(
extension: IExtensionDescription,
viewType: string,
serializer: vscode.WebviewPanelSerializer
): vscode.Disposable {
if (this._serializers.has(viewType)) {
throw new Error(`Serializer for '${viewType}' already registered`);
}
this._serializers.set(viewType, { serializer, extension });
this._proxy.$registerSerializer(viewType);
return new extHostTypes.Disposable(() => {
this._serializers.delete(viewType);
this._proxy.$unregisterSerializer(viewType);
});
}
async $deserializeWebviewPanel(
webviewHandle: extHostProtocol.WebviewPanelHandle,
viewType: string,
title: string,
state: any,
position: EditorViewColumn,
options: modes.IWebviewOptions & modes.IWebviewPanelOptions
): Promise<void> {
const entry = this._serializers.get(viewType);
if (!entry) {
throw new Error(`No serializer found for '${viewType}'`);
}
const { serializer, extension } = entry;
const webview = this.createNewWebview(webviewHandle, options, extension);
const revivedPanel = this.createNewWebviewPanel(webviewHandle, viewType, title, position, options, webview);
await serializer.deserializeWebviewPanel(revivedPanel, state);
}
public createNewWebviewPanel(webviewHandle: string, viewType: string, title: string, position: number, options: modes.IWebviewOptions & modes.IWebviewPanelOptions, webview: ExtHostWebview) {
const panel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
this._webviewPanels.set(webviewHandle, panel);
@@ -1,66 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as modes from 'vs/editor/common/modes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import type * as vscode from 'vscode';
import * as extHostProtocol from './extHost.protocol';
import * as extHostTypes from './extHostTypes';
export class ExtHostWebviewSerializer implements extHostProtocol.ExtHostWebviewPanelsShape {
private readonly _proxy: extHostProtocol.MainThreadWebviewPanelsAndViewsShape;
private readonly _serializers = new Map<string, {
readonly serializer: vscode.WebviewPanelSerializer;
readonly extension: IExtensionDescription;
}>();
constructor(
mainContext: extHostProtocol.IMainContext,
private readonly _webviewService: ExtHostWebviews,
) {
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviewService);
}
public registerWebviewPanelSerializer(
extension: IExtensionDescription,
viewType: string,
serializer: vscode.WebviewPanelSerializer
): vscode.Disposable {
if (this._serializers.has(viewType)) {
throw new Error(`Serializer for '${viewType}' already registered`);
}
this._serializers.set(viewType, { serializer, extension });
this._proxy.$registerSerializer(viewType);
return new extHostTypes.Disposable(() => {
this._serializers.delete(viewType);
this._proxy.$unregisterSerializer(viewType);
});
}
async $deserializeWebviewPanel(
webviewHandle: extHostProtocol.WebviewPanelHandle,
viewType: string,
title: string,
state: any,
position: EditorViewColumn,
options: modes.IWebviewOptions & modes.IWebviewPanelOptions
): Promise<void> {
const entry = this._serializers.get(viewType);
if (!entry) {
throw new Error(`No serializer found for '${viewType}'`);
}
const { serializer, extension } = entry;
const webview = this._webviewService.createNewWebview(webviewHandle, options, extension);
const revivedPanel = this._webviewService.createNewWebviewPanel(webviewHandle, viewType, title, position, options, webview);
await serializer.deserializeWebviewPanel(revivedPanel, state);
}
}
@@ -13,7 +13,6 @@ import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
import { NullApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
import { ExtHostWebviewSerializer } from 'vs/workbench/api/common/extHostWebviewSerializer';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import type * as vscode from 'vscode';
import { SingleProxyRPCProtocol } from './testRPCProtocol';
@@ -36,8 +35,6 @@ suite('ExtHostWebview', () => {
isExtensionDevelopmentDebug: false,
}, undefined, new NullLogService(), NullApiDeprecationService);
const extHostWebviewSerializer = new ExtHostWebviewSerializer(rpcProtocol!, extHostWebviews);
let lastInvokedDeserializer: vscode.WebviewPanelSerializer | undefined = undefined;
class NoopSerializer implements vscode.WebviewPanelSerializer {
@@ -51,20 +48,20 @@ suite('ExtHostWebview', () => {
const serializerA = new NoopSerializer();
const serializerB = new NoopSerializer();
const serializerARegistration = extHostWebviewSerializer.registerWebviewPanelSerializer(extension, viewType, serializerA);
const serializerARegistration = extHostWebviews.registerWebviewPanelSerializer(extension, viewType, serializerA);
await extHostWebviewSerializer.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {});
await extHostWebviews.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {});
assert.strictEqual(lastInvokedDeserializer, serializerA);
assert.throws(
() => extHostWebviewSerializer.registerWebviewPanelSerializer(extension, viewType, serializerB),
() => extHostWebviews.registerWebviewPanelSerializer(extension, viewType, serializerB),
'Should throw when registering two serializers for the same view');
serializerARegistration.dispose();
extHostWebviewSerializer.registerWebviewPanelSerializer(extension, viewType, serializerB);
extHostWebviews.registerWebviewPanelSerializer(extension, viewType, serializerB);
await extHostWebviewSerializer.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {});
await extHostWebviews.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {});
assert.strictEqual(lastInvokedDeserializer, serializerB);
});