Allow atom.commands to participate in activationEvents

* Activation events can be handled via atom.commands
* Pre-existing listeners registered via atom.commands are disabled when
  replaying events for the activated package.
This commit is contained in:
Nathan Sobo
2014-09-23 15:55:59 -06:00
parent 2df5957f9b
commit a492596f7f
4 changed files with 38 additions and 5 deletions

View File

@@ -6,8 +6,11 @@ class Foo
module.exports =
activateCallCount: 0
activationEventCallCount: 0
activationCommandCallCount: 0
activate: ->
@activateCallCount++
atom.workspaceView.getActiveView()?.command 'activation-event', =>
@activationEventCallCount++
atom.commands.add '.workspace', 'activation-event', =>
@activationCommandCallCount++

View File

@@ -98,6 +98,8 @@ describe "PackageManager", ->
beforeEach ->
atom.workspaceView.attachToDom()
mainModule = require './fixtures/packages/package-with-activation-events/index'
mainModule.activationEventCallCount = 0
mainModule.activationCommandCallCount = 0
spyOn(mainModule, 'activate').andCallThrough()
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
@@ -116,15 +118,21 @@ describe "PackageManager", ->
runs ->
editorView = atom.workspaceView.getActiveView()
eventHandler = jasmine.createSpy("activation-event")
eventHandler = jasmine.createSpy("activation event handler")
globalCommandHandler = jasmine.createSpy("activation global command handler")
editorView.command 'activation-event', eventHandler
commandDisposable = atom.commands.add '.workspace', 'activation-event', globalCommandHandler
editorView[0].dispatchEvent(new CustomEvent('activation-event', bubbles: true))
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.activationEventCallCount).toBe 1
expect(mainModule.activationCommandCallCount).toBe 1
expect(eventHandler.callCount).toBe 1
expect(globalCommandHandler.callCount).toBe 1
editorView[0].dispatchEvent(new CustomEvent('activation-event', bubbles: true))
expect(mainModule.activationEventCallCount).toBe 2
expect(mainModule.activationCommandCallCount).toBe 2
expect(eventHandler.callCount).toBe 2
expect(globalCommandHandler.callCount).toBe 2
expect(mainModule.activate.callCount).toBe 1
it "activates the package immediately when the events are empty", ->

View File

@@ -137,6 +137,25 @@ class CommandRegistry
commands
disableCommands: (target, commandName) ->
if @rootNode.contains(target)
currentTarget = target
else
currentTarget = @rootNode
disabledListeners = []
loop
for listener in @listenersByCommandName[commandName] ? []
if currentTarget.webkitMatchesSelector(listener.selector)
listener.enabled = false
disabledListeners.push(listener)
break if currentTarget is @rootNode
currentTarget = currentTarget.parentNode
new Disposable =>
listener.enabled = true for listener in disabledListeners
# Public: Simulate the dispatch of a command on a DOM node.
#
# This can be useful for testing when you want to simulate the invocation of a
@@ -183,7 +202,7 @@ class CommandRegistry
matched = true if matchingListeners.length > 0
for listener in matchingListeners
for listener in matchingListeners when listener.enabled
break if immediatePropagationStopped
listener.callback.call(currentTarget, syntheticEvent)
@@ -195,6 +214,8 @@ class CommandRegistry
matched
class CommandListener
enabled: true
constructor: (@selector, @callback) ->
@specificity = (SpecificityCache[@selector] ?= specificity(@selector))
@sequenceNumber = SequenceCount++

View File

@@ -342,12 +342,13 @@ class Package
handleActivationEvent: (event) =>
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
disabledCommands = atom.commands.disableCommands(event.target, event.type)
@activateNow()
$ ?= require('./space-pen-extensions').$
$(event.target).trigger(event)
event.target.dispatchEvent(new CustomEvent(event.type, bubbles: true))
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
disabledCommands.dispose()
@unsubscribeFromActivationEvents()
false
event.stopImmediatePropagation()
unsubscribeFromActivationEvents: ->
return unless atom.workspaceView?