From 1d1a85f9ea96fc6ea28192cbede71f40e492928d Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Mon, 13 Dec 2021 10:45:24 -0500 Subject: [PATCH] Use electron.clipboard for all clipboard uses (#4535) --- .../components/clipboard/clipboard.scss | 24 ----- .../components/clipboard/clipboard.tsx | 88 ------------------- src/renderer/components/clipboard/index.ts | 22 ----- .../components/dialog/logs-dialog.tsx | 7 +- .../kubeconfig-dialog/kubeconfig-dialog.tsx | 14 +-- src/renderer/utils/copyToClipboard.ts | 52 ----------- src/renderer/utils/index.ts | 1 - 7 files changed, 7 insertions(+), 201 deletions(-) delete mode 100644 src/renderer/components/clipboard/clipboard.scss delete mode 100644 src/renderer/components/clipboard/clipboard.tsx delete mode 100644 src/renderer/components/clipboard/index.ts delete mode 100644 src/renderer/utils/copyToClipboard.ts diff --git a/src/renderer/components/clipboard/clipboard.scss b/src/renderer/components/clipboard/clipboard.scss deleted file mode 100644 index b90314cc61..0000000000 --- a/src/renderer/components/clipboard/clipboard.scss +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2021 OpenLens Authors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -.Clipboard { - cursor: pointer; -} \ No newline at end of file diff --git a/src/renderer/components/clipboard/clipboard.tsx b/src/renderer/components/clipboard/clipboard.tsx deleted file mode 100644 index 6f5a7063e1..0000000000 --- a/src/renderer/components/clipboard/clipboard.tsx +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2021 OpenLens Authors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -import "./clipboard.scss"; -import React from "react"; -import { findDOMNode } from "react-dom"; -import { boundMethod } from "../../../common/utils"; -import { Notifications } from "../notifications"; -import { copyToClipboard } from "../../utils/copyToClipboard"; -import logger from "../../../main/logger"; -import { cssNames } from "../../utils"; - -export interface CopyToClipboardProps { - resetSelection?: boolean; - showNotification?: boolean; - cssSelectorLimit?: string; // allows to copy partial content with css-selector in children-element context - getNotificationMessage?(copiedText: string): React.ReactNode; -} - -export const defaultProps: Partial = { - getNotificationMessage(copiedText: string) { - return

Copied to clipboard: {copiedText}

; - }, -}; - -export class Clipboard extends React.Component { - static displayName = "Clipboard"; - static defaultProps = defaultProps as object; - - get rootElem(): HTMLElement { - // eslint-disable-next-line react/no-find-dom-node - return findDOMNode(this) as HTMLElement; - } - - get rootReactElem(): React.ReactElement> { - return React.Children.only(this.props.children) as React.ReactElement; - } - - @boundMethod - onClick(evt: React.MouseEvent) { - if (this.rootReactElem.props.onClick) { - this.rootReactElem.props.onClick(evt); // pass event to children-root-element if any - } - const { showNotification, resetSelection, getNotificationMessage, cssSelectorLimit } = this.props; - const contentElem = this.rootElem.querySelector(cssSelectorLimit) || this.rootElem; - - if (contentElem) { - const { copiedText, copied } = copyToClipboard(contentElem, { resetSelection }); - - if (copied && showNotification) { - Notifications.ok(getNotificationMessage(copiedText)); - } - } - } - - render() { - try { - const rootElem = this.rootReactElem; - - return React.cloneElement(rootElem, { - className: cssNames(Clipboard.displayName, rootElem.props.className), - onClick: this.onClick, - }); - } catch (err) { - logger.error(`Invalid usage components/CopyToClick usage. Children must contain root html element.`, { err: String(err) }); - - return this.rootReactElem; - } - } -} diff --git a/src/renderer/components/clipboard/index.ts b/src/renderer/components/clipboard/index.ts deleted file mode 100644 index 9f6ae846bc..0000000000 --- a/src/renderer/components/clipboard/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2021 OpenLens Authors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -export * from "./clipboard"; diff --git a/src/renderer/components/dialog/logs-dialog.tsx b/src/renderer/components/dialog/logs-dialog.tsx index 83f685ba5b..4299129466 100644 --- a/src/renderer/components/dialog/logs-dialog.tsx +++ b/src/renderer/components/dialog/logs-dialog.tsx @@ -24,10 +24,10 @@ import "./logs-dialog.scss"; import React from "react"; import { Dialog, DialogProps } from "../dialog"; import { Wizard, WizardStep } from "../wizard"; -import { copyToClipboard } from "../../utils"; import { Notifications } from "../notifications"; import { Button } from "../button"; import { Icon } from "../icon"; +import { clipboard } from "electron"; // todo: make as external BrowserWindow (?) @@ -40,9 +40,8 @@ export class LogsDialog extends React.Component { public logsElem: HTMLElement; copyToClipboard = () => { - if (copyToClipboard(this.logsElem)) { - Notifications.ok(`Logs copied to clipboard.`); - } + clipboard.writeText(this.props.logs); + Notifications.ok(`Logs copied to clipboard.`); }; render() { diff --git a/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog.tsx b/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog.tsx index 8c9f6a44d1..02a240043a 100644 --- a/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog.tsx +++ b/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog.tsx @@ -25,7 +25,7 @@ import { makeObservable, observable } from "mobx"; import { observer } from "mobx-react"; import yaml from "js-yaml"; import type { ServiceAccount } from "../../../common/k8s-api/endpoints"; -import { copyToClipboard, saveFileDialog } from "../../utils"; +import { saveFileDialog } from "../../utils"; import { Button } from "../button"; import { Dialog, DialogProps } from "../dialog"; import { Icon } from "../icon"; @@ -33,6 +33,7 @@ import { Notifications } from "../notifications"; import { Wizard, WizardStep } from "../wizard"; import { apiBase } from "../../api"; import { MonacoEditor } from "../monaco-editor"; +import { clipboard } from "electron"; interface IKubeconfigDialogData { title?: React.ReactNode; @@ -49,7 +50,6 @@ const dialogState = observable.object({ @observer export class KubeConfigDialog extends React.Component { - @observable.ref configTextArea: HTMLTextAreaElement; // required for coping config text @observable config = ""; // parsed kubeconfig in yaml format constructor(props: Props) { @@ -89,9 +89,8 @@ export class KubeConfigDialog extends React.Component { } copyToClipboard = () => { - if (this.config && copyToClipboard(this.configTextArea)) { - Notifications.ok("Config copied to clipboard"); - } + clipboard.writeText(this.config); + Notifications.ok("Config copied to clipboard"); }; download = () => { @@ -131,11 +130,6 @@ export class KubeConfigDialog extends React.Component { className={styles.editor} value={yamlConfig} /> -