1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix: use webview-tag in production instead of iframe to avoid possible ipc-issues with normal frames

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-09-19 12:37:35 +03:00
parent bddc6b33e3
commit cf3f458ec7
5 changed files with 40 additions and 27 deletions

View File

@ -209,13 +209,17 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
export const clusterStore = ClusterStore.getInstance<ClusterStore>();
export function isClusterView(): boolean {
return !!getHostedClusterId(); // note: process.isMainFrame cannot be used here since it's "true" for webview-tags
}
export function getClusterIdFromHost(hostname: string): ClusterId {
const subDomains = hostname.split(":")[0].split(".");
return subDomains.slice(-2)[0]; // e.g host == "%clusterId.localhost:45345"
return hostname.match(/^(.*?)\.localhost/)?.[1]
}
export function getClusterFrameUrl(clusterId: ClusterId) {
return `//${clusterId}.${location.host}`;
const { protocol, host } = location
return `${protocol}//${clusterId}.${host}`
}
export function getHostedClusterId() {

View File

@ -31,6 +31,7 @@ export class WindowManager {
nodeIntegration: true,
nodeIntegrationInSubFrames: true,
enableRemoteModule: true,
webviewTag: true,
},
});
this.windowState.manage(this.mainView);

View File

@ -4,7 +4,7 @@ import { render } from "react-dom";
import { isMac } from "../common/vars";
import { userStore } from "../common/user-store";
import { workspaceStore } from "../common/workspace-store";
import { clusterStore } from "../common/cluster-store";
import { clusterStore, isClusterView } from "../common/cluster-store";
import { i18nStore } from "./i18n";
import { themeStore } from "./theme.store";
import { App } from "./components/app";
@ -35,4 +35,4 @@ export async function bootstrap(App: AppComponent) {
}
// run
bootstrap(process.isMainFrame ? LensApp : App);
bootstrap(isClusterView() ? App : LensApp);

View File

@ -2,7 +2,7 @@ import { reaction } from "mobx";
import { ipcRenderer } from "electron";
import { matchPath, RouteProps } from "react-router";
import { buildURL, navigation } from "../../navigation";
import { clusterStore } from "../../../common/cluster-store";
import { clusterStore, isClusterView } from "../../../common/cluster-store";
export interface IClusterViewRouteParams {
clusterId: string;
@ -30,7 +30,7 @@ export function getMatchedCluster() {
}
if (ipcRenderer) {
if (process.isMainFrame) {
if (isClusterView()) {
// Keep track of active cluster-id for handling IPC/menus/etc.
reaction(() => getMatchedClusterId(), clusterId => {
ipcRenderer.send("cluster-view:current-id", clusterId);

View File

@ -1,12 +1,16 @@
import { WebviewTag } from "electron";
import { observable, when } from "mobx";
import { ClusterId, clusterStore, getClusterFrameUrl } from "../../../common/cluster-store";
import { getMatchedCluster } from "./cluster-view.route"
import logger from "../../../main/logger";
import { isDebugging, isDevelopment, isProduction } from "../../../common/vars";
import { getMatchedCluster } from "./cluster-view.route";
export type LensViewElem = HTMLIFrameElement | WebviewTag;
export interface LensView {
isLoaded?: boolean
clusterId: ClusterId;
view: HTMLIFrameElement
view: LensViewElem;
}
export const lensViews = observable.map<ClusterId, LensView>();
@ -20,31 +24,35 @@ export async function initView(clusterId: ClusterId) {
return;
}
logger.info(`[LENS-VIEW]: init dashboard, clusterId=${clusterId}`)
let view: LensViewElem;
const cluster = clusterStore.getById(clusterId);
const parentElem = document.getElementById("lens-views");
const iframe = document.createElement("iframe");
iframe.name = cluster.contextName;
iframe.setAttribute("src", getClusterFrameUrl(clusterId))
iframe.addEventListener("load", () => {
logger.info(`[LENS-VIEW]: loaded from ${iframe.src}`)
const frameUrl = getClusterFrameUrl(clusterId);
const onLoad = () => {
logger.info(`[LENS-VIEW]: loaded from ${view.src}`)
lensViews.get(clusterId).isLoaded = true;
}, { once: true });
lensViews.set(clusterId, { clusterId, view: iframe });
parentElem.appendChild(iframe);
await autoCleanOnRemove(clusterId, iframe);
};
if (isDevelopment || isDebugging) {
view = document.createElement("iframe");
view.addEventListener("load", onLoad);
view.name = cluster.contextName;
} else if (isProduction) {
view = document.createElement("webview");
view.addEventListener("did-frame-finish-load", onLoad);
view.setAttribute("nodeintegration", "true");
view.setAttribute("enableremotemodule", "true");
}
view.setAttribute("src", frameUrl);
parentElem.appendChild(view);
lensViews.set(clusterId, { clusterId, view });
await autoCleanOnRemove(clusterId, view);
}
export async function autoCleanOnRemove(clusterId: ClusterId, iframe: HTMLIFrameElement) {
export async function autoCleanOnRemove(clusterId: ClusterId, view: LensViewElem) {
await when(() => !clusterStore.getById(clusterId));
logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`)
lensViews.delete(clusterId)
// Keep frame in DOM to avoid possible bugs when same cluster re-created after being removed.
// In that case for some reasons `webFrame.routingId` returns some previous frameId (usage in app.tsx)
// Issue: https://github.com/lensapp/lens/issues/811
iframe.dataset.meta = `${iframe.name} was removed at ${new Date().toLocaleString()}`;
iframe.removeAttribute("src")
iframe.removeAttribute("name")
lensViews.delete(clusterId);
view.parentElement.removeChild(view);
}
export function refreshViews() {