diff --git a/src/freenet/clients/http/QueueToadlet.java b/src/freenet/clients/http/QueueToadlet.java index bf3a29ee619..91a6f2bf8ae 100644 --- a/src/freenet/clients/http/QueueToadlet.java +++ b/src/freenet/clients/http/QueueToadlet.java @@ -1979,7 +1979,11 @@ private HTMLNode createSizeCell(long dataSize, boolean confirmed, boolean advanc private HTMLNode createKeyCell(FreenetURI uri, boolean addSlash) { HTMLNode keyCell = new HTMLNode("td", "class", "request-key"); if (uri != null) { - keyCell.addChild("span", "class", "key_is").addChild("a", "href", '/' + uri.toString() + (addSlash ? "/" : ""), uri.toShortString() + (addSlash ? "/" : "")); + keyCell.addChild("span", "class", "key_is") + .addChild("a", + new String[]{"class", "data-copytext", "data-copytitle", "href"}, + new String[]{"copy-to-clipboard", uri.toString(), l10n("copyToClipboardTitle"), '/' + uri.toString() + (addSlash ? "/" : "")}, + uri.toShortString() + (addSlash ? "/" : "")); } else { keyCell.addChild("span", "class", "key_unknown", l10n("unknown")); } @@ -2115,6 +2119,9 @@ private HTMLNode createRequestTable(PageMaker pageMaker, ToadletContext ctx, Lis HTMLNode formDiv = new HTMLNode("div", "class", "request-table-form"); HTMLNode form = ctx.addFormChild(formDiv, path(), "request-table-form-"+id+(advancedModeEnabled?"-advanced":"-simple")); + if (core.getNode().isFProxyJavascriptEnabled()) { + form.addChild("script", new String[] {"type", "src"}, new String[] {"text/javascript", "/static/js/clipboard.js"}); + } createRequestTableButtons(form, pageMaker, ctx, mimeType, hasFriends, advancedModeEnabled, priorityClasses, true, queueType); diff --git a/src/freenet/clients/http/staticfiles/color.css b/src/freenet/clients/http/staticfiles/color.css index 9c8dd3359b0..098070d2154 100644 --- a/src/freenet/clients/http/staticfiles/color.css +++ b/src/freenet/clients/http/staticfiles/color.css @@ -431,3 +431,12 @@ div#statusbar div.separator { } +.copy-to-clipboard-element { + user-select: none; /* do not copy this text */ + cursor: pointer; /* this is an action */ +} +.copy-to-clipboard-element:active { + color: red; + font-weight: bold; +} + diff --git a/src/freenet/clients/http/staticfiles/js/clipboard.js b/src/freenet/clients/http/staticfiles/js/clipboard.js new file mode 100644 index 00000000000..a13744ad1b5 --- /dev/null +++ b/src/freenet/clients/http/staticfiles/js/clipboard.js @@ -0,0 +1,25 @@ +// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later +if (typeof(document.addCopyKeyFieldToFinishedTransfers) === 'undefined') { + function addCopyKeyFieldToFinishedTransfers () { + if (navigator.clipboard) { + var matching = document.getElementsByClassName('copy-to-clipboard'); + for (var matchingElement of matching) { + // must use const to avoid the weird scoping of var replacing all text with the last element + // const for declaration is usable in IE11+. + const text = matchingElement.dataset.copytext; + if (text) { + var toClipboard = document.createElement('span'); + // SVG image thanks to bertm! + toClipboard.innerHTML = ''; + toClipboard.classList.add('copy-to-clipboard-element'); + toClipboard.setAttribute('title', matchingElement.dataset.copytitle); + toClipboard.onclick = () => navigator.clipboard.writeText(text); + matchingElement.after(toClipboard); + } + } + } + } + document.addCopyKeyFieldToFinishedTransfers = addCopyKeyFieldToFinishedTransfers; + document.addEventListener('DOMContentLoaded', addCopyKeyFieldToFinishedTransfers); +} +// @license-end diff --git a/src/freenet/clients/http/staticfiles/themes/boxed/color.css b/src/freenet/clients/http/staticfiles/themes/boxed/color.css index 82cba4045d9..bd4ef326037 100644 --- a/src/freenet/clients/http/staticfiles/themes/boxed/color.css +++ b/src/freenet/clients/http/staticfiles/themes/boxed/color.css @@ -260,3 +260,13 @@ div#statusbar div.separator { background-color: black; } + +.copy-to-clipboard-element { + user-select: none; /* do not copy this text */ + cursor: pointer; /* this is an action */ +} +.copy-to-clipboard-element:active { + color: red; + font-weight: bold; +} + diff --git a/src/freenet/clients/http/staticfiles/themes/clean/color.css b/src/freenet/clients/http/staticfiles/themes/clean/color.css index 8d7f8ea763b..385ca7bddfe 100644 --- a/src/freenet/clients/http/staticfiles/themes/clean/color.css +++ b/src/freenet/clients/http/staticfiles/themes/clean/color.css @@ -59,3 +59,13 @@ /* * Statusbar */ + +.copy-to-clipboard-element { + user-select: none; /* do not copy this text */ + cursor: pointer; /* this is an action */ +} +.copy-to-clipboard-element:active { + color: red; + font-weight: bold; +} + diff --git a/src/freenet/clients/http/staticfiles/themes/grayandblue/color.css b/src/freenet/clients/http/staticfiles/themes/grayandblue/color.css index fbff689789e..5f8ef628e77 100644 --- a/src/freenet/clients/http/staticfiles/themes/grayandblue/color.css +++ b/src/freenet/clients/http/staticfiles/themes/grayandblue/color.css @@ -289,3 +289,13 @@ tr.priority6, td.priority6 { background-color: transparent !important; } + +.copy-to-clipboard-element { + user-select: none; /* do not copy this text */ + cursor: pointer; /* this is an action */ +} +.copy-to-clipboard-element:active { + color: red; + font-weight: bold; +} + diff --git a/src/freenet/clients/http/staticfiles/themes/sky/color.css b/src/freenet/clients/http/staticfiles/themes/sky/color.css index a78083d9a42..161bbf7fab3 100644 --- a/src/freenet/clients/http/staticfiles/themes/sky/color.css +++ b/src/freenet/clients/http/staticfiles/themes/sky/color.css @@ -229,3 +229,13 @@ table.queue span.progress_fraction_finalized { #statusbar div.separator { background-color: #d0d0f0; } + +.copy-to-clipboard-element { + user-select: none; /* do not copy this text */ + cursor: pointer; /* this is an action */ +} +.copy-to-clipboard-element:active { + color: red; + font-weight: bold; +} + diff --git a/src/freenet/clients/http/staticfiles/themes/winterfacey/theme.css b/src/freenet/clients/http/staticfiles/themes/winterfacey/theme.css index 2702b080e7b..f63b085bd1e 100644 --- a/src/freenet/clients/http/staticfiles/themes/winterfacey/theme.css +++ b/src/freenet/clients/http/staticfiles/themes/winterfacey/theme.css @@ -1482,6 +1482,16 @@ body[id*="Sone"] { } +.copy-to-clipboard-element { + user-select: none; /* do not copy this text */ + cursor: pointer; /* this is an action */ +} +.copy-to-clipboard-element:active { + color: red; + font-weight: bold; +} + + /** Media query **/ @media (max-width: 1500px) { diff --git a/src/freenet/l10n/freenet.l10n.en.properties b/src/freenet/l10n/freenet.l10n.en.properties index d00092d7c69..71f39cfd55c 100644 --- a/src/freenet/l10n/freenet.l10n.en.properties +++ b/src/freenet/l10n/freenet.l10n.en.properties @@ -1645,6 +1645,7 @@ QueueToadlet.UinProgress=Uploads in progress (${size}) QueueToadlet.cancelSelected=Cancel QueueToadlet.compatModeLabel=Compatibility mode QueueToadlet.compatibilityMode=Compatibility mode +QueueToadlet.copyToClipboardTitle=Copy to Clipboard QueueToadlet.change=Change QueueToadlet.changeDownloadPriorities=Change priority of downloads QueueToadlet.changeUploadPriorities=Change priority of uploads