feat: preloads and nodeIntegration in iframes (#16425)

* feat: add support for node / preloads in subframes

This feature has delibrately been built / implemented in such a way
that it has minimum impact on existing apps / code-paths.
Without enabling the new "nodeSupportInSubFrames" option basically none of this
new code will be hit.

The things that I believe need extra scrutiny are:

* Introduction of `event.reply` for IPC events and usage of `event.reply` instead of `event.sender.send()`
* Usage of `node::FreeEnvironment(env)` when the new option is enabled in order to avoid memory leaks.  I have tested this quite a bit and haven't managed to cause a crash but it is still feature flagged behind the "nodeSupportInSubFrames" flag to avoid potential impact.

Closes #10569
Closes #10401
Closes #11868
Closes #12505
Closes #14035

* feat: add support preloads in subframes for sandboxed renderers

* spec: add tests for new nodeSupportInSubFrames option

* spec: fix specs for .reply and ._replyInternal for internal messages

* chore: revert change to use flag instead of environment set size

* chore: clean up subframe impl

* chore: apply suggestions from code review

Co-Authored-By: MarshallOfSound <samuel.r.attard@gmail.com>

* chore: clean up reply usage

* chore: fix TS docs generation

* chore: cleanup after rebase

* chore: rename wrap to add in event fns
This commit is contained in:
Samuel Attard 2019-01-22 11:24:46 -08:00 committed by GitHub
parent 92b9525cfd
commit 58a6fe13d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 332 additions and 49 deletions

View file

@ -143,6 +143,18 @@ WebContents.prototype._sendInternalToAll = function (channel, ...args) {
return this._send(internal, sendToAll, channel, args)
}
WebContents.prototype.sendToFrame = function (frameId, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument')
} else if (typeof frameId !== 'number') {
throw new Error('Missing required frameId argument')
}
const internal = false
const sendToAll = false
return this._sendToFrame(internal, sendToAll, frameId, channel, args)
}
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument')
@ -330,6 +342,22 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
}))
}
const addReplyToEvent = (event) => {
event.reply = (...args) => {
event.sender.sendToFrame(event.frameId, ...args)
}
}
const addReplyInternalToEvent = (event) => {
Object.defineProperty(event, '_replyInternal', {
configurable: false,
enumerable: false,
value: (...args) => {
event.sender._sendToFrameInternal(event.frameId, ...args)
}
})
}
// Add JavaScript wrappers for WebContents class.
WebContents.prototype._init = function () {
// The navigation controller.
@ -343,6 +371,7 @@ WebContents.prototype._init = function () {
// Dispatch IPC messages to the ipc module.
this.on('-ipc-message', function (event, [channel, ...args]) {
addReplyToEvent(event)
this.emit('ipc-message', event, channel, ...args)
ipcMain.emit(channel, event, ...args)
})
@ -354,11 +383,13 @@ WebContents.prototype._init = function () {
},
get: function () {}
})
addReplyToEvent(event)
this.emit('ipc-message-sync', event, channel, ...args)
ipcMain.emit(channel, event, ...args)
})
this.on('ipc-internal-message', function (event, [channel, ...args]) {
addReplyInternalToEvent(event)
ipcMainInternal.emit(channel, event, ...args)
})
@ -369,6 +400,7 @@ WebContents.prototype._init = function () {
},
get: function () {}
})
addReplyInternalToEvent(event)
ipcMainInternal.emit(channel, event, ...args)
})