refactor: move common logic to handleRemoteCommand

This commit is contained in:
Milan Burda 2018-08-24 01:27:52 +02:00
parent f1fe485768
commit 28e4fcea3b
2 changed files with 108 additions and 138 deletions

View file

@ -19,10 +19,10 @@ const FUNCTION_PROPERTIES = [
// The remote functions in renderer processes. // The remote functions in renderer processes.
// id => Function // id => Function
let rendererFunctions = v8Util.createDoubleIDWeakMap() const rendererFunctions = v8Util.createDoubleIDWeakMap()
// Return the description of object's members: // Return the description of object's members:
let getObjectMembers = function (object) { const getObjectMembers = function (object) {
let names = Object.getOwnPropertyNames(object) let names = Object.getOwnPropertyNames(object)
// For Function, we should not override following properties even though they // For Function, we should not override following properties even though they
// are "own" properties. // are "own" properties.
@ -46,7 +46,7 @@ let getObjectMembers = function (object) {
} }
// Return the description of object's prototype. // Return the description of object's prototype.
let getObjectPrototype = function (object) { const getObjectPrototype = function (object) {
let proto = Object.getPrototypeOf(object) let proto = Object.getPrototypeOf(object)
if (proto === null || proto === Object.prototype) return null if (proto === null || proto === Object.prototype) return null
return { return {
@ -56,7 +56,7 @@ let getObjectPrototype = function (object) {
} }
// Convert a real value into meta data. // 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. // Determine the type of value.
const meta = { type: typeof value } const meta = { type: typeof value }
if (meta.type === 'object') { if (meta.type === 'object') {
@ -244,7 +244,7 @@ const callFunction = function (event, contextId, func, caller, args) {
func.apply(caller, args) func.apply(caller, args)
} else { } else {
const ret = func.apply(caller, args) const ret = func.apply(caller, args)
event.returnValue = valueToMeta(event.sender, contextId, ret, true) return valueToMeta(event.sender, contextId, ret, true)
} }
} catch (error) { } catch (error) {
// Catch functions thrown further down in function invocation and wrap // Catch functions thrown further down in function invocation and wrap
@ -257,148 +257,118 @@ const callFunction = function (event, contextId, func, caller, args) {
} }
} }
ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) { const handleRemoteCommand = function (channel, handler) {
try { ipcMain.on(channel, (event, contextId, ...args) => {
event.returnValue = valueToMeta(event.sender, contextId, process.mainModule.require(module)) let returnValue
} catch (error) { try {
event.returnValue = exceptionToMeta(event.sender, contextId, error) returnValue = handler(event, contextId, ...args)
} } catch (error) {
}) returnValue = exceptionToMeta(event.sender, contextId, error)
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)
}
})
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)
}
})
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)
}
})
ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
event.returnValue = valueToMeta(event.sender, contextId, event.sender)
})
ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let constructor = objectsRegistry.get(id)
if (constructor == null) {
throwRPCError(`Cannot call constructor on missing remote object ${id}`)
} }
if (returnValue !== undefined) {
event.returnValue = valueToMeta(event.sender, contextId, new constructor(...args)) event.returnValue = returnValue
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
})
ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
try {
args = unwrapArgs(event.sender, contextId, args)
let func = objectsRegistry.get(id)
if (func == null) {
throwRPCError(`Cannot call function on missing remote object ${id}`)
} }
})
}
callFunction(event, contextId, func, global, args) handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) {
} catch (error) { return valueToMeta(event.sender, contextId, process.mainModule.require(module))
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
}) })
ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) { handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
try { return valueToMeta(event.sender, contextId, electron[module])
args = unwrapArgs(event.sender, contextId, args)
let object = objectsRegistry.get(id)
if (object == null) {
throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
}
event.returnValue = valueToMeta(event.sender, contextId, new object[method](...args))
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
}) })
ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) { handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, name) {
try { return valueToMeta(event.sender, contextId, global[name])
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
}
callFunction(event, contextId, obj[method], obj, args)
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
}) })
ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) { handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
try { return valueToMeta(event.sender, contextId, event.sender.getOwnerBrowserWindow())
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
}
obj[name] = args[0]
event.returnValue = null
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
}) })
ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) { handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
try { return valueToMeta(event.sender, contextId, event.sender)
let obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
}
event.returnValue = valueToMeta(event.sender, contextId, obj[name])
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
}) })
ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, id) { handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, contextId, args)
let constructor = objectsRegistry.get(id)
if (constructor == null) {
throwRPCError(`Cannot call constructor on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, new constructor(...args))
})
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, contextId, args)
let func = objectsRegistry.get(id)
if (func == null) {
throwRPCError(`Cannot call function on missing remote object ${id}`)
}
return callFunction(event, contextId, func, global, args)
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, contextId, args)
let object = objectsRegistry.get(id)
if (object == null) {
throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, new object[method](...args))
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
}
return callFunction(event, contextId, obj[method], obj, args)
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, contextId, args)
let obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
}
obj[name] = args[0]
return null
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) {
let obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, obj[name])
})
handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, id) {
objectsRegistry.remove(event.sender, 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) objectsRegistry.clear(event.sender, contextId)
event.returnValue = null return null
}) })
ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) { handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
try { let guestViewManager = require('./guest-view-manager')
let guestViewManager = require('./guest-view-manager') return valueToMeta(event.sender, contextId, guestViewManager.getGuest(guestInstanceId))
event.returnValue = valueToMeta(event.sender, contextId, guestViewManager.getGuest(guestInstanceId))
} catch (error) {
event.returnValue = exceptionToMeta(event.sender, contextId, error)
}
}) })
ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, contextId, requestId, guestInstanceId, method, ...args) { ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, contextId, requestId, guestInstanceId, method, ...args) {

View file

@ -275,21 +275,21 @@ function metaToException (meta) {
return error return error
} }
function handleMessage (channel, handler) {
ipcRenderer.on(channel, (event, passedContextId, ...args) => {
if (passedContextId === contextId) {
handler(...args)
}
})
}
// Browser calls a callback in renderer. // Browser calls a callback in renderer.
ipcRenderer.on('ELECTRON_RENDERER_CALLBACK', (event, passedContextId, id, args) => { handleMessage('ELECTRON_RENDERER_CALLBACK', (id, args) => {
if (passedContextId !== contextId) {
// The invoked callback belongs to an old page in this renderer.
return
}
callbacksRegistry.apply(id, metaToValue(args)) callbacksRegistry.apply(id, metaToValue(args))
}) })
// A callback in browser is released. // A callback in browser is released.
ipcRenderer.on('ELECTRON_RENDERER_RELEASE_CALLBACK', (event, passedContextId, id) => { handleMessage('ELECTRON_RENDERER_RELEASE_CALLBACK', (id) => {
if (passedContextId !== contextId) {
// The freed callback belongs to an old page in this renderer.
return
}
callbacksRegistry.remove(id) callbacksRegistry.remove(id)
}) })