Skip to content

Commit

Permalink
Use more stable hostname for webviews #13092 (#13225)
Browse files Browse the repository at this point in the history
* add optional viewId to WebviewWidgetIdentifier, which may be used to create stable hostnames for webviews
* use this viewId to store a uuid which will be used as part of the stable hostname
  • Loading branch information
jfaltermeier authored Jan 3, 2024
1 parent b18be89 commit 72421be
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { injectable, inject, postConstruct, optional } from '@theia/core/shared/
import {
ApplicationShell, ViewContainer as ViewContainerWidget, WidgetManager, QuickViewService,
ViewContainerIdentifier, ViewContainerTitleOptions, Widget, FrontendApplicationContribution,
StatefulWidget, CommonMenus, TreeViewWelcomeWidget, ViewContainerPart, BaseWidget
StatefulWidget, CommonMenus, TreeViewWelcomeWidget, ViewContainerPart, BaseWidget,
} from '@theia/core/lib/browser';
import { ViewContainer, View, ViewWelcome, PluginViewType } from '../../../common';
import { PluginSharedStyle } from '../plugin-shared-style';
Expand Down Expand Up @@ -424,7 +424,10 @@ export class PluginViewRegistry implements FrontendApplicationContribution {

protected async createNewWebviewView(viewId: string): Promise<WebviewView> {
const webview = await this.widgetManager.getOrCreateWidget<WebviewWidget>(
WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: v4() });
WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{
id: v4(),
viewId,
});
webview.setContentOptions({ allowScripts: true });

let _description: string | undefined;
Expand Down Expand Up @@ -893,7 +896,7 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
const webviewView = await this.createNewWebviewView(viewId);
webviewId = webviewView.webview.identifier.id;
}
const webviewWidget = this.widgetManager.getWidget(WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: webviewId });
const webviewWidget = this.widgetManager.getWidget(WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: webviewId, viewId });
return webviewWidget;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import { interfaces } from '@theia/core/shared/inversify';
import { WebviewWidget, WebviewWidgetIdentifier, WebviewWidgetExternalEndpoint } from './webview';
import { WebviewEnvironment } from './webview-environment';
import { StorageService } from '@theia/core/lib/browser';
import { v4 } from 'uuid';

export class WebviewWidgetFactory {

Expand All @@ -30,7 +32,7 @@ export class WebviewWidgetFactory {

async createWidget(identifier: WebviewWidgetIdentifier): Promise<WebviewWidget> {
const externalEndpoint = await this.container.get(WebviewEnvironment).externalEndpoint();
let endpoint = externalEndpoint.replace('{{uuid}}', identifier.id);
let endpoint = externalEndpoint.replace('{{uuid}}', identifier.viewId ? await this.getOrigin(this.container.get(StorageService), identifier.viewId) : identifier.id);
if (endpoint[endpoint.length - 1] === '/') {
endpoint = endpoint.slice(0, endpoint.length - 1);
}
Expand All @@ -40,4 +42,16 @@ export class WebviewWidgetFactory {
return child.get(WebviewWidget);
}

protected async getOrigin(storageService: StorageService, viewId: string): Promise<string> {
const key = 'plugin-view-registry.origin.' + viewId;
const origin = await storageService.getData<string>(key);
if (!origin) {
const newOrigin = v4();
storageService.setData(key, newOrigin);
return newOrigin;
} else {
return origin;
}
}

}
1 change: 1 addition & 0 deletions packages/plugin-ext/src/main/browser/webview/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export interface WebviewConsoleLog {
@injectable()
export class WebviewWidgetIdentifier {
id: string;
viewId?: string;
}

export const WebviewWidgetExternalEndpoint = Symbol('WebviewWidgetExternalEndpoint');
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-ext/src/main/browser/webviews-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
showOptions: WebviewPanelShowOptions,
options: WebviewPanelOptions & WebviewOptions
): Promise<void> {
const view = await this.widgetManager.getOrCreateWidget<WebviewWidget>(WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: panelId });
const view = await this.widgetManager.getOrCreateWidget<WebviewWidget>(WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: panelId, viewId: viewType });
this.hookWebview(view);
view.viewType = viewType;
view.title.label = title;
Expand Down Expand Up @@ -269,7 +269,7 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
}

private async tryGetWebview(id: string): Promise<WebviewWidget | undefined> {
const webview = await this.widgetManager.getWidget<WebviewWidget>(WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id })
const webview = this.widgetManager.getWidgets(WebviewWidget.FACTORY_ID).find(widget => widget instanceof WebviewWidget && widget.identifier.id === id) as WebviewWidget
|| await this.widgetManager.getWidget<CustomEditorWidget>(CustomEditorWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id });
return webview;
}
Expand Down

0 comments on commit 72421be

Please sign in to comment.