From 5c318932c2e8992612c3eeee0be17b33cc032e3c Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 2 Nov 2017 21:07:40 -0400 Subject: [PATCH] add some structural changes --- lib/renderer/api/remote.js | 100 ++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index e38c531c90a5..1e4c292ac834 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -103,41 +103,40 @@ function setObjectMembers (ref, object, metaId, members) { let descriptor = { enumerable: member.enumerable } if (member.type === 'method') { const remoteMemberFunction = function (...args) { + let command if (this && this.constructor === remoteMemberFunction) { - // Constructor call. - const ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(args)) - return metaToValue(ret) + command = 'ELECTRON_BROWSER_MEMBER_CONSTRUCTOR' } else { - // Call member function. - const ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CALL', metaId, member.name, wrapArgs(args)) - return metaToValue(ret) + command = 'ELECTRON_BROWSER_MEMBER_CALL' } + const ret = ipcRenderer.sendSync(command, metaId, member.name, wrapArgs(args)) + return metaToValue(ret) } let descriptorFunction = proxyFunctionProperties(remoteMemberFunction, metaId, member.name) - descriptor.get = function () { + descriptor.get = () => { descriptorFunction.ref = ref // The member should reference its object. return descriptorFunction } // Enable monkey-patch the method - descriptor.set = function (value) { + descriptor.set = (value) => { descriptorFunction = value return value } descriptor.configurable = true } else if (member.type === 'get') { - descriptor.get = function () { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_GET', metaId, member.name)) + descriptor.get = () => { + const command = 'ELECTRON_BROWSER_MEMBER_GET' + const meta = ipcRenderer.sendSync(command, metaId, member.name) + return metaToValue(meta) } - // Only set setter when it is writable. if (member.writable) { - descriptor.set = function (value) { + descriptor.set = (value) => { const args = wrapArgs([value]) - const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_SET', metaId, member.name, args) - // Meta will be non-null when a setter error occurred so parse it - // to a value so it gets re-thrown. + const command = 'ELECTRON_BROWSER_MEMBER_SET' + const meta = ipcRenderer.sendSync(command, metaId, member.name, args) if (meta != null) metaToValue(meta) return value } @@ -151,7 +150,7 @@ function setObjectMembers (ref, object, metaId, members) { // Populate object's prototype from descriptor. // This matches |getObjectPrototype| in rpc-server. function setObjectPrototype (ref, object, metaId, descriptor) { - if (!descriptor) return + if (descriptor === null) return let proto = {} setObjectMembers(ref, proto, metaId, descriptor.members) setObjectPrototype(ref, proto, metaId, descriptor.proto) @@ -166,7 +165,8 @@ function proxyFunctionProperties (remoteMemberFunction, metaId, name) { const loadRemoteProperties = () => { if (loaded) return loaded = true - const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_GET', metaId, name) + const command = 'ELECTRON_BROWSER_MEMBER_GET' + const meta = ipcRenderer.sendSync(command, metaId, name) setObjectMembers(remoteMemberFunction, remoteMemberFunction, meta.id, meta.members) } @@ -179,13 +179,9 @@ function proxyFunctionProperties (remoteMemberFunction, metaId, name) { get: (target, property, receiver) => { if (!target.hasOwnProperty(property)) loadRemoteProperties() const value = target[property] - - // Bind toString to target if it is a function to avoid - // Function.prototype.toString is not generic errors if (property === 'toString' && typeof value === 'function') { return value.bind(target) } - return value }, ownKeys: (target) => { @@ -204,29 +200,34 @@ function proxyFunctionProperties (remoteMemberFunction, metaId, name) { // Convert meta data from browser into real value. function metaToValue (meta) { const types = { - 'value': () => meta.value, - 'array': () => meta.members.map((member) => metaToValue(member)), - 'buffer': () => Buffer.from(meta.value), - 'promise': () => resolvePromise({then: metaToValue(meta.then)}), - 'error': () => metaToPlainObject(meta), - 'date': () => new Date(meta.value), - 'exception': () => new Error(`${meta.message}\n${meta.stack}`) + value: () => meta.value, + array: () => meta.members.map((member) => metaToValue(member)), + buffer: () => Buffer.from(meta.value), + promise: () => resolvePromise({then: metaToValue(meta.then)}), + error: () => metaToPlainObject(meta), + date: () => new Date(meta.value), + exception: () => { throw new Error(`${meta.message}\n${meta.stack}`) } } if (meta.type in types) { - return types[meta.type] + return types[meta.type]() } else { let ret - if (remoteObjectCache.has(meta.id)) return remoteObjectCache.get(meta.id) + if (remoteObjectCache.has(meta.id)) { + return remoteObjectCache.get(meta.id) + } // A shadow class to represent the remote function object. if (meta.type === 'function') { let remoteFunction = function (...args) { + let command if (this && this.constructor === remoteFunction) { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(args))) + command = 'ELECTRON_BROWSER_CONSTRUCTOR' } else { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(args))) + command = 'ELECTRON_BROWSER_FUNCTION_CALL' } + const obj = ipcRenderer.sendSync(command, meta.id, wrapArgs(args)) + return metaToValue(obj) } ret = remoteFunction } else { @@ -235,8 +236,6 @@ function metaToValue (meta) { setObjectMembers(ret, ret, meta.id, meta.members) setObjectPrototype(ret, ret, meta.id, meta.proto) - - // Set constructor.name to object's name. Object.defineProperty(ret.constructor, 'name', { value: meta.name }) // Track delegate obj's lifetime & tell browser to clean up when object is GCed. @@ -254,7 +253,10 @@ function metaToPlainObject (meta) { const obj = {} const members = meta.members - members.forEach((key, val) => { obj[key] = val }) + members.forEach((member) => { + const {key, value} = member + obj[key] = value + }) return obj } @@ -269,22 +271,27 @@ ipcRenderer.on('ELECTRON_RENDERER_RELEASE_CALLBACK', (event, id) => { }) process.on('exit', () => { - ipcRenderer.sendSync('ELECTRON_BROWSER_CONTEXT_RELEASE') + const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE' + ipcRenderer.sendSync(command) }) -// Get remote module. exports.require = (module) => { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_REQUIRE', module)) + const command = 'ELECTRON_BROWSER_REQUIRE' + const meta = ipcRenderer.sendSync(command, module) + return metaToValue(meta) } // Alias to remote.require('electron').xxx. exports.getBuiltin = (module) => { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_GET_BUILTIN', module)) + const command = 'ELECTRON_BROWSER_GET_BUILTIN' + const meta = ipcRenderer.sendSync(command, module) + return metaToValue(meta) } -// Get current BrowserWindow. exports.getCurrentWindow = () => { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_CURRENT_WINDOW')) + const command = 'ELECTRON_BROWSER_CURRENT_WINDOW' + const meta = ipcRenderer.sendSync(command) + return metaToValue(meta) } // Get current WebContents object. @@ -294,7 +301,9 @@ exports.getCurrentWebContents = () => { // Get a global object in browser. exports.getGlobal = (name) => { - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_GLOBAL', name)) + const command = 'ELECTRON_BROWSER_GLOBAL' + const meta = ipcRenderer.sendSync(command, name) + return metaToValue(meta) } // Get the process object in browser. @@ -309,15 +318,14 @@ exports.createFunctionWithReturnValue = (returnValue) => { // Get the guest WebContents from guestInstanceId. exports.getGuestWebContents = (guestInstanceId) => { - const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', guestInstanceId) + const command = 'ELECTRON_BROWSER_GUEST_WEB_CONTENTS' + const meta = ipcRenderer.sendSync(command, guestInstanceId) return metaToValue(meta) } const addBuiltinProperty = (name) => { Object.defineProperty(exports, name, { - get: function () { - return exports.getBuiltin(name) - } + get: () => exports.getBuiltin(name) }) }