Merge pull request #938 from atom/ks-url-api

Add API to open urls
This commit is contained in:
Kevin Sawicki
2013-10-07 16:19:21 -07:00
5 changed files with 60 additions and 37 deletions

View File

@@ -18,6 +18,7 @@ atom.themes.loadBaseStylesheets()
atom.themes.requireStylesheet '../static/jasmine'
fixturePackagesPath = path.resolve(__dirname, './fixtures/packages')
atom.packages.packageDirPaths.unshift(fixturePackagesPath)
atom.keymap.loadBundledKeymaps()
[bindingSetsToRestore, bindingSetsByFirstKeystrokeToRestore] = []
@@ -50,7 +51,9 @@ beforeEach ->
bindingSetsByFirstKeystrokeToRestore = _.clone(keymap.bindingSetsByFirstKeystroke)
# reset config before each spec; don't load or save from/to `config.json`
config = new Config()
config = new Config
resourcePath: window.resourcePath
configDirPath: atom.getConfigDirPath()
config.packageDirPaths.unshift(fixturePackagesPath)
spyOn(config, 'load')
spyOn(config, 'save')

View File

@@ -51,7 +51,7 @@ class AtomApplication
version: null
constructor: (options) ->
{@resourcePath, @version} = options
{@resourcePath, @version, @devMode} = options
global.atomApplication = this
@pidsToOpenWindows = {}
@@ -147,7 +147,7 @@ class AtomApplication
app.on 'open-url', (event, urlToOpen) =>
event.preventDefault()
@openUrl(urlToOpen)
@openUrl({urlToOpen, @devMode})
autoUpdater.on 'ready-for-update-on-quit', (event, version, quitAndUpdateCallback) =>
event.preventDefault()
@@ -251,9 +251,11 @@ class AtomApplication
console.log("Killing process #{pid} failed: #{error.code}")
delete @pidsToOpenWindows[pid]
# Private: Handles an atom:// url.
# Private: Open an atom:// url.
#
# Currently only supports atom://session/<session-id> urls.
# The host of the URL being opened is assumed to be the package name
# responsible for opening the URL. A new window will be created with
# that package's `urlMain` as the bootstrap script.
#
# * options
# + urlToOpen:
@@ -261,15 +263,25 @@ class AtomApplication
# + devMode:
# Boolean to control the opened window's dev mode.
openUrl: ({urlToOpen, devMode}) ->
parsedUrl = url.parse(urlToOpen)
if parsedUrl.host is 'session'
sessionId = parsedUrl.path.split('/')[1]
console.log "Joining session #{sessionId}"
if sessionId
bootstrapScript = 'collaboration/lib/bootstrap'
new AtomWindow({bootstrapScript, @resourcePath, sessionId, devMode})
unless @packages?
PackageManager = require './package-manager'
fsUtils = require './fs-utils'
@packages = new PackageManager
configDirPath: fsUtils.absolute('~/.atom')
devMode: devMode
resourcePath: @resourcePath
packageName = url.parse(urlToOpen).host
pack = _.find @packages.getAvailablePackageMetadata(), ({name}) -> name is packageName
if pack?
if pack.urlMain
packagePath = @packages.resolvePackagePath(packageName)
bootstrapScript = path.resolve(packagePath, pack.urlMain)
new AtomWindow({bootstrapScript, @resourcePath, devMode, urlToOpen})
else
console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}"
else
console.log "Opening unknown url #{urlToOpen}"
console.log "Opening unknown url: #{urlToOpen}"
# Private: Opens up a new {AtomWindow} to run specs within.
#

View File

@@ -27,6 +27,9 @@ class Atom
initialize: ->
@unsubscribe()
{devMode, resourcePath} = atom.getLoadSettings()
configDirPath = @getConfigDirPath()
Config = require './config'
Keymap = require './keymap'
PackageManager = require './package-manager'
@@ -35,7 +38,7 @@ class Atom
ThemeManager = require './theme-manager'
ContextMenuManager = require './context-menu-manager'
@packages = new PackageManager()
@packages = new PackageManager({devMode, configDirPath, resourcePath})
#TODO Remove once packages have been updated to not touch atom.packageStates directly
@__defineGetter__ 'packageStates', => @packages.packageStates
@@ -43,8 +46,8 @@ class Atom
@subscribe @packages, 'loaded', => @watchThemes()
@themes = new ThemeManager()
@contextMenu = new ContextMenuManager(@getLoadSettings().devMode)
@config = new Config()
@contextMenu = new ContextMenuManager(devMode)
@config = new Config({configDirPath, resourcePath})
@pasteboard = new Pasteboard()
@keymap = new Keymap()
@syntax = deserialize(@getWindowState('syntax')) ? new Syntax()
@@ -213,6 +216,10 @@ class Atom
getHomeDirPath: ->
app.getHomeDir()
# Public: Get the directory path to Atom's configuration area.
getConfigDirPath: ->
@configDirPath ?= fsUtils.absolute('~/.atom')
getWindowStatePath: ->
switch @windowMode
when 'spec'

View File

@@ -7,8 +7,6 @@ path = require 'path'
async = require 'async'
pathWatcher = require 'pathwatcher'
configDirPath = fsUtils.absolute("~/.atom")
# Public: Used to access all of Atom's configuration details.
#
# A global instance of this class is available to all plugins which can be
@@ -35,27 +33,26 @@ class Config
configFileHasErrors: null
# Private: Created during initialization, available as `global.config`
constructor: ->
@configDirPath = configDirPath
@bundledKeymapsDirPath = path.join(resourcePath, "keymaps")
@nodeModulesDirPath = path.join(resourcePath, "node_modules")
constructor: ({@configDirPath, @resourcePath}={}) ->
@bundledKeymapsDirPath = path.join(@resourcePath, "keymaps")
@nodeModulesDirPath = path.join(@resourcePath, "node_modules")
@bundledPackageDirPaths = [@nodeModulesDirPath]
@lessSearchPaths = [
path.join(resourcePath, 'static', 'variables')
path.join(resourcePath, 'static')
path.join(@resourcePath, 'static', 'variables')
path.join(@resourcePath, 'static')
]
@packageDirPaths = [path.join(configDirPath, "packages")]
@packageDirPaths = [path.join(@configDirPath, "packages")]
if atom.getLoadSettings().devMode
@packageDirPaths.unshift(path.join(configDirPath, "dev", "packages"))
@packageDirPaths.unshift(path.join(@configDirPath, "dev", "packages"))
@userPackageDirPaths = _.clone(@packageDirPaths)
@userStoragePath = path.join(configDirPath, "storage")
@userStoragePath = path.join(@configDirPath, "storage")
@defaultSettings =
core: _.clone(require('./root-view').configDefaults)
editor: _.clone(require('./editor').configDefaults)
@settings = {}
@configFilePath = fsUtils.resolve(configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(configDirPath, 'config.cson')
@configFilePath = fsUtils.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(@configDirPath, 'config.cson')
# Private:
initializeConfigDirectory: (done) ->
@@ -67,7 +64,7 @@ class Config
fsUtils.copy(sourcePath, destinationPath, callback)
queue.drain = done
templateConfigDirPath = fsUtils.resolve(window.resourcePath, 'dot-atom')
templateConfigDirPath = fsUtils.resolve(@resourcePath, 'dot-atom')
onConfigDirFile = (sourcePath) =>
relativePath = sourcePath.substring(templateConfigDirPath.length + 1)
destinationPath = path.join(@configDirPath, relativePath)

View File

@@ -8,7 +8,11 @@ module.exports =
class PackageManager
_.extend @prototype, EventEmitter
constructor: ->
constructor: ({configDirPath, devMode, @resourcePath}) ->
@packageDirPaths = [path.join(configDirPath, "packages")]
if devMode
@packageDirPaths.unshift(path.join(configDirPath, "dev", "packages"))
@loadedPackages = {}
@activePackages = {}
@packageStates = {}
@@ -83,10 +87,10 @@ class PackageManager
resolvePackagePath: (name) ->
return name if fsUtils.isDirectorySync(name)
packagePath = fsUtils.resolve(config.packageDirPaths..., name)
packagePath = fsUtils.resolve(@packageDirPaths..., name)
return packagePath if fsUtils.isDirectorySync(packagePath)
packagePath = path.join(window.resourcePath, 'node_modules', name)
packagePath = path.join(@resourcePath, 'node_modules', name)
return packagePath if @isInternalPackage(packagePath)
isInternalPackage: (packagePath) ->
@@ -108,11 +112,11 @@ class PackageManager
getAvailablePackagePaths: ->
packagePaths = []
for packageDirPath in config.packageDirPaths
for packageDirPath in @packageDirPaths
for packagePath in fsUtils.listSync(packageDirPath)
packagePaths.push(packagePath) if fsUtils.isDirectorySync(packagePath)
for packagePath in fsUtils.listSync(path.join(window.resourcePath, 'node_modules'))
for packagePath in fsUtils.listSync(path.join(@resourcePath, 'node_modules'))
packagePaths.push(packagePath) if @isInternalPackage(packagePath)
_.uniq(packagePaths)
@@ -122,8 +126,8 @@ class PackageManager
getAvailablePackageMetadata: ->
packages = []
for packagePath in atom.getAvailablePackagePaths()
for packagePath in @getAvailablePackagePaths()
name = path.basename(packagePath)
metadata = atom.getLoadedPackage(name)?.metadata ? Package.loadMetadata(packagePath, true)
metadata = @getLoadedPackage(name)?.metadata ? Package.loadMetadata(packagePath, true)
packages.push(metadata)
packages