Merge branch 'master' into mq-replace-optimist

This commit is contained in:
Machiste Quintana
2015-05-19 19:35:29 -04:00
67 changed files with 2074 additions and 1259 deletions

View File

@@ -9,11 +9,10 @@ _ = require 'underscore-plus'
# and maintain the state of all menu items.
module.exports =
class ApplicationMenu
constructor: (@version) ->
constructor: (@version, @autoUpdateManager) ->
@windowTemplates = new WeakMap()
@setActiveTemplate(@getDefaultTemplate())
global.atomApplication.autoUpdateManager.on 'state-changed', (state) =>
@showUpdateMenuItem(state)
@autoUpdateManager.on 'state-changed', (state) => @showUpdateMenuItem(state)
# Public: Updates the entire menu with the given keybindings.
#
@@ -33,7 +32,7 @@ class ApplicationMenu
@menu = Menu.buildFromTemplate(_.deepClone(template))
Menu.setApplicationMenu(@menu)
@showUpdateMenuItem(global.atomApplication.autoUpdateManager.getState())
@showUpdateMenuItem(@autoUpdateManager.getState())
# Register a BrowserWindow with this application menu.
addWindow: (window) ->
@@ -162,8 +161,8 @@ class ApplicationMenu
firstKeystroke = keystrokesByCommand[command]?[0]
return null unless firstKeystroke
modifiers = firstKeystroke.split('-')
key = modifiers.pop()
modifiers = firstKeystroke.split(/-(?=.)/)
key = modifiers.pop().toUpperCase().replace('+', 'Plus')
modifiers = modifiers.map (modifier) ->
modifier.replace(/shift/ig, "Shift")
@@ -171,5 +170,5 @@ class ApplicationMenu
.replace(/ctrl/ig, "Ctrl")
.replace(/alt/ig, "Alt")
keys = modifiers.concat([key.toUpperCase()])
keys = modifiers.concat([key])
keys.join("+")

View File

@@ -56,6 +56,7 @@ class AtomApplication
atomProtocolHandler: null
resourcePath: null
version: null
quitting: false
exit: (status) -> app.exit(status)
@@ -71,8 +72,8 @@ class AtomApplication
@pathsToOpen ?= []
@windows = []
@autoUpdateManager = new AutoUpdateManager(@version)
@applicationMenu = new ApplicationMenu(@version)
@autoUpdateManager = new AutoUpdateManager(@version, options.test)
@applicationMenu = new ApplicationMenu(@version, @autoUpdateManager)
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)
@listenForArgumentsFromNewProcess()
@@ -85,20 +86,26 @@ class AtomApplication
else
@loadState() or @openPath(options)
openWithOptions: ({pathsToOpen, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, apiPreviewMode, newWindow, specDirectory, logFile}) ->
openWithOptions: ({pathsToOpen, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, apiPreviewMode, newWindow, specDirectory, logFile, profileStartup}) ->
if test
@runSpecs({exitWhenDone: true, @resourcePath, specDirectory, logFile})
@runSpecs({exitWhenDone: true, @resourcePath, specDirectory, logFile, apiPreviewMode})
else if pathsToOpen.length > 0
@openPaths({pathsToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode})
@openPaths({pathsToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, profileStartup})
else if urlsToOpen.length > 0
@openUrl({urlToOpen, devMode, safeMode, apiPreviewMode}) for urlToOpen in urlsToOpen
else
@openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode}) # Always open a editor window if this is the first instance of Atom.
# Always open a editor window if this is the first instance of Atom.
@openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, profileStartup})
# Public: Removes the {AtomWindow} from the global window list.
removeWindow: (window) ->
@windows.splice @windows.indexOf(window), 1
@applicationMenu?.enableWindowSpecificItems(false) if @windows.length is 0
if @windows.length is 0
@applicationMenu?.enableWindowSpecificItems(false)
if process.platform in ['win32', 'linux']
app.quit()
return
@saveState() unless window.isSpec or @quitting
# Public: Adds the {AtomWindow} to the global window list.
addWindow: (window) ->
@@ -109,10 +116,14 @@ class AtomApplication
unless window.isSpec
focusHandler = => @lastFocusedWindow = window
blurHandler = => @saveState()
window.browserWindow.on 'focus', focusHandler
window.browserWindow.on 'blur', blurHandler
window.browserWindow.once 'closed', =>
@lastFocusedWindow = null if window is @lastFocusedWindow
window.browserWindow.removeListener 'focus', focusHandler
window.browserWindow.removeListener 'blur', blurHandler
window.browserWindow.webContents.once 'did-finish-load', => @saveState()
# Creates server to listen for additional atom application launches.
#
@@ -175,7 +186,7 @@ class AtomApplication
@on 'application:report-issue', -> require('shell').openExternal('https://github.com/atom/atom/blob/master/CONTRIBUTING.md#submitting-issues')
@on 'application:search-issues', -> require('shell').openExternal('https://github.com/issues?q=+is%3Aissue+user%3Aatom')
@on 'application:install-update', -> @autoUpdateManager.install()
@on 'application:install-update', => @autoUpdateManager.install()
@on 'application:check-for-update', => @autoUpdateManager.check()
if process.platform is 'darwin'
@@ -198,17 +209,15 @@ class AtomApplication
@openPathOnEvent('application:open-your-stylesheet', 'atom://.atom/stylesheet')
@openPathOnEvent('application:open-license', path.join(process.resourcesPath, 'LICENSE.md'))
app.on 'window-all-closed', ->
app.quit() if process.platform in ['win32', 'linux']
app.on 'before-quit', =>
@saveState()
@quitting = true
app.on 'will-quit', =>
@killAllProcesses()
@deleteSocketFile()
app.on 'will-exit', =>
@saveState() unless @windows.every (window) -> window.isSpec
@killAllProcesses()
@deleteSocketFile()
@@ -343,9 +352,10 @@ class AtomApplication
# :devMode - Boolean to control the opened window's dev mode.
# :safeMode - Boolean to control the opened window's safe mode.
# :apiPreviewMode - Boolean to control the opened window's 1.0 API preview mode.
# :profileStartup - Boolean to control creating a profile of the startup time.
# :window - {AtomWindow} to open file paths in.
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, window}) ->
@openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, window})
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, profileStartup, window}) ->
@openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, profileStartup, window})
# Public: Opens multiple paths, in existing windows if possible.
#
@@ -358,7 +368,7 @@ class AtomApplication
# :apiPreviewMode - Boolean to control the opened window's 1.0 API preview mode.
# :windowDimensions - Object with height and width keys.
# :window - {AtomWindow} to open file paths in.
openPaths: ({pathsToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, windowDimensions, window}={}) ->
openPaths: ({pathsToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, apiPreviewMode, windowDimensions, profileStartup, window}={}) ->
pathsToOpen = (fs.normalize(pathToOpen) for pathToOpen in pathsToOpen)
locationsToOpen = (@locationForPathToOpen(pathToOpen) for pathToOpen in pathsToOpen)
@@ -388,7 +398,7 @@ class AtomApplication
bootstrapScript ?= require.resolve('../window-bootstrap')
resourcePath ?= @resourcePath
openedWindow = new AtomWindow({locationsToOpen, bootstrapScript, resourcePath, devMode, safeMode, apiPreviewMode, windowDimensions})
openedWindow = new AtomWindow({locationsToOpen, bootstrapScript, resourcePath, devMode, safeMode, apiPreviewMode, windowDimensions, profileStartup})
if pidToKillWhenClosed?
@pidsToOpenWindows[pidToKillWhenClosed] = openedWindow
@@ -420,14 +430,9 @@ class AtomApplication
saveState: ->
states = []
for window in @windows
if loadSettings = window.getLoadSettings()
unless loadSettings.isSpec
states.push(_.pick(loadSettings,
'initialPaths'
'devMode'
'safeMode'
'apiPreviewMode'
))
unless window.isSpec
if loadSettings = window.getLoadSettings()
states.push(initialPaths: loadSettings.initialPaths)
@storageFolder.store('application.json', states)
loadState: ->
@@ -436,9 +441,9 @@ class AtomApplication
@openWithOptions({
pathsToOpen: state.initialPaths
urlsToOpen: []
devMode: state.devMode
safeMode: state.safeMode
apiPreviewMode: state.apiPreviewMode
devMode: @devMode
safeMode: @safeMode
apiPreviewMode: @apiPreviewMode
})
true
else
@@ -484,7 +489,7 @@ class AtomApplication
# :specPath - The directory to load specs from.
# :safeMode - A Boolean that, if true, won't run specs from ~/.atom/packages
# and ~/.atom/dev/packages, defaults to false.
runSpecs: ({exitWhenDone, resourcePath, specDirectory, logFile, safeMode}) ->
runSpecs: ({exitWhenDone, resourcePath, specDirectory, logFile, safeMode, apiPreviewMode}) ->
if resourcePath isnt @resourcePath and not fs.existsSync(resourcePath)
resourcePath = @resourcePath
@@ -496,7 +501,8 @@ class AtomApplication
isSpec = true
devMode = true
safeMode ?= false
new AtomWindow({bootstrapScript, resourcePath, exitWhenDone, isSpec, devMode, specDirectory, logFile, safeMode})
apiPreviewMode ?= false
new AtomWindow({bootstrapScript, resourcePath, exitWhenDone, isSpec, devMode, specDirectory, logFile, safeMode, apiPreviewMode})
runBenchmarks: ({exitWhenDone, specDirectory}={}) ->
try
@@ -514,13 +520,15 @@ class AtomApplication
return {pathToOpen} unless pathToOpen
return {pathToOpen} if fs.existsSync(pathToOpen)
pathToOpen = pathToOpen.replace(/[:\s]+$/, '')
[fileToOpen, initialLine, initialColumn] = path.basename(pathToOpen).split(':')
return {pathToOpen} unless initialLine
return {pathToOpen} unless parseInt(initialLine) > 0
return {pathToOpen} unless parseInt(initialLine) >= 0
# Convert line numbers to a base of 0
initialLine -= 1 if initialLine
initialColumn -= 1 if initialColumn
initialLine = Math.max(0, initialLine - 1) if initialLine
initialColumn = Math.max(0, initialColumn - 1) if initialColumn
pathToOpen = path.join(path.dirname(pathToOpen), fileToOpen)
{pathToOpen, initialLine, initialColumn}

View File

@@ -15,7 +15,7 @@ module.exports =
class AutoUpdateManager
_.extend @prototype, EventEmitter.prototype
constructor: (@version) ->
constructor: (@version, @testMode) ->
@state = IdleState
if process.platform is 'win32'
# Squirrel for Windows can't handle query params
@@ -53,7 +53,7 @@ class AutoUpdateManager
@emitUpdateAvailableEvent(@getWindows()...)
# Only released versions should check for updates.
@check(hidePopups: true) unless /\w{7}/.test(@version)
@scheduleUpdateCheck() unless /\w{7}/.test(@version)
switch process.platform
when 'win32'
@@ -75,15 +75,21 @@ class AutoUpdateManager
getState: ->
@state
scheduleUpdateCheck: ->
checkForUpdates = => @check(hidePopups: true)
fourHours = 1000 * 60 * 60 * 4
setInterval(checkForUpdates, fourHours)
checkForUpdates()
check: ({hidePopups}={}) ->
unless hidePopups
autoUpdater.once 'update-not-available', @onUpdateNotAvailable
autoUpdater.once 'error', @onUpdateError
autoUpdater.checkForUpdates()
autoUpdater.checkForUpdates() unless @testMode
install: ->
autoUpdater.quitAndInstall()
autoUpdater.quitAndInstall() unless @testMode
onUpdateNotAvailable: =>
autoUpdater.removeListener 'error', @onUpdateError

View File

@@ -110,6 +110,7 @@ parseCommandLine = ->
options.alias('h', 'help').boolean('h').describe('h', 'Print this usage message.')
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
options.boolean('profile-startup').describe('profile-startup', 'Create a profile of the startup execution time.')
options.alias('r', 'resource-path').string('r').describe('r', 'Set the path to the Atom source directory and enable dev-mode.')
options.alias('s', 'spec-directory').string('s').describe('s', 'Set the directory from which to run package specs (default: Atom\'s spec directory).')
options.boolean('safe').describe('safe', 'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.')
@@ -132,13 +133,13 @@ parseCommandLine = ->
safeMode = args['safe']
apiPreviewMode = args['one']
pathsToOpen = args._
pathsToOpen = [executedFrom] if executedFrom and pathsToOpen.length is 0
test = args['test']
specDirectory = args['spec-directory']
newWindow = args['new-window']
pidToKillWhenClosed = args['pid'] if args['wait']
logFile = args['log-file']
socketPath = args['socket-path']
profileStartup = args['profile-startup']
if args['resource-path']
devMode = true
@@ -165,6 +166,6 @@ parseCommandLine = ->
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed,
devMode, apiPreviewMode, safeMode, newWindow, specDirectory, logFile,
socketPath}
socketPath, profileStartup}
start()