Merge pull request #6867 from electron/remote-function-properties
Allow accessing remote function properties
This commit is contained in:
commit
f854b27bfb
6 changed files with 115 additions and 4 deletions
|
@ -99,7 +99,7 @@ const setObjectMembers = function (ref, object, metaId, members) {
|
||||||
|
|
||||||
let descriptor = { enumerable: member.enumerable }
|
let descriptor = { enumerable: member.enumerable }
|
||||||
if (member.type === 'method') {
|
if (member.type === 'method') {
|
||||||
let remoteMemberFunction = function () {
|
const remoteMemberFunction = function () {
|
||||||
if (this && this.constructor === remoteMemberFunction) {
|
if (this && this.constructor === remoteMemberFunction) {
|
||||||
// Constructor call.
|
// Constructor call.
|
||||||
let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(arguments))
|
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)
|
return metaToValue(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let descriptorFunction = proxyFunctionProperties(remoteMemberFunction, metaId, member.name)
|
||||||
|
|
||||||
descriptor.get = function () {
|
descriptor.get = function () {
|
||||||
remoteMemberFunction.ref = ref // The member should reference its object.
|
descriptorFunction.ref = ref // The member should reference its object.
|
||||||
return remoteMemberFunction
|
return descriptorFunction
|
||||||
}
|
}
|
||||||
// Enable monkey-patch the method
|
// Enable monkey-patch the method
|
||||||
descriptor.set = function (value) {
|
descriptor.set = function (value) {
|
||||||
remoteMemberFunction = value
|
descriptorFunction = value
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
descriptor.configurable = true
|
descriptor.configurable = true
|
||||||
|
@ -148,6 +151,36 @@ const setObjectPrototype = function (ref, object, metaId, descriptor) {
|
||||||
Object.setPrototypeOf(object, proto)
|
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.
|
// Convert meta data from browser into real value.
|
||||||
const metaToValue = function (meta) {
|
const metaToValue = function (meta) {
|
||||||
var el, i, len, ref1, results, ret
|
var el, i, len, ref1, results, ret
|
||||||
|
|
|
@ -52,6 +52,34 @@ describe('ipc module', function () {
|
||||||
comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules'))
|
comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should work with function properties', function () {
|
||||||
|
var a = remote.require(path.join(fixtures, 'module', 'export-function-with-properties.js'))
|
||||||
|
assert.equal(typeof a, 'function')
|
||||||
|
assert.equal(a.bar, 'baz')
|
||||||
|
|
||||||
|
a = remote.require(path.join(fixtures, 'module', 'function-with-properties.js'))
|
||||||
|
assert.equal(typeof a, 'object')
|
||||||
|
assert.equal(a.foo(), 'hello')
|
||||||
|
assert.equal(a.foo.bar, 'baz')
|
||||||
|
assert.equal(a.foo.nested.prop, 'yes')
|
||||||
|
assert.equal(a.foo.method1(), 'world')
|
||||||
|
assert.equal(a.foo.method1.prop1(), 123)
|
||||||
|
|
||||||
|
assert.ok(Object.keys(a.foo).includes('bar'))
|
||||||
|
assert.ok(Object.keys(a.foo).includes('nested'))
|
||||||
|
assert.ok(Object.keys(a.foo).includes('method1'))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should work with static class members', function () {
|
||||||
|
var a = remote.require(path.join(fixtures, 'module', 'remote-static.js'))
|
||||||
|
assert.equal(typeof a.Foo, 'function')
|
||||||
|
assert.equal(a.Foo.foo(), 3)
|
||||||
|
assert.equal(a.Foo.bar, 'baz')
|
||||||
|
|
||||||
|
var foo = new a.Foo()
|
||||||
|
assert.equal(foo.baz(), 123)
|
||||||
|
})
|
||||||
|
|
||||||
it('handles circular references in arrays and objects', function () {
|
it('handles circular references in arrays and objects', function () {
|
||||||
var a = remote.require(path.join(fixtures, 'module', 'circular.js'))
|
var a = remote.require(path.join(fixtures, 'module', 'circular.js'))
|
||||||
|
|
||||||
|
@ -120,6 +148,10 @@ describe('ipc module', function () {
|
||||||
assert.equal(property.property, 1127)
|
assert.equal(property.property, 1127)
|
||||||
property.property = 1007
|
property.property = 1007
|
||||||
assert.equal(property.property, 1007)
|
assert.equal(property.property, 1007)
|
||||||
|
assert.equal(property.getFunctionProperty(), 'foo-browser')
|
||||||
|
property.func.property = 'bar'
|
||||||
|
assert.equal(property.getFunctionProperty(), 'bar-browser')
|
||||||
|
|
||||||
var property2 = remote.require(path.join(fixtures, 'module', 'property.js'))
|
var property2 = remote.require(path.join(fixtures, 'module', 'property.js'))
|
||||||
assert.equal(property2.property, 1007)
|
assert.equal(property2.property, 1007)
|
||||||
property.property = 1127
|
property.property = 1127
|
||||||
|
|
4
spec/fixtures/module/export-function-with-properties.js
vendored
Normal file
4
spec/fixtures/module/export-function-with-properties.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
function foo () {}
|
||||||
|
foo.bar = 'baz'
|
||||||
|
|
||||||
|
module.exports = foo
|
17
spec/fixtures/module/function-with-properties.js
vendored
Normal file
17
spec/fixtures/module/function-with-properties.js
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
function foo () {
|
||||||
|
return 'hello'
|
||||||
|
}
|
||||||
|
foo.bar = 'baz'
|
||||||
|
foo.nested = {
|
||||||
|
prop: 'yes'
|
||||||
|
}
|
||||||
|
foo.method1 = function () {
|
||||||
|
return 'world'
|
||||||
|
}
|
||||||
|
foo.method1.prop1 = function () {
|
||||||
|
return 123
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
foo: foo
|
||||||
|
}
|
10
spec/fixtures/module/property.js
vendored
10
spec/fixtures/module/property.js
vendored
|
@ -1 +1,11 @@
|
||||||
exports.property = 1127
|
exports.property = 1127
|
||||||
|
|
||||||
|
function func () {
|
||||||
|
|
||||||
|
}
|
||||||
|
func.property = 'foo'
|
||||||
|
exports.func = func
|
||||||
|
|
||||||
|
exports.getFunctionProperty = () => {
|
||||||
|
return `${func.property}-${process.type}`
|
||||||
|
}
|
||||||
|
|
15
spec/fixtures/module/remote-static.js
vendored
Normal file
15
spec/fixtures/module/remote-static.js
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
class Foo {
|
||||||
|
static foo () {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
|
||||||
|
baz () {
|
||||||
|
return 123
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo.bar = 'baz'
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Foo: Foo
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue