From c73844c961af91bc7e4ce2ea01d50f5b8ffbee79 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Thu, 3 Nov 2016 23:53:05 -0400 Subject: [PATCH] Fix opening URLs and files on Windows Fix #5352 Fix #4795 I stll need to add some automated tests for this section of code but it was also not in testing before. Test Plan: - On each OS test opening .html files both whent he browser is started and not started. - Type a mailto: link and http: link in Slack and click them both when the browser is started and not started. - Try setting Brave as the mailto handler and not. Auditors: @aekeus --- app/cmdLine.js | 59 +++++++++++++++++++++++++-------------------- app/index.js | 6 ++--- app/sessionStore.js | 11 +++++++++ 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/app/cmdLine.js b/app/cmdLine.js index 57232b82031..25249f22d6d 100644 --- a/app/cmdLine.js +++ b/app/cmdLine.js @@ -11,9 +11,13 @@ const messages = require('../js/constants/messages') const BrowserWindow = electron.BrowserWindow const appActions = require('../js/actions/appActions') const urlParse = require('url').parse -const {navigatableTypes} = require('../js/lib/appUrlUtil') +const {fileUrl} = require('../js/lib/appUrlUtil') +const sessionStore = require('./sessionStore') const isDarwin = process.platform === 'darwin' +const fs = require('fs') +const path = require('path') let appInitialized = false +let newWindowURL const focusOrOpenWindow = function (url) { // don't try to do anything if the app hasn't been initialized @@ -43,43 +47,34 @@ const focusOrOpenWindow = function (url) { return true } -const isProtocolHandled = (protocol) => { - protocol = (protocol || '').split(':')[0] - return navigatableTypes.includes(`${protocol}:`) || - electron.session.defaultSession.protocol.isNavigatorProtocolHandled(protocol) -} - // Checks an array of arguments if it can find a url const getUrlFromCommandLine = (argv) => { if (argv) { if (argv.length === 2 && !argv[1].startsWith('-')) { const parsedUrl = urlParse(argv[1]) - if (isProtocolHandled(parsedUrl.protocol)) { + if (sessionStore.isProtocolHandled(parsedUrl.protocol)) { return argv[1] } + const filePath = path.resolve(argv[1]) + if (fs.existsSync(filePath)) { + return fileUrl(filePath) + } } const index = argv.indexOf('--') if (index !== -1 && index + 1 < argv.length && !argv[index + 1].startsWith('-')) { const parsedUrl = urlParse(argv[index + 1]) - if (isProtocolHandled(parsedUrl.protocol)) { + if (sessionStore.isProtocolHandled(parsedUrl.protocol)) { return argv[index + 1] } + const filePath = path.resolve(argv[index + 1]) + if (fs.existsSync(filePath)) { + return fileUrl(filePath) + } } } return undefined } -// For macOS, there are events like open-url instead -if (!isDarwin) { - const openUrl = getUrlFromCommandLine(process.argv) - if (openUrl) { - const parsedUrl = urlParse(openUrl) - if (isProtocolHandled(parsedUrl.protocol)) { - module.exports.newWindowURL = openUrl - } - } -} - app.on('ready', () => { if (process.env.NODE_ENV !== 'development' && process.env.NODE_ENV !== 'test') { const appAlreadyStartedShouldQuit = app.makeSingleInstance((argv, workingDirectory) => { @@ -106,10 +101,12 @@ app.on('will-finish-launching', () => { // open -a Brave http://www.brave.com app.on('open-url', (event, path) => { event.preventDefault() - const parsedUrl = urlParse(path) - if (isProtocolHandled(parsedUrl.protocol)) { - if (!focusOrOpenWindow(path)) { - module.exports.newWindowURL = path + if (!appInitialized) { + newWindowURL = path + } else { + const parsedUrl = urlParse(path) + if (sessionStore.isProtocolHandled(parsedUrl.protocol)) { + focusOrOpenWindow(path) } } }) @@ -117,11 +114,21 @@ app.on('will-finish-launching', () => { // User clicked on a file or dragged a file to the dock on macOS app.on('open-file', (event, path) => { event.preventDefault() - if (!focusOrOpenWindow(path)) { - module.exports.newWindowURL = path + newWindowURL = path } }) }) process.on(messages.APP_INITIALIZED, () => { appInitialized = true }) + +module.exports.newWindowURL = () => { + const openUrl = newWindowURL || getUrlFromCommandLine(process.argv) + if (openUrl) { + const parsedUrl = urlParse(openUrl) + if (sessionStore.isProtocolHandled(parsedUrl.protocol)) { + newWindowURL = openUrl + } + } + return newWindowURL +} diff --git a/app/index.js b/app/index.js index cd851ce369e..919b3a7c4fe 100644 --- a/app/index.js +++ b/app/index.js @@ -434,7 +434,7 @@ app.on('ready', () => { AdInsertion.init() if (!loadedPerWindowState || loadedPerWindowState.length === 0) { - if (!CmdLine.newWindowURL) { + if (!CmdLine.newWindowURL()) { appActions.newWindow() } } else { @@ -457,9 +457,9 @@ app.on('ready', () => { appActions.changeSetting(settings.IS_DEFAULT_BROWSER, isDefaultBrowser) } - if (CmdLine.newWindowURL) { + if (CmdLine.newWindowURL()) { appActions.newWindow(Immutable.fromJS({ - location: CmdLine.newWindowURL + location: CmdLine.newWindowURL() })) } diff --git a/app/sessionStore.js b/app/sessionStore.js index 7cebbf0591c..d236a242ea8 100644 --- a/app/sessionStore.js +++ b/app/sessionStore.js @@ -25,6 +25,7 @@ const siteUtil = require('../js/state/siteUtil') const sessionStorageVersion = 1 const filtering = require('./filtering') const autofill = require('./autofill') +const {navigatableTypes} = require('../js/lib/appUrlUtil') // const tabState = require('./common/state/tabState') const getSetting = require('../js/settings').getSetting @@ -479,3 +480,13 @@ module.exports.defaultAppState = () => { defaultWindowParams: {} } } + +/** + * Determines if a protocol is handled. + * app.on('ready') must have been fired before this is called. + */ +module.exports.isProtocolHandled = (protocol) => { + protocol = (protocol || '').split(':')[0] + return navigatableTypes.includes(`${protocol}:`) || + electron.session.defaultSession.protocol.isNavigatorProtocolHandled(protocol) +}