From 09f2919946f163137da511fc2b3b416741df7e6b Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 9 Aug 2022 19:25:11 -0700 Subject: [PATCH] Remove usage of deprecated xtermjs's registerLinkMatcher API (#5996) * Make openBrowser->openLinkInBrowser injectable Signed-off-by: Sebastian Malton * Remove use of deprecated link matcher API from XtermJS Signed-off-by: Sebastian Malton * Fix type errors Signed-off-by: Sebastian Malton --- package.json | 3 +- src/common/utils/index.ts | 1 - ...-browser.global-override-for-injectable.ts | 9 +++++ .../utils/open-link-in-browser.injectable.ts | 28 ++++++++++++++ src/common/utils/openBrowser.ts | 29 -------------- src/extensions/common-api/utils.ts | 11 +++++- .../menu/application-menu-items.injectable.ts | 7 ++-- .../create-electron-window.injectable.ts | 5 ++- .../port-forward-menu.tsx | 7 +++- .../service-port-component.tsx | 10 +++-- .../+workloads-pods/pod-container-port.tsx | 10 +++-- .../terminal/create-terminal.injectable.ts | 4 ++ .../components/dock/terminal/terminal.ts | 21 ++++++---- .../open-port-forward.injectable.ts | 38 +++++++++++++++++++ .../port-forward/port-forward-dialog.tsx | 7 +++- .../port-forward/port-forward-utils.ts | 22 ----------- yarn.lock | 9 ++++- 17 files changed, 144 insertions(+), 77 deletions(-) create mode 100644 src/common/utils/open-link-in-browser.global-override-for-injectable.ts create mode 100644 src/common/utils/open-link-in-browser.injectable.ts delete mode 100644 src/common/utils/openBrowser.ts create mode 100644 src/renderer/port-forward/open-port-forward.injectable.ts diff --git a/package.json b/package.json index 6d08bb8f55..9e88238fa7 100644 --- a/package.json +++ b/package.json @@ -282,7 +282,8 @@ "winston": "^3.8.1", "winston-console-format": "^1.0.8", "winston-transport-browserconsole": "^1.0.5", - "ws": "^8.8.1" + "ws": "^8.8.1", + "xterm-link-provider": "^1.3.1" }, "devDependencies": { "@async-fn/jest": "1.6.4", diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index f0aa66294b..e16f803c56 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -22,7 +22,6 @@ export * from "./hash-set"; export * from "./n-fircate"; export * from "./noop"; export * from "./observable-crate/impl"; -export * from "./openBrowser"; export * from "./paths"; export * from "./promise-exec"; export * from "./readonly"; diff --git a/src/common/utils/open-link-in-browser.global-override-for-injectable.ts b/src/common/utils/open-link-in-browser.global-override-for-injectable.ts new file mode 100644 index 0000000000..62c1539757 --- /dev/null +++ b/src/common/utils/open-link-in-browser.global-override-for-injectable.ts @@ -0,0 +1,9 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getGlobalOverride } from "../test-utils/get-global-override"; +import openLinkInBrowserInjectable from "./open-link-in-browser.injectable"; + +export default getGlobalOverride(openLinkInBrowserInjectable, () => async () => {}); diff --git a/src/common/utils/open-link-in-browser.injectable.ts b/src/common/utils/open-link-in-browser.injectable.ts new file mode 100644 index 0000000000..eaa91939e9 --- /dev/null +++ b/src/common/utils/open-link-in-browser.injectable.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { shell } from "electron"; + +const allowedProtocols = new Set(["http:", "https:"]); + +export type OpenLinkInBrowser = (url: string) => Promise; + +const openLinkInBrowserInjectable = getInjectable({ + id: "open-link-in-browser", + instantiate: (): OpenLinkInBrowser => ( + async (url) => { + const { protocol } = new URL(url); + + if (!allowedProtocols.has(protocol)) { + throw new TypeError("not an http(s) URL"); + } + + await shell.openExternal(url); + } + ), + causesSideEffects: true, +}); + +export default openLinkInBrowserInjectable; diff --git a/src/common/utils/openBrowser.ts b/src/common/utils/openBrowser.ts deleted file mode 100644 index 3ba29b699b..0000000000 --- a/src/common/utils/openBrowser.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import { shell } from "electron"; - -const allowedProtocols = new Set(["http:", "https:"]); - -/** - * Opens a link using the program configured as the default browser - * on the target platform. Will reject URLs with a scheme other than - * http or https to prevent programs other than the default browser - * running. - * - * @param url The URL to open - */ -export function openBrowser(url: string): Promise { - if (allowedProtocols.has(new URL(url).protocol)) { - return shell.openExternal(url); - } - - return Promise.reject(new TypeError("not an http(s) URL")); -} - -/** - * @deprecated use openBrowser - */ -export const openExternal = openBrowser; diff --git a/src/extensions/common-api/utils.ts b/src/extensions/common-api/utils.ts index 8e6ba1c9af..3dea165238 100644 --- a/src/extensions/common-api/utils.ts +++ b/src/extensions/common-api/utils.ts @@ -3,6 +3,15 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -export { Singleton, openExternal, openBrowser, getAppVersion } from "../../common/utils"; +import openLinkInBrowserInjectable from "../../common/utils/open-link-in-browser.injectable"; +import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api"; + +export { Singleton, getAppVersion } from "../../common/utils"; export { prevDefault, stopPropagation } from "../../renderer/utils/prevDefault"; export { cssNames } from "../../renderer/utils/cssNames"; + +/** + * @deprecated Use {@link openBrowser} instead + */ +export const openExternal = asLegacyGlobalFunctionForExtensionApi(openLinkInBrowserInjectable); +export const openBrowser = asLegacyGlobalFunctionForExtensionApi(openLinkInBrowserInjectable); diff --git a/src/main/menu/application-menu-items.injectable.ts b/src/main/menu/application-menu-items.injectable.ts index f223c539c6..b96cfabfad 100644 --- a/src/main/menu/application-menu-items.injectable.ts +++ b/src/main/menu/application-menu-items.injectable.ts @@ -5,7 +5,6 @@ import { getInjectable } from "@ogre-tools/injectable"; import { docsUrl, productName, supportUrl } from "../../common/vars"; import { broadcastMessage } from "../../common/ipc"; -import { openBrowser } from "../../common/utils"; import type { MenuItemConstructorOptions } from "electron"; import { webContents } from "electron"; import loggerInjectable from "../../common/logger.injectable"; @@ -25,6 +24,7 @@ import applicationWindowInjectable from "../start-main-application/lens-window/a import reloadWindowInjectable from "../start-main-application/lens-window/reload-window.injectable"; import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable"; import processCheckingForUpdatesInjectable from "../application-update/check-for-updates/process-checking-for-updates.injectable"; +import openLinkInBrowserInjectable from "../../common/utils/open-link-in-browser.injectable"; function ignoreIf(check: boolean, menuItems: MenuItemOpts[]) { return check ? [] : menuItems; @@ -54,6 +54,7 @@ const applicationMenuItemsInjectable = getInjectable({ const navigateToAddCluster = di.inject(navigateToAddClusterInjectable); const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable); const processCheckingForUpdates = di.inject(processCheckingForUpdatesInjectable); + const openLinkInBrowser = di.inject(openLinkInBrowserInjectable); logger.info(`[MENU]: autoUpdateEnabled=${updatingIsEnabled}`); @@ -260,7 +261,7 @@ const applicationMenuItemsInjectable = getInjectable({ label: "Documentation", id: "documentation", click: async () => { - openBrowser(docsUrl).catch((error) => { + openLinkInBrowser(docsUrl).catch((error) => { logger.error("[MENU]: failed to open browser", { error }); }); }, @@ -269,7 +270,7 @@ const applicationMenuItemsInjectable = getInjectable({ label: "Support", id: "support", click: async () => { - openBrowser(supportUrl).catch((error) => { + openLinkInBrowser(supportUrl).catch((error) => { logger.error("[MENU]: failed to open browser", { error }); }); }, diff --git a/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts index 00fcdb6231..7521a64696 100644 --- a/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts +++ b/src/main/start-main-application/lens-window/application-window/create-electron-window.injectable.ts @@ -6,10 +6,10 @@ import { getInjectable } from "@ogre-tools/injectable"; import loggerInjectable from "../../../../common/logger.injectable"; import applicationWindowStateInjectable from "./application-window-state.injectable"; import { BrowserWindow } from "electron"; -import { openBrowser } from "../../../../common/utils"; import sendToChannelInElectronBrowserWindowInjectable from "./send-to-channel-in-electron-browser-window.injectable"; import type { ElectronWindow } from "./create-lens-window.injectable"; import type { RequireExactlyOne } from "type-fest"; +import openLinkInBrowserInjectable from "../../../../common/utils/open-link-in-browser.injectable"; export type ElectronWindowTitleBarStyle = "hiddenInset" | "hidden" | "default" | "customButtonsOnHover"; @@ -46,6 +46,7 @@ const createElectronWindowInjectable = getInjectable({ instantiate: (di): CreateElectronWindow => { const logger = di.inject(loggerInjectable); const sendToChannelInLensWindow = di.inject(sendToChannelInElectronBrowserWindowInjectable); + const openLinkInBrowser = di.inject(openLinkInBrowserInjectable); return (configuration) => { const applicationWindowState = di.inject( @@ -158,7 +159,7 @@ const createElectronWindowInjectable = getInjectable({ }) .setWindowOpenHandler((details) => { - openBrowser(details.url).catch((error) => { + openLinkInBrowser(details.url).catch((error) => { logger.error("[CREATE-ELECTRON-WINDOW]: failed to open browser", { error, }); diff --git a/src/renderer/components/+network-port-forwards/port-forward-menu.tsx b/src/renderer/components/+network-port-forwards/port-forward-menu.tsx index 70b5a0278d..a0edc693a6 100644 --- a/src/renderer/components/+network-port-forwards/port-forward-menu.tsx +++ b/src/renderer/components/+network-port-forwards/port-forward-menu.tsx @@ -6,7 +6,6 @@ import React from "react"; import { autoBind, cssNames } from "../../utils"; import type { PortForwardItem, PortForwardStore } from "../../port-forward"; -import { openPortForward } from "../../port-forward"; import type { MenuActionsProps } from "../menu/menu-actions"; import { MenuActions } from "../menu/menu-actions"; import { MenuItem } from "../menu"; @@ -15,6 +14,8 @@ import { Notifications } from "../notifications"; import { withInjectables } from "@ogre-tools/injectable-react"; import portForwardDialogModelInjectable from "../../port-forward/port-forward-dialog-model/port-forward-dialog-model.injectable"; import portForwardStoreInjectable from "../../port-forward/port-forward-store/port-forward-store.injectable"; +import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable"; +import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable"; export interface PortForwardMenuProps extends MenuActionsProps { portForward: PortForwardItem; @@ -24,6 +25,7 @@ export interface PortForwardMenuProps extends MenuActionsProps { interface Dependencies { portForwardStore: PortForwardStore; openPortForwardDialog: (item: PortForwardItem) => void; + openPortForward: OpenPortForward; } class NonInjectedPortForwardMenu extends React.Component { @@ -94,7 +96,7 @@ class NonInjectedPortForwardMenu { portForward.status === "Active" && ( - openPortForward(portForward)}> + this.props.openPortForward(portForward)}> ({ portForwardStore: di.inject(portForwardStoreInjectable), openPortForwardDialog: di.inject(portForwardDialogModelInjectable).open, + openPortForward: di.inject(openPortForwardInjectable), ...props, }), }, diff --git a/src/renderer/components/+network-services/service-port-component.tsx b/src/renderer/components/+network-services/service-port-component.tsx index e151a32382..79aeff7ec5 100644 --- a/src/renderer/components/+network-services/service-port-component.tsx +++ b/src/renderer/components/+network-services/service-port-component.tsx @@ -13,7 +13,7 @@ import { cssNames } from "../../utils"; import { Notifications } from "../notifications"; import { Button } from "../button"; import type { ForwardedPort, PortForwardStore } from "../../port-forward"; -import { openPortForward, predictProtocol } from "../../port-forward"; +import { predictProtocol } from "../../port-forward"; import { Spinner } from "../spinner"; import { withInjectables } from "@ogre-tools/injectable-react"; import portForwardStoreInjectable from "../../port-forward/port-forward-store/port-forward-store.injectable"; @@ -21,6 +21,8 @@ import portForwardDialogModelInjectable from "../../port-forward/port-forward-di import logger from "../../../common/logger"; import aboutPortForwardingInjectable from "../../port-forward/about-port-forwarding.injectable"; import notifyErrorPortForwardingInjectable from "../../port-forward/notify-error-port-forwarding.injectable"; +import type { OpenPortForward } from "../../port-forward/open-port-forward.injectable"; +import openPortForwardInjectable from "../../port-forward/open-port-forward.injectable"; export interface ServicePortComponentProps { service: Service; @@ -32,6 +34,7 @@ interface Dependencies { openPortForwardDialog: (item: ForwardedPort, options: { openInBrowser: boolean; onClose: () => void }) => void; aboutPortForwarding: () => void; notifyErrorPortForwarding: (message: string) => void; + openPortForward: OpenPortForward; } @observer @@ -88,7 +91,7 @@ class NonInjectedServicePortComponent extends React.Component this.portForward()}> {port.toString()} -