Fix #95, #384 - Use electron-context-menu, supporting cut/copy/paste (PR #588)

The electron-context-menu package uses the context-menu event emitted by WebContents (API added in Electron 1.0.2) to add a general context menu supporting generic actions (e.g. cut/copy/paste) that can be customized. This change replaces the existing context menu, which relies on adding an event listener in preload.js, with one built using the new package.
This commit is contained in:
David Kramer 2018-04-22 16:48:56 -07:00 committed by Ronan Jouchet
parent 92bc44a712
commit ec1023d7ef
4 changed files with 24 additions and 70 deletions

View File

@ -4,6 +4,7 @@
"description": "Placeholder for the nativefier cli to override with a target url",
"main": "lib/main.js",
"dependencies": {
"electron-context-menu": "^0.9.1",
"electron-dl": "^1.10.0",
"electron-window-state": "^4.1.1",
"loglevel": "^1.5.1",

View File

@ -1,47 +1,26 @@
// Because we are changing the properties of `mainWindow` in initContextMenu()
/* eslint-disable no-param-reassign */
import { Menu, ipcMain, shell, clipboard, BrowserWindow } from 'electron';
import { shell, BrowserWindow } from 'electron';
import contextMenu from 'electron-context-menu';
function initContextMenu(mainWindow) {
ipcMain.on('contextMenuOpened', (event, targetHref) => {
const contextMenuTemplate = [
{
label: 'Open with default browser',
click: () => {
if (targetHref) {
shell.openExternal(targetHref);
}
},
},
{
label: 'Open in new window',
click: () => {
if (targetHref) {
new BrowserWindow().loadURL(targetHref);
return;
}
mainWindow.useDefaultWindowBehaviour = true;
mainWindow.webContents.send('contextMenuClosed');
},
},
{
label: 'Copy link location',
click: () => {
if (targetHref) {
clipboard.writeText(targetHref);
return;
}
mainWindow.useDefaultWindowBehaviour = true;
mainWindow.webContents.send('contextMenuClosed');
},
},
];
const contextMenu = Menu.buildFromTemplate(contextMenuTemplate);
contextMenu.popup(mainWindow);
mainWindow.contextMenuOpen = true;
function initContextMenu() {
contextMenu({
prepend: (params) => {
const items = [];
if (params.linkURL) {
items.push({
label: 'Open Link in Default Browser',
click: () => {
shell.openExternal(params.linkURL);
},
});
items.push({
label: 'Open Link in New Window',
click: () => {
new BrowserWindow().loadURL(params.linkURL);
},
});
}
return items;
},
});
}

View File

@ -162,7 +162,7 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
createMenu(menuOptions);
if (!options.disableContextMenu) {
initContextMenu(mainWindow);
initContextMenu();
}
if (options.userAgent) {

View File

@ -25,11 +25,6 @@ function setNotificationCallback(callback) {
window.Notification = newNotify;
}
function clickSelector(element) {
const mouseEvent = new MouseEvent('click');
element.dispatchEvent(mouseEvent);
}
function injectScripts() {
const needToInject = fs.existsSync(INJECT_JS_PATH);
if (!needToInject) {
@ -45,27 +40,6 @@ setNotificationCallback((title, opt) => {
});
document.addEventListener('DOMContentLoaded', () => {
window.addEventListener('contextmenu', (event) => {
event.preventDefault();
let targetElement = event.srcElement;
// the clicked element is the deepest in the DOM, and may not be the <a> bearing the href
// for example, <a href="..."><span>Google</span></a>
while (!targetElement.href && targetElement.parentElement) {
targetElement = targetElement.parentElement;
}
const targetHref = targetElement.href;
if (!targetHref) {
ipcRenderer.once('contextMenuClosed', () => {
clickSelector(event.target);
ipcRenderer.send('cancelNewWindowOverride');
});
}
ipcRenderer.send('contextMenuOpened', targetHref);
}, false);
injectScripts();
});