Skip to content

Commit 7ef8e6b

Browse files
authored
Use consistent origin for webview views (#163602)
For #132464
1 parent 6451298 commit 7ef8e6b

File tree

4 files changed

+61
-55
lines changed

4 files changed

+61
-55
lines changed

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

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@
66
import { onUnexpectedError } from 'vs/base/common/errors';
77
import { Disposable, DisposableMap } from 'vs/base/common/lifecycle';
88
import { URI } from 'vs/base/common/uri';
9-
import { generateUuid } from 'vs/base/common/uuid';
109
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
11-
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
12-
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
10+
import { IStorageService } from 'vs/platform/storage/common/storage';
1311
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
1412
import { MainThreadWebviews, reviveWebviewContentOptions, reviveWebviewExtension } from 'vs/workbench/api/browser/mainThreadWebviews';
1513
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
1614
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
1715
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
18-
import { Memento, MementoObject } from 'vs/workbench/common/memento';
19-
import { WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview';
16+
import { WebviewOptions, WebviewOriginStore } from 'vs/workbench/contrib/webview/browser/webview';
2017
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
2118
import { WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager';
2219
import { IWebViewShowOptions, IWebviewWorkbenchService } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
@@ -79,43 +76,6 @@ class WebviewViewTypeTransformer {
7976
}
8077
}
8178

82-
/**
83-
* Stores the unique origins for webviews.
84-
*
85-
* These are randomly generated, but keyed on extension and webview viewType.
86-
*/
87-
class WebviewOriginStore {
88-
89-
private readonly memento: Memento;
90-
private readonly state: MementoObject;
91-
92-
constructor(
93-
storageKey: string,
94-
@IStorageService storageService: IStorageService,
95-
) {
96-
this.memento = new Memento(storageKey, storageService);
97-
this.state = this.memento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE);
98-
}
99-
100-
public getOrigin(extId: ExtensionIdentifier, viewType: string): string {
101-
const key = this.getKey(extId, viewType);
102-
103-
const existing = this.state[key];
104-
if (existing && typeof existing === 'string') {
105-
return existing;
106-
}
107-
108-
const newOrigin = generateUuid();
109-
this.state[key] = newOrigin;
110-
this.memento.saveMemento();
111-
return newOrigin;
112-
}
113-
114-
private getKey(extId: ExtensionIdentifier, viewType: string): string {
115-
return JSON.stringify([extId.value, viewType]);
116-
}
117-
}
118-
11979
export class MainThreadWebviewPanels extends Disposable implements extHostProtocol.MainThreadWebviewPanelsShape {
12080

12181
private readonly webviewPanelViewType = new WebviewViewTypeTransformer('mainThreadWebview-');
@@ -198,7 +158,7 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
198158
} : {};
199159

200160
const extension = reviveWebviewExtension(extensionData);
201-
const origin = this.webviewOriginStore.getOrigin(extension.id, viewType);
161+
const origin = this.webviewOriginStore.getOrigin(viewType, extension.id);
202162

203163
const webview = this._webviewWorkbenchService.openWebview({
204164
id: handle,

src/vs/workbench/browser/parts/views/viewsViewlet.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
1919
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
2020

2121
export interface IViewletViewOptions extends IViewPaneOptions {
22-
fromExtensionId?: ExtensionIdentifier;
22+
readonly fromExtensionId?: ExtensionIdentifier;
2323
}
2424

2525
export abstract class FilterViewPaneContainer extends ViewPaneContainer {

src/vs/workbench/contrib/webview/browser/webview.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ import { Event } from 'vs/base/common/event';
1010
import { IDisposable } from 'vs/base/common/lifecycle';
1111
import { isEqual } from 'vs/base/common/resources';
1212
import { URI } from 'vs/base/common/uri';
13+
import { generateUuid } from 'vs/base/common/uuid';
1314
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
1415
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
1516
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
17+
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
1618
import { IWebviewPortMapping } from 'vs/platform/webview/common/webviewPortMapping';
19+
import { Memento, MementoObject } from 'vs/workbench/common/memento';
1720
import { WebviewInitInfo } from 'vs/workbench/contrib/webview/browser/webviewElement';
1821

1922
/**
@@ -85,9 +88,6 @@ export interface WebviewOptions {
8588
transformCssVariables?(styles: WebviewStyles): WebviewStyles;
8689
}
8790

88-
/**
89-
*
90-
*/
9191
export interface WebviewContentOptions {
9292
/**
9393
* Should the webview allow `acquireVsCodeApi` to be called multiple times? Defaults to false.
@@ -272,3 +272,40 @@ export interface IOverlayWebview extends IWebview {
272272
*/
273273
layoutWebviewOverElement(element: HTMLElement, dimension?: Dimension, clippingContainer?: HTMLElement): void;
274274
}
275+
276+
/**
277+
* Stores the unique origins for a webview.
278+
*
279+
* These are randomly generated, but keyed on extension and webview viewType.
280+
*/
281+
export class WebviewOriginStore {
282+
283+
private readonly memento: Memento;
284+
private readonly state: MementoObject;
285+
286+
constructor(
287+
rootStorageKey: string,
288+
@IStorageService storageService: IStorageService,
289+
) {
290+
this.memento = new Memento(rootStorageKey, storageService);
291+
this.state = this.memento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE);
292+
}
293+
294+
public getOrigin(viewType: string, extId: ExtensionIdentifier | undefined): string {
295+
const key = this.getKey(viewType, extId);
296+
297+
const existing = this.state[key];
298+
if (existing && typeof existing === 'string') {
299+
return existing;
300+
}
301+
302+
const newOrigin = generateUuid();
303+
this.state[key] = newOrigin;
304+
this.memento.saveMemento();
305+
return newOrigin;
306+
}
307+
308+
private getKey(viewType: string, extId: ExtensionIdentifier | undefined): string {
309+
return JSON.stringify({ viewType, extension: extId?.value });
310+
}
311+
}

src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane';
2424
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
2525
import { Memento, MementoObject } from 'vs/workbench/common/memento';
2626
import { IViewBadge, IViewDescriptorService, IViewsService } from 'vs/workbench/common/views';
27-
import { IOverlayWebview, IWebviewService, WebviewContentPurpose } from 'vs/workbench/contrib/webview/browser/webview';
27+
import { IOverlayWebview, IWebviewService, WebviewContentPurpose, WebviewOriginStore } from 'vs/workbench/contrib/webview/browser/webview';
2828
import { WebviewWindowDragMonitor } from 'vs/workbench/contrib/webview/browser/webviewWindowDragMonitor';
2929
import { IWebviewViewService, WebviewView } from 'vs/workbench/contrib/webviewView/browser/webviewViewService';
3030
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
@@ -38,6 +38,13 @@ const storageKeys = {
3838

3939
export class WebviewViewPane extends ViewPane {
4040

41+
private static _originStore?: WebviewOriginStore;
42+
43+
private static getOriginStore(storageService: IStorageService): WebviewOriginStore {
44+
this._originStore ??= new WebviewOriginStore('webviewViews.origins', storageService);
45+
return this._originStore;
46+
}
47+
4148
private readonly _webview = this._register(new MutableDisposable<IOverlayWebview>());
4249
private readonly _webviewDisposables = this._register(new DisposableStore());
4350
private _activated = false;
@@ -58,22 +65,22 @@ export class WebviewViewPane extends ViewPane {
5865

5966
constructor(
6067
options: IViewletViewOptions,
61-
@IKeybindingService keybindingService: IKeybindingService,
62-
@IContextMenuService contextMenuService: IContextMenuService,
6368
@IConfigurationService configurationService: IConfigurationService,
6469
@IContextKeyService contextKeyService: IContextKeyService,
65-
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
70+
@IContextMenuService contextMenuService: IContextMenuService,
6671
@IInstantiationService instantiationService: IInstantiationService,
72+
@IKeybindingService keybindingService: IKeybindingService,
6773
@IOpenerService openerService: IOpenerService,
68-
@IThemeService themeService: IThemeService,
6974
@ITelemetryService telemetryService: ITelemetryService,
70-
@IStorageService storageService: IStorageService,
75+
@IThemeService themeService: IThemeService,
76+
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
77+
@IActivityService private readonly activityService: IActivityService,
7178
@IExtensionService private readonly extensionService: IExtensionService,
7279
@IProgressService private readonly progressService: IProgressService,
80+
@IStorageService private readonly storageService: IStorageService,
81+
@IViewsService private readonly viewService: IViewsService,
7382
@IWebviewService private readonly webviewService: IWebviewService,
7483
@IWebviewViewService private readonly webviewViewService: IWebviewViewService,
75-
@IViewsService private readonly viewService: IViewsService,
76-
@IActivityService private activityService: IActivityService
7784
) {
7885
super({ ...options, titleMenuId: MenuId.ViewTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
7986
this.extensionId = options.fromExtensionId;
@@ -167,8 +174,10 @@ export class WebviewViewPane extends ViewPane {
167174
this._activated = true;
168175

169176
const webviewId = generateUuid();
177+
const origin = WebviewViewPane.getOriginStore(this.storageService).getOrigin(this.id, this.extensionId);
170178
const webview = this.webviewService.createWebviewOverlay({
171179
id: webviewId,
180+
origin,
172181
providedViewType: this.id,
173182
options: { purpose: WebviewContentPurpose.WebviewView },
174183
contentOptions: {},

0 commit comments

Comments
 (0)