From 8b2942c2795d2371aea0dacfddd2b58a66752c58 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 20:30:40 +0800 Subject: [PATCH] Optimize remote.require('electron') --- atom/browser/api/lib/exports/electron.coffee | 3 +++ atom/browser/lib/rpc-server.coffee | 18 ++++++++++++++++-- atom/common/api/lib/exports/electron.coffee | 2 +- atom/renderer/api/lib/remote.coffee | 19 ++++++++++++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee index a09a6441c3f..6f70e6b38b3 100644 --- a/atom/browser/api/lib/exports/electron.coffee +++ b/atom/browser/api/lib/exports/electron.coffee @@ -1,6 +1,9 @@ # Import common modules. module.exports = require '../../../../common/api/lib/exports/electron' +v8Util = process.atomBinding 'v8_util' +v8Util.setHiddenValue module.exports, 'electronModule', true + Object.defineProperties module.exports, # Browser side modules, please sort with alphabet order. app: diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 3479f30f0b5..5c67026debf 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -1,5 +1,7 @@ -{ipcMain} = require 'electron' path = require 'path' + +electron = require 'electron' +{ipcMain} = electron objectsRegistry = require './objects-registry' v8Util = process.atomBinding 'v8_util' @@ -14,7 +16,11 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta.type = 'array' if Array.isArray value meta.type = 'error' if value instanceof Error meta.type = 'date' if value instanceof Date - meta.type = 'promise' if value? and value.constructor.name is 'Promise' + meta.type = 'promise' if value?.constructor.name is 'Promise' + + # require('electron'). + if meta.type is 'object' and v8Util.getHiddenValue value, 'electronModule' + meta.type = 'electronModule' # Treat simple objects as value. if optimizeSimpleObject and meta.type is 'object' and v8Util.getHiddenValue value, 'simple' @@ -43,6 +49,8 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta.members = plainObjectToMeta value else if meta.type is 'date' meta.value = value.getTime() + else if meta.type is 'electronModule' + meta.members = (name for name of value) else meta.type = 'value' meta.value = value @@ -122,6 +130,12 @@ ipcMain.on 'ATOM_BROWSER_REQUIRE', (event, module) -> catch e event.returnValue = exceptionToMeta e +ipcMain.on 'ATOM_BROWSER_GET_BUILTIN', (event, module) -> + try + event.returnValue = valueToMeta event.sender, electron[module] + catch e + event.returnValue = exceptionToMeta e + ipcMain.on 'ATOM_BROWSER_GLOBAL', (event, name) -> try event.returnValue = valueToMeta event.sender, global[name] diff --git a/atom/common/api/lib/exports/electron.coffee b/atom/common/api/lib/exports/electron.coffee index 26e8ce2f183..7bcb23a2ca4 100644 --- a/atom/common/api/lib/exports/electron.coffee +++ b/atom/common/api/lib/exports/electron.coffee @@ -4,7 +4,7 @@ Object.defineProperties exports, # Must be enumerable, otherwise it woulde be invisible to remote module. enumerable: true get: -> require '../clipboard' - crashRepoter: + crashReporter: enumerable: true get: -> require '../crash-reporter' nativeImage: diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 9faed14bf5c..09e7dcdcb57 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -18,7 +18,7 @@ wrapArgs = (args, visited=[]) -> type: 'array', value: wrapArgs(value, visited) else if Buffer.isBuffer value type: 'buffer', value: Array::slice.call(value, 0) - else if value? and value.constructor.name is 'Promise' + else if value?.constructor.name is 'Promise' type: 'promise', then: valueToMeta(value.then.bind(value)) else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId' type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId' @@ -49,6 +49,15 @@ metaToValue = (meta) -> when 'date' then new Date(meta.value) when 'exception' throw new Error("#{meta.message}\n#{meta.stack}") + when 'electronModule' + # require('electron'). + ret = {} + for member in meta.members + do (member) -> + Object.defineProperty ret, member, + enumerable: true + get: -> exports.getBuiltin member + ret else if meta.type is 'function' # A shadow class to represent the remote function object. @@ -135,6 +144,14 @@ exports.require = (module) -> meta = ipcRenderer.sendSync 'ATOM_BROWSER_REQUIRE', module moduleCache[module] = metaToValue meta +# Alias to remote.require('electron').xxx. +builtinCache = {} +exports.getBuiltin = (module) -> + return builtinCache[module] if builtinCache[module]? + + meta = ipcRenderer.sendSync 'ATOM_BROWSER_GET_BUILTIN', module + builtinCache[module] = metaToValue meta + # Get current BrowserWindow object. windowCache = null exports.getCurrentWindow = ->