From 72d89eb8dd21a9bd6208e8bae97535cbd8b0b095 Mon Sep 17 00:00:00 2001
From: silverwind <me@silverwind.io>
Date: Sun, 30 Jul 2023 00:56:45 +0200
Subject: [PATCH] Fix attachment clipboard copy on insecure origin (#26224)

Fixes: https://github.com/go-gitea/gitea/issues/26202

Actually later I found out the code did not use `clippie`, so I fixed
it. The bug was never in the clippie module like I initially suspected.
Also, I added a tooltip for feedback.

<img width="139" alt="image"
src="https://github.com/go-gitea/gitea/assets/115237/da501670-9c15-4412-969a-b559773c7ab9">

---------

Co-authored-by: Giteabot <teabot@gitea.io>
---
 web_src/js/features/common-global.js | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js
index 474993045b..be337ee903 100644
--- a/web_src/js/features/common-global.js
+++ b/web_src/js/features/common-global.js
@@ -1,5 +1,6 @@
 import $ from 'jquery';
 import 'jquery.are-you-sure';
+import {clippie} from 'clippie';
 import {createDropzone} from './dropzone.js';
 import {initCompColorPicker} from './comp/ColorPicker.js';
 import {showGlobalErrorMessage} from '../bootstrap.js';
@@ -7,7 +8,7 @@ import {handleGlobalEnterQuickSubmit} from './comp/QuickSubmit.js';
 import {svg} from '../svg.js';
 import {hideElem, showElem, toggleElem} from '../utils/dom.js';
 import {htmlEscape} from 'escape-goat';
-import {createTippy} from '../modules/tippy.js';
+import {createTippy, showTemporaryTooltip} from '../modules/tippy.js';
 import {confirmModal} from './comp/ConfirmModal.js';
 import {showErrorToast} from '../modules/toast.js';
 
@@ -240,7 +241,7 @@ export function initGlobalDropzone() {
           copyLinkElement.className = 'gt-text-center';
           // The a element has a hardcoded cursor: pointer because the default is overridden by .dropzone
           copyLinkElement.innerHTML = `<a href="#" style="cursor: pointer;">${svg('octicon-copy', 14, 'copy link')} Copy link</a>`;
-          copyLinkElement.addEventListener('click', (e) => {
+          copyLinkElement.addEventListener('click', async (e) => {
             e.preventDefault();
             let fileMarkdown = `[${file.name}](/attachments/${file.uuid})`;
             if (file.type.startsWith('image/')) {
@@ -248,7 +249,8 @@ export function initGlobalDropzone() {
             } else if (file.type.startsWith('video/')) {
               fileMarkdown = `<video src="/attachments/${file.uuid}" title="${htmlEscape(file.name)}" controls></video>`;
             }
-            navigator.clipboard.writeText(fileMarkdown);
+            const success = await clippie(fileMarkdown);
+            showTemporaryTooltip(e.target, success ? i18n.copy_success : i18n.copy_error);
           });
           file.previewTemplate.append(copyLinkElement);
         });