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`); console.log(`${label}: ${now.getTime() - start.getTime()}ms`);
start = now; 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> </template>
<script> <script>
import * as options from "options/options"; import * as options from "options/options";
import Util from "../common/util";
export default { export default {
name: 'PShareDialog', name: 'PShareDialog',
@ -175,9 +176,14 @@ export default {
ev.target.select(); ev.target.select();
}, },
copyUrl(link) { async copyUrl(link) {
window.navigator.clipboard.writeText(link.url()) try {
.then(() => this.$notify.success(this.$gettext("Copied to clipboard")), () => this.$notify.error(this.$gettext("Failed copying to clipboard"))); 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) { expires(link) {
let result = this.$gettext('Expires'); let result = this.$gettext('Expires');

View file

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