Split main thread webview serializer code into own file
This commit is contained in:
parent
daf5143e35
commit
04de465524
|
@ -25,6 +25,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
|
|||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IUndoRedoService, UndoRedoElementType } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { MainThreadWebviewSerializers } from 'vs/workbench/api/browser/mainThreadWebviewSerializer';
|
||||
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
|
||||
import { IEditorInput, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor';
|
||||
|
@ -104,7 +105,7 @@ const enum ModelType {
|
|||
Text,
|
||||
}
|
||||
|
||||
const webviewPanelViewType = new WebviewViewTypeTransformer('mainThreadWebview-');
|
||||
export const webviewPanelViewType = new WebviewViewTypeTransformer('mainThreadWebview-');
|
||||
|
||||
@extHostNamedCustomer(extHostProtocol.MainContext.MainThreadWebviews)
|
||||
export class MainThreadWebviews extends Disposable implements extHostProtocol.MainThreadWebviewsShape {
|
||||
|
@ -118,12 +119,10 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
]);
|
||||
|
||||
private readonly _proxy: extHostProtocol.ExtHostWebviewsShape;
|
||||
private readonly _proxySerializer: extHostProtocol.ExtHostWebviewSerializerShape;
|
||||
private readonly _proxyViews: extHostProtocol.ExtHostWebviewViewsShape;
|
||||
private readonly _proxyCustomEditors: extHostProtocol.ExtHostCustomEditorsShape;
|
||||
|
||||
private readonly _webviewInputs = new WebviewInputStore();
|
||||
private readonly _revivers = new Map<string, IDisposable>();
|
||||
|
||||
private readonly _webviewViewProviders = new Map<string, IDisposable>();
|
||||
private readonly _webviewViews = new Map<string, WebviewView>();
|
||||
|
@ -131,6 +130,8 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
private readonly _editorProviders = new Map<string, IDisposable>();
|
||||
private readonly _webviewFromDiffEditorHandles = new Set<string>();
|
||||
|
||||
private readonly serializers: MainThreadWebviewSerializers;
|
||||
|
||||
constructor(
|
||||
context: extHostProtocol.IExtHostContext,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
|
@ -149,8 +150,9 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
) {
|
||||
super();
|
||||
|
||||
this.serializers = new MainThreadWebviewSerializers(this, context, extensionService, _editorGroupService, _webviewWorkbenchService);
|
||||
|
||||
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviews);
|
||||
this._proxySerializer = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewSerializer);
|
||||
this._proxyViews = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewViews);
|
||||
this._proxyCustomEditors = context.getProxy(extHostProtocol.ExtHostContext.ExtHostCustomEditors);
|
||||
|
||||
|
@ -167,24 +169,6 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
this.updateWebviewViewStates(this._editorService.activeEditor);
|
||||
}));
|
||||
|
||||
// This reviver's only job is to activate extensions.
|
||||
// This should trigger the real reviver to be registered from the extension host side.
|
||||
this._register(_webviewWorkbenchService.registerResolver({
|
||||
canResolve: (webview: WebviewInput) => {
|
||||
if (webview instanceof CustomEditorInput) {
|
||||
extensionService.activateByEvent(`onCustomEditor:${webview.viewType}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const viewType = webviewPanelViewType.toExternal(webview.viewType);
|
||||
if (typeof viewType === 'string') {
|
||||
extensionService.activateByEvent(`onWebviewPanel:${viewType}`);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
resolveWebview: () => { throw new Error('not implemented'); }
|
||||
}));
|
||||
|
||||
workingCopyFileService.registerWorkingCopyProvider((editorResource) => {
|
||||
const matchedWorkingCopies: IWorkingCopy[] = [];
|
||||
|
||||
|
@ -209,6 +193,11 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
this._editorProviders.clear();
|
||||
}
|
||||
|
||||
public addWebviewInput(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput): void {
|
||||
this._webviewInputs.add(handle, input);
|
||||
this.hookupWebviewEventDelegate(handle, input.webview);
|
||||
}
|
||||
|
||||
public $createWebviewPanel(
|
||||
extensionData: extHostProtocol.WebviewExtensionDescription,
|
||||
handle: extHostProtocol.WebviewPanelHandle,
|
||||
|
@ -288,53 +277,12 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
return true;
|
||||
}
|
||||
|
||||
public $registerSerializer(viewType: string): void {
|
||||
if (this._revivers.has(viewType)) {
|
||||
throw new Error(`Reviver for ${viewType} already registered`);
|
||||
}
|
||||
|
||||
this._revivers.set(viewType, this._webviewWorkbenchService.registerResolver({
|
||||
canResolve: (webviewInput) => {
|
||||
return webviewInput.viewType === webviewPanelViewType.fromExternal(viewType);
|
||||
},
|
||||
resolveWebview: async (webviewInput): Promise<void> => {
|
||||
const viewType = webviewPanelViewType.toExternal(webviewInput.viewType);
|
||||
if (!viewType) {
|
||||
webviewInput.webview.html = MainThreadWebviews.getWebviewResolvedFailedContent(webviewInput.viewType);
|
||||
return;
|
||||
}
|
||||
|
||||
const handle = webviewInput.id;
|
||||
this._webviewInputs.add(handle, webviewInput);
|
||||
this.hookupWebviewEventDelegate(handle, webviewInput.webview);
|
||||
|
||||
let state = undefined;
|
||||
if (webviewInput.webview.state) {
|
||||
try {
|
||||
state = JSON.parse(webviewInput.webview.state);
|
||||
} catch (e) {
|
||||
console.error('Could not load webview state', e, webviewInput.webview.state);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await this._proxySerializer.$deserializeWebviewPanel(handle, viewType, webviewInput.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webviewInput.group || 0), webviewInput.webview.options);
|
||||
} catch (error) {
|
||||
onUnexpectedError(error);
|
||||
webviewInput.webview.html = MainThreadWebviews.getWebviewResolvedFailedContent(viewType);
|
||||
}
|
||||
}
|
||||
}));
|
||||
$registerSerializer(viewType: string): void {
|
||||
this.serializers.$registerSerializer(viewType);
|
||||
}
|
||||
|
||||
public $unregisterSerializer(viewType: string): void {
|
||||
const reviver = this._revivers.get(viewType);
|
||||
if (!reviver) {
|
||||
throw new Error(`No reviver for ${viewType} registered`);
|
||||
}
|
||||
|
||||
reviver.dispose();
|
||||
this._revivers.delete(viewType);
|
||||
$unregisterSerializer(viewType: string): void {
|
||||
this.serializers.$unregisterSerializer(viewType);
|
||||
}
|
||||
|
||||
public $registerWebviewViewProvider(viewType: string, options?: { retainContextWhenHidden?: boolean }): void {
|
||||
|
@ -657,7 +605,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
|||
return model;
|
||||
}
|
||||
|
||||
private static getWebviewResolvedFailedContent(viewType: string) {
|
||||
public static getWebviewResolvedFailedContent(viewType: string) {
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
102
src/vs/workbench/api/browser/mainThreadWebviewSerializer.ts
Normal file
102
src/vs/workbench/api/browser/mainThreadWebviewSerializer.ts
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { MainThreadWebviews, webviewPanelViewType } from 'vs/workbench/api/browser/mainThreadWebview';
|
||||
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { editorGroupToViewColumn } from 'vs/workbench/api/common/shared/editor';
|
||||
import { CustomEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput';
|
||||
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
|
||||
import { IWebviewWorkbenchService } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
export class MainThreadWebviewSerializers extends Disposable {
|
||||
|
||||
private readonly _proxy: extHostProtocol.ExtHostWebviewSerializerShape;
|
||||
|
||||
private readonly _revivers = new Map<string, IDisposable>();
|
||||
|
||||
constructor(
|
||||
private readonly mainThreadWebviews: MainThreadWebviews,
|
||||
context: extHostProtocol.IExtHostContext,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
|
||||
@IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewSerializer);
|
||||
|
||||
// This reviver's only job is to activate extensions.
|
||||
// This should trigger the real reviver to be registered from the extension host side.
|
||||
this._register(_webviewWorkbenchService.registerResolver({
|
||||
canResolve: (webview: WebviewInput) => {
|
||||
if (webview instanceof CustomEditorInput) {
|
||||
extensionService.activateByEvent(`onCustomEditor:${webview.viewType}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const viewType = webviewPanelViewType.toExternal(webview.viewType);
|
||||
if (typeof viewType === 'string') {
|
||||
extensionService.activateByEvent(`onWebviewPanel:${viewType}`);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
resolveWebview: () => { throw new Error('not implemented'); }
|
||||
}));
|
||||
}
|
||||
|
||||
public $registerSerializer(viewType: string): void {
|
||||
if (this._revivers.has(viewType)) {
|
||||
throw new Error(`Reviver for ${viewType} already registered`);
|
||||
}
|
||||
|
||||
this._revivers.set(viewType, this._webviewWorkbenchService.registerResolver({
|
||||
canResolve: (webviewInput) => {
|
||||
return webviewInput.viewType === webviewPanelViewType.fromExternal(viewType);
|
||||
},
|
||||
resolveWebview: async (webviewInput): Promise<void> => {
|
||||
const viewType = webviewPanelViewType.toExternal(webviewInput.viewType);
|
||||
if (!viewType) {
|
||||
webviewInput.webview.html = MainThreadWebviews.getWebviewResolvedFailedContent(webviewInput.viewType);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const handle = webviewInput.id;
|
||||
|
||||
this.mainThreadWebviews.addWebviewInput(handle, webviewInput);
|
||||
|
||||
let state = undefined;
|
||||
if (webviewInput.webview.state) {
|
||||
try {
|
||||
state = JSON.parse(webviewInput.webview.state);
|
||||
} catch (e) {
|
||||
console.error('Could not load webview state', e, webviewInput.webview.state);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
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 = MainThreadWebviews.getWebviewResolvedFailedContent(viewType);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public $unregisterSerializer(viewType: string): void {
|
||||
const reviver = this._revivers.get(viewType);
|
||||
if (!reviver) {
|
||||
throw new Error(`No reviver for ${viewType} registered`);
|
||||
}
|
||||
|
||||
reviver.dispose();
|
||||
this._revivers.delete(viewType);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue