Frontend: Copy to clipboard without HTTPS (#1222)

* Allow copy content to the clipboard even if the window.navigator.clipboard doesn't supported

* Fix typo

Co-authored-by: Alexis Lefebvre <alexislefebvre@users.noreply.github.com>

* Better 'copyToMachineClipboard' implementation

* Minor lint

* Minor lint

Co-authored-by: Alexis Lefebvre <alexislefebvre@users.noreply.github.com>
This commit is contained in:
Haim Kastner 2021-04-30 11:15:46 +03:00 committed by GitHub
parent a2cb5c928f
commit 22f0d7b5eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 6 deletions

View file

@ -145,4 +145,45 @@ export default class Util {
console.log(`${label}: ${now.getTime() - start.getTime()}ms`);
start = now;
}
static async copyToMachineClipboard(text) {
if (window.navigator.clipboard) {
await window.navigator.clipboard.writeText(text);
} else if (document.execCommand) {
// Clipboard is available only in HTTPS pages. see https://web.dev/async-clipboard/
// So if the the official 'clipboard' doesn't supported and the 'document.execCommand' is supported.
// copy by a work-around by creating a textarea in the DOM and execute copy command from him.
// Create the text area element (to copy from)
const clipboardElement = document.createElement("textarea");
// Set the text content to copy
clipboardElement.value = text;
// Avoid scrolling to bottom
clipboardElement.style.top = "0";
clipboardElement.style.left = "0";
clipboardElement.style.position = "fixed";
// Add element to DOM
document.body.appendChild(clipboardElement);
// "Select" the new textarea
clipboardElement.focus();
clipboardElement.select();
// Copy the selected textarea content
const succeed = document.execCommand('copy');
// Remove the textarea from DOM
document.body.removeChild(clipboardElement);
// Validate operation succeed
if (!succeed) {
throw new Error('Failed copying to clipboard');
}
} else {
throw new Error('Copy to clipboard does not support in your browser');
}
}
}

View file

@ -128,6 +128,7 @@
</template>
<script>
import * as options from "options/options";
import Util from "../common/util";
export default {
name: 'PShareDialog',
@ -175,9 +176,14 @@ export default {
ev.target.select();
},
copyUrl(link) {
window.navigator.clipboard.writeText(link.url())
.then(() => this.$notify.success(this.$gettext("Copied to clipboard")), () => this.$notify.error(this.$gettext("Failed copying to clipboard")));
async copyUrl(link) {
try {
const url = link.url();
await Util.copyToMachineClipboard(url);
this.$notify.success(this.$gettext("Copied to clipboard"))
} catch (error) {
this.$notify.error(this.$gettext("Failed copying to clipboard"))
}
},
expires(link) {
let result = this.$gettext('Expires');

View file

@ -49,6 +49,8 @@
</template>
<script>
import Util from "../common/util";
export default {
name: 'PDialogWebdav',
props: {
@ -79,9 +81,13 @@ export default {
this.copyUrl();
},
copyUrl() {
window.navigator.clipboard.writeText(this.webdavUrl())
.then(() => this.$notify.success(this.$gettext("Copied to clipboard")), () => this.$notify.error(this.$gettext("Failed copying to clipboard")));
async copyUrl() {
try {
await Util.copyToMachineClipboard(this.webdavUrl());
this.$notify.success(this.$gettext("Copied to clipboard"));
} catch (error) {
this.$notify.error(this.$gettext("Failed copying to clipboard"))
}
},
webdavUrl() {
return `${window.location.protocol}//admin@${window.location.host}/originals/`;