diff --git a/CHANGELOG.md b/CHANGELOG.md index 8702b55a41c..0e1cc4a57e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [0.7.12](https://github.com/brave/browser-laptop/releases/v0.7.12dev) +- Various crash fixes and window.opener fixes. +- Fix for state saving when an update is applied. +- Fix for update error handling when on a flaky connection. +- Visual indicator for Session Tabs added. +- Installers and updates reduced by ~40%. +- Windows taskbar grouping fix. +- Initial window size is now bigger. +- Various keyboard shortcuts added. +- HTTPS Everywhere fixes. + ## [0.7.11](https://github.com/brave/browser-laptop/releases/v0.7.11dev) - Security fix (Severity: High): Prevent BrowserWindow from navigating to remote content ([#445](https://github.com/brave/browser-laptop/issues/445)). Impact: if the user is tricked into dragging and dropping a malicious link outside of the tab content area, the linked site is loaded outside the webview sandbox and can compromise the user's system. diff --git a/app/content/webviewPreload.js b/app/content/webviewPreload.js index 20a3a5857e1..c8003cb411a 100644 --- a/app/content/webviewPreload.js +++ b/app/content/webviewPreload.js @@ -198,6 +198,27 @@ function hasSelection (node) { return false } +/** + * Whether an element is editable or can be typed into. + * @param {Element} elem + * @return {boolean} + */ +function isEditable (elem) { + // TODO: find other node types that are editable + return (elem.contentEditable === 'true' || + elem.nodeName === 'INPUT' || + elem.nodeName === 'TEXTAREA') +} + +/** + * Whether we are on OS X + * @return {boolean} + */ +function isPlatformOSX () { + // TODO: navigator.platform is getting deprecated + return window.navigator.platform.includes('Mac') +} + document.addEventListener('contextmenu', (e) => { var name = e.target.nodeName.toUpperCase() var nodeProps = { @@ -210,12 +231,48 @@ document.addEventListener('contextmenu', (e) => { e.preventDefault() }, false) +var shiftDown = false +var cmdDown = false document.onkeydown = (e) => { switch (e.keyCode) { case KeyCodes.ESC: e.preventDefault() ipc.send(messages.STOP_LOAD) break + case KeyCodes.BACKSPACE: + const msg = shiftDown ? messages.GO_FORWARD : messages.GO_BACK + if (!isEditable(document.activeElement)) { + ipc.send(msg) + } + break + case KeyCodes.SHIFT: + shiftDown = true + break + case KeyCodes.CMD1: + case KeyCodes.CMD2: + cmdDown = true + break + case KeyCodes.LEFT: + if (cmdDown && !isEditable(document.activeElement) && isPlatformOSX()) { + ipc.send(messages.GO_BACK) + } + break + case KeyCodes.RIGHT: + if (cmdDown && !isEditable(document.activeElement) && isPlatformOSX()) { + ipc.send(messages.GO_FORWARD) + } + break + } +} +document.onkeyup = (e) => { + switch (e.keyCode) { + case KeyCodes.SHIFT: + shiftDown = false + break + case KeyCodes.CMD1: + case KeyCodes.CMD2: + cmdDown = false + break } } diff --git a/app/dates.js b/app/dates.js new file mode 100644 index 00000000000..b9767c663a6 --- /dev/null +++ b/app/dates.js @@ -0,0 +1,15 @@ +const moment = require('moment') + +exports.todayYMD = () => { + return moment().format('YYYY-MM-DD') +} + +exports.todayWOY = () => { + return moment().isoWeek() +} + +// Months a returned zero based from moment +// We add 1 to make sure January does not fail a truth test +exports.todayMonth = () => { + return moment().month() + 1 +} diff --git a/app/httpsEverywhere.js b/app/httpsEverywhere.js index a0db3e52ad7..8f9d066a5e3 100644 --- a/app/httpsEverywhere.js +++ b/app/httpsEverywhere.js @@ -191,8 +191,9 @@ function onBeforeHTTPRequest (details, cb) { return } - if (canonicalizeUrl(details.url) in redirectBlacklist) { + if (redirectBlacklist.includes(canonicalizeUrl(details.url))) { // Don't try to rewrite this request, it'll probably just redirect again. + console.log('https everywhere ignoring blacklisted url', details.url) cb({}) } else { getRewrittenUrl(details.url, (url) => { @@ -232,7 +233,7 @@ function onBeforeRedirect (details) { */ function canonicalizeUrl (url) { var parsed = urlParse(url) - return [parsed.host, parsed.pathname].join('/') + return [parsed.host, parsed.pathname].join('') } /** diff --git a/app/index.js b/app/index.js index 570c4eef90c..9a0a5011f8f 100644 --- a/app/index.js +++ b/app/index.js @@ -4,12 +4,8 @@ 'use strict' - // windows installation events etc... if (process.platform === 'win32') { - // TODO - register browser as HTTP handler in Windows (maybe need to fork) - if (require('electron-squirrel-startup')) { - process.exit(0) - } + require('./windowsInit') } const Immutable = require('immutable') @@ -31,6 +27,7 @@ const AdBlock = require('./adBlock') const HttpsEverywhere = require('./httpsEverywhere') const SiteHacks = require('./siteHacks') const CmdLine = require('./cmdLine') +const UpdateStatus = require('../js/constants/updateStatus') let loadAppStatePromise = SessionStore.loadAppState().catch(() => { return SessionStore.defaultAppState() @@ -47,9 +44,23 @@ const saveIfAllCollected = () => { const ignoreCatch = () => {} if (process.env.NODE_ENV !== 'test') { + // If the status is still UPDATE_AVAILABLE then the user wants to quit + // and not restart + if (appState.updates.status === UpdateStatus.UPDATE_AVAILABLE || + appState.updates.status === UpdateStatus.UPDATE_AVAILABLE_DEFERRED) { + appState.updates.status = UpdateStatus.UPDATE_APPLYING_NO_RESTART + } + SessionStore.saveAppState(appState).catch(ignoreCatch).then(() => { sessionStateStoreAttempted = true - app.quit() + // If there's an update to apply, then do it here. + // Otherwise just quit. + if (appState.updates.status === UpdateStatus.UPDATE_APPLYING_NO_RESTART || + appState.updates.status === UpdateStatus.UPDATE_APPLYING_RESTART) { + Updater.quitAndInstall() + } else { + app.quit() + } }) } else { sessionStateStoreAttempted = true @@ -134,6 +145,12 @@ app.on('ready', function () { ipcMain.on(messages.STOP_LOAD, () => { BrowserWindow.getFocusedWindow().webContents.send(messages.STOP_LOAD) }) + ipcMain.on(messages.GO_BACK, () => { + BrowserWindow.getFocusedWindow().webContents.send(messages.GO_BACK) + }) + ipcMain.on(messages.GO_FORWARD, () => { + BrowserWindow.getFocusedWindow().webContents.send(messages.GO_FORWARD) + }) Menu.init() @@ -146,7 +163,7 @@ app.on('ready', function () { SiteHacks.init() ipcMain.on(messages.UPDATE_REQUESTED, () => { - Updater.update() + Updater.updateNowRequested() }) // Setup the crash handling diff --git a/app/localShortcuts.js b/app/localShortcuts.js index 97aa1eafd3d..e06cf8314a1 100644 --- a/app/localShortcuts.js +++ b/app/localShortcuts.js @@ -15,8 +15,6 @@ module.exports.register = (win) => { const simpleWebContentEvents = [ ['CmdOrCtrl+Shift+]', messages.SHORTCUT_NEXT_TAB], ['CmdOrCtrl+Shift+[', messages.SHORTCUT_PREV_TAB], - ['CmdOrCtrl+Right', messages.SHORTCUT_ACTIVE_FRAME_FORWARD], - ['CmdOrCtrl+Left', messages.SHORTCUT_ACTIVE_FRAME_BACK], ['CmdOrCtrl+9', messages.SHORTCUT_SET_ACTIVE_FRAME_TO_LAST] ] diff --git a/app/locales/en-US/app.l20n b/app/locales/en-US/app.l20n index 1b1f2432ca0..d81ebd58f92 100644 --- a/app/locales/en-US/app.l20n +++ b/app/locales/en-US/app.l20n @@ -78,7 +78,10 @@ - + + + diff --git a/app/menu.js b/app/menu.js index ffd87c3c487..50746a7d3f8 100644 --- a/app/menu.js +++ b/app/menu.js @@ -3,7 +3,6 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ const electron = require('electron') -const BrowserWindow = electron.BrowserWindow const AppConfig = require('../js/constants/appConfig') const Menu = require('menu') const messages = require('../js/constants/messages') @@ -70,15 +69,6 @@ const init = (args) => { } const fileMenu = [ - { - label: 'Check for updates ...', - click: function (item, focusedWindow) { - if (BrowserWindow.getAllWindows().length === 0) { - AppActions.newWindow() - } - process.emit(messages.CHECK_FOR_UPDATE) - } - }, // Note: we are keeping this here for testing. Calling process.crash() from the inspector does not create a crash report. // { // label: 'Crash!!!!!', @@ -201,6 +191,9 @@ const init = (args) => { if (isWindows) { fileMenu.push(CommonMenu.separatorMenuItem) fileMenu.push(CommonMenu.quitMenuItem) + helpMenu.push(CommonMenu.separatorMenuItem) + helpMenu.push(CommonMenu.checkForUpdateMenuItem) + helpMenu.push(CommonMenu.separatorMenuItem) helpMenu.push(aboutBraveMenuItem) } @@ -515,6 +508,8 @@ const init = (args) => { submenu: [ aboutBraveMenuItem, CommonMenu.separatorMenuItem, + CommonMenu.checkForUpdateMenuItem, + CommonMenu.separatorMenuItem, preferencesMenuItem, CommonMenu.separatorMenuItem, { diff --git a/app/sessionStore.js b/app/sessionStore.js index 012809ef73a..fecad1c75cf 100644 --- a/app/sessionStore.js +++ b/app/sessionStore.js @@ -14,6 +14,7 @@ const fs = require('fs') const path = require('path') const app = require('app') +const UpdateStatus = require('../js/constants/updateStatus') const sessionStorageVersion = 1 const sessionStorageName = `session-store-${sessionStorageVersion}` const storagePath = path.join(app.getPath('userData'), sessionStorageName) @@ -34,11 +35,6 @@ module.exports.saveAppState = (payload) => { wndPayload.frames = wndPayload.frames.filter(frame => !frame.isPrivate)) } - // Always recalculate the update status - if (payload.updates) { - delete payload.updates.status - } - // payload.frames = payload.frames.filter(frame => !frame.isPrivate) fs.writeFile(storagePath, JSON.stringify(payload), (err) => { if (err) { @@ -159,6 +155,19 @@ module.exports.loadAppState = () => { reject(e) return } + // Always recalculate the update status + if (data.updates) { + const updateStatus = data.updates.status + delete data.updates.status + // The process always restarts after an update so if the state + // indicates that a restart isn't wanted, close right away. + if (updateStatus === UpdateStatus.UPDATE_APPLYING_NO_RESTART) { + module.exports.saveAppState(data) + // Exit immediately without doing the session store saving stuff + // since we want the same state saved except for the update status + app.exit(0) + } + } if (data.perWindowState) { data.perWindowState.forEach(module.exports.cleanSessionData) } diff --git a/app/updater.js b/app/updater.js index 673914e0481..1e9cdeda215 100644 --- a/app/updater.js +++ b/app/updater.js @@ -14,6 +14,7 @@ const querystring = require('querystring') const AppStore = require('../js/stores/appStore') const AppActions = require('../js/actions/appActions') const Immutable = require('immutable') +const dates = require('./dates') const fs = require('fs') const path = require('path') @@ -23,6 +24,7 @@ const updateLogPath = path.join(app.getPath('userData'), 'updateLog.log') // in built mode console.log output is not emitted to the terminal // in prod mode we pipe to a file var debug = function (contents) { + console.log(contents) fs.appendFile(updateLogPath, new Date().toISOString() + ' - ' + contents + '\n') } @@ -86,67 +88,44 @@ exports.init = (platform, ver) => { } } -const secondsPerDay = 24 * 60 * 60 -const secondsPerWeek = secondsPerDay * 7 -const secondsPerMonth = secondsPerDay * 30 - // Build a set of three params providing flags determining when the last update occurred // This is a privacy preserving policy. Instead of passing personally identifying -// information, the browser will pass the three boolean values indicating when the last +// information, the browser will pass thefour boolean values indicating when the last // update check occurred. -var paramsFromLastCheckDelta = (seconds) => { - // Default params - var params = { - daily: false, - weekly: false, - monthly: false - } - - // First ever check - if (seconds === 0) { - params.daily = true - return params - } - - // More than one today - if (seconds < secondsPerDay) { - return params - } - - // If we have not checked today, but we have since last week (first check as well) - if (seconds === 0 || (seconds > secondsPerDay && seconds < secondsPerWeek)) { - params.daily = true - return params - } - - // If we have not checked this week, but have this month - if (seconds >= secondsPerWeek && seconds < secondsPerMonth) { - params.weekly = true - return params +var paramsFromLastCheckDelta = (lastCheckYMD, lastCheckWOY, lastCheckMonth, firstCheckMade) => { + return { + daily: !lastCheckYMD || (dates.todayYMD() > lastCheckYMD), + weekly: !lastCheckWOY || (dates.todayWOY() !== lastCheckWOY), + monthly: !lastCheckMonth || (dates.todayMonth() !== lastCheckMonth), + first: !firstCheckMade } - - params.monthly = true - - return params } // Make a request to the update server to retrieve meta data var requestVersionInfo = (done) => { if (!platformBaseUrl) throw new Error('platformBaseUrl not set') - // Get the timestamp of the last update request - var lastCheckTimestamp = AppStore.getState().toJS().updates['lastCheckTimestamp'] || 0 - debug(`lastCheckTimestamp = ${lastCheckTimestamp}`) + // Get the daily, week of year and month update checks + var lastCheckYMD = AppStore.getState().toJS().updates['lastCheckYMD'] || null + debug(`lastCheckYMD = ${lastCheckYMD}`) - // Calculate the number of seconds since the last update - var secondsSinceLastCheck = 0 - if (lastCheckTimestamp) { - secondsSinceLastCheck = Math.round(((new Date()).getTime() - lastCheckTimestamp) / 1000) - } - debug(`secondsSinceLastCheck = ${secondsSinceLastCheck}`) + var lastCheckWOY = AppStore.getState().toJS().updates['lastCheckWOY'] || null + debug(`lastCheckWOY = ${lastCheckWOY}`) - // Build query string based on the number of seconds since last check - var query = paramsFromLastCheckDelta(secondsSinceLastCheck) + var lastCheckMonth = AppStore.getState().toJS().updates['lastCheckMonth'] || null + debug(`lastCheckMonth = ${lastCheckMonth}`) + + // Has the browser ever asked for an update + var firstCheckMade = AppStore.getState().toJS().updates['firstCheckMade'] || false + debug(`firstCheckMade = ${firstCheckMade}`) + + // Build query string based on the last date an update request was made + var query = paramsFromLastCheckDelta( + lastCheckYMD, + lastCheckWOY, + lastCheckMonth, + firstCheckMade + ) var queryString = `${platformBaseUrl}?${querystring.stringify(query)}` debug(queryString) @@ -161,7 +140,7 @@ var requestVersionInfo = (done) => { done(null, body) } else { // Network error or mis-configuration - debug(err.toString()) + autoUpdater.emit('error', err) } }) } @@ -204,8 +183,13 @@ exports.checkForUpdate = (verbose) => { } // The UI indicates that we should update the software -exports.update = () => { +exports.updateNowRequested = () => { debug('update requested in updater') + // App shutdown process will save state and then call autoUpdater.quitAndInstall + AppActions.setUpdateStatus(UpdateStatus.UPDATE_APPLYING_RESTART) +} + +exports.quitAndInstall = () => { autoUpdater.quitAndInstall() } diff --git a/app/windowsInit.js b/app/windowsInit.js new file mode 100644 index 00000000000..7ff75ffc69a --- /dev/null +++ b/app/windowsInit.js @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const electron = require('electron') +const app = electron.app +const appUserModelId = 'BraveSoftware.Brave.browser' + + // windows installation events etc... +if (process.platform === 'win32') { + // TODO - register browser as HTTP handler in Windows (maybe need to fork) + if (require('electron-squirrel-startup')) { + process.exit(0) + } +} + +app.on('will-finish-launching', function () { + app.setAppUserModelId(appUserModelId) +}) diff --git a/js/actions/appActions.js b/js/actions/appActions.js index 117a1532087..1908b0a490f 100644 --- a/js/actions/appActions.js +++ b/js/actions/appActions.js @@ -44,8 +44,6 @@ const AppActions = { * Dispatches an event to the main process to update the browser */ updateRequested: function () { - // TODO - change to dispatcher - console.log('appActions updateRequested') global.require('electron').ipcRenderer.send(messages.UPDATE_REQUESTED) }, diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js index 3b59ec5280d..efdd073eade 100644 --- a/js/actions/windowActions.js +++ b/js/actions/windowActions.js @@ -42,6 +42,7 @@ const WindowActions = { * @param {string} location - The URL of the page to load */ loadUrl: function (activeFrame, location) { + location = location.trim() let newFrame = false if (activeFrame.get('isPinned')) { try { @@ -82,6 +83,7 @@ const WindowActions = { * it is active the URL text will also be changed. */ setLocation: function (location, key) { + location = location.trim() if (UrlUtil.isURL(location)) { location = UrlUtil.getUrlFromInput(location) } diff --git a/js/commonMenu.js b/js/commonMenu.js index fe5dd959983..6af20750ec9 100644 --- a/js/commonMenu.js +++ b/js/commonMenu.js @@ -68,7 +68,7 @@ module.exports.newPrivateTabMenuItem = { } module.exports.newPartitionedTabMenuItem = { - label: 'New Partitioned Session', + label: 'New Session Tab', accelerator: 'CmdOrCtrl+Alt+S', click: function (item, focusedWindow) { module.exports.sendToFocusedWindow(focusedWindow, [messages.SHORTCUT_NEW_FRAME, undefined, { isPartitioned: true }]) @@ -101,6 +101,16 @@ module.exports.findOnPageMenuItem = { } } +module.exports.checkForUpdateMenuItem = { + label: 'Check for updates ...', + click: function (item, focusedWindow) { + if (electron.BrowserWindow.getAllWindows().length === 0) { + AppActions.newWindow() + } + process.emit(messages.CHECK_FOR_UPDATE) + } +} + module.exports.buildBraveryMenu = function (settings, init) { const replaceAds = settings[adInsertion] || false const blockAds = settings[adblock] || false diff --git a/js/components/main.js b/js/components/main.js index 426fd3bcfea..2d0e5e3773a 100644 --- a/js/components/main.js +++ b/js/components/main.js @@ -35,6 +35,14 @@ class Main extends ImmutableComponent { ipc.on(messages.STOP_LOAD, () => { electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_STOP) }) + ipc.on(messages.GO_BACK, () => { + console.log('going back') + electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_BACK) + }) + ipc.on(messages.GO_FORWARD, () => { + console.log('going forward') + electron.remote.getCurrentWebContents().send(messages.SHORTCUT_ACTIVE_FRAME_FORWARD) + }) ipc.on(messages.CONTEXT_MENU_OPENED, (e, nodeProps) => { contextMenus.onMainContextMenu(nodeProps) }) diff --git a/js/components/tab.js b/js/components/tab.js index 82d11e2a8ff..de02e83bf81 100644 --- a/js/components/tab.js +++ b/js/components/tab.js @@ -210,6 +210,10 @@ class Tab extends ImmutableComponent { style={activeTabStyle}> { this.props.frameProps.get('isPrivate') ?
: null } + { this.props.frameProps.get('partitionNumber') + ?
: null }
{ } const whitelistedUrl = process.env.NODE_ENV === 'development' - ? 'file://' + __dirname + '/../../app/index-dev.html?' + queryString - : 'file://' + __dirname + '/../../app/index.html?' + queryString + ? 'file://' + path.resolve(__dirname, '..', '..') + '/app/index-dev.html?' + queryString + : 'file://' + path.resolve(__dirname + '..', '..', '..') + '/app/index.html?' + queryString mainWindow.loadURL(whitelistedUrl) mainWindow.webContents.on('will-navigate', willNavigateHandler.bind(null, whitelistedUrl)) appStore.emitChange() @@ -247,6 +251,10 @@ const handleAppAction = (action) => { break case AppConstants.APP_UPDATE_LAST_CHECK: appState = appState.setIn(['updates', 'lastCheckTimestamp'], (new Date()).getTime()) + appState = appState.setIn(['updates', 'lastCheckYMD'], dates.todayYMD()) + appState = appState.setIn(['updates', 'lastCheckWOY'], dates.todayWOY()) + appState = appState.setIn(['updates', 'lastCheckMonth'], dates.todayMonth()) + appState = appState.setIn(['updates', 'firstCheckMade'], true) appStore.emitChange() break case AppConstants.APP_SET_UPDATE_STATUS: @@ -260,6 +268,9 @@ const handleAppAction = (action) => { if (action.metadata !== undefined) { appState = appState.setIn(['updates', 'metadata'], action.metadata) } + if (action.status === UpdateStatus.UPDATE_APPLYING_RESTART) { + app.quit() + } appStore.emitChange() break case AppConstants.APP_SET_RESOURCE_ENABLED: diff --git a/package.json b/package.json index fd62146ba83..77b67e388d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "brave", - "version": "0.7.11", + "version": "0.7.12", "description": "Brave laptop and desktop browser", "main": "./app/index.js", "scripts": { @@ -20,6 +20,7 @@ "clean-session-store": "rm -f ~/Library/Application\\ Support/Brave/session-store-*", "clean-adblock-data": "rm -f ~/Library/Application\\ Support/Brave/ABPFilterParserData.dat", "clean-tp-data": "rm -f ~/Library/Application\\ Support/Brave/TrackingProtection.dat", + "clean-httpse-data": "rm -f ~/Library/Application\\ Support/Brave/httpse-targets.json ~/Library/Application\\ Support/Brave/rulesets.sqlite*", "postinstall": "node ./tools/rebuildNativeModules.js&&webpack", "test": "NODE_ENV=test mocha --compilers js:babel-register --recursive $(find test -name '*Test.js')" }, @@ -59,6 +60,7 @@ "font-awesome": "^4.5.0", "font-awesome-webpack": "0.0.4", "immutable": "^3.7.5", + "moment": "^2.11.1", "react": "^0.14.3", "react-dom": "^0.14.3", "sqlite3": "^3.1.0", diff --git a/preload-httpse.js b/preload-httpse.js index 97fa5620813..4f2e8c67ab9 100644 --- a/preload-httpse.js +++ b/preload-httpse.js @@ -5,7 +5,10 @@ var parseString = require('xml2js').parseString // Manually exclude sites that are broken until they are fixed in the next // HTTPS Everywhere release. var exclusions = { - 'Nike.com.xml': 'breaks nikeplus.com' + 'Nike.com.xml': 'breaks nikeplus.com', + 'PJ_Media.xml': 'mixed content on https://pjmedia.com/instapundit/', + 'Slashdot.xml': 'redirect loop on mobile slashdot.org', + 'Vox.com.xml': 'redirect loop on vox.com' } // Preload mapping of HTTPS Everywhere hosts to ruleset IDs and convert diff --git a/test/lib/brave.js b/test/lib/brave.js index e926cc515e5..e7ab8915e7a 100644 --- a/test/lib/brave.js +++ b/test/lib/brave.js @@ -109,7 +109,7 @@ var exports = { return this.execute(function () { let screen = require('electron').screen let primaryDisplay = screen.getPrimaryDisplay() - return Math.floor(primaryDisplay.bounds.height / 2) + return primaryDisplay.workAreaSize.height }).then((response) => response.value) }) @@ -117,7 +117,7 @@ var exports = { return this.execute(function () { let screen = require('electron').screen let primaryDisplay = screen.getPrimaryDisplay() - return Math.floor(primaryDisplay.bounds.width / 2) + return primaryDisplay.workAreaSize.width }).then((response) => response.value) }) @@ -185,6 +185,18 @@ var exports = { require('electron').ipcRenderer.emit('ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-' + internal.viewInstanceId, ...params) }, frameKey, eventName, ...params).then((response) => response.value) }) + + this.app.client.addCommand('waitForElementFocus', function (selector) { + let activeElement + return this.waitUntil(function () { + return this.elementActive() + .then(function (el) { + activeElement = el + return this.element(selector) + }) + .then(queryElement => queryElement.value.ELEMENT === activeElement.value.ELEMENT) + }) + }) }, startApp: function () { diff --git a/test/navigationBarTest.js b/test/navigationBarTest.js index 83a1181bc37..eacfebb4c19 100644 --- a/test/navigationBarTest.js +++ b/test/navigationBarTest.js @@ -18,9 +18,7 @@ describe('urlbar', function () { .ipcSend('shortcut-new-frame') // wait for correct urlInput based on frameKey .waitForVisible('div[id="navigator"][data-frame-key="' + frameKey + '"] ' + urlInput) - .waitUntil(function () { - return this.getAttribute(':focus', 'id').then(value => value === 'urlInput') - }) + .waitForElementFocus(urlInput) } function blur (client) { @@ -31,12 +29,6 @@ describe('urlbar', function () { }) } - function hasFocus (client) { - return client.waitUntil(function () { - return this.getAttribute(':focus', 'id').then(function (value) { return value === 'urlInput' }) - }) - } - function defaultUrlInputValue (client) { return client.waitUntil(function () { return this.getAttribute(urlInput, 'value').then(value => value === '') @@ -220,7 +212,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) it('selects the text', function *() { @@ -228,7 +220,7 @@ describe('urlbar', function () { }) }) - describe('new tab', function () { + describe('new tab from ipc', function () { Brave.beforeAll(this) before(function *() { @@ -242,7 +234,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) }) @@ -302,7 +294,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) it('selects the text', function *() { @@ -321,7 +313,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) it('selects the text', function *() { @@ -426,7 +418,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) it('selects the text', function *() { @@ -449,7 +441,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) it('unselects the text', function *() { @@ -478,7 +470,7 @@ describe('urlbar', function () { }) it('has focus', function *() { - yield hasFocus(this.app.client) + yield this.app.client.waitForElementFocus(urlInput) }) }) }) diff --git a/tools/buildPackage.js b/tools/buildPackage.js index f54b19eba0a..975d949008d 100644 --- a/tools/buildPackage.js +++ b/tools/buildPackage.js @@ -1,5 +1,10 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + var VersionInfo = require('./lib/versionInfo') var execute = require('./lib/execute') +const ignoredPaths = require('./lib/ignoredPaths') const isWindows = process.platform === 'win32' const isDarwin = process.platform === 'darwin' @@ -45,7 +50,7 @@ cmds = cmds.concat([ 'npm run checks', 'node ./node_modules/electron-packager/cli.js . Brave' + ' --overwrite' + - ' --ignore="electron-download|electron-rebuild|electron-packager|electron-builder|electron-prebuilt|electron-rebuild|babel$|babel-(?!polyfill|regenerator-runtime)"' + + ' --ignore="' + ignoredPaths.join('|') + '"' + ' --platform=' + process.platform + ' --arch=' + arch + ' --version=' + VersionInfo.electronVersion + diff --git a/tools/lib/ignoredPaths.js b/tools/lib/ignoredPaths.js new file mode 100644 index 00000000000..246549ce71f --- /dev/null +++ b/tools/lib/ignoredPaths.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +module.exports = [ + 'test/', + 'tools/', + 'abp-filter-parser-cpp/(node_modules|test|perf|sample|scripts|test|vendor|ABPFilterParserData.dat)', + 'tracking-protection/(node_modules|test|data|scripts|vendor)', + 'sqlite3/(src|deps)', + 'sqlite3/build/Release/(obj|obj.target|.deps)', + 'abp-filter-parser-cpp/build/Release/(obj|obj.target|.deps)', + 'tracking-protection/build/Release/(obj|obj.target|.deps)', + 'nsp/node_modules', + 'electron-installer-squirrel-windows', + 'electron-chromedriver', + 'node-notifier/vendor', + 'node-gyp', + '.brave-gyp', + 'electron-download', + 'electron-rebuild', + 'electron-packager', + 'electron-builder', + 'electron-prebuilt', + 'electron-rebuild', + 'babel$', + 'babel-(?!polyfill|regenerator-runtime)' +]