From 49049b7a1ddf90ee446705aebbe4b7552a7137b0 Mon Sep 17 00:00:00 2001 From: yan Date: Mon, 21 Dec 2015 12:13:26 -0800 Subject: [PATCH 1/6] Replace webview messages with constants --- app/content/webviewPreload.js | 11 ++++++----- js/components/frame.js | 10 ++++++---- js/constants/messages.js | 10 +++++++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/content/webviewPreload.js b/app/content/webviewPreload.js index 281cf2167ba..1fd402b6306 100644 --- a/app/content/webviewPreload.js +++ b/app/content/webviewPreload.js @@ -4,26 +4,27 @@ var webFrame = require('electron').webFrame var ipc = require('electron').ipcRenderer +var messages = require('../../js/constants/messages') var browserZoomLevel = 0 var browserMaxZoom = 9 var browserMinZoom = -8 -ipc.on('zoom-in', function () { +ipc.on(messages.ZOOM_IN, function () { if (browserMaxZoom > browserZoomLevel) { browserZoomLevel += 1 } webFrame.setZoomLevel(browserZoomLevel) }) -ipc.on('zoom-out', function () { +ipc.on(messages.ZOOM_OUT, function () { if (browserMinZoom < browserZoomLevel) { browserZoomLevel -= 1 } webFrame.setZoomLevel(browserZoomLevel) }) -ipc.on('zoom-reset', function () { +ipc.on(messages.ZOOM_RESET, function () { browserZoomLevel = 0 webFrame.setZoomLevel(browserZoomLevel) }) @@ -130,7 +131,7 @@ function processAdNode (node, iframeData, replacementUrl) { } // Fires when the browser has ad replacement information to give -ipc.on('set-ad-div-candidates', function (e, adDivCandidates, placeholderUrl) { +ipc.on(messages.SET_AD_DIV_CANDIDATES, function (e, adDivCandidates, placeholderUrl) { // Keep a lookup for skipped common elements var fallbackNodeDataForCommon = {} @@ -171,6 +172,6 @@ ipc.on('set-ad-div-candidates', function (e, adDivCandidates, placeholderUrl) { }) document.addEventListener('contextmenu', (e) => { - ipc.send('context-menu-opened', e.target.nodeName) + ipc.send(messages.CONTEXT_MENU_OPENED, e.target.nodeName) e.preventDefault() }, false) diff --git a/js/components/frame.js b/js/components/frame.js index b099dc522dc..e67a3fa854f 100644 --- a/js/components/frame.js +++ b/js/components/frame.js @@ -8,6 +8,7 @@ const WindowActions = require('../actions/windowActions') const ImmutableComponent = require('./immutableComponent') const cx = require('../lib/classSet.js') const UrlUtil = require('./../../node_modules/urlutil.js/dist/node-urlutil.js') +const messages = require('../constants/messages.js') import adInfo from '../data/adInfo.js' import Config from '../constants/config.js' @@ -38,13 +39,13 @@ class Frame extends ImmutableComponent { this.webview.reloadIgnoringCache() break case 'zoom-in': - this.webview.send('zoom-in') + this.webview.send(messages.ZOOM_IN) break case 'zoom-out': - this.webview.send('zoom-out') + this.webview.send(messages.ZOOM_OUT) break case 'zoom-reset': - this.webview.send('zoom-reset') + this.webview.send(messages.ZOOM_RESET) break case 'toggle-dev-tools': if (this.webview.isDevToolsOpened()) { @@ -128,7 +129,8 @@ class Frame extends ImmutableComponent { let host = new window.URL(currentLocation).hostname.replace('www.', '') let adDivCandidates = adInfo[host] if (adDivCandidates) { - this.webview.send('set-ad-div-candidates', adDivCandidates, Config.vault.replacementUrl) + this.webview.send(messages.SET_AD_DIV_CANDIDATES, + adDivCandidates, Config.vault.replacementUrl) } } diff --git a/js/constants/messages.js b/js/constants/messages.js index 37d446778ac..2c8b8aa67c0 100644 --- a/js/constants/messages.js +++ b/js/constants/messages.js @@ -30,14 +30,18 @@ const messages = { // Window management CLOSE_WINDOW: _, NEW_WINDOW: _, - // Misc - CONTEXT_MENU_OPENED: _, /** @arg {string} nodeName of node being clicked */ QUIT_APPLICATION: _, // Updates UPDATE_REQUESTED: _, UPDATE_AVAILABLE: _, UPDATE_NOT_AVAILABLE: _, - CHECK_FOR_UPDATE: _ + CHECK_FOR_UPDATE: _, + // Webview page messages + ZOOM_IN: _, + ZOOM_OUT: _, + ZOOM_RESET: _, + SET_AD_DIV_CANDIDATES: _, /** @arg {Array} adDivCandidates, @arg {string} placeholderUrl */ + CONTEXT_MENU_OPENED: _ /** @arg {string} nodeName of node being clicked */ } module.exports = mapValuesByKeys(messages) From 30b78b01b14a53dc8e933f7b0e1539c83dfb4edb Mon Sep 17 00:00:00 2001 From: yan Date: Mon, 21 Dec 2015 12:48:40 -0800 Subject: [PATCH 2/6] Add sendToFocusedWindow helper method --- app/localShortcuts.js | 1 - app/menu.js | 70 ++++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/app/localShortcuts.js b/app/localShortcuts.js index 4d2df615978..06a70885c73 100644 --- a/app/localShortcuts.js +++ b/app/localShortcuts.js @@ -13,7 +13,6 @@ module.exports.register = (win) => { // the URL bar. In those cases it's acceptable for the individual components to // listen to the events. const simpleWebContentEvents = [ - ['CmdOrCtrl+L', messages.SHORTCUT_FOCUS_URL], ['Ctrl+Tab', messages.SHORTCUT_NEXT_TAB], ['Ctrl+Shift+Tab', messages.SHORTCUT_PREV_TAB], ['CmdOrCtrl+Shift+]', messages.SHORTCUT_NEXT_TAB], diff --git a/app/menu.js b/app/menu.js index c064bca689d..84eba2ac062 100644 --- a/app/menu.js +++ b/app/menu.js @@ -7,6 +7,21 @@ const app = electron.app const Menu = require('menu') const messages = require('../js/constants/messages') +/** + * Sends a message to the web contents of the focused window. + * @param {Object} focusedWindow the focusedWindow if any + * @param {Array} message message and arguments to send + * @return {boolean} whether the message was sent + */ +const sendToFocusedWindow = (focusedWindow, message) => { + if (focusedWindow) { + focusedWindow.webContents.send.apply(focusedWindow.webContents, message) + return true + } else { + return false + } +} + const init = () => { var template = [ { @@ -22,9 +37,7 @@ const init = () => { label: 'New Tab', accelerator: 'CmdOrCtrl+T', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_NEW_FRAME) - } else { + if (!sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_NEW_FRAME])) { // no active windows process.emit(messages.NEW_WINDOW) } @@ -33,7 +46,7 @@ const init = () => { label: 'New Private Tab', accelerator: 'CmdOrCtrl+Alt+T', click: function (item, focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_NEW_FRAME) + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_NEW_FRAME]) } }, { label: 'New Window', @@ -50,7 +63,10 @@ const init = () => { accelerator: 'CmdOrCtrl+O' }, { label: 'Open Location...', - accelerator: 'CmdOrCtrl+L' + accelerator: 'CmdOrCtrl+L', + click: function (item, focusedWindow) { + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_FOCUS_URL]) + } }, { type: 'separator' }, { @@ -68,9 +84,7 @@ const init = () => { label: 'Close Tab', accelerator: 'CmdOrCtrl+W', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_CLOSE_FRAME) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_CLOSE_FRAME]) } }, { // this should be disabled when @@ -164,25 +178,19 @@ const init = () => { label: 'Actual Size', accelerator: 'CmdOrCtrl+0', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_ACTIVE_FRAME_ZOOM_RESET) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_ZOOM_RESET]) } }, { label: 'Zoom In', accelerator: 'CmdOrCtrl+=', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_ACTIVE_FRAME_ZOOM_IN) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_ZOOM_IN]) } }, { label: 'Zoom Out', accelerator: 'CmdOrCtrl+-', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_ACTIVE_FRAME_ZOOM_OUT) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_ZOOM_OUT]) } }, { type: 'separator' @@ -200,17 +208,13 @@ const init = () => { label: 'Reload Page', accelerator: 'CmdOrCtrl+R', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_ACTIVE_FRAME_RELOAD) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_RELOAD]) } }, { label: 'Clean Reload', accelerator: 'CmdOrCtrl+Shift+R', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_ACTIVE_FRAME_CLEAN_RELOAD) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_CLEAN_RELOAD]) } }, { type: 'separator' @@ -238,9 +242,7 @@ const init = () => { label: 'Toggle Developer Tools', accelerator: 'CmdOrCtrl+Alt+I', click: function (item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_ACTIVE_FRAME_TOGGLE_DEV_TOOLS) - } + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_TOGGLE_DEV_TOOLS]) } }, { label: 'Toggle Browser Console', @@ -418,22 +420,22 @@ const init = () => { { label: 'Brave Help', click: function (item, focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_NEW_FRAME, - 'https://brave.com') + sendToFocusedWindow(focusedWindow, + [messages.SHORTCUT_NEW_FRAME, 'https://brave.com/']) } }, { type: 'separator' }, { label: 'Submit Feedback...', click: function (item, focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_NEW_FRAME, - 'https://brave.com') + sendToFocusedWindow(focusedWindow, + [messages.SHORTCUT_NEW_FRAME, 'https://brave.com/']) } }, { label: 'Spread the word about Brave...', click: function (item, focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_NEW_FRAME, - 'https://brave.com') + sendToFocusedWindow(focusedWindow, + [messages.SHORTCUT_NEW_FRAME, 'https://brave.com/']) } } ] @@ -458,8 +460,8 @@ const init = () => { }, { label: 'Send us Feedback...', click: function (item, focusedWindow) { - focusedWindow.webContents.send(messages.SHORTCUT_NEW_FRAME, - 'https://brave.com') + sendToFocusedWindow(focusedWindow, + [messages.SHORTCUT_NEW_FRAME, 'https://brave.com/']) } }, { type: 'separator' From 0984b2b618e95b4acaf3473618620b510cb13e5a Mon Sep 17 00:00:00 2001 From: yan Date: Mon, 21 Dec 2015 13:07:54 -0800 Subject: [PATCH 3/6] Autoselect URL on cmd-L --- js/components/urlBar.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/components/urlBar.js b/js/components/urlBar.js index 89a71542a87..d3c417177dd 100644 --- a/js/components/urlBar.js +++ b/js/components/urlBar.js @@ -145,7 +145,10 @@ class UrlBar extends ImmutableComponent { } componentWillMount () { - ipc.on(messages.SHORTCUT_FOCUS_URL, this.onFocus.bind(this)) + ipc.on(messages.SHORTCUT_FOCUS_URL, () => { + this.onFocus.bind(this) + AppActions.setUrlBarAutoselected(true) + }) // escape key handling ipc.on(messages.SHORTCUT_ACTIVE_FRAME_STOP, this.onActiveFrameStop.bind(this)) } From 22516c70ebfd1d3948c6a0dac496c45e48f41a3f Mon Sep 17 00:00:00 2001 From: yan Date: Mon, 21 Dec 2015 15:54:16 -0800 Subject: [PATCH 4/6] Add open, save, and print shortcuts --- app/content/webviewPreload.js | 4 ++++ app/menu.js | 24 +++++++++++++++++++++--- js/components/frame.js | 8 ++++++++ js/constants/messages.js | 3 +++ js/stores/windowStore.js | 2 +- 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/content/webviewPreload.js b/app/content/webviewPreload.js index 1fd402b6306..daa544cd375 100644 --- a/app/content/webviewPreload.js +++ b/app/content/webviewPreload.js @@ -29,6 +29,10 @@ ipc.on(messages.ZOOM_RESET, function () { webFrame.setZoomLevel(browserZoomLevel) }) +ipc.on(messages.PRINT_PAGE, function () { + window.print() +}) + /** * Ensures a node replacement div is visible and has a proper zIndex */ diff --git a/app/menu.js b/app/menu.js index 84eba2ac062..ad1e672f5be 100644 --- a/app/menu.js +++ b/app/menu.js @@ -6,6 +6,7 @@ const electron = require('electron') const app = electron.app const Menu = require('menu') const messages = require('../js/constants/messages') +const dialog = electron.dialog /** * Sends a message to the web contents of the focused window. @@ -60,7 +61,18 @@ const init = () => { type: 'separator' }, { label: 'Open File...', - accelerator: 'CmdOrCtrl+O' + accelerator: 'CmdOrCtrl+O', + click: (item, focusedWindow) => { + dialog.showOpenDialog(focusedWindow, { + properties: ['openFile', 'multiSelections'] + }, function (paths) { + if (paths) { + paths.forEach((path) => { + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_NEW_FRAME, path]) + }) + } + }) + } }, { label: 'Open Location...', accelerator: 'CmdOrCtrl+L', @@ -100,7 +112,10 @@ const init = () => { type: 'separator' }, { label: 'Save Page As...', - accelerator: 'CmdOrCtrl+S' + accelerator: 'CmdOrCtrl+S', + click: function (item, focusedWindow) { + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_SAVE]) + } }, { label: 'Share...', submenu: [ @@ -114,7 +129,10 @@ const init = () => { type: 'separator' }, { label: 'Print...', - accelerator: 'CmdOrCtrl+P' + accelerator: 'CmdOrCtrl+P', + click: function (item, focusedWindow) { + sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_ACTIVE_FRAME_PRINT]) + } } ] }, { diff --git a/js/components/frame.js b/js/components/frame.js index e67a3fa854f..d2f911262a0 100644 --- a/js/components/frame.js +++ b/js/components/frame.js @@ -9,6 +9,7 @@ const ImmutableComponent = require('./immutableComponent') const cx = require('../lib/classSet.js') const UrlUtil = require('./../../node_modules/urlutil.js/dist/node-urlutil.js') const messages = require('../constants/messages.js') +const remote = global.require('electron').remote import adInfo from '../data/adInfo.js' import Config from '../constants/config.js' @@ -59,6 +60,13 @@ class Frame extends ImmutableComponent { WindowActions.loadUrl(src) // TODO: Make the URL bar show the view-source: prefix break + case 'save': + // TODO: Sometimes this tries to save in a non-existent directory + remote.getCurrentWebContents().downloadURL(this.webview.getURL()) + break + case 'print': + this.webview.send(messages.PRINT_PAGE) + break } if (activeShortcut) { WindowActions.setActiveFrameShortcut(null) diff --git a/js/constants/messages.js b/js/constants/messages.js index 2c8b8aa67c0..eff636f25f3 100644 --- a/js/constants/messages.js +++ b/js/constants/messages.js @@ -19,6 +19,8 @@ const messages = { SHORTCUT_SET_ACTIVE_FRAME_BY_INDEX: _, /** @arg {number} index of frame */ SHORTCUT_ACTIVE_FRAME_VIEW_SOURCE: _, SHORTCUT_SET_ACTIVE_FRAME_TO_LAST: _, + SHORTCUT_ACTIVE_FRAME_SAVE: _, + SHORTCUT_ACTIVE_FRAME_PRINT: _, // Frame management shortcuts SHORTCUT_NEW_FRAME: _, /** @arg {string} opt_url to load if any */ SHORTCUT_CLOSE_FRAME: _, /** @arg {number} opt_key of frame, defaults to active frame */ @@ -40,6 +42,7 @@ const messages = { ZOOM_IN: _, ZOOM_OUT: _, ZOOM_RESET: _, + PRINT_PAGE: _, SET_AD_DIV_CANDIDATES: _, /** @arg {Array} adDivCandidates, @arg {string} placeholderUrl */ CONTEXT_MENU_OPENED: _ /** @arg {string} nodeName of node being clicked */ } diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js index afe83a42d36..54a681d9913 100644 --- a/js/stores/windowStore.js +++ b/js/stores/windowStore.js @@ -300,7 +300,7 @@ ipc.on(messages.SHORTCUT_PREV_TAB, () => { windowStore.emitChange() }) -const frameShortcuts = ['stop', 'reload', 'zoom-in', 'zoom-out', 'zoom-reset', 'toggle-dev-tools', 'clean-reload', 'view-source', 'mute'] +const frameShortcuts = ['stop', 'reload', 'zoom-in', 'zoom-out', 'zoom-reset', 'toggle-dev-tools', 'clean-reload', 'view-source', 'mute', 'save', 'print'] frameShortcuts.forEach(shortcut => { // Listen for actions on the active frame ipc.on(`shortcut-active-frame-${shortcut}`, () => { From 7fefbd276009920d59a5410c2f2889aba326ec7e Mon Sep 17 00:00:00 2001 From: yan Date: Tue, 22 Dec 2015 13:24:05 -0800 Subject: [PATCH 5/6] s/AppActions/WindowActions from bad merging --- js/components/urlBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/components/urlBar.js b/js/components/urlBar.js index d3c417177dd..0b014d77728 100644 --- a/js/components/urlBar.js +++ b/js/components/urlBar.js @@ -147,7 +147,7 @@ class UrlBar extends ImmutableComponent { componentWillMount () { ipc.on(messages.SHORTCUT_FOCUS_URL, () => { this.onFocus.bind(this) - AppActions.setUrlBarAutoselected(true) + WindowActions.setUrlBarAutoselected(true) }) // escape key handling ipc.on(messages.SHORTCUT_ACTIVE_FRAME_STOP, this.onActiveFrameStop.bind(this)) From 569b2683055bc9c9d93a4f47a199ea00a35d77f0 Mon Sep 17 00:00:00 2001 From: yan Date: Tue, 22 Dec 2015 14:38:02 -0800 Subject: [PATCH 6/6] Actually call onFocus on URL focus shortcut --- js/components/urlBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/components/urlBar.js b/js/components/urlBar.js index 0b014d77728..3bf3165708a 100644 --- a/js/components/urlBar.js +++ b/js/components/urlBar.js @@ -146,7 +146,7 @@ class UrlBar extends ImmutableComponent { componentWillMount () { ipc.on(messages.SHORTCUT_FOCUS_URL, () => { - this.onFocus.bind(this) + this.onFocus() WindowActions.setUrlBarAutoselected(true) }) // escape key handling