From 666a668d913858025d542c4c2de347842c136108 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Aug 2016 13:58:48 -0700 Subject: [PATCH] Support remote function keys and property descriptors --- lib/renderer/api/remote.js | 36 +++++++++++++++++++++++++++++------- spec/api-ipc-spec.js | 4 ++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 22f5674e8..af741f924 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -111,13 +111,7 @@ const setObjectMembers = function (ref, object, metaId, members) { } } - // Wrap function in proxy for accessing remote properties - let descriptorFunction = new Proxy(remoteMemberFunction, { - get: (target, property, receiver) => { - if (target.hasOwnProperty(property)) return target[property] - return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_GET', metaId, member.name))[property] - } - }) + let descriptorFunction = proxyFunctionProperties(remoteMemberFunction, metaId, member.name) descriptor.get = function () { descriptorFunction.ref = ref // The member should reference its object. @@ -157,6 +151,34 @@ 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 + 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 diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 88e7af7a8..51147888e 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -64,6 +64,10 @@ describe('ipc module', function () { 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 () {