import browser from "webextension-polyfill"; import { createItem, setBadgeText, openNextItemOrOptionsPage, } from "../item/item.js"; /** * Get properties for all the context menu entries. * * @returns The context menu entries. */ export function getContextMenus(): browser.Menus.CreateCreatePropertiesType[] { // In Manifest V2 the WebExtension icon is referred to as the // "browser action", in MV3 it's just "action". const actionContext: browser.Menus.ContextType = $browser === "firefox" ? "browser_action" : "action"; const contextMenus: ReturnType = [ { id: "queue-add-new-link", title: "Add to Queue", contexts: ["link"], }, { id: "queue-open-next-link-in-new-tab", title: "Open next link in new tab", contexts: [actionContext], }, { id: "queue-open-options-page", title: "Open the extension page", contexts: [actionContext], }, ]; // Only Firefox supports context menu entries for tabs. if ($browser === "firefox") { contextMenus.push({ id: "queue-add-new-link-tab", title: "Add to Queue", contexts: ["tab"], }); } return contextMenus; } /** * Initialize all the context menu entries. */ export async function initializeContextMenus(): Promise { const contextMenus = getContextMenus(); await browser.contextMenus.removeAll(); for (const contextMenu of contextMenus) { browser.contextMenus.create(contextMenu, contextCreatedHandler); } } /** * Event handler for context menu creation. */ function contextCreatedHandler(): void { const error = browser.runtime.lastError; if (error !== null && error !== undefined) { console.error("Queue", error.message); } } /** * Event handler for context menu clicks. * * @param contextMenuIds A set of all our context menu IDs. * @param info The context menu click data. * @param tab The browser tab, if available. */ export async function contextClicked( contextMenuIds: Set, info: browser.Menus.OnClickData, tab?: browser.Tabs.Tab, ): Promise { // Only handle context menus that we know the ID of. const id = info.menuItemId.toString(); if (!contextMenuIds.has(id)) { return; } if (id.startsWith("queue-add-new-link")) { let text: string | undefined; let url: string | undefined; if (id === "queue-add-new-link") { text = info.linkText; url = info.linkUrl; } else if (id === "queue-add-new-link-tab") { text = tab?.title; url = info.pageUrl; } else { console.warn(`Encountered unknown context menu ID: ${id}`); return; } if (url === undefined) { console.warn("Cannot add a new item without a URL."); return; } const item = await createItem(text, url); await item.save(); await setBadgeText(); } else if (id === "queue-open-next-link-in-new-tab") { await openNextItemOrOptionsPage(true); } else if (id === "queue-open-options-page") { await browser.runtime.openOptionsPage(); } }