Skip to content

Commit 251f5fb

Browse files
committed
Replace clipboard.js with async clipboard api
Use async clipboard api [1] over this dependency, saving around 10kB bundle size before minify while delivering the same functionality. The issue comment button works but does not have a popup indication. We could add some toast-style notifications in the future to fix that but I think it's out of scope of this PR. [1] https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
1 parent c3aaf5e commit 251f5fb

File tree

5 files changed

+36
-88
lines changed

5 files changed

+36
-88
lines changed

package-lock.json

Lines changed: 0 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"@claviska/jquery-minicolors": "2.3.5",
1010
"@primer/octicons": "13.0.0",
1111
"add-asset-webpack-plugin": "2.0.1",
12-
"clipboard": "2.0.8",
1312
"codemirror": "5.61.0",
1413
"css-loader": "5.2.4",
1514
"dropzone": "5.9.2",

templates/repo/clone_buttons.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<input id="repo-clone-url" value="{{if $.PageIsWiki}}{{$.WikiCloneLink.SSH}}{{else}}{{$.CloneLink.SSH}}{{end}}" readonly>
1515
{{end}}
1616
{{if or (not $.DisableHTTP) (and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH))}}
17-
<button class="ui basic icon button poping up clipboard" id="clipboard-btn" data-original="{{.i18n.Tr "repo.copy_link"}}" data-success="{{.i18n.Tr "repo.copy_link_success"}}" data-error="{{.i18n.Tr "repo.copy_link_error"}}" data-content="{{.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-target="#repo-clone-url">
17+
<button class="ui basic icon button poping up" id="clipboard-btn" data-original="{{.i18n.Tr "repo.copy_link"}}" data-success="{{.i18n.Tr "repo.copy_link_success"}}" data-error="{{.i18n.Tr "repo.copy_link_error"}}" data-content="{{.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-target="#repo-clone-url">
1818
{{svg "octicon-clippy"}}
1919
</button>
2020
{{end}}

templates/repo/issue/view_content/context_menu.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
{{ else }}
1111
{{ $referenceUrl = Printf "%s%s/pulls/%d/files#%s" AppUrl .ctx.Repository.FullName .ctx.Issue.Index .item.HashTag }}
1212
{{ end }}
13-
<div class="item context clipboard" data-clipboard-text="{{$referenceUrl}}">{{.ctx.i18n.Tr "repo.issues.context.copy_link"}}</div>
13+
<div class="item context" data-clipboard-text="{{$referenceUrl}}">{{.ctx.i18n.Tr "repo.issues.context.copy_link"}}</div>
1414
<div class="item context quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.ID}}">{{.ctx.i18n.Tr "repo.issues.context.quote_reply"}}</div>
1515
{{if not .ctx.UnitIssuesGlobalDisabled}}
1616
<div class="item context reference-issue" data-target="{{.item.ID}}" data-modal="#reference-issue-modal" data-poster="{{.item.Poster.GetDisplayName}}" data-reference="{{$referenceUrl}}">{{.ctx.i18n.Tr "repo.issues.context.reference_issue"}}</div>

web_src/js/features/clipboard.js

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
1-
export default async function initClipboard() {
2-
const els = document.querySelectorAll('.clipboard');
3-
if (!els || !els.length) return;
1+
const selector = '[data-clipboard-target], [data-clipboard-text]';
42

5-
const {default: ClipboardJS} = await import(/* webpackChunkName: "clipboard" */'clipboard');
3+
// TODO: replace these with toast-style notifications
4+
function onSuccess(btn) {
5+
if (!btn.dataset.content) return;
6+
$(btn).popup('destroy');
7+
btn.dataset.content = btn.dataset.success;
8+
$(btn).popup('show');
9+
btn.dataset.content = btn.dataset.original;
10+
}
11+
function onError(btn) {
12+
if (!btn.dataset.content) return;
13+
$(btn).popup('destroy');
14+
btn.dataset.content = btn.dataset.error;
15+
$(btn).popup('show');
16+
btn.dataset.content = btn.dataset.original;
17+
}
618

7-
const clipboard = new ClipboardJS(els);
8-
clipboard.on('success', (e) => {
9-
e.clearSelection();
10-
$(e.trigger).popup('destroy');
11-
e.trigger.dataset.content = e.trigger.dataset.success;
12-
$(e.trigger).popup('show');
13-
e.trigger.dataset.content = e.trigger.dataset.original;
14-
});
19+
export default async function initClipboard() {
20+
for (const btn of document.querySelectorAll(selector) || []) {
21+
btn.addEventListener('click', async () => {
22+
let text;
23+
if (btn.dataset.clipboardText) {
24+
text = btn.dataset.clipboardText;
25+
} else if (btn.dataset.clipboardTarget) {
26+
text = document.querySelector(btn.dataset.clipboardTarget)?.value;
27+
}
28+
if (!text) return;
1529

16-
clipboard.on('error', (e) => {
17-
$(e.trigger).popup('destroy');
18-
e.trigger.dataset.content = e.trigger.dataset.error;
19-
$(e.trigger).popup('show');
20-
e.trigger.dataset.content = e.trigger.dataset.original;
21-
});
30+
try {
31+
await navigator.clipboard.writeText(text);
32+
onSuccess(btn);
33+
} catch {
34+
onError(btn);
35+
}
36+
});
37+
}
2238
}

0 commit comments

Comments
 (0)