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…
	
	Add table
		Add a link
		
	
		Reference in a new issue