Merge pull request #3428 from atom/remote-enhance

Make it easier to use browser side modules
This commit is contained in:
Cheng Zhao 2015-11-14 00:26:03 +08:00
commit fe214e0806
12 changed files with 35 additions and 38 deletions

View file

@ -1,9 +1,6 @@
# 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:
@ -45,7 +42,7 @@ Object.defineProperties module.exports,
screen:
enumerable: true
get: -> require '../screen'
tray:
Tray:
enumerable: true
get: -> require '../tray'
# The internal modules, invisible unless you know their names.

View file

@ -18,10 +18,6 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) ->
meta.type = 'date' if value instanceof Date
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'
meta.type = 'value'
@ -49,8 +45,6 @@ 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
@ -212,3 +206,6 @@ ipcMain.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
event.returnValue = valueToMeta event.sender, guestViewManager.getGuest(guestInstanceId)
catch e
event.returnValue = exceptionToMeta e
ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) ->
event.returnValue = (name for name of electron)

View file

@ -1,6 +1,5 @@
if process.platform is 'linux' and process.type is 'renderer'
{remote} = require 'electron'
# On Linux we could not access clipboard in renderer process.
module.exports = remote.getBuiltin 'clipboard'
module.exports = require('electron').remote.clipboard
else
module.exports = process.atomBinding 'clipboard'

View file

@ -16,11 +16,7 @@ class CrashReporter
submitURL ?= options.submitUrl
deprecate.warn 'submitUrl', 'submitURL'
{app} =
if process.type is 'browser'
electron
else
electron.remote.require 'electron'
{app} = if process.type is 'browser' then electron else electron.remote
@productName ?= app.getName()
companyName ?= 'GitHub, Inc'

View file

@ -49,15 +49,6 @@ 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.
@ -134,6 +125,13 @@ ipcRenderer.on 'ATOM_RENDERER_CALLBACK', (event, id, args) ->
ipcRenderer.on 'ATOM_RENDERER_RELEASE_CALLBACK', (event, id) ->
callbacksRegistry.remove id
# List all built-in modules in browser process.
browserModules = ipcRenderer.sendSync 'ATOM_BROWSER_LIST_MODULES'
# And add a helper receiver for each one.
for name in browserModules
do (name) ->
Object.defineProperty exports, name, get: -> exports.getBuiltin name
# Get remote module.
# (Just like node's require, the modules are cached permanently, note that this
# is safe leak since the object is not expected to get freed in browser)
@ -144,6 +142,9 @@ exports.require = (module) ->
meta = ipcRenderer.sendSync 'ATOM_BROWSER_REQUIRE', module
moduleCache[module] = metaToValue meta
# Optimize require('electron').
moduleCache.electron = exports
# Alias to remote.require('electron').xxx.
builtinCache = {}
exports.getBuiltin = (module) ->

View file

@ -1 +1 @@
module.exports = require('electron').remote.require('electron').screen
module.exports = require('electron').remote.screen

View file

@ -33,7 +33,7 @@ convertToMenuTemplate = (items) ->
createMenu = (x, y, items, document) ->
{remote} = require 'electron'
{Menu} = remote.require 'electron'
{Menu} = remote
menu = Menu.buildFromTemplate convertToMenuTemplate(items)
# The menu is expected to show asynchronously.
@ -43,7 +43,7 @@ createMenu = (x, y, items, document) ->
showFileChooserDialog = (callback) ->
{remote} = require 'electron'
{dialog} = remote.require 'electron'
{dialog} = remote
files = dialog.showOpenDialog {}
callback pathToHtml5FileObject files[0] if files?

View file

@ -67,19 +67,17 @@ window.open = (url, frameName='', features='') ->
# Use the dialog API to implement alert().
window.alert = (message, title='') ->
dialog = remote.require 'dialog'
buttons = ['OK']
message = message.toString()
dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
remote.dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
# Alert should always return undefined.
return
# And the confirm().
window.confirm = (message, title='') ->
dialog = remote.require 'dialog'
buttons = ['OK', 'Cancel']
cancelId = 1
not dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons, cancelId}
not remote.dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons, cancelId}
# But we do not support prompt().
window.prompt = ->

View file

@ -17,8 +17,8 @@ the user right clicks the page:
<!-- index.html -->
<script>
const remote = require('electron').remote;
const Menu = remote.require('electron').Menu;
const MenuItem = remote.require('electron').MenuItem;
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;
var menu = new Menu();
menu.append(new MenuItem({ label: 'MenuItem1', click: function() { console.log('item 1 clicked'); } }));

View file

@ -13,7 +13,7 @@ renderer process:
```javascript
const remote = require('electron').remote;
const BrowserWindow = remote.require('electron').BrowserWindow;
const BrowserWindow = remote.BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL('https://github.com');
@ -118,6 +118,15 @@ passed to the main process. This involves cleaning up event handlers, or
ensuring the main process is explicitly told to deference callbacks that came
from a renderer process that is exiting.
## Accessing built-in modules in the main process
The built-in modules in the main process are added as getters in the `remote`
module, so you can use them directly like the `electron` module.
```javascript
const app = remote.app;
```
## Methods
The `remote` module has the following methods:

View file

@ -38,7 +38,7 @@ extra ability to use node modules:
<body>
<script>
const remote = require('electron').remote;
console.log(remote.require('electron').app.getVersion());
console.log(remote.app.getVersion());
</script>
</body>
</html>

View file

@ -24,7 +24,7 @@ Then you can load the extension in Electron by opening DevTools in any window,
and running the following code in the DevTools console:
```javascript
const BrowserWindow = require('electron').remote.require('electron').BrowserWindow;
const BrowserWindow = require('electron').remote.BrowserWindow;
BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome');
```