diff options
author | silverwind <me@silverwind.io> | 2023-04-02 11:25:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-02 17:25:36 +0800 |
commit | f5593d08dc6d615e650fe5e954b300d1895212b7 (patch) | |
tree | 3b8e7762bdf5790ad988d4d4fce27da8f42d2087 /web_src | |
parent | fcb9ef8788da02c13ee7201b5b8bce216da3f0d7 (diff) | |
download | gitea-f5593d08dc6d615e650fe5e954b300d1895212b7.tar.gz gitea-f5593d08dc6d615e650fe5e954b300d1895212b7.zip |
Use clippie module to copy to clipboard (#23801)
Externalize clipboard copying to the
[clippie](https://github.com/silverwind/clippie) module which I feel I
can maintain outside this repo for shared benefit with my other
projects.
The module is feature-equivalent to the previous code and has one
improvement where it sets `aria-hidden` on the fallback textarea,
preventing screen readers from picking it up. Also it support `Array` of
`content` as well to copy multiple items at once, in case it's ever
needed.
Diffstat (limited to 'web_src')
-rw-r--r-- | web_src/js/features/clipboard.js | 43 | ||||
-rw-r--r-- | web_src/js/features/copycontent.js | 4 | ||||
-rw-r--r-- | web_src/js/features/repo-code.js | 4 |
3 files changed, 6 insertions, 45 deletions
diff --git a/web_src/js/features/clipboard.js b/web_src/js/features/clipboard.js index 07c439504e..bcbdae2704 100644 --- a/web_src/js/features/clipboard.js +++ b/web_src/js/features/clipboard.js @@ -1,48 +1,9 @@ import {showTemporaryTooltip} from '../modules/tippy.js'; import {toAbsoluteUrl} from '../utils.js'; +import {clippie} from 'clippie'; const {copy_success, copy_error} = window.config.i18n; -export async function copyToClipboard(content) { - if (content instanceof Blob) { - const item = new ClipboardItem({[content.type]: content}); - await navigator.clipboard.write([item]); - } else { // text - try { - await navigator.clipboard.writeText(content); - } catch { - return fallbackCopyToClipboard(content); - } - } - return true; -} - -// Fallback to use if navigator.clipboard doesn't exist. Achieved via creating -// a temporary textarea element, selecting the text, and using document.execCommand -function fallbackCopyToClipboard(text) { - if (!document.execCommand) return false; - - const tempTextArea = document.createElement('textarea'); - tempTextArea.value = text; - - // avoid scrolling - tempTextArea.style.top = 0; - tempTextArea.style.left = 0; - tempTextArea.style.position = 'fixed'; - - document.body.appendChild(tempTextArea); - - tempTextArea.select(); - - // if unsecure (not https), there is no navigator.clipboard, but we can still - // use document.execCommand to copy to clipboard - const success = document.execCommand('copy'); - - document.body.removeChild(tempTextArea); - - return success; -} - // For all DOM elements with [data-clipboard-target] or [data-clipboard-text], // this copy-to-clipboard will work for them export function initGlobalCopyToClipboardListener() { @@ -61,7 +22,7 @@ export function initGlobalCopyToClipboardListener() { e.preventDefault(); (async() => { - const success = await copyToClipboard(text); + const success = await clippie(text); showTemporaryTooltip(target, success ? copy_success : copy_error); })(); diff --git a/web_src/js/features/copycontent.js b/web_src/js/features/copycontent.js index 5a4b99ae9b..e51953625d 100644 --- a/web_src/js/features/copycontent.js +++ b/web_src/js/features/copycontent.js @@ -1,11 +1,11 @@ -import {copyToClipboard} from './clipboard.js'; +import {clippie} from 'clippie'; import {showTemporaryTooltip} from '../modules/tippy.js'; import {convertImage} from '../utils.js'; const {i18n} = window.config; async function doCopy(content, btn) { - const success = await copyToClipboard(content); + const success = await clippie(content); showTemporaryTooltip(btn, success ? i18n.copy_success : i18n.copy_error); } diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js index 1c59913132..c0dced44eb 100644 --- a/web_src/js/features/repo-code.js +++ b/web_src/js/features/repo-code.js @@ -2,7 +2,7 @@ import $ from 'jquery'; import {svg} from '../svg.js'; import {invertFileFolding} from './file-fold.js'; import {createTippy} from '../modules/tippy.js'; -import {copyToClipboard} from './clipboard.js'; +import {clippie} from 'clippie'; import {toAbsoluteUrl} from '../utils.js'; export const singleAnchorRegex = /^#(L|n)([1-9][0-9]*)$/; @@ -190,7 +190,7 @@ export function initRepoCodeView() { currentTarget.closest('tr').outerHTML = blob; }); $(document).on('click', '.copy-line-permalink', async (e) => { - const success = await copyToClipboard(toAbsoluteUrl(e.currentTarget.getAttribute('data-url'))); + const success = await clippie(toAbsoluteUrl(e.currentTarget.getAttribute('data-url'))); if (!success) return; document.querySelector('.code-line-button')?._tippy?.hide(); }); |