Skip to content

Commit

Permalink
refactor: move common logic to handleRemoteCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
miniak committed Aug 25, 2018
1 parent 2a253c7 commit d241964
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 117 deletions.
184 changes: 77 additions & 107 deletions lib/browser/rpc-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const FUNCTION_PROPERTIES = [

// The remote functions in renderer processes.
// id => Function
let rendererFunctions = v8Util.createDoubleIDWeakMap()
const rendererFunctions = v8Util.createDoubleIDWeakMap()

// Return the description of object's members:
let getObjectMembers = function (object) {
const getObjectMembers = function (object) {
let names = Object.getOwnPropertyNames(object)
// For Function, we should not override following properties even though they
// are "own" properties.
Expand All @@ -46,7 +46,7 @@ let getObjectMembers = function (object) {
}

// Return the description of object's prototype.
let getObjectPrototype = function (object) {
const getObjectPrototype = function (object) {
let proto = Object.getPrototypeOf(object)
if (proto === null || proto === Object.prototype) return null
return {
Expand All @@ -56,7 +56,7 @@ let getObjectPrototype = function (object) {
}

// Convert a real value into meta data.
let valueToMeta = function (sender, contextId, value, optimizeSimpleObject = false) {
const valueToMeta = function (sender, contextId, value, optimizeSimpleObject = false) {
// Determine the type of value.
const meta = { type: typeof value }
if (meta.type === 'object') {
Expand Down Expand Up @@ -244,7 +244,7 @@ const callFunction = function (event, contextId, func, caller, args) {
func.apply(caller, args)
} else {
const ret = func.apply(caller, args)
event.returnValue = valueToMeta(event.sender, contextId, ret, true)
return valueToMeta(event.sender, contextId, ret, true)
}
} catch (error) {
// Catch functions thrown further down in function invocation and wrap
Expand All @@ -257,148 +257,118 @@ const callFunction = function (event, contextId, func, caller, args) {
}
}

ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) {
try {
event.returnValue = valueToMeta(event.sender, contextId, process.mainModule.require(module))
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
})
const handleRemoteCommand = function (channel, handler) {
ipcMain.on(channel, (event, contextId, ...args) => {
let returnValue
try {
returnValue = handler(event, contextId, ...args)
} catch (error) {
returnValue = exceptionToMeta(event.sender, contextId, error)
}
if (returnValue !== undefined) {
event.returnValue = returnValue
}
})
}

ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
try {
event.returnValue = valueToMeta(event.sender, contextId, electron[module])
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) {
return valueToMeta(event.sender, contextId, process.mainModule.require(module))
})

ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, contextId, name) {
try {
event.returnValue = valueToMeta(event.sender, contextId, global[name])
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
return valueToMeta(event.sender, contextId, electron[module])
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
try {
event.returnValue = valueToMeta(event.sender, contextId, event.sender.getOwnerBrowserWindow())
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, name) {
return valueToMeta(event.sender, contextId, global[name])
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
event.returnValue = valueToMeta(event.sender, contextId, event.sender)
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
return valueToMeta(event.sender, contextId, event.sender.getOwnerBrowserWindow())
})

ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let constructor = objectsRegistry.get(id)
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
return valueToMeta(event.sender, contextId, event.sender)
})

if (constructor == null) {
throwRPCError(`Cannot call constructor on missing remote object ${id}`)
}
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, contextId, args)
let constructor = objectsRegistry.get(id)

event.returnValue = valueToMeta(event.sender, contextId, new constructor(...args))
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
if (constructor == null) {
throwRPCError(`Cannot call constructor on missing remote object ${id}`)
}
})

ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let func = objectsRegistry.get(id)
return valueToMeta(event.sender, contextId, new constructor(...args))
})

if (func == null) {
throwRPCError(`Cannot call function on missing remote object ${id}`)
}
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, contextId, args)
let func = objectsRegistry.get(id)

callFunction(event, contextId, func, global, args)
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
if (func == null) {
throwRPCError(`Cannot call function on missing remote object ${id}`)
}
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let object = objectsRegistry.get(id)
return callFunction(event, contextId, func, global, args)
})

if (object == null) {
throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
}
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, contextId, args)
let object = objectsRegistry.get(id)

event.returnValue = valueToMeta(event.sender, contextId, new object[method](...args))
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
if (object == null) {
throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
}
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)
return valueToMeta(event.sender, contextId, new object[method](...args))
})

if (obj == null) {
throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
}
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)

callFunction(event, contextId, obj[method], obj, args)
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
if (obj == null) {
throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
}
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)
return callFunction(event, contextId, obj[method], obj, args)
})

if (obj == null) {
throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
}
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)

obj[name] = args[0]
event.returnValue = null
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
if (obj == null) {
throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
}
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) {
try {
let obj = objectsRegistry.get(id)
obj[name] = args[0]
return null
})

if (obj == null) {
throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
}
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) {
let obj = objectsRegistry.get(id)

event.returnValue = valueToMeta(event.sender, contextId, obj[name])
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
if (obj == null) {
throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
}

return valueToMeta(event.sender, contextId, obj[name])
})

ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, id) {
handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, id) {
objectsRegistry.remove(event.sender, contextId, id)
})

ipcMain.on('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
objectsRegistry.clear(event.sender, contextId)
event.returnValue = null
return null
})

ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
try {
let guestViewManager = require('./guest-view-manager')
event.returnValue = valueToMeta(event.sender, contextId, guestViewManager.getGuest(guestInstanceId))
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
let guestViewManager = require('./guest-view-manager')
return valueToMeta(event.sender, contextId, guestViewManager.getGuest(guestInstanceId))
})

ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, contextId, requestId, guestInstanceId, method, ...args) {
Expand Down
20 changes: 10 additions & 10 deletions lib/renderer/api/remote.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,21 +275,21 @@ function metaToException (meta) {
return error
}

function handleMessage (channel, handler) {
ipcRenderer.on(channel, (event, passedContextId, ...args) => {
if (passedContextId === contextId) {
handler(...args)
}
})
}

// Browser calls a callback in renderer.
ipcRenderer.on('ELECTRON_RENDERER_CALLBACK', (event, passedContextId, id, args) => {
if (passedContextId !== contextId) {
// The invoked callback belongs to an old page in this renderer.
return
}
handleMessage('ELECTRON_RENDERER_CALLBACK', (id, args) => {
callbacksRegistry.apply(id, metaToValue(args))
})

// A callback in browser is released.
ipcRenderer.on('ELECTRON_RENDERER_RELEASE_CALLBACK', (event, passedContextId, id) => {
if (passedContextId !== contextId) {
// The freed callback belongs to an old page in this renderer.
return
}
handleMessage('ELECTRON_RENDERER_RELEASE_CALLBACK', (id) => {
callbacksRegistry.remove(id)
})

Expand Down

0 comments on commit d241964

Please sign in to comment.