clipboard.ts

1.8 KB · raw

1import { getSettings } from "./vault";23const DEFAULT_CLEAR_SECONDS = 30;45let clipboardClearTimer: ReturnType<typeof setTimeout> | null = null;67async function writeToClipboard(text: string): Promise<void> {8  // Prefer chrome.scripting.executeScript which reliably works in MV3 service workers9  // by running in the context of the active tab page, falling back to direct write.10  try {11    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });12    if (tab?.id) {13      await chrome.scripting.executeScript({14        target: { tabId: tab.id },15        func: (value: string) => navigator.clipboard.writeText(value),16        args: [text],17      });18      return;19    }20  } catch {21    // Fall through to direct write22  }23  // Fallback: direct navigator.clipboard (may fail if service worker is backgrounded)24  await navigator.clipboard.writeText(text);25}2627export async function copyToClipboard(28  text: string,29  _label: string,30  alreadyWritten = false,31): Promise<void> {32  if (clipboardClearTimer) {33    clearTimeout(clipboardClearTimer);34    clipboardClearTimer = null;35  }36  // The popup/content caller may have already written the clipboard from a37  // focused document with a fresh user gesture — that path is more reliable38  // than the SW's `executeScript` into the active tab. When that happens, we39  // only need to schedule the auto-clear timer here.40  if (!alreadyWritten) {41    await writeToClipboard(text);42  }4344  const settingsSeconds = getSettings().clipboardClearSeconds;45  const clearAfterMs =46    (typeof settingsSeconds === "number" && settingsSeconds > 047      ? settingsSeconds48      : DEFAULT_CLEAR_SECONDS) * 1000;4950  clipboardClearTimer = setTimeout(async () => {51    try {52      await writeToClipboard("");53    } catch {}54    clipboardClearTimer = null;55  }, clearAfterMs);56}