From 4de0865d289764c82e959b2378569dd313dcb39e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 5 Sep 2014 09:19:59 -0600 Subject: [PATCH] Allow listeners to be removed via a Disposable returned from ::add --- spec/command-registry-spec.coffee | 15 +++++++++++++++ src/command-registry.coffee | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/spec/command-registry-spec.coffee b/spec/command-registry-spec.coffee index 2b28c175a..0a2321cdc 100644 --- a/spec/command-registry-spec.coffee +++ b/spec/command-registry-spec.coffee @@ -77,3 +77,18 @@ describe "CommandRegistry", -> grandchild.dispatchEvent(new CustomEvent('command', bubbles: true)) expect(calls).toEqual ['child-1'] + + it "allows listeners to be removed via a disposable returned by ::add", -> + calls = [] + + disposable1 = registry.add 'command', '.parent', -> calls.push('parent') + disposable2 = registry.add 'command', '.child', -> calls.push('child') + + disposable1.dispose() + grandchild.dispatchEvent(new CustomEvent('command', bubbles: true)) + expect(calls).toEqual ['child'] + + calls = [] + disposable2.dispose() + grandchild.dispatchEvent(new CustomEvent('command', bubbles: true)) + expect(calls).toEqual [] diff --git a/src/command-registry.coffee b/src/command-registry.coffee index 650dd8450..3ceb5437a 100644 --- a/src/command-registry.coffee +++ b/src/command-registry.coffee @@ -1,3 +1,4 @@ +{Disposable} = require 'event-kit' {specificity} = require 'clear-cut' SequenceCount = 0 @@ -13,7 +14,15 @@ class CommandRegistry @rootNode.addEventListener(commandName, @dispatchCommand, true) @listenersByCommandName[commandName] = [] - @listenersByCommandName[commandName].push(new CommandListener(selector, callback)) + listener = new CommandListener(selector, callback) + listenersForCommand = @listenersByCommandName[commandName] + listenersForCommand.push(listener) + + new Disposable => + listenersForCommand.splice(listenersForCommand.indexOf(listener), 1) + if listenersForCommand.length is 0 + delete @listenersByCommandName[commandName] + @rootNode.removeEventListener(commandName, @dispatchCommand, true) dispatchCommand: (event) => propagationStopped = false