Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
If an event listener is removed during an event dispatch, it shouldn't receive the active event. So now in addition to storing a defensive copy, we use a wrapper object for the event handler to store an `on` boolean. This is set to false when the listener is removed, preventing that handler from receiving the current event.
- Loading branch information
Mike Bostock
committed
Jul 27, 2010
1 parent
2df0e89
commit da40e9d
Showing
2 changed files
with
18 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,32 +1,35 @@ | |||
po.dispatch = function(that) { | po.dispatch = function(that) { | ||
var handlers = {}; | var types = {}; | ||
|
|
||
that.on = function(type, handler) { | that.on = function(type, handler) { | ||
var array = handlers[type] || (handlers[type] = []); | var listeners = types[type] || (types[type] = []); | ||
for (var i = 0; i < array.length; i++) { | for (var i = 0; i < listeners.length; i++) { | ||
if (array[i] == handler) return that; // already registered | if (listeners[i].handler == handler) return that; // already registered | ||
} | } | ||
array.push(handler); | listeners.push({handler: handler, on: true}); | ||
return that; | return that; | ||
}; | }; | ||
|
|
||
that.off = function(type, handler) { | that.off = function(type, handler) { | ||
var array = handlers[type]; | var listeners = types[type]; | ||
if (array) for (var i = 0; i < array.length; i++) { | if (listeners) for (var i = 0; i < listeners.length; i++) { | ||
if (array[i] == handler) { | var l = listeners[i]; | ||
array.splice(i, 1); | if (l.handler == handler) { | ||
l.on = false; | |||
listeners.splice(i, 1); | |||
break; | break; | ||
} | } | ||
} | } | ||
return that; | return that; | ||
}; | }; | ||
|
|
||
return function(event) { | return function(event) { | ||
var array = handlers[event.type]; | var listeners = types[event.type]; | ||
if (!array) return; | if (!listeners) return; | ||
array = array.slice(); // defensive copy | listeners = listeners.slice(); // defensive copy | ||
for (var i = 0; i < array.length; i++) { | for (var i = 0; i < listeners.length; i++) { | ||
array[i].call(that, event); | var l = listeners[i]; | ||
if (l.on) l.handler.call(that, event); | |||
} | } | ||
}; | }; | ||
}; | }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters