Support remote function keys and property descriptors
authorKevin Sawicki <kevinsawicki@gmail.com>
Wed, 17 Aug 2016 20:58:48 +0000 (13:58 -0700)
committerKevin Sawicki <kevinsawicki@gmail.com>
Tue, 23 Aug 2016 00:07:18 +0000 (17:07 -0700)
lib/renderer/api/remote.js
spec/api-ipc-spec.js

index 22f5674..af741f9 100644 (file)
@@ -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
index 88e7af7..5114788 100644 (file)
@@ -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 () {