Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run all webview panels of a given viewtype in the same origin #163236

Merged
merged 1 commit into from Oct 11, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/vs/workbench/api/browser/mainThreadWebviewPanels.ts
Expand Up @@ -6,12 +6,16 @@
import { onUnexpectedError } from 'vs/base/common/errors';
import { Disposable, DisposableMap } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { MainThreadWebviews, reviveWebviewContentOptions, reviveWebviewExtension } from 'vs/workbench/api/browser/mainThreadWebviews';
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { Memento, MementoObject } from 'vs/workbench/common/memento';
import { WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview';
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
import { WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager';
Expand Down Expand Up @@ -75,6 +79,43 @@ class WebviewViewTypeTransformer {
}
}

/**
* Stores the unique origins for webviews.
*
* These are randomly generated, but keyed on extension and webview viewType.
*/
class WebviewOriginStore {

private readonly memento: Memento;
private readonly state: MementoObject;

constructor(
storageKey: string,
@IStorageService storageService: IStorageService,
) {
this.memento = new Memento(storageKey, storageService);
this.state = this.memento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE);
}

public getOrigin(extId: ExtensionIdentifier, viewType: string): string {
const key = this.getKey(extId, viewType);

const existing = this.state[key];
if (existing && typeof existing === 'string') {
return existing;
}

const newOrigin = generateUuid();
this.state[key] = newOrigin;
this.memento.saveMemento();
return newOrigin;
}

private getKey(extId: ExtensionIdentifier, viewType: string): string {
return JSON.stringify([extId.value, viewType]);
}
}

export class MainThreadWebviewPanels extends Disposable implements extHostProtocol.MainThreadWebviewPanelsShape {

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

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

private readonly webviewOriginStore: WebviewOriginStore;

constructor(
context: IExtHostContext,
private readonly _mainThreadWebviews: MainThreadWebviews,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IEditorService private readonly _editorService: IEditorService,
@IExtensionService extensionService: IExtensionService,
@IStorageService storageService: IStorageService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService,
) {
super();

this.webviewOriginStore = new WebviewOriginStore('mainThreadWebviewPanel.origins', storageService);

this._proxy = context.getProxy(extHostProtocol.ExtHostContext.ExtHostWebviewPanels);

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

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

const webview = this._webviewWorkbenchService.openWebview({
id: handle,
origin,
providedViewType: viewType,
options: reviveWebviewOptions(initData.panelOptions),
contentOptions: reviveWebviewContentOptions(initData.webviewOptions),
Expand Down