From 1195a9e3be3e7b9b281120d4cf1b1d17a92ca94e Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sat, 17 May 2025 14:41:55 +0300 Subject: [PATCH] web: moved clipboard to own file --- web/share/js/kvm/clipboard.js | 78 +++++++++++++++++++++++++++++++++++ web/share/js/kvm/ocr.js | 3 +- web/share/js/kvm/switch.js | 3 +- web/share/js/wm.js | 44 -------------------- 4 files changed, 82 insertions(+), 46 deletions(-) create mode 100644 web/share/js/kvm/clipboard.js diff --git a/web/share/js/kvm/clipboard.js b/web/share/js/kvm/clipboard.js new file mode 100644 index 00000000..0ca91a4b --- /dev/null +++ b/web/share/js/kvm/clipboard.js @@ -0,0 +1,78 @@ +/***************************************************************************** +# # +# KVMD - The main PiKVM daemon. # +# # +# Copyright (C) 2018-2024 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +*****************************************************************************/ + + +"use strict"; + + +import {tools} from "../tools.js"; +import {wm} from "../wm.js"; + + +export var clipboard = new function() { + var self = this; + + /************************************************************************/ + + self.setText = function(text) { + let workaround = function(ex) { + // https://stackoverflow.com/questions/60317969/document-execcommandcopy-not-working-even-though-the-dom-element-is-created + wm.info("Press OK to copy the text to the clipboard").then(function() { + tools.error("clipboard.setText(): navigator.clipboard.writeText() is not working:", ex); + tools.info("clipboard.setText(): Trying a workaround..."); + + let el = document.createElement("textarea"); + el.readonly = true; + el.contentEditable = true; + el.style.position = "absolute"; + el.style.top = "-1000px"; + el.value = text; + document.body.appendChild(el); + + // Select the content of the textarea + el.select(); // Ordinary browsers + el.setSelectionRange(0, el.value.length); // iOS + + try { + ex = (document.execCommand("copy") ? null : "Unknown error"); + } catch (ex) { // eslint-disable-line no-unused-vars + } + + // Remove the added textarea again: + document.body.removeChild(el); + + if (ex) { + tools.error("clipboard.setText(): Workaround failed:", ex); + wm.error("Can't copy text to the clipboard", `${ex}`); + } + }); + }; + if (navigator.clipboard) { + navigator.clipboard.writeText(text).then(function() { + wm.info("The text has been copied to the clipboard"); + }, function(ex) { + workaround(ex); + }); + } else { + workaround("navigator.clipboard is not available"); + } + }; +}; diff --git a/web/share/js/kvm/ocr.js b/web/share/js/kvm/ocr.js index 08b3f52c..4b25115e 100644 --- a/web/share/js/kvm/ocr.js +++ b/web/share/js/kvm/ocr.js @@ -25,6 +25,7 @@ import {tools, $} from "../tools.js"; import {wm} from "../wm.js"; +import {clipboard} from "./clipboard.js"; export function Ocr(__getGeometry) { @@ -189,7 +190,7 @@ export function Ocr(__getGeometry) { }; tools.httpGet("api/streamer/snapshot", params, function(http) { if (http.status === 200) { - wm.copyTextToClipboard(http.responseText); + clipboard.setText(http.responseText); } else { wm.error("OCR error:
", http.responseText); } diff --git a/web/share/js/kvm/switch.js b/web/share/js/kvm/switch.js index 7a6e47cf..8fd5498e 100644 --- a/web/share/js/kvm/switch.js +++ b/web/share/js/kvm/switch.js @@ -26,6 +26,7 @@ import {ROOT_PREFIX} from "../vars.js"; import {tools, $} from "../tools.js"; import {wm} from "../wm.js"; +import {clipboard} from "./clipboard.js"; export function Switch() { @@ -234,7 +235,7 @@ export function Switch() { if (edid_id && __state && __state.edids) { let data = __state.edids.all[edid_id].data; data = data.replace(/(.{32})/g, "$1\n"); - wm.copyTextToClipboard(data); + clipboard.setText(data); } }; diff --git a/web/share/js/wm.js b/web/share/js/wm.js index 6179951d..bc088f7e 100644 --- a/web/share/js/wm.js +++ b/web/share/js/wm.js @@ -187,50 +187,6 @@ function __WindowManager() { /************************************************************************/ - self.copyTextToClipboard = function(text) { - let workaround = function(ex) { - // https://stackoverflow.com/questions/60317969/document-execcommandcopy-not-working-even-though-the-dom-element-is-created - __modalDialog("Info", "Press OK to copy the text to the clipboard", true, false).then(function() { - tools.error("copyTextToClipboard(): navigator.clipboard.writeText() is not working:", ex); - tools.info("copyTextToClipboard(): Trying a workaround..."); - - let el = document.createElement("textarea"); - el.readonly = true; - el.contentEditable = true; - el.style.position = "absolute"; - el.style.top = "-1000px"; - el.value = text; - document.body.appendChild(el); - - // Select the content of the textarea - el.select(); // Ordinary browsers - el.setSelectionRange(0, el.value.length); // iOS - - try { - ex = (document.execCommand("copy") ? null : "Unknown error"); - } catch (ex) { // eslint-disable-line no-unused-vars - } - - // Remove the added textarea again: - document.body.removeChild(el); - - if (ex) { - tools.error("copyTextToClipboard(): Workaround failed:", ex); - self.error("Can't copy text to the clipboard", `${ex}`); - } - }); - }; - if (navigator.clipboard) { - navigator.clipboard.writeText(text).then(function() { - self.info("The text has been copied to the clipboard"); - }, function(ex) { - workaround(ex); - }); - } else { - workaround("navigator.clipboard is not available"); - } - }; - self.info = (html, ...args) => __modalCodeDialog("Info", html, args.join("\n"), true, false); self.error = (html, ...args) => __modalCodeDialog("Error", html, args.join("\n"), true, false); self.confirm = (html, ...args) => __modalCodeDialog("Question", html, args.join("\n"), true, true);