Skip to content

Commit f4c5848

Browse files
authored
Run all webview panels of a given viewtype in the same origin (microsoft#163236)
For microsoft#132464
1 parent ae34e8d commit f4c5848

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
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';
910
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';
1013
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
1114
import { MainThreadWebviews, reviveWebviewContentOptions, reviveWebviewExtension } from 'vs/workbench/api/browser/mainThreadWebviews';
1215
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
1316
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
1417
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
18+
import { Memento, MementoObject } from 'vs/workbench/common/memento';
1519
import { WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview';
1620
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
1721
import { WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager';
@@ -75,6 +79,43 @@ class WebviewViewTypeTransformer {
7579
}
7680
}
7781

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+
78119
export class MainThreadWebviewPanels extends Disposable implements extHostProtocol.MainThreadWebviewPanelsShape {
79120

80121
private readonly webviewPanelViewType = new WebviewViewTypeTransformer('mainThreadWebview-');
@@ -85,18 +126,23 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
85126

86127
private readonly _revivers = this._register(new DisposableMap<string>());
87128

129+
private readonly webviewOriginStore: WebviewOriginStore;
130+
88131
constructor(
89132
context: IExtHostContext,
90133
private readonly _mainThreadWebviews: MainThreadWebviews,
91134
@IConfigurationService private readonly _configurationService: IConfigurationService,
92135
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
93136
@IEditorService private readonly _editorService: IEditorService,
94137
@IExtensionService extensionService: IExtensionService,
138+
@IStorageService storageService: IStorageService,
95139
@ITelemetryService private readonly _telemetryService: ITelemetryService,
96140
@IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService,
97141
) {
98142
super();
99143

144+
this.webviewOriginStore = new WebviewOriginStore('mainThreadWebviewPanel.origins', storageService);
145+
100146
this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewPanels);
101147

102148
this._register(_editorService.onDidActiveEditorChange(() => {
@@ -152,9 +198,11 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
152198
} : {};
153199

154200
const extension = reviveWebviewExtension(extensionData);
201+
const origin = this.webviewOriginStore.getOrigin(extension.id, viewType);
155202

156203
const webview = this._webviewWorkbenchService.openWebview({
157204
id: handle,
205+
origin,
158206
providedViewType: viewType,
159207
options: reviveWebviewOptions(initData.panelOptions),
160208
contentOptions: reviveWebviewContentOptions(initData.webviewOptions),

0 commit comments

Comments
 (0)