diff --git a/spec/app/atom-package-spec.coffee b/spec/app/atom-package-spec.coffee new file mode 100644 index 000000000..ab6a8bbb6 --- /dev/null +++ b/spec/app/atom-package-spec.coffee @@ -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 diff --git a/spec/fixtures/packages/package-with-activation-events/main.coffee b/spec/fixtures/packages/package-with-activation-events/main.coffee new file mode 100644 index 000000000..fc2588ef9 --- /dev/null +++ b/spec/fixtures/packages/package-with-activation-events/main.coffee @@ -0,0 +1,6 @@ +module.exports = + activationEventCallCount: 0 + + activate: -> + rootView.getActiveEditor()?.command 'activation-event', => + @activationEventCallCount++ diff --git a/spec/fixtures/packages/package-with-activation-events/package.cson b/spec/fixtures/packages/package-with-activation-events/package.cson new file mode 100644 index 000000000..80903d6f4 --- /dev/null +++ b/spec/fixtures/packages/package-with-activation-events/package.cson @@ -0,0 +1,2 @@ +'activationEvents': ['activation-event'] +'main': 'main' diff --git a/src/app/atom-package.coffee b/src/app/atom-package.coffee index e355d5483..f174e9cce 100644 --- a/src/app/atom-package.coffee +++ b/src/app/atom-package.coffee @@ -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) diff --git a/src/packages/go-to-line/lib/go-to-line-view.coffee b/src/packages/go-to-line/lib/go-to-line-view.coffee index ae2370521..ef734aa3b 100644 --- a/src/packages/go-to-line/lib/go-to-line-view.coffee +++ b/src/packages/go-to-line/lib/go-to-line-view.coffee @@ -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', => diff --git a/src/packages/go-to-line/package.cson b/src/packages/go-to-line/package.cson index 6fdbc5937..4711ed56c 100644 --- a/src/packages/go-to-line/package.cson +++ b/src/packages/go-to-line/package.cson @@ -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' diff --git a/src/packages/strip-trailing-whitespace/package.cson b/src/packages/strip-trailing-whitespace/package.cson index 25e3026d8..0daeeb412 100644 --- a/src/packages/strip-trailing-whitespace/package.cson +++ b/src/packages/strip-trailing-whitespace/package.cson @@ -1 +1 @@ -'main': 'strip-trailing-whitespace/lib/strip-trailing-whitespace' +'main': './lib/strip-trailing-whitespace'