refactor: move common logic to handleRemoteCommand
This commit is contained in:
parent
f1fe485768
commit
28e4fcea3b
2 changed files with 108 additions and 138 deletions
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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') {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
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}`)
|
||||
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)
|
||||
}
|
||||
|
||||
event.returnValue = valueToMeta(event.sender, contextId, new constructor(...args))
|
||||
} 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}`)
|
||||
if (returnValue !== undefined) {
|
||||
event.returnValue = returnValue
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
callFunction(event, contextId, func, global, args)
|
||||
} 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_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
|
||||
try {
|
||||
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)
|
||||
}
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
|
||||
return valueToMeta(event.sender, contextId, electron[module])
|
||||
})
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
|
||||
try {
|
||||
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)
|
||||
}
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, name) {
|
||||
return valueToMeta(event.sender, contextId, global[name])
|
||||
})
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
|
||||
try {
|
||||
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)
|
||||
}
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
|
||||
return valueToMeta(event.sender, contextId, event.sender.getOwnerBrowserWindow())
|
||||
})
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) {
|
||||
try {
|
||||
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)
|
||||
}
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
|
||||
return valueToMeta(event.sender, contextId, event.sender)
|
||||
})
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue