118 lines
3.0 KiB
TypeScript
118 lines
3.0 KiB
TypeScript
|
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<typeof getContextMenus> = [
|
||
|
{
|
||
|
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<void> {
|
||
|
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<string>,
|
||
|
info: browser.Menus.OnClickData,
|
||
|
tab?: browser.Tabs.Tab,
|
||
|
): Promise<void> {
|
||
|
// 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();
|
||
|
}
|
||
|
}
|