mirror of https://github.com/vector-im/riot-web
split webContents context handling into own file, as main was growing
add handlers for editable fields, with Cut Copy Paste Undo Redo etc add Copy Image feature to all images, working on not only the download buttons now Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/4021/head
parent
7d59742a22
commit
c4c78c9b3e
|
@ -24,11 +24,11 @@ const check_squirrel_hooks = require('./squirrelhooks');
|
||||||
if (check_squirrel_hooks()) return;
|
if (check_squirrel_hooks()) return;
|
||||||
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
const tray = require('./tray');
|
const tray = require('./tray');
|
||||||
|
|
||||||
const VectorMenu = require('./vectormenu');
|
const VectorMenu = require('./vectormenu');
|
||||||
|
const webContentsHandler = require('./webcontents-handler');
|
||||||
|
|
||||||
const windowStateKeeper = require('electron-window-state');
|
const windowStateKeeper = require('electron-window-state');
|
||||||
|
|
||||||
|
@ -42,60 +42,12 @@ try {
|
||||||
// Continue with the defaults (ie. an empty config)
|
// Continue with the defaults (ie. an empty config)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PERMITTED_URL_SCHEMES = [
|
|
||||||
'http:',
|
|
||||||
'https:',
|
|
||||||
'mailto:',
|
|
||||||
];
|
|
||||||
|
|
||||||
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
|
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
|
||||||
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
|
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
|
||||||
|
|
||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
let appQuitting = false;
|
let appQuitting = false;
|
||||||
|
|
||||||
function safeOpenURL(target) {
|
|
||||||
// openExternal passes the target to open/start/xdg-open,
|
|
||||||
// so put fairly stringent limits on what can be opened
|
|
||||||
// (for instance, open /bin/sh does indeed open a terminal
|
|
||||||
// with a shell, albeit with no arguments)
|
|
||||||
const parsed_url = url.parse(target);
|
|
||||||
if (PERMITTED_URL_SCHEMES.indexOf(parsed_url.protocol) > -1) {
|
|
||||||
// explicitly use the URL re-assembled by the url library,
|
|
||||||
// so we know the url parser has understood all the parts
|
|
||||||
// of the input string
|
|
||||||
const new_target = url.format(parsed_url);
|
|
||||||
electron.shell.openExternal(new_target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWindowOrNavigate(ev, target) {
|
|
||||||
// always prevent the default: if something goes wrong,
|
|
||||||
// we don't want to end up opening it in the electron
|
|
||||||
// app, as we could end up opening any sort of random
|
|
||||||
// url in a window that has node scripting access.
|
|
||||||
ev.preventDefault();
|
|
||||||
safeOpenURL(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLinkContextMenu(ev, params) {
|
|
||||||
const popup_menu = new electron.Menu();
|
|
||||||
popup_menu.append(new electron.MenuItem({
|
|
||||||
label: params.linkURL,
|
|
||||||
click() {
|
|
||||||
safeOpenURL(params.linkURL);
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
popup_menu.append(new electron.MenuItem({
|
|
||||||
label: 'Copy Link Address',
|
|
||||||
click() {
|
|
||||||
electron.clipboard.writeText(params.linkURL);
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
popup_menu.popup();
|
|
||||||
ev.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
function installUpdate() {
|
function installUpdate() {
|
||||||
// for some reason, quitAndInstall does not fire the
|
// for some reason, quitAndInstall does not fire the
|
||||||
// before-quit event, so we need to set the flag here.
|
// before-quit event, so we need to set the flag here.
|
||||||
|
@ -259,15 +211,7 @@ electron.app.on('ready', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mainWindow.webContents.on('new-window', onWindowOrNavigate);
|
webContentsHandler(mainWindow.webContents);
|
||||||
mainWindow.webContents.on('will-navigate', onWindowOrNavigate);
|
|
||||||
|
|
||||||
mainWindow.webContents.on('context-menu', function(ev, params) {
|
|
||||||
if (params.linkURL) {
|
|
||||||
onLinkContextMenu(ev, params);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindowState.manage(mainWindow);
|
mainWindowState.manage(mainWindow);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
const {clipboard, nativeImage, Menu, MenuItem, shell} = require('electron');
|
||||||
|
const url = require('url');
|
||||||
|
|
||||||
|
let webContents;
|
||||||
|
|
||||||
|
const PERMITTED_URL_SCHEMES = [
|
||||||
|
'http:',
|
||||||
|
'https:',
|
||||||
|
'mailto:',
|
||||||
|
];
|
||||||
|
|
||||||
|
function safeOpenURL(target) {
|
||||||
|
// openExternal passes the target to open/start/xdg-open,
|
||||||
|
// so put fairly stringent limits on what can be opened
|
||||||
|
// (for instance, open /bin/sh does indeed open a terminal
|
||||||
|
// with a shell, albeit with no arguments)
|
||||||
|
const parsedUrl = url.parse(target);
|
||||||
|
if (PERMITTED_URL_SCHEMES.indexOf(parsedUrl.protocol) > -1) {
|
||||||
|
// explicitly use the URL re-assembled by the url library,
|
||||||
|
// so we know the url parser has understood all the parts
|
||||||
|
// of the input string
|
||||||
|
const newTarget = url.format(parsedUrl);
|
||||||
|
shell.openExternal(newTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowOrNavigate(ev, target) {
|
||||||
|
// always prevent the default: if something goes wrong,
|
||||||
|
// we don't want to end up opening it in the electron
|
||||||
|
// app, as we could end up opening any sort of random
|
||||||
|
// url in a window that has node scripting access.
|
||||||
|
ev.preventDefault();
|
||||||
|
safeOpenURL(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onLinkContextMenu(ev, params) {
|
||||||
|
const url = params.linkURL || params.srcURL;
|
||||||
|
|
||||||
|
const popupMenu = new Menu();
|
||||||
|
popupMenu.append(new MenuItem({
|
||||||
|
label: url,
|
||||||
|
click() {
|
||||||
|
safeOpenURL(url);
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
|
||||||
|
popupMenu.append(new MenuItem({
|
||||||
|
label: 'Copy Image',
|
||||||
|
click() {
|
||||||
|
if (url.startsWith('data:')) {
|
||||||
|
clipboard.writeImage(nativeImage.createFromDataURL(url));
|
||||||
|
} else {
|
||||||
|
ev.sender.copyImageAt(params.x, params.y);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
popupMenu.append(new MenuItem({
|
||||||
|
label: 'Copy Link Address',
|
||||||
|
click() {
|
||||||
|
clipboard.writeText(url);
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
popupMenu.popup();
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _CutCopyPasteSelectContextMenus(params) {
|
||||||
|
return [{
|
||||||
|
role: 'cut',
|
||||||
|
enabled: params.editFlags.canCut,
|
||||||
|
}, {
|
||||||
|
role: 'copy',
|
||||||
|
enabled: params.editFlags.canCopy,
|
||||||
|
}, {
|
||||||
|
role: 'paste',
|
||||||
|
enabled: params.editFlags.canPaste,
|
||||||
|
}, {
|
||||||
|
role: 'pasteandmatchstyle',
|
||||||
|
enabled: params.editFlags.canPaste,
|
||||||
|
}, {
|
||||||
|
role: 'selectall',
|
||||||
|
enabled: params.editFlags.canSelectAll,
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSelectedContextMenu(ev, params) {
|
||||||
|
const items = _CutCopyPasteSelectContextMenus(params);
|
||||||
|
const popupMenu = Menu.buildFromTemplate(items);
|
||||||
|
|
||||||
|
popupMenu.popup();
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEditableContextMenu(ev, params) {
|
||||||
|
const items = [
|
||||||
|
{ role: 'undo' },
|
||||||
|
{ role: 'redo', enabled: params.editFlags.canRedo },
|
||||||
|
{ type: 'separator' },
|
||||||
|
].concat(_CutCopyPasteSelectContextMenus(params));
|
||||||
|
|
||||||
|
const popupMenu = Menu.buildFromTemplate(items);
|
||||||
|
|
||||||
|
popupMenu.popup();
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = (_webContents) => {
|
||||||
|
webContents = _webContents;
|
||||||
|
|
||||||
|
webContents.on('new-window', onWindowOrNavigate);
|
||||||
|
webContents.on('will-navigate', onWindowOrNavigate);
|
||||||
|
|
||||||
|
webContents.on('context-menu', function(ev, params) {
|
||||||
|
if (params.linkURL || params.srcURL) {
|
||||||
|
onLinkContextMenu(ev, params);
|
||||||
|
} else if (params.selectionText) {
|
||||||
|
onSelectedContextMenu(ev, params);
|
||||||
|
} else if (params.isEditable) {
|
||||||
|
onEditableContextMenu(ev, params);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue