Optimizer UI: copy fallback for non-secure context (#23176)

This commit is contained in:
Michael Geers 2025-08-22 18:32:39 +02:00 • committed by GitHub
parent 6949787a1a
commit e2bde30022
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 11 deletions

View file

@ -52,17 +52,54 @@ export default defineComponent({
},
methods: {
handleCopy() {
navigator.clipboard
.writeText(this.content)
.then(() => {
this.copied = true;
setTimeout(() => {
this.copied = false;
}, 2000); // Reset after 2 seconds
})
.catch((err) => {
console.error("Failed to copy to clipboard:", err);
});
// Modern browser API, requires secure context (localhost or https)
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard
.writeText(this.content)
.then(() => {
this.showCopiedFeedback();
})
.catch((err) => {
console.error("Failed to copy to clipboard:", err);
this.fallbackCopy();
});
} else {
// Fallback method for HTTP/non-secure contexts
this.fallbackCopy();
}
},
fallbackCopy() {
try {
// Create a temporary textarea element
const textarea = document.createElement("textarea");
textarea.value = this.content;
textarea.style.position = "fixed";
textarea.style.left = "-999999px";
textarea.style.top = "-999999px";
document.body.appendChild(textarea);
// Select and copy the text
textarea.focus();
textarea.select();
const successful = document.execCommand("copy");
document.body.removeChild(textarea);
if (successful) {
this.showCopiedFeedback();
} else {
alert("Copy failed. Please copy manually.");
}
} catch (err) {
console.error("Fallback copy failed:", err);
// Show user feedback that copy failed
alert("Copy failed. Please copy manually.");
}
},
showCopiedFeedback() {
this.copied = true;
setTimeout(() => {
this.copied = false;
}, 2000);
},
},
});

View file

@ -20,6 +20,14 @@ export default {
control: "boolean",
description: "Whether the sponsorship is expiring soon",
},
token: {
control: "text",
description: "Sponsor token (optional)",
},
fromYaml: {
control: "boolean",
description: "Whether the sponsor config comes from YAML",
},
},
} as Meta<typeof Sponsor>;

View file

@ -79,6 +79,7 @@ export default defineComponent({
expiresAt: String,
expiresSoon: Boolean,
fromYaml: Boolean,
token: String,
},
computed: {
isTrial() {