Retrigger event after package module is activated

The event that triggers the package module to be activated is
now retriggered after the package module is initialized but without
any previously registered handlers. Instead only the handlers registered
by the package module will be triggered.  The prior event handlers are then
restored after the event is retriggered.

This allows package modules to bind event handlers during initialization
that will be triggered by the same event that caused the package module
intialization to occur.  This simplifies the common case of having the same
event cause a package module to initialize and attach.
This commit is contained in:
Kevin Sawicki & Nathan Sobo
2013-02-06 22:43:45 -08:00
committed by Corey Johnson & Kevin Sawicki
parent 51f5bb95d0
commit 641a0d43cc
7 changed files with 80 additions and 11 deletions

View File

@@ -0,0 +1,36 @@
RootView = require 'root-view'
AtomPackage = require 'atom-package'
fs = require 'fs'
describe "AtomPackage", ->
describe ".load()", ->
[packageMainModule, pack, rootView] = []
beforeEach ->
rootView = new RootView(fixturesProject.getPath())
pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-activation-events'))
packageMainModule = require 'fixtures/packages/package-with-activation-events/main'
spyOn(packageMainModule, 'activate').andCallThrough()
pack.load()
afterEach ->
rootView.deactivate()
describe "when the package metadata includes activation events", ->
it "defers activating the package until an activation event bubbles to the root view", ->
expect(packageMainModule.activate).not.toHaveBeenCalled()
rootView.trigger 'activation-event'
expect(packageMainModule.activate).toHaveBeenCalled()
it "triggers the activation event on all handlers registered during activation", ->
rootView.open('sample.js')
editor = rootView.getActiveEditor()
eventHandler = jasmine.createSpy("activation-event")
editor.command 'activation-event', eventHandler
editor.trigger 'activation-event'
expect(packageMainModule.activate.callCount).toBe 1
expect(packageMainModule.activationEventCallCount).toBe 1
expect(eventHandler.callCount).toBe 1
editor.trigger 'activation-event'
expect(packageMainModule.activationEventCallCount).toBe 2
expect(eventHandler.callCount).toBe 2
expect(packageMainModule.activate.callCount).toBe 1

View File

@@ -0,0 +1,6 @@
module.exports =
activationEventCallCount: 0
activate: ->
rootView.getActiveEditor()?.command 'activation-event', =>
@activationEventCallCount++

View File

@@ -0,0 +1,2 @@
'activationEvents': ['activation-event']
'main': 'main'

View File

@@ -1,6 +1,7 @@
Package = require 'package'
fs = require 'fs'
_ = require 'underscore'
$ = require 'jquery'
module.exports =
class AtomPackage extends Package
@@ -25,16 +26,40 @@ class AtomPackage extends Package
console.warn "Failed to load package named '#{@name}'", e.stack
this
subscribeToActivationEvents: (activationEvents) ->
disableEventHandlersOnBubblePath: (event) ->
bubblePathEventHandlers = []
element = $(event.target)
while element.length
if eventHandlers = element.data('events')?[event.type]
for eventHandler in eventHandlers
eventHandler.disabledHandler = eventHandler.handler
eventHandler.handler = ->
bubblePathEventHandlers.push(eventHandler)
element = element.parent()
bubblePathEventHandlers
restoreEventHandlersOnBubblePath: (eventHandlers) ->
for eventHandler in eventHandlers
eventHandler.handler = eventHandler.disabledHandler
delete eventHandler.disabledHandler
unsubscribeFromActivationEvents: (activationEvents, activateHandler) ->
if _.isArray(activationEvents)
rootView.off(event, activateHandler) for event in activationEvents
else
rootView.off(event, selector, activateHandler) for event, selector of activationEvents
subscribeToActivationEvents: (activationEvents) ->
activateHandler = (event) =>
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
@activatePackageMain()
$(event.target).trigger(event)
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
@unsubscribeFromActivationEvents(activationEvents, activateHandler)
if _.isArray(activationEvents)
activateHandler = =>
@activatePackageMain()
rootView.off(event, activateHandler) for event in activationEvents
rootView.command(event, activateHandler) for event in activationEvents
else
activateHandler = =>
@activatePackageMain()
rootView.off(event, selector, activateHandler) for event, selector of activationEvents
rootView.command(event, selector, activateHandler) for event, selector of activationEvents
activatePackageMain: ->
@@ -42,7 +67,7 @@ class AtomPackage extends Package
rootView?.activatePackage(@name, packageMain)
getPackageMain: ->
mainPath = require.resolve(@metadata.main) if @metadata.main
mainPath = require.resolve(fs.join(@path, @metadata.main)) if @metadata.main
if mainPath
require(mainPath)
else if require.resolve(@path)

View File

@@ -6,7 +6,7 @@ Point = require 'point'
module.exports =
class GoToLineView extends View
@activate: (rootView) -> new GoToLineView(rootView).attach()
@activate: (rootView) -> new GoToLineView(rootView)
@content: ->
@div class: 'go-to-line overlay from-top mini', =>

View File

@@ -1,3 +1,3 @@
'activationEvents':
'editor:go-to-line': '.editor'
'main': 'go-to-line/lib/go-to-line-view'
'main': './lib/go-to-line-view'

View File

@@ -1 +1 @@
'main': 'strip-trailing-whitespace/lib/strip-trailing-whitespace'
'main': './lib/strip-trailing-whitespace'