@laserware/hoverboard
Version:
Better context menus for Electron.
154 lines (152 loc) • 5.11 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/main/index.ts
var main_exports = {};
__export(main_exports, {
configureContextMenus: () => configureContextMenus
});
module.exports = __toCommonJS(main_exports);
// src/main/configureContextMenus.ts
var import_electron = require("electron");
function createCustomContextMenu(id, template) {
const contextMenu = import_electron.Menu.buildFromTemplate(template);
return Object.assign(contextMenu, { id });
}
function configureContextMenus(options) {
const contextMenus = /* @__PURE__ */ new Map();
const closeContextMenu = (menuId, window) => {
contextMenus.get(menuId)?.closePopup(window);
contextMenus.delete(menuId);
};
const handleShowContextMenu = (event, request) => {
const browserWindow = import_electron.BrowserWindow.fromWebContents(event.sender);
if (browserWindow === null) {
return;
}
const { menuId, position, template, linkURL } = request;
return new Promise((resolve) => {
closeContextMenu(menuId, browserWindow);
for (const item of walkMenuTemplate(template)) {
item.icon = getIconForMenuItem(item);
if (item.type !== "separator" && item.role === void 0) {
item.click = (menuItem, window, event2) => {
if (item.id === void 0) {
throw new Error("Clickable item must have an ID");
}
resolve({
menuId,
menuItemId: item.id,
event: event2
});
};
}
}
const zoomFactor = browserWindow.webContents.getZoomFactor();
const x = Math.floor(position.x * zoomFactor);
const y = Math.floor(position.y * zoomFactor);
if (linkURL !== void 0) {
template.push(
{ type: "separator" },
{
label: "Copy Link",
type: "normal",
click: () => {
void import_electron.clipboard.writeText(linkURL, "clipboard");
}
},
{
label: "Open Link",
type: "normal",
click: () => {
void import_electron.shell.openExternal(linkURL);
}
}
);
}
if (options.inspectElement) {
template.push(
{ type: "separator" },
{
label: "Inspect Element",
type: "normal",
click: () => {
browserWindow.webContents?.inspectElement(x, y);
}
}
);
}
const contextMenu = createCustomContextMenu(menuId, template);
contextMenus.set(menuId, contextMenu);
contextMenu.popup({
window: browserWindow,
x,
y,
callback() {
contextMenus.delete(menuId);
resolve({
menuId,
menuItemId: null,
event: {}
});
}
});
});
};
const handleHideContextMenu = (event, menuId) => {
const browserWindow = import_electron.BrowserWindow.fromWebContents(event.sender);
if (browserWindow === null) {
return;
}
closeContextMenu(menuId, browserWindow);
};
import_electron.ipcMain.handle("hoverboard/contextMenu/show" /* ForShowContextMenu */, handleShowContextMenu);
import_electron.ipcMain.handle("hoverboard/contextMenu/hide" /* ForHideContextMenu */, handleHideContextMenu);
return {
dispose() {
import_electron.ipcMain.removeHandler("hoverboard/contextMenu/show" /* ForShowContextMenu */);
import_electron.ipcMain.removeHandler("hoverboard/contextMenu/hide" /* ForHideContextMenu */);
}
};
}
function getIconForMenuItem(menuItem) {
if (typeof menuItem.icon !== "string") {
return void 0;
}
let image = import_electron.nativeImage.createFromPath(menuItem.icon);
if (image.isEmpty()) {
image = import_electron.nativeImage.createFromDataURL(menuItem.icon);
}
return image.resize({ width: 16, height: 16, quality: "best" });
}
function* walkMenuTemplate(template) {
function* recurse(items) {
for (const item of items) {
yield item;
if (Array.isArray(item.submenu)) {
yield* recurse(item.submenu);
}
}
}
yield* recurse(template);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
configureContextMenus
});
//# sourceMappingURL=main.cjs.map