From 2422baec3053c333d069544969b8fda330a985dc Mon Sep 17 00:00:00 2001 From: Siddharth Kumar Sah Date: Sat, 4 Apr 2026 16:17:11 +0800 Subject: [PATCH] docs: add execCommand fallback to clipboard utility in design spec Without the fallback, every Copy button is dead on HTTP. The execCommand approach is deprecated but works in all current browsers and does not require a secure context. --- .../2026-04-04-http-compatibility-design.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/superpowers/specs/2026-04-04-http-compatibility-design.md b/docs/superpowers/specs/2026-04-04-http-compatibility-design.md index 96ba771f..064be6ca 100644 --- a/docs/superpowers/specs/2026-04-04-http-compatibility-design.md +++ b/docs/superpowers/specs/2026-04-04-http-compatibility-design.md @@ -49,12 +49,27 @@ export async function copyToClipboard(text: string): Promise { await navigator.clipboard.writeText(text); return true; } catch { - return false; + // Fallback for non-secure contexts (HTTP on LAN) + // document.execCommand is deprecated but works in all current browsers + // and does not require a secure context + try { + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.style.position = "fixed"; + textarea.style.opacity = "0"; + document.body.appendChild(textarea); + textarea.select(); + const ok = document.execCommand("copy"); + document.body.removeChild(textarea); + return ok; + } catch { + return false; + } } } ``` -Returns `true`/`false` so callers can decide whether to show a "Copied!" confirmation. On HTTP, the call fails silently and the UI does not show the confirmation. No behavior change for HTTPS/localhost users. +Tries the Clipboard API first (works on HTTPS/localhost). Falls back to `document.execCommand("copy")` which is deprecated but works in all current browsers including non-secure contexts. This is the standard clipboard compatibility pattern used by GitHub, Stack Overflow, etc. Returns `true`/`false` so callers can decide whether to show a "Copied!" confirmation. Only returns `false` if both approaches fail. **4 call sites replaced** (`navigator.clipboard.writeText()` -> `copyToClipboard()`):