diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2024-11-08 08:44:28 +0100 |
---|---|---|
committer | skjnldsv <skjnldsv@protonmail.com> | 2024-11-08 14:01:33 +0100 |
commit | ed901604abd96faedf2cc6045b64a78b863b8ba7 (patch) | |
tree | 46d5d8acc63276cd749a954cade65f9d68b6d7c2 /core | |
parent | 5193ca41f92f8fb6ad88e40be3277ae7ea912361 (diff) | |
download | nextcloud-server-ed901604abd96faedf2cc6045b64a78b863b8ba7.tar.gz nextcloud-server-ed901604abd96faedf2cc6045b64a78b863b8ba7.zip |
feat(core): offer clipboard fallback for non-secure environments
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/src/init.js | 2 | ||||
-rw-r--r-- | core/src/utils/ClipboardFallback.ts | 47 |
2 files changed, 49 insertions, 0 deletions
diff --git a/core/src/init.js b/core/src/init.js index fab97d2ee2b..9e10a6941e1 100644 --- a/core/src/init.js +++ b/core/src/init.js @@ -14,6 +14,7 @@ import { setUp as setUpContactsMenu } from './components/ContactsMenu.js' import { setUp as setUpMainMenu } from './components/MainMenu.js' import { setUp as setUpUserMenu } from './components/UserMenu.js' import { interceptRequests } from './utils/xhr-request.js' +import { initFallbackClipboardAPI } from './utils/ClipboardFallback.ts' // keep in sync with core/css/variables.scss const breakpointMobileWidth = 1024 @@ -58,6 +59,7 @@ moment.locale(locale) */ export const initCore = () => { interceptRequests() + initFallbackClipboardAPI() $(window).on('unload.main', () => { OC._unloadCalled = true }) $(window).on('beforeunload.main', () => { diff --git a/core/src/utils/ClipboardFallback.ts b/core/src/utils/ClipboardFallback.ts new file mode 100644 index 00000000000..b374f9d0a44 --- /dev/null +++ b/core/src/utils/ClipboardFallback.ts @@ -0,0 +1,47 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +import { t } from '@nextcloud/l10n' + +/** + * + * @param text + */ +function unsecuredCopyToClipboard(text) { + const textArea = document.createElement('textarea') + const textAreaContent = document.createTextNode(text) + textArea.appendChild(textAreaContent) + document.body.appendChild(textArea) + + textArea.focus({ preventScroll: true }) + textArea.select() + + try { + // This is a fallback for browsers that do not support the Clipboard API + // execCommand is deprecated, but it is the only way to copy text to the clipboard in some browsers + document.execCommand('copy') + } catch (err) { + window.prompt(t('core', 'Clipboard not available, please copy manually'), text) + console.error('[ERROR] core: files Unable to copy to clipboard', err) + } + + document.body.removeChild(textArea) +} + +/** + * + */ +function initFallbackClipboardAPI() { + if (!window.navigator?.clipboard?.writeText) { + console.info('[INFO] core: Clipboard API not available, using fallback') + Object.defineProperty(window.navigator, 'clipboard', { + value: { + writeText: unsecuredCopyToClipboard, + }, + writable: false, + }) + } +} + +export { initFallbackClipboardAPI } |