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", "description": "Placeholder for the nativefier cli to override with a target url",
"main": "lib/main.js", "main": "lib/main.js",
"dependencies": { "dependencies": {
"electron-context-menu": "^0.9.1",
"electron-dl": "^1.10.0", "electron-dl": "^1.10.0",
"electron-window-state": "^4.1.1", "electron-window-state": "^4.1.1",
"loglevel": "^1.5.1", "loglevel": "^1.5.1",

View File

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

View File

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

View File

@ -25,11 +25,6 @@ function setNotificationCallback(callback) {
window.Notification = newNotify; window.Notification = newNotify;
} }
function clickSelector(element) {
const mouseEvent = new MouseEvent('click');
element.dispatchEvent(mouseEvent);
}
function injectScripts() { function injectScripts() {
const needToInject = fs.existsSync(INJECT_JS_PATH); const needToInject = fs.existsSync(INJECT_JS_PATH);
if (!needToInject) { if (!needToInject) {
@ -45,27 +40,6 @@ setNotificationCallback((title, opt) => {
}); });
document.addEventListener('DOMContentLoaded', () => { 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(); injectScripts();
}); });