Browse Source

Optimize remote.require('electron')

Cheng Zhao 9 years ago
parent
commit
8b2942c279

+ 3 - 0
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:

+ 16 - 2
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]

+ 1 - 1
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:

+ 18 - 1
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 = ->