// Firefox stores Mac shortcuts with Command, MacCtrl, and Alt, and reads a // manifest's Ctrl as Command there (ShortcutUtils' chromeModifierKeyMap). const MAC_KEY_NAMES = { Ctrl: "Cmd", Command: "Cmd", MacCtrl: "Ctrl", Alt: "Option", Enter: "Return" }; const OTHER_KEY_NAMES = { Command: "Ctrl", MacCtrl: "Ctrl" }; // The keys of a Firefox shortcut such as "Alt+Shift+G", named for the platform. export function shortcutKeys(shortcut, os) { const names = os === "mac" ? MAC_KEY_NAMES : OTHER_KEY_NAMES; return shortcut.split("+").map((key) => names[key] ?? key); } // Writes a shortcut the way the page does: named keys in angle brackets and // single characters plain, "++G". export function formatShortcut(shortcut, os) { return shortcutKeys(shortcut, os) .map((name) => (name.length > 1 ? `<${name}>` : name)) .join("+"); } // The page's static hotkeys are written for Windows and Linux. export function renderStaticShortcuts(document, os) { for (const element of document.querySelectorAll("[data-shortcut]")) { element.textContent = formatShortcut(element.dataset.shortcut, os); } } // Firefox owns shortcut preferences; never copy them into extension storage. export async function initializeShortcut({ commands, document, window, os }) { const field = (id) => document.getElementById(id); let refreshId = 0; // One key cap per key for the drawing, joined by plain "+" text. function keycaps(shortcut) { return shortcutKeys(shortcut, os).flatMap((name, index) => { const key = document.createElement("kbd"); key.className = "drawing-key"; key.textContent = name; return index ? ["+", key] : [key]; }); } function render(shortcut) { const keys = shortcut ? formatShortcut(shortcut, os) : ""; field("shortcut-intro").hidden = !keys; field("shortcut-intro-key").textContent = keys; field("shortcut-keycaps").replaceChildren(...(keys ? keycaps(shortcut) : [])); field("shortcut-current").textContent = shortcut === null ? "Could not read the keyboard shortcut. Check Manage Extension Shortcuts in Add-ons." : keys ? `Current shortcut: ${keys}` : "No keyboard shortcut assigned."; } async function refresh() { const requestId = ++refreshId; try { const all = await commands.getAll(); const command = all.find(({ name }) => name === "ask-chatgpt"); if (requestId === refreshId) render(command?.shortcut ?? ""); } catch { if (requestId === refreshId) render(null); } } const button = field("change-shortcut"); button.hidden = typeof commands?.openShortcutSettings !== "function"; button.addEventListener("click", async () => { try { await commands.openShortcutSettings(); } catch { field("shortcut-current").textContent = "Open Add-ons, then the gear menu → Manage Extension Shortcuts to change your shortcut."; } }); commands?.onChanged?.addListener(({ name }) => { if (name === "ask-chatgpt") void refresh(); }); window.addEventListener("focus", refresh); document.addEventListener("visibilitychange", () => { if (document.visibilityState === "visible") void refresh(); }); await refresh(); }