electron/lib/renderer/override.js

258 lines
7.3 KiB
JavaScript
Raw Normal View History

2016-03-25 19:57:17 +00:00
'use strict'
2016-03-25 19:57:17 +00:00
const ipcRenderer = require('electron').ipcRenderer
const remote = require('electron').remote
2016-10-25 01:21:42 +00:00
const parseFeaturesString = require('../common/parse-features-string')
2016-01-12 02:40:23 +00:00
2016-01-14 18:35:29 +00:00
// Helper function to resolve relative url.
2016-03-25 19:57:17 +00:00
var a = window.top.document.createElement('a')
var resolveURL = function (url) {
a.href = url
return a.href
}
2016-01-12 02:40:23 +00:00
2016-01-14 18:35:29 +00:00
// Window object returned by "window.open".
2016-03-25 19:57:17 +00:00
var BrowserWindowProxy = (function () {
BrowserWindowProxy.proxies = {}
BrowserWindowProxy.getOrCreate = function (guestId) {
var base = this.proxies
base[guestId] != null ? base[guestId] : base[guestId] = new BrowserWindowProxy(guestId)
return base[guestId]
2016-03-25 19:57:17 +00:00
}
BrowserWindowProxy.remove = function (guestId) {
return delete this.proxies[guestId]
}
function BrowserWindowProxy (guestId1) {
Object.defineProperty(this, 'guestId', {
configurable: false,
enumerable: true,
writeable: false,
value: guestId1
})
2016-03-25 19:57:17 +00:00
this.closed = false
ipcRenderer.once('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_' + this.guestId, () => {
2016-03-25 19:57:17 +00:00
BrowserWindowProxy.remove(this.guestId)
this.closed = true
})
2016-01-12 02:40:23 +00:00
}
2016-03-25 19:57:17 +00:00
BrowserWindowProxy.prototype.close = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId)
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
BrowserWindowProxy.prototype.focus = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus')
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
BrowserWindowProxy.prototype.blur = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur')
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
BrowserWindowProxy.prototype.print = function () {
2016-05-27 18:11:55 +00:00
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print')
}
Object.defineProperty(BrowserWindowProxy.prototype, 'location', {
2016-03-25 19:57:17 +00:00
get: function () {
return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'getURL')
},
2016-03-25 19:57:17 +00:00
set: function (url) {
url = resolveURL(url)
return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'loadURL', url)
}
2016-03-25 19:57:17 +00:00
})
2016-03-25 19:57:17 +00:00
BrowserWindowProxy.prototype.postMessage = function (message, targetOrigin) {
2016-01-12 02:40:23 +00:00
if (targetOrigin == null) {
2016-03-25 19:57:17 +00:00
targetOrigin = '*'
2016-01-12 02:40:23 +00:00
}
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, window.location.origin)
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
BrowserWindowProxy.prototype['eval'] = function (...args) {
return ipcRenderer.send.apply(ipcRenderer, ['ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript'].concat(args))
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
return BrowserWindowProxy
})()
2016-01-12 02:40:23 +00:00
if (process.guestInstanceId == null) {
2016-01-14 18:35:29 +00:00
// Override default window.close.
2016-03-25 19:57:17 +00:00
window.close = function () {
return remote.getCurrentWindow().close()
}
2016-01-12 02:40:23 +00:00
}
2016-01-14 18:35:29 +00:00
// Make the browser window or guest view emit "new-window" event.
2016-03-25 19:57:17 +00:00
window.open = function (url, frameName, features) {
var feature, guestId, i, j, len, len1, name, options, ref1, ref2, value, additionalFeatures
2016-01-12 02:40:23 +00:00
if (frameName == null) {
2016-03-25 19:57:17 +00:00
frameName = ''
2016-01-12 02:40:23 +00:00
}
if (features == null) {
2016-03-25 19:57:17 +00:00
features = ''
2016-01-12 02:40:23 +00:00
}
2016-03-25 19:57:17 +00:00
options = {}
2016-04-28 16:39:37 +00:00
const ints = ['x', 'y', 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight', 'zoomFactor']
const webPreferences = ['zoomFactor', 'nodeIntegration', 'preload']
const disposition = 'new-window'
2016-01-12 02:40:23 +00:00
// Used to store additional features
additionalFeatures = []
2016-10-25 01:21:42 +00:00
// Parse the features
parseFeaturesString(features, function (key, value) {
if (value === undefined) {
2016-10-25 01:21:42 +00:00
additionalFeatures.push(key)
} else {
2016-10-25 01:21:42 +00:00
if (webPreferences.includes(key)) {
if (options.webPreferences == null) {
options.webPreferences = {}
}
2016-10-25 01:21:42 +00:00
options.webPreferences[key] = value
} else {
2016-10-25 01:21:42 +00:00
options[key] = value
}
}
2016-10-25 01:21:42 +00:00
})
2016-01-12 02:40:23 +00:00
if (options.left) {
if (options.x == null) {
2016-03-25 19:57:17 +00:00
options.x = options.left
2016-01-12 02:40:23 +00:00
}
}
if (options.top) {
if (options.y == null) {
2016-03-25 19:57:17 +00:00
options.y = options.top
2016-01-12 02:40:23 +00:00
}
}
if (options.title == null) {
2016-03-25 19:57:17 +00:00
options.title = frameName
2016-01-12 02:40:23 +00:00
}
if (options.width == null) {
2016-03-25 19:57:17 +00:00
options.width = 800
2016-01-12 02:40:23 +00:00
}
if (options.height == null) {
2016-03-25 19:57:17 +00:00
options.height = 600
2016-01-12 02:40:23 +00:00
}
2016-01-14 18:35:29 +00:00
// Resolve relative urls.
2016-09-09 00:11:10 +00:00
if (url == null || url === '') {
url = 'about:blank'
} else {
url = resolveURL(url)
}
2016-01-12 02:40:23 +00:00
for (j = 0, len1 = ints.length; j < len1; j++) {
2016-03-25 19:57:17 +00:00
name = ints[j]
2016-01-12 02:40:23 +00:00
if (options[name] != null) {
2016-03-25 19:57:17 +00:00
options[name] = parseInt(options[name], 10)
2016-01-12 02:40:23 +00:00
}
}
guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, disposition, options, additionalFeatures)
2016-01-12 02:40:23 +00:00
if (guestId) {
2016-03-25 19:57:17 +00:00
return BrowserWindowProxy.getOrCreate(guestId)
2016-01-12 02:40:23 +00:00
} else {
2016-03-25 19:57:17 +00:00
return null
2016-01-12 02:40:23 +00:00
}
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-01-14 18:35:29 +00:00
// Use the dialog API to implement alert().
window.alert = function (message = '', title = '') {
2016-01-12 02:40:23 +00:00
remote.dialog.showMessageBox(remote.getCurrentWindow(), {
message: String(message),
title: String(title),
buttons: ['OK']
2016-03-25 19:57:17 +00:00
})
}
2016-01-12 02:40:23 +00:00
2016-01-14 18:35:29 +00:00
// And the confirm().
2016-03-25 19:57:17 +00:00
window.confirm = function (message, title) {
var buttons, cancelId
2016-01-12 02:40:23 +00:00
if (title == null) {
2016-03-25 19:57:17 +00:00
title = ''
2016-01-12 02:40:23 +00:00
}
2016-03-25 19:57:17 +00:00
buttons = ['OK', 'Cancel']
cancelId = 1
2016-01-12 02:40:23 +00:00
return !remote.dialog.showMessageBox(remote.getCurrentWindow(), {
message: message,
title: title,
buttons: buttons,
cancelId: cancelId
2016-03-25 19:57:17 +00:00
})
}
2016-01-12 02:40:23 +00:00
2016-01-14 18:35:29 +00:00
// But we do not support prompt().
2016-03-25 19:57:17 +00:00
window.prompt = function () {
throw new Error('prompt() is and will not be supported.')
}
2016-01-12 02:40:23 +00:00
if (process.openerId != null) {
2016-03-25 19:57:17 +00:00
window.opener = BrowserWindowProxy.getOrCreate(process.openerId)
2016-01-12 02:40:23 +00:00
}
ipcRenderer.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (event, sourceId, message, sourceOrigin) {
2016-01-14 18:35:29 +00:00
// Manually dispatch event instead of using postMessage because we also need to
// set event.source.
2016-03-25 19:57:17 +00:00
event = document.createEvent('Event')
event.initEvent('message', false, false)
event.data = message
event.origin = sourceOrigin
event.source = BrowserWindowProxy.getOrCreate(sourceId)
2016-05-19 22:28:08 +00:00
window.dispatchEvent(event)
2016-03-25 19:57:17 +00:00
})
2016-01-12 02:40:23 +00:00
2016-01-14 18:35:29 +00:00
// Forward history operations to browser.
2016-03-25 19:57:17 +00:00
var sendHistoryOperation = function (...args) {
return ipcRenderer.send.apply(ipcRenderer, ['ELECTRON_NAVIGATION_CONTROLLER'].concat(args))
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
var getHistoryOperation = function (...args) {
return ipcRenderer.sendSync.apply(ipcRenderer, ['ELECTRON_SYNC_NAVIGATION_CONTROLLER'].concat(args))
2016-03-25 19:57:17 +00:00
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
window.history.back = function () {
return sendHistoryOperation('goBack')
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
window.history.forward = function () {
return sendHistoryOperation('goForward')
}
2016-01-12 02:40:23 +00:00
2016-03-25 19:57:17 +00:00
window.history.go = function (offset) {
return sendHistoryOperation('goToOffset', offset)
}
2016-01-12 02:40:23 +00:00
Object.defineProperty(window.history, 'length', {
2016-03-25 19:57:17 +00:00
get: function () {
return getHistoryOperation('length')
2016-01-12 02:40:23 +00:00
}
2016-03-25 19:57:17 +00:00
})
2016-01-12 02:40:23 +00:00
2016-04-13 13:56:11 +00:00
// The initial visibilityState.
let cachedVisibilityState = process.argv.includes('--hidden-page') ? 'hidden' : 'visible'
2016-04-13 13:56:11 +00:00
// Subscribe to visibilityState changes.
ipcRenderer.on('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, visibilityState) {
2016-04-13 14:10:31 +00:00
if (cachedVisibilityState !== visibilityState) {
cachedVisibilityState = visibilityState
document.dispatchEvent(new Event('visibilitychange'))
}
})
2016-01-14 18:35:29 +00:00
// Make document.hidden and document.visibilityState return the correct value.
2016-01-12 02:40:23 +00:00
Object.defineProperty(document, 'hidden', {
get: function () {
2016-04-13 14:10:31 +00:00
return cachedVisibilityState !== 'visible'
}
2016-03-25 19:57:17 +00:00
})
2016-01-12 02:40:23 +00:00
Object.defineProperty(document, 'visibilityState', {
2016-03-25 19:57:17 +00:00
get: function () {
return cachedVisibilityState
2016-01-12 02:40:23 +00:00
}
2016-03-25 19:57:17 +00:00
})