copy.ts

1.1 KB · raw

1/**2 * Popup-side copy helper.3 *4 * MV3 service workers can't reliably write the clipboard from a non-focused5 * tab — the SW path's `chrome.scripting.executeScript` into the active tab6 * loses the popup's user gesture and the page document is not focused, so7 * `navigator.clipboard.writeText` rejects with NotAllowed. The popup itself8 * is a focused document with a fresh user gesture and `clipboardWrite`9 * permission, so it can call the API directly. We then notify the SW with10 * `alreadyWritten: true` so it skips its own write and only schedules the11 * auto-clear timer.12 */1314import { sendMessage } from "./App";1516export async function popupCopy(text: string, label: string): Promise<boolean> {17  let alreadyWritten = false;18  try {19    await navigator.clipboard.writeText(text);20    alreadyWritten = true;21  } catch {22    // Some popup contexts (jsdom in tests, or rare permission-denied edge23    // cases) reject the direct write. Fall through to the SW path.24  }2526  const response = await sendMessage({27    type: "COPY",28    payload: { text, label, alreadyWritten },29  });30  return alreadyWritten || Boolean((response as { ok?: boolean })?.ok);31}