summaryrefslogtreecommitdiffstats
path: root/web_src/js/features/copycontent.js
diff options
context:
space:
mode:
authorsilverwind <me@silverwind.io>2022-11-21 10:59:42 +0100
committerGitHub <noreply@github.com>2022-11-21 17:59:42 +0800
commitc2fb27beb4a0f9a9ad1478937439bcf4c43aff4a (patch)
tree0f690c4aeecb6caa0a8cb24623141f3e569b8e72 /web_src/js/features/copycontent.js
parente4eaa68a2b2355c7333406fdcbb8b118677b95df (diff)
downloadgitea-c2fb27beb4a0f9a9ad1478937439bcf4c43aff4a.tar.gz
gitea-c2fb27beb4a0f9a9ad1478937439bcf4c43aff4a.zip
Improvements for Content Copy (#21842)
It now supports copying Markdown, SVG and Images (not in Firefox currently because of lacking [`ClipboardItem`](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem) support, but can be enabled in `about:config` and works). It will fetch the data if in a rendered view or when it's an image. Followup to https://github.com/go-gitea/gitea/pull/21629.
Diffstat (limited to 'web_src/js/features/copycontent.js')
-rw-r--r--web_src/js/features/copycontent.js59
1 files changed, 59 insertions, 0 deletions
diff --git a/web_src/js/features/copycontent.js b/web_src/js/features/copycontent.js
new file mode 100644
index 0000000000..9b791bedba
--- /dev/null
+++ b/web_src/js/features/copycontent.js
@@ -0,0 +1,59 @@
+import {copyToClipboard} from './clipboard.js';
+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);
+ showTemporaryTooltip(btn, success ? i18n.copy_success : i18n.copy_error);
+}
+
+export function initCopyContent() {
+ const btn = document.getElementById('copy-content');
+ if (!btn || btn.classList.contains('disabled')) return;
+
+ btn.addEventListener('click', async () => {
+ if (btn.classList.contains('is-loading')) return;
+ let content, isImage;
+ const link = btn.getAttribute('data-link');
+
+ // when data-link is present, we perform a fetch. this is either because
+ // the text to copy is not in the DOM or it is an image which should be
+ // fetched to copy in full resolution
+ if (link) {
+ btn.classList.add('is-loading');
+ try {
+ const res = await fetch(link, {credentials: 'include', redirect: 'follow'});
+ const contentType = res.headers.get('content-type');
+
+ if (contentType.startsWith('image/') && !contentType.startsWith('image/svg')) {
+ isImage = true;
+ content = await res.blob();
+ } else {
+ content = await res.text();
+ }
+ } catch {
+ return showTemporaryTooltip(btn, i18n.copy_error);
+ } finally {
+ btn.classList.remove('is-loading');
+ }
+ } else { // text, read from DOM
+ const lineEls = document.querySelectorAll('.file-view .lines-code');
+ content = Array.from(lineEls).map((el) => el.textContent).join('');
+ }
+
+ try {
+ await doCopy(content, btn);
+ } catch {
+ if (isImage) { // convert image to png as last-resort as some browser only support png copy
+ try {
+ await doCopy(await convertImage(content, 'image/png'), btn);
+ } catch {
+ showTemporaryTooltip(btn, i18n.copy_error);
+ }
+ } else {
+ showTemporaryTooltip(btn, i18n.copy_error);
+ }
+ }
+ });
+}