Skip to content

Commit 041cf5d

Browse files
committed
Split main thread webview views to own file
1 parent 5ec7e96 commit 041cf5d

3 files changed

Lines changed: 113 additions & 71 deletions

File tree

src/vs/workbench/api/browser/mainThreadCustomEditors.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ export class MainThreadCustomEditors extends Disposable {
9797
throw new Error(`Provider for ${viewType} already registered`);
9898
}
9999

100-
101100
const disposables = new DisposableStore();
102101

103102
disposables.add(this._customEditorService.registerCustomEditorCapabilities(viewType, {

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

Lines changed: 21 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { CancellationToken } from 'vs/base/common/cancellation';
7-
import { onUnexpectedError } from 'vs/base/common/errors';
86
import { Disposable, DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
97
import { Schemas } from 'vs/base/common/network';
108
import { isWeb } from 'vs/base/common/platform';
@@ -17,16 +15,16 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
1715
import { IOpenerService } from 'vs/platform/opener/common/opener';
1816
import { IProductService } from 'vs/platform/product/common/productService';
1917
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
20-
import { MainThreadCustomEditors, CustomEditorModelType } from 'vs/workbench/api/browser/mainThreadCustomEditors';
18+
import { CustomEditorModelType, MainThreadCustomEditors } from 'vs/workbench/api/browser/mainThreadCustomEditors';
2119
import { MainThreadWebviewSerializers } from 'vs/workbench/api/browser/mainThreadWebviewSerializer';
20+
import { MainThreadWebviewsViews } from 'vs/workbench/api/browser/mainThreadWebviewViews';
2221
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
2322
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
2423
import { IEditorInput } from 'vs/workbench/common/editor';
2524
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
2625
import { Webview, WebviewExtensionDescription, WebviewIcons, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview';
2726
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
2827
import { ICreateWebViewShowOptions, IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
29-
import { IWebviewViewService, WebviewView } from 'vs/workbench/contrib/webviewView/browser/webviewViewService';
3028
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
3129
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
3230
import { extHostNamedCustomer } from '../common/extHostCustomers';
@@ -98,18 +96,16 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
9896
public readonly webviewPanelViewType = new WebviewViewTypeTransformer('mainThreadWebview-');
9997

10098
private readonly _proxy: extHostProtocol.ExtHostWebviewsShape;
101-
private readonly _proxyViews: extHostProtocol.ExtHostWebviewViewsShape;
10299

100+
private readonly _webviews = new Map<string, Webview>();
103101
private readonly _webviewInputs = new WebviewInputStore();
104102

105-
private readonly _webviewViewProviders = new Map<string, IDisposable>();
106-
private readonly _webviewViews = new Map<string, WebviewView>();
107-
108103
private readonly _editorProviders = new Map<string, IDisposable>();
109104
private readonly _webviewFromDiffEditorHandles = new Set<string>();
110105

111106
private readonly serializers: MainThreadWebviewSerializers;
112107
private readonly customEditors: MainThreadCustomEditors;
108+
private readonly webviewViews: MainThreadWebviewsViews;
113109

114110
constructor(
115111
context: extHostProtocol.IExtHostContext,
@@ -120,15 +116,14 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
120116
@ITelemetryService private readonly _telemetryService: ITelemetryService,
121117
@IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService,
122118
@IInstantiationService private readonly _instantiationService: IInstantiationService,
123-
@IWebviewViewService private readonly _webviewViewService: IWebviewViewService,
124119
) {
125120
super();
126121

122+
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviews);
123+
127124
this.serializers = this._instantiationService.createInstance(MainThreadWebviewSerializers, this, context);
128125
this.customEditors = this._instantiationService.createInstance(MainThreadCustomEditors, this, context);
129-
130-
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviews);
131-
this._proxyViews = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewViews);
126+
this.webviewViews = this._instantiationService.createInstance(MainThreadWebviewsViews, this, context);
132127

133128
this._register(_editorService.onDidActiveEditorChange(() => {
134129
const activeInput = this._editorService.activeEditor;
@@ -142,7 +137,6 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
142137
this._register(_editorService.onDidVisibleEditorsChange(() => {
143138
this.updateWebviewViewStates(this._editorService.activeEditor);
144139
}));
145-
146140
}
147141

148142
dispose() {
@@ -158,7 +152,12 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
158152

159153
public addWebviewInput(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput): void {
160154
this._webviewInputs.add(handle, input);
161-
this.hookupWebviewEventDelegate(handle, input.webview);
155+
this.addWebview(handle, input.webview);
156+
}
157+
158+
public addWebview(handle: extHostProtocol.WebviewPanelHandle, webview: WebviewOverlay): void {
159+
this._webviews.set(handle, webview);
160+
this.hookupWebviewEventDelegate(handle, webview);
162161
}
163162

164163
public $createWebviewPanel(
@@ -200,11 +199,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
200199
}
201200

202201
public $setWebviewViewTitle(handle: extHostProtocol.WebviewPanelHandle, value: string | undefined): void {
203-
const webviewView = this._webviewViews.get(handle);
204-
if (!webviewView) {
205-
throw new Error('unknown webview view');
206-
}
207-
webviewView.title = value;
202+
this.webviewViews.$setWebviewViewTitle(handle, value);
208203
}
209204

210205
public $setIconPath(handle: extHostProtocol.WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void {
@@ -240,65 +235,20 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
240235
return true;
241236
}
242237

243-
$registerSerializer(viewType: string): void {
238+
public $registerSerializer(viewType: string): void {
244239
this.serializers.$registerSerializer(viewType);
245240
}
246241

247-
$unregisterSerializer(viewType: string): void {
242+
public $unregisterSerializer(viewType: string): void {
248243
this.serializers.$unregisterSerializer(viewType);
249244
}
250245

251246
public $registerWebviewViewProvider(viewType: string, options?: { retainContextWhenHidden?: boolean }): void {
252-
if (this._webviewViewProviders.has(viewType)) {
253-
throw new Error(`View provider for ${viewType} already registered`);
254-
}
255-
256-
this._webviewViewService.register(viewType, {
257-
resolve: async (webviewView: WebviewView, cancellation: CancellationToken) => {
258-
this._webviewViews.set(viewType, webviewView);
259-
260-
const handle = viewType;
261-
this.hookupWebviewEventDelegate(handle, webviewView.webview);
262-
263-
let state = undefined;
264-
if (webviewView.webview.state) {
265-
try {
266-
state = JSON.parse(webviewView.webview.state);
267-
} catch (e) {
268-
console.error('Could not load webview state', e, webviewView.webview.state);
269-
}
270-
}
271-
272-
if (options) {
273-
webviewView.webview.options = options;
274-
}
275-
276-
webviewView.onDidChangeVisibility(visible => {
277-
this._proxyViews.$onDidChangeWebviewViewVisibility(handle, visible);
278-
});
279-
280-
webviewView.onDispose(() => {
281-
this._proxyViews.$disposeWebviewView(handle);
282-
});
283-
284-
try {
285-
await this._proxyViews.$resolveWebviewView(handle, viewType, state, cancellation);
286-
} catch (error) {
287-
onUnexpectedError(error);
288-
webviewView.webview.html = this.getWebviewResolvedFailedContent(viewType);
289-
}
290-
}
291-
});
247+
this.webviewViews.$registerWebviewViewProvider(viewType, options);
292248
}
293249

294250
public $unregisterWebviewViewProvider(viewType: string): void {
295-
const provider = this._webviewViewProviders.get(viewType);
296-
if (!provider) {
297-
throw new Error(`No view provider for ${viewType} registered`);
298-
}
299-
300-
provider.dispose();
301-
this._webviewViewProviders.delete(viewType);
251+
this.webviewViews.$unregisterWebviewViewProvider(viewType);
302252
}
303253

304254
public $registerTextEditorProvider(extensionData: extHostProtocol.WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: extHostProtocol.CustomTextEditorCapabilities): void {
@@ -321,7 +271,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
321271
this.customEditors.$onContentChange(resourceComponents, viewType);
322272
}
323273

324-
private hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, webview: WebviewOverlay) {
274+
public hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, webview: WebviewOverlay) {
325275
const disposables = new DisposableStore();
326276

327277
disposables.add(webview.onDidClickLink((uri) => this.onDidClickLink(handle, uri)));
@@ -332,6 +282,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
332282
disposables.dispose();
333283

334284
this._proxy.$onDidDisposeWebviewPanel(handle).finally(() => {
285+
this._webviews.delete(handle);
335286
this._webviewInputs.delete(handle);
336287
});
337288
}));
@@ -416,7 +367,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
416367
}
417368

418369
private getWebview(handle: extHostProtocol.WebviewPanelHandle): Webview {
419-
const webview = this.tryGetWebviewInput(handle)?.webview ?? this._webviewViews.get(handle)?.webview;
370+
const webview = this._webviews.get(handle);
420371
if (!webview) {
421372
throw new Error(`Unknown webview handle:${handle}`);
422373
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { CancellationToken } from 'vs/base/common/cancellation';
7+
import { onUnexpectedError } from 'vs/base/common/errors';
8+
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
9+
import type { MainThreadWebviews } from 'vs/workbench/api/browser/mainThreadWebview';
10+
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
11+
import { IWebviewViewService, WebviewView } from 'vs/workbench/contrib/webviewView/browser/webviewViewService';
12+
13+
14+
export class MainThreadWebviewsViews extends Disposable {
15+
16+
private readonly _proxyViews: extHostProtocol.ExtHostWebviewViewsShape;
17+
18+
private readonly _webviewViews = new Map<string, WebviewView>();
19+
private readonly _webviewViewProviders = new Map<string, IDisposable>();
20+
21+
constructor(
22+
private readonly mainThreadWebviews: MainThreadWebviews,
23+
context: extHostProtocol.IExtHostContext,
24+
@IWebviewViewService private readonly _webviewViewService: IWebviewViewService,
25+
) {
26+
super();
27+
28+
this._proxyViews = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewViews);
29+
}
30+
31+
public $setWebviewViewTitle(handle: extHostProtocol.WebviewPanelHandle, value: string | undefined): void {
32+
const webviewView = this._webviewViews.get(handle);
33+
if (!webviewView) {
34+
throw new Error('unknown webview view');
35+
}
36+
webviewView.title = value;
37+
}
38+
39+
public $registerWebviewViewProvider(viewType: string, options?: { retainContextWhenHidden?: boolean }): void {
40+
if (this._webviewViewProviders.has(viewType)) {
41+
throw new Error(`View provider for ${viewType} already registered`);
42+
}
43+
44+
this._webviewViewService.register(viewType, {
45+
resolve: async (webviewView: WebviewView, cancellation: CancellationToken) => {
46+
this._webviewViews.set(viewType, webviewView);
47+
48+
const handle = viewType;
49+
this.mainThreadWebviews.addWebview(handle, webviewView.webview);
50+
51+
let state = undefined;
52+
if (webviewView.webview.state) {
53+
try {
54+
state = JSON.parse(webviewView.webview.state);
55+
} catch (e) {
56+
console.error('Could not load webview state', e, webviewView.webview.state);
57+
}
58+
}
59+
60+
if (options) {
61+
webviewView.webview.options = options;
62+
}
63+
64+
webviewView.onDidChangeVisibility(visible => {
65+
this._proxyViews.$onDidChangeWebviewViewVisibility(handle, visible);
66+
});
67+
68+
webviewView.onDispose(() => {
69+
this._proxyViews.$disposeWebviewView(handle);
70+
});
71+
72+
try {
73+
await this._proxyViews.$resolveWebviewView(handle, viewType, state, cancellation);
74+
} catch (error) {
75+
onUnexpectedError(error);
76+
webviewView.webview.html = this.mainThreadWebviews.getWebviewResolvedFailedContent(viewType);
77+
}
78+
}
79+
});
80+
}
81+
82+
public $unregisterWebviewViewProvider(viewType: string): void {
83+
const provider = this._webviewViewProviders.get(viewType);
84+
if (!provider) {
85+
throw new Error(`No view provider for ${viewType} registered`);
86+
}
87+
88+
provider.dispose();
89+
this._webviewViewProviders.delete(viewType);
90+
}
91+
}
92+

0 commit comments

Comments
 (0)