128 lines
4.7 KiB
CoffeeScript
128 lines
4.7 KiB
CoffeeScript
EventEmitter = require('events').EventEmitter
|
|
IDWeakMap = require 'id-weak-map'
|
|
app = require 'app'
|
|
ipc = require 'ipc'
|
|
|
|
BrowserWindow = process.atomBinding('window').BrowserWindow
|
|
BrowserWindow::__proto__ = EventEmitter.prototype
|
|
|
|
wrapWebContents = (webContents) ->
|
|
return null unless webContents.isAlive()
|
|
# webContents is an EventEmitter.
|
|
webContents.__proto__ = EventEmitter.prototype
|
|
|
|
# Wrap around the send method.
|
|
webContents.send = (args...) ->
|
|
@_send 'ATOM_INTERNAL_MESSAGE', [args...]
|
|
|
|
# Dispatch the ipc messages.
|
|
webContents.on 'ipc-message', (event, channel, args...) =>
|
|
Object.defineProperty event, 'sender', value: webContents
|
|
ipc.emit channel, event, args...
|
|
webContents.on 'ipc-message-sync', (event, channel, args...) =>
|
|
set = (value) -> event.sendReply JSON.stringify(value)
|
|
Object.defineProperty event, 'returnValue', {set}
|
|
Object.defineProperty event, 'sender', value: webContents
|
|
ipc.emit channel, event, args...
|
|
|
|
webContents
|
|
|
|
# Store all created windows in the weak map.
|
|
BrowserWindow.windows = new IDWeakMap
|
|
|
|
BrowserWindow::_init = ->
|
|
# Simulate the application menu on platforms other than OS X.
|
|
if process.platform isnt 'darwin'
|
|
menu = app.getApplicationMenu()
|
|
@setMenu menu if menu?
|
|
|
|
@webContents = @getWebContents()
|
|
@webContents.once 'destroyed', => @webContents = null
|
|
|
|
# Define getter for devToolsWebContents.
|
|
devToolsWebContents = null
|
|
@__defineGetter__ 'devToolsWebContents', ->
|
|
if @isDevToolsOpened()
|
|
# Get a new devToolsWebContents if previous one has been destroyed, it
|
|
# could happen when the devtools has been closed and then reopened.
|
|
devToolsWebContents = null unless devToolsWebContents?.isAlive()
|
|
devToolsWebContents ?= @getDevToolsWebContents()
|
|
else
|
|
devToolsWebContents = null
|
|
|
|
# Remember the window.
|
|
id = BrowserWindow.windows.add this
|
|
|
|
# Remove the window from weak map immediately when it's destroyed, since we
|
|
# could be iterating windows before GC happended.
|
|
@once 'closed', ->
|
|
BrowserWindow.windows.remove id if BrowserWindow.windows.has id
|
|
|
|
# Tell the rpc server that a render view has been deleted and we need to
|
|
# release all objects owned by it.
|
|
@webContents.on 'render-view-deleted', (event, processId, routingId) ->
|
|
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', processId, routingId
|
|
|
|
BrowserWindow::toggleDevTools = ->
|
|
if @isDevToolsOpened() then @closeDevTools() else @openDevTools()
|
|
|
|
BrowserWindow::getWebContents = ->
|
|
wrapWebContents @_getWebContents()
|
|
|
|
BrowserWindow::getDevToolsWebContents = ->
|
|
wrapWebContents @_getDevToolsWebContents()
|
|
|
|
BrowserWindow::restart = ->
|
|
@loadUrl(@getUrl())
|
|
|
|
BrowserWindow::setMenu = (menu) ->
|
|
if process.platform is 'darwin'
|
|
throw new Error('BrowserWindow.setMenu is not available on OS X')
|
|
|
|
throw new TypeError('Invalid menu') unless menu?.constructor?.name is 'Menu'
|
|
|
|
@menu = menu # Keep a reference of menu in case of GC.
|
|
@menu.attachToWindow this
|
|
|
|
BrowserWindow.getAllWindows = ->
|
|
windows = BrowserWindow.windows
|
|
windows.get key for key in windows.keys()
|
|
|
|
BrowserWindow.getFocusedWindow = ->
|
|
windows = BrowserWindow.getAllWindows()
|
|
return window for window in windows when window.isFocused()
|
|
|
|
BrowserWindow.fromProcessIdAndRoutingId = (processId, routingId) ->
|
|
windows = BrowserWindow.getAllWindows()
|
|
return window for window in windows when window.getProcessId() == processId and
|
|
window.getRoutingId() == routingId
|
|
|
|
BrowserWindow.fromDevTools = (processId, routingId) ->
|
|
windows = BrowserWindow.getAllWindows()
|
|
for window in windows when window.isDevToolsOpened()
|
|
devtools = window.getDevTools()
|
|
return window if devtools.processId == processId and
|
|
devtools.routingId == routingId
|
|
|
|
# Helpers.
|
|
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
|
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
|
|
|
# Be compatible with old API.
|
|
BrowserWindow::getUrl = -> @webContents.getUrl()
|
|
BrowserWindow::reload = -> @webContents.reload()
|
|
BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache()
|
|
BrowserWindow::getPageTitle = -> @webContents.getTitle()
|
|
BrowserWindow::isLoading = -> @webContents.isLoading()
|
|
BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse()
|
|
BrowserWindow::stop = -> @webContents.stop()
|
|
BrowserWindow::getRoutingId = -> @webContents.getRoutingId()
|
|
BrowserWindow::getProcessId = -> @webContents.getProcessId()
|
|
BrowserWindow::isCrashed = -> @webContents.isCrashed()
|
|
BrowserWindow::getDevTools = ->
|
|
processId: @devToolsWebContents.getProcessId()
|
|
routingId: @devToolsWebContents.getRoutingId()
|
|
BrowserWindow::executeJavaScriptInDevTools = (code) ->
|
|
@devToolsWebContents.executeJavaScript code
|
|
|
|
module.exports = BrowserWindow
|