mirror of
https://github.com/atom/atom.git
synced 2026-01-24 14:28:14 -05:00
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:
committed by
Corey Johnson & Kevin Sawicki
parent
51f5bb95d0
commit
641a0d43cc
36
spec/app/atom-package-spec.coffee
Normal file
36
spec/app/atom-package-spec.coffee
Normal 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
|
||||
6
spec/fixtures/packages/package-with-activation-events/main.coffee
vendored
Normal file
6
spec/fixtures/packages/package-with-activation-events/main.coffee
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports =
|
||||
activationEventCallCount: 0
|
||||
|
||||
activate: ->
|
||||
rootView.getActiveEditor()?.command 'activation-event', =>
|
||||
@activationEventCallCount++
|
||||
2
spec/fixtures/packages/package-with-activation-events/package.cson
vendored
Normal file
2
spec/fixtures/packages/package-with-activation-events/package.cson
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
'activationEvents': ['activation-event']
|
||||
'main': 'main'
|
||||
@@ -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)
|
||||
|
||||
@@ -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', =>
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -1 +1 @@
|
||||
'main': 'strip-trailing-whitespace/lib/strip-trailing-whitespace'
|
||||
'main': './lib/strip-trailing-whitespace'
|
||||
|
||||
Reference in New Issue
Block a user