Merge pull request #6867 from electron/remote-function-properties

Allow accessing remote function properties
This commit is contained in:
Cheng Zhao 2016-08-31 17:28:09 +09:00 committed by GitHub
commit f854b27bfb
6 changed files with 115 additions and 4 deletions

View file

@ -99,7 +99,7 @@ const setObjectMembers = function (ref, object, metaId, members) {
let descriptor = { enumerable: member.enumerable }
if (member.type === 'method') {
let remoteMemberFunction = function () {
const remoteMemberFunction = function () {
if (this && this.constructor === remoteMemberFunction) {
// Constructor call.
let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(arguments))
@ -110,13 +110,16 @@ const setObjectMembers = function (ref, object, metaId, members) {
return metaToValue(ret)
}
}
let descriptorFunction = proxyFunctionProperties(remoteMemberFunction, metaId, member.name)
descriptor.get = function () {
remoteMemberFunction.ref = ref // The member should reference its object.
return remoteMemberFunction
descriptorFunction.ref = ref // The member should reference its object.
return descriptorFunction
}
// Enable monkey-patch the method
descriptor.set = function (value) {
remoteMemberFunction = value
descriptorFunction = value
return value
}
descriptor.configurable = true
@ -148,6 +151,36 @@ const setObjectPrototype = function (ref, object, metaId, descriptor) {
Object.setPrototypeOf(object, proto)
}
// Wrap function in Proxy for accessing remote properties
const proxyFunctionProperties = function (remoteMemberFunction, metaId, name) {
let loaded = false
// Lazily load function properties
const loadRemoteProperties = () => {
if (loaded) return
loaded = true
const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_GET', metaId, name)
setObjectMembers(remoteMemberFunction, remoteMemberFunction, meta.id, meta.members)
}
return new Proxy(remoteMemberFunction, {
get: (target, property, receiver) => {
if (!target.hasOwnProperty(property)) loadRemoteProperties()
return target[property]
},
ownKeys: (target) => {
loadRemoteProperties()
return Object.getOwnPropertyNames(target)
},
getOwnPropertyDescriptor: (target, property) => {
let descriptor = Object.getOwnPropertyDescriptor(target, property)
if (descriptor != null) return descriptor
loadRemoteProperties()
return Object.getOwnPropertyDescriptor(target, property)
}
})
}
// Convert meta data from browser into real value.
const metaToValue = function (meta) {
var el, i, len, ref1, results, ret