diff --git a/index.html b/index.html
index bf0650f..dd00ac8 100644
--- a/index.html
+++ b/index.html
@@ -1346,12 +1346,37 @@
Get Started in Seconds
});
// ── Copy prompt from use case ──
+// Clipboard with a fallback for insecure contexts (e.g. the page opened via
+// file://), where navigator.clipboard is undefined and writeText() would throw,
+// leaving the copy buttons silently dead.
+function copyToClipboard(text) {
+ if (navigator.clipboard && window.isSecureContext) {
+ return navigator.clipboard.writeText(text);
+ }
+ return new Promise((resolve, reject) => {
+ try {
+ const ta = document.createElement('textarea');
+ ta.value = text;
+ ta.setAttribute('readonly', '');
+ ta.style.position = 'fixed';
+ ta.style.opacity = '0';
+ document.body.appendChild(ta);
+ ta.select();
+ const ok = document.execCommand('copy');
+ document.body.removeChild(ta);
+ ok ? resolve() : reject(new Error('copy command was rejected'));
+ } catch (err) {
+ reject(err);
+ }
+ });
+}
+
function copyPrompt(el) {
const hint = el.querySelector('.uc-copy-hint');
const text = el.textContent.replace(hint.textContent, '').trim();
const copiedText = (i18n['common.copied'] && i18n['common.copied'][currentLang]) || 'Copied!';
const clickText = (i18n['common.click_to_copy'] && i18n['common.click_to_copy'][currentLang]) || 'Click to copy';
- navigator.clipboard.writeText(text).then(() => {
+ copyToClipboard(text).then(() => {
el.classList.add('copied');
hint.textContent = copiedText;
setTimeout(() => { el.classList.remove('copied'); hint.textContent = clickText; }, 2000);
@@ -1372,7 +1397,7 @@ Get Started in Seconds
const cmd = block.querySelector('.cmd').textContent;
const copiedText = (i18n['common.copied'] && i18n['common.copied'][currentLang]) || 'Copied!';
const copyText = (i18n['common.copy'] && i18n['common.copy'][currentLang]) || 'Copy';
- navigator.clipboard.writeText(cmd).then(() => {
+ copyToClipboard(cmd).then(() => {
const btn = block.querySelector('.copy-btn');
btn.textContent = copiedText;
btn.classList.add('copied');