Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1296 from beakerbrowser/electron4
Browse files Browse the repository at this point in the history
Update to Electron 4
  • Loading branch information
pfrazee committed Feb 2, 2019
2 parents d4a60ab + 15326b1 commit bf3315e
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 39 deletions.
17 changes: 17 additions & 0 deletions app/background-process/browser.js
Expand Up @@ -102,6 +102,14 @@ export function setup () {
}
})

// quick sync getters
ipcMain.on('get-markdown-renderer-script', e => {
e.returnValue = fs.readFileSync(path.join(app.getAppPath(), 'markdown-renderer.build.js'), 'utf8')
})
ipcMain.on('get-json-renderer-script', e => {
e.returnValue = fs.readFileSync(path.join(app.getAppPath(), 'json-renderer.build.js'), 'utf8')
})

// HACK
// Electron doesn't give us a convenient way to check the content-types of responses
// so we track the last 100 responses' headers to accomplish this
Expand Down Expand Up @@ -570,6 +578,14 @@ function onUpdateError (e) {

function onWebContentsCreated (e, webContents) {
webContents.on('will-prevent-unload', onWillPreventUnload)
webContents.on('remote-require', e => {
// do not allow
e.preventDefault()
})
webContents.on('remote-get-global', e => {
// do not allow
e.preventDefault()
})
}

function onWillPreventUnload (e) {
Expand All @@ -591,6 +607,7 @@ function onCompleted (details) {
function set (v) {
resourceContentTypes.set(details.url, Array.isArray(v) ? v[0] : v)
}
if (!details.responseHeaders) return
if ('Content-Type' in details.responseHeaders) {
set(details.responseHeaders['Content-Type'])
} else if ('content-type' in details.responseHeaders) {
Expand Down
8 changes: 7 additions & 1 deletion app/background-process/hidden-windows.js
Expand Up @@ -10,7 +10,13 @@ var hiddenWindows = {}

export async function spawn (id, modulePath) {
var fullModulePath = require.resolve(modulePath)
var win = new BrowserWindow({show: false})
var win = new BrowserWindow({
show: false,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: false
}
})
// win.webContents.toggleDevTools()
console.log('[', id, '] Starting...')
win.loadURL(`beaker-hidden-window://loader/?module=${encodeURIComponent(fullModulePath)}&userDataPath=${encodeURIComponent(app.getPath('userData'))}`)
Expand Down
6 changes: 5 additions & 1 deletion app/background-process/ui/windows.js
Expand Up @@ -135,9 +135,13 @@ export function createShellWindow (windowState) {
backgroundColor: '#ddd',
defaultEncoding: 'UTF-8',
webPreferences: {
sandbox: true,
preload: PRELOAD_PATH,
nodeIntegration: false,
contextIsolation: false,
webviewTag: true,
sandbox: true,
webSecurity: false, // disable same-origin-policy in the shell window, webviews have it restored
// enableRemoteModule: false, TODO would prefer this were true, but shell window needs this to get the webviews' webContents IDs -prf
allowRunningInsecureContent: false,
nativeWindowOpen: true
},
Expand Down
3 changes: 0 additions & 3 deletions app/package.json
Expand Up @@ -91,8 +91,5 @@
"utp-native": "^2.0.0",
"yo-yo": "^1.4.0",
"zerr": "^1.0.4"
},
"devDependencies": {
"devtron": "^1.4.0"
}
}
35 changes: 14 additions & 21 deletions app/shell-window/pages.js
Expand Up @@ -3,7 +3,6 @@
import { ipcRenderer, remote } from 'electron'
import EventEmitter from 'events'
import path from 'path'
import fs from 'fs'
import throttle from 'lodash.throttle'
import parseDatURL from 'parse-dat-url'
import errorPage from '@beaker/core/lib/error-page'
Expand Down Expand Up @@ -135,6 +134,8 @@ export function create (opts) {
isReceivingAssets: false, // has the webview started receiving assets, in the current load-cycle?
isActive: false, // is the active page?
isInpageFinding: false, // showing the inpage find ctrl?
isCurrentlyAudible: false, // is the page currently playing music?
isAudioMuted: false, // is the page muted?
inpageFindInfo: null, // any info available on the inpage find {activeMatchOrdinal, matches}
liveReloadEvents: false, // live-reload event stream
zoom: 0, // what's the current zoom level?
Expand Down Expand Up @@ -173,9 +174,6 @@ export function create (opts) {
executeJavascriptCalls: {},
executeJavascriptCallCounter: 0,

// hackfix reload failsafe
reloadHackfixCounter: 0,

// get the current URL
getURL () {
return this.url
Expand Down Expand Up @@ -393,6 +391,8 @@ export function create (opts) {
page.webviewEl.addEventListener('found-in-page', onFoundInPage)
page.webviewEl.addEventListener('enter-html-full-screen', onEnterHtmlFullScreen)
page.webviewEl.addEventListener('leave-html-full-screen', onLeaveHtmlFullScreen)
page.webviewEl.addEventListener('media-started-playing', onMediaChange)
page.webviewEl.addEventListener('media-paused', onMediaChange)
page.webviewEl.addEventListener('close', onClose)
page.webviewEl.addEventListener('crashed', onCrashed)
page.webviewEl.addEventListener('gpu-crashed', onCrashed)
Expand Down Expand Up @@ -790,21 +790,6 @@ function onDidStopLoading (e) {
statusBar.setIsLoading(false)
}

// HACK
// there is a race condition with Electron where the CSPs will sometimes prevent the preload from executing
// this can be detected by attempting to call executeJavaScript; if it takes longer than a second, that's too long
// reloading the page usually gets it to execute correctly
// -prf
let webviewCheckTO = setTimeout(() => {
if (page.reloadHackfixCounter > 5) return // stop, we're endlessly redirecting
page.reloadAsync()
page.reloadHackfixCounter++
}, 1000)
page.executeJavaScript('true').then(res => {
page.reloadHackfixCounter = 0
clearTimeout(webviewCheckTO)
})

// determine content type
let contentType = beaker.browser.getResourceContentType(page.getURL()) || ''
let isMD = contentType.startsWith('text/markdown') || contentType.startsWith('text/x-markdown')
Expand Down Expand Up @@ -851,7 +836,7 @@ function onDidStopLoading (e) {
.markdown pre > code { display: block; }
`)
if (!cachedMarkdownRendererScript) {
cachedMarkdownRendererScript = fs.readFileSync(path.join(APP_PATH, 'markdown-renderer.build.js'), 'utf8')
cachedMarkdownRendererScript = ipcRenderer.sendSync('get-markdown-renderer-script')
}

// NOTE uses webviewEl.executeJavaScript because we dont want to run the markdown renderer in an isolated world
Expand Down Expand Up @@ -889,7 +874,7 @@ function onDidStopLoading (e) {
`)

if (!cachedJSONRendererScript) {
cachedJSONRendererScript = fs.readFileSync(path.join(APP_PATH, 'json-renderer.build.js'), 'utf8')
cachedJSONRendererScript = ipcRenderer.sendSync('get-json-renderer-script')
}

page.executeJavaScript(cachedJSONRendererScript)
Expand Down Expand Up @@ -1020,6 +1005,13 @@ function onLeaveHtmlFullScreen (e) {
document.body.classList.remove('page-fullscreen')
}

async function onMediaChange (e) {
var page = getByWebview(e.target)
await new Promise(r => setTimeout(r, 1e3)) // the event consistently precedes the audible check by at most 1s
page.isCurrentlyAudible = await page.isCurrentlyAudibleAsync()
events.emit('media-change', page)
}

function onClose (e) {
var page = getByWebview(e.target)
if (page) {
Expand Down Expand Up @@ -1106,6 +1098,7 @@ export function createWebviewEl (id, url) {
var el = document.createElement('webview')
el.dataset.id = id
el.setAttribute('preload', 'file://' + path.join(APP_PATH, 'webview-preload.build.js'))
el.setAttribute('enableremotemodule', 'false')
el.setAttribute('webpreferences', 'allowDisplayingInsecureContent,defaultEncoding=utf-8,scrollBounce,nativeWindowOpen=yes')
// TODO re-enable nativeWindowOpen when https://github.com/electron/electron/issues/9558 lands
el.setAttribute('src', url || DEFAULT_URL)
Expand Down
22 changes: 13 additions & 9 deletions app/shell-window/ui/tabs.js
Expand Up @@ -48,6 +48,7 @@ export function setup () {
pages.on('did-stop-loading', onUpdateTab)
pages.on('page-title-updated', onUpdateTab)
pages.on('page-favicon-updated', onUpdateTab)
pages.on('media-change', onUpdateTab)
window.addEventListener('resize', debounce(onWindowResize, 500))
}

Expand All @@ -57,6 +58,8 @@ export function setup () {
function drawTab (page) {
const isActive = page.isActive
const isTabDragging = page.isTabDragging && (page.tabDragOffset !== 0)
const isAudioMuted = page.isAudioMuted
const isCurrentlyAudible = page.isCurrentlyAudible

// pick a favicon
var favicon
Expand Down Expand Up @@ -102,7 +105,11 @@ function drawTab (page) {
}

// normal rendering:

const audioIcon = isAudioMuted
? yo`<span class="fas fa-volume-mute"></span>`
: isCurrentlyAudible
? yo`<span class="fas fa-volume-up"></span>`
: ''
return yo`
<div class=${'chrome-tab' + cls}
data-id=${page.id}
Expand All @@ -113,7 +120,7 @@ function drawTab (page) {
title=${getNiceTitle(page)}>
<div class="chrome-tab-bg"></div>
<div class="chrome-tab-favicon">${favicon}</div>
<div class="chrome-tab-title">${getNiceTitle(page) || 'New Tab'}</div>
<div class="chrome-tab-title">${audioIcon}${getNiceTitle(page) || 'New Tab'}</div>
<div class="chrome-tab-close" title="Close tab" onclick=${onClickTabClose(page)}></div>
</div>`
}
Expand Down Expand Up @@ -219,8 +226,9 @@ function onToggleMuted (page) {
return () => {
if (page.webviewEl) {
const wc = page.webviewEl.getWebContents()
const isMuted = wc.isAudioMuted()
wc.setAudioMuted(!isMuted)
page.isAudioMuted = !wc.isAudioMuted()
wc.setAudioMuted(page.isAudioMuted)
onUpdateTab(page)
}
}
}
Expand Down Expand Up @@ -272,16 +280,12 @@ function onClickReopenClosedTab () {
function onContextMenuTab (page) {
return e => {
const { Menu } = remote
var isMuted = false
if (page.webviewEl) {
isMuted = page.webviewEl.getWebContents().isAudioMuted()
}
var menu = Menu.buildFromTemplate([
{ label: 'New Tab', click: onClickNew },
{ type: 'separator' },
{ label: 'Duplicate', click: onClickDuplicate(page) },
{ label: (page.isPinned) ? 'Unpin Tab' : 'Pin Tab', click: onClickPin(page) },
{ label: (isMuted) ? 'Unmute Tab' : 'Mute Tab', click: onToggleMuted(page) },
{ label: (page.isAudioMuted) ? 'Unmute Tab' : 'Mute Tab', click: onToggleMuted(page) },
{ type: 'separator' },
{ label: 'Close Tab', click: onClickTabClose(page) },
{ label: 'Close Other Tabs', click: onClickCloseOtherTabs(page) },
Expand Down
1 change: 1 addition & 0 deletions app/shell-window/webview-async.js
Expand Up @@ -38,6 +38,7 @@ const methods = [
'inspectElement',
'setAudioMuted',
'isAudioMuted',
'isCurrentlyAudible',
'undo',
'redo',
'cut',
Expand Down
5 changes: 5 additions & 0 deletions app/stylesheets/shell-window/chrome-tabs.less
Expand Up @@ -88,6 +88,11 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

.fa-volume-up,
.fa-volume-mute {
margin-right: 4px;
}
}

&.chrome-tab-nofavicon .chrome-tab-title {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -3,7 +3,7 @@
"name": "beakerbrowser",
"devDependencies": {
"browserify": "^13.0.1",
"electron": "3.0.9",
"electron": "4.0.3",
"electron-builder": "~20.8.0",
"eslint": "^4.5.0",
"eslint-plugin-import": "^2.7.0",
Expand Down
12 changes: 10 additions & 2 deletions tasks/rebuild.js
Expand Up @@ -2,14 +2,22 @@ var gulp = require('gulp')
var path = require('path')
var run = require('./util-run')

//(cd app && npm rebuild --runtime=electron --target=3.0.9 --disturl=https://atom.io/download/atom-shell --build-from-source); gulp build
//(cd app && npm rebuild --runtime=electron --target=4.0.3 --disturl=https://atom.io/download/atom-shell --build-from-source); gulp build

gulp.task('rebuild', gulp.series(function () {
// TODO read electron version
var cwd = path.join(process.cwd(), 'app')
console.log(cwd)
return new Promise(resolve => {
run(`npm rebuild --runtime=electron --target=3.0.9 --disturl=https://atom.io/download/atom-shell --build-from-source`, {cwd, shell: true}, function () {
var env = {}
if (process.platform === 'darwin') {
env = {
// required to make spellchecker compile
CXXFLAGS: '-mmacosx-version-min=10.10',
LDFLAGS: '-mmacosx-version-min=10.10'
}
}
run(`npm rebuild --runtime=electron --target=4.0.3 --disturl=https://atom.io/download/atom-shell --build-from-source`, {cwd, env, shell: true}, function () {
run(`npm run build`, {shell: true}, function () {
resolve()
})
Expand Down
2 changes: 1 addition & 1 deletion tasks/util-run.js
Expand Up @@ -5,7 +5,7 @@ module.exports = function (cmd, opts, cb) {
console.log(cmd)
cmd = cmd.split(' ')
opts.stdio = 'inherit'
opts.env = process.env
opts.env = Object.assign({}, process.env, opts.env || {})
childProcess.spawn(cmd[0], cmd.slice(1), opts)
.on('error', console.log)
.on('close', cb)
Expand Down

0 comments on commit bf3315e

Please sign in to comment.