import { getSettings } from "./vault"; const DEFAULT_CLEAR_SECONDS = 30; let clipboardClearTimer: ReturnType | null = null; async function writeToClipboard(text: string): Promise { // Prefer chrome.scripting.executeScript which reliably works in MV3 service workers // by running in the context of the active tab page, falling back to direct write. try { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (tab?.id) { await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: (value: string) => navigator.clipboard.writeText(value), args: [text], }); return; } } catch { // Fall through to direct write } // Fallback: direct navigator.clipboard (may fail if service worker is backgrounded) await navigator.clipboard.writeText(text); } export async function copyToClipboard( text: string, _label: string, alreadyWritten = false, ): Promise { if (clipboardClearTimer) { clearTimeout(clipboardClearTimer); clipboardClearTimer = null; } // The popup/content caller may have already written the clipboard from a // focused document with a fresh user gesture — that path is more reliable // than the SW's `executeScript` into the active tab. When that happens, we // only need to schedule the auto-clear timer here. if (!alreadyWritten) { await writeToClipboard(text); } const settingsSeconds = getSettings().clipboardClearSeconds; const clearAfterMs = (typeof settingsSeconds === "number" && settingsSeconds > 0 ? settingsSeconds : DEFAULT_CLEAR_SECONDS) * 1000; clipboardClearTimer = setTimeout(async () => { try { await writeToClipboard(""); } catch {} clipboardClearTimer = null; }, clearAfterMs); }