Support activationCommands field in package.json

This field mandates selectors in its structure and closely matches the
API of `atom.commands.add`. It will supplant `activationEvents` moving
forward.
This commit is contained in:
Nathan Sobo 2014-09-23 18:09:28 -06:00
parent c71457e9d4
commit 63181a17c8
4 changed files with 62 additions and 33 deletions

View File

@ -0,0 +1,2 @@
module.exports =
activate: ->

View File

@ -0,0 +1,3 @@
activationCommands:
'.workspace': 'workspace-command'
'.editor': ['editor-command-1', 'editor-command-2']

View File

@ -92,7 +92,7 @@ describe "PackageManager", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
describe "when the package metadata includes activation events", ->
describe "when the package metadata includes `activationEvents`", ->
[mainModule, promise, workspaceCommandListener] = []
beforeEach ->
@ -150,6 +150,21 @@ describe "PackageManager", ->
runs ->
expect(mainModule.activate.callCount).toBe 1
describe "when the package metadata includes `activationCommands`", ->
it "defers activation until one of the commands is invoked", ->
atom.workspaceView.attachToDom()
mainModule = require './fixtures/packages/package-with-activation-commands/index'
mainModule.commands = []
spyOn(mainModule, 'activate').andCallThrough()
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
promise = atom.packages.activatePackage('package-with-activation-commands')
expect(promise.isFulfilled()).not.toBeTruthy()
atom.workspaceView[0].dispatchEvent(new CustomEvent('workspace-command', bubbles: true))
waitsForPromise -> promise
describe "when the package has no main module", ->
it "does not throw an exception", ->
spyOn(console, "error")

View File

@ -99,7 +99,7 @@ class Package
@loadMenus()
@loadStylesheets()
@scopedPropertiesPromise = @loadScopedProperties()
@requireMainModule() unless @hasActivationEvents()
@requireMainModule() unless @hasActivationCommands()
catch error
console.warn "Failed to load package named '#{@name}'", error.stack ? error
@ -119,8 +119,8 @@ class Package
@activationDeferred = Q.defer()
@measure 'activateTime', =>
@activateResources()
if @hasActivationEvents()
@subscribeToActivationEvents()
if @hasActivationCommands()
@subscribeToActivationCommands()
else
@activateNow()
@ -319,41 +319,50 @@ class Package
path.join(@path, 'index')
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
hasActivationEvents: ->
if _.isArray(@metadata.activationEvents)
return @metadata.activationEvents.some (activationEvent) ->
activationEvent?.length > 0
else if _.isString(@metadata.activationEvents)
return @metadata.activationEvents.length > 0
else if _.isObject(@metadata.activationEvents)
for event, selector of @metadata.activationEvents
return true if event.length > 0 and selector.length > 0
hasActivationCommands: ->
for selector, commands of @getActivationCommands()
return true if commands.length > 0
false
subscribeToActivationEvents: ->
return unless @metadata.activationEvents?
subscribeToActivationCommands: ->
@activationCommandSubscriptions = new CompositeDisposable
if _.isArray(@metadata.activationEvents)
for eventName in @metadata.activationEvents
for selector, commands of @getActivationCommands()
for command in commands
@activationCommandSubscriptions.add(
atom.commands.add('.workspace', eventName, @handleActivationEvent)
)
else if _.isString(@metadata.activationEvents)
eventName = @metadata.activationEvents
@activationCommandSubscriptions.add(
atom.commands.add('.workspace', eventName, @handleActivationEvent)
)
else
for eventName, selector of @metadata.activationEvents
selector ?= '.workspace'
@activationCommandSubscriptions.add(
atom.commands.add(selector, eventName, @handleActivationEvent)
atom.commands.add(selector, command, @handleActivationCommand)
)
handleActivationEvent: (event) =>
getActivationCommands: ->
return @activationCommands if @activationCommands?
@activationCommands = {}
if @metadata.activationCommands?
for selector, commands of @metadata.activationCommands
@activationCommands[selector] ?= []
if _.isString(commands)
@activationCommands[selector].push(commands)
else if _.isArray(commands)
@activationCommands[selector].push(commands...)
if @metadata.activationEvents?
if _.isArray(@metadata.activationEvents)
for eventName in @metadata.activationEvents
@activationCommands['.workspace'] ?= []
@activationCommands['.workspace'].push(eventName)
else if _.isString(@metadata.activationEvents)
eventName = @metadata.activationEvents
@activationCommands['.workspace'] ?= []
@activationCommands['.workspace'].push(eventName)
else
for eventName, selector of @metadata.activationEvents
selector ?= '.workspace'
@activationCommands[selector] ?= []
@activationCommands[selector].push(eventName)
@activationCommands
handleActivationCommand: (event) =>
event.stopImmediatePropagation()
@activationCommandSubscriptions.dispose()
reenableInvokedListeners = event.disableInvokedListeners()