merge #1141 and clean it up

This commit is contained in:
Vladimir Agafonkin 2013-01-31 17:29:40 +02:00
commit ef02f60387

View File

@ -10,9 +10,10 @@ L.Mixin.Events = {
addEventListener: function (types, fn, context) { // (String, Function[, Object]) or (Object[, Object])
var events = this[key] = this[key] || {},
type, i, len;
type, i, len, evt,
contextId, objKey, objLenKey, eventsObj;
// Types can be a map of types/handlers
// types can be a map of types/handlers
if (typeof types === 'object') {
for (type in types) {
if (types.hasOwnProperty(type)) {
@ -23,26 +24,50 @@ L.Mixin.Events = {
return this;
}
// types can be a string of space-separated words
types = L.Util.splitWords(types);
for (i = 0, len = types.length; i < len; i++) {
events[types[i]] = events[types[i]] || [];
events[types[i]].push({
evt = {
action: fn,
context: context || this
});
};
contextId = context && context._leaflet_id;
if (contextId) {
// store listeners of a particular context in a separate hash (if it has an id)
// gives a major performance boost when removing thousands of map layers
objKey = types[i] + '_idx',
objLenKey = objKey + '_len',
eventsObj = events[objKey] = events[objKey] || {};
if (eventsObj[contextId]) {
eventsObj[contextId].push(evt);
} else {
eventsObj[contextId] = [evt];
events[objLenKey] = (events[objLenKey] || 0) + 1;
}
} else {
events[types[i]] = events[types[i]] || [];
events[types[i]].push(evt);
}
}
return this;
},
hasEventListeners: function (type) { // (String) -> Boolean
return (key in this) && (type in this[key]) && (this[key][type].length > 0);
return (key in this) &&
(((type in this[key]) && this[key][type].length > 0) ||
(this[key][type + '_idx_len'] > 0));
},
removeEventListener: function (types, fn, context) { // (String[, Function, Object]) or (Object[, Object])
var events = this[key],
type, i, len, listeners, j;
type, i, len, listeners, j,
contextId, objKey, objLenKey;
if (typeof types === 'object') {
for (type in types) {
@ -50,25 +75,35 @@ L.Mixin.Events = {
this.removeEventListener(type, types[type], fn);
}
}
return this;
}
types = L.Util.splitWords(types);
for (i = 0, len = types.length; i < len; i++) {
if (this.hasEventListeners(types[i])) {
listeners = events[types[i]];
// if the context has an id, use it to find the listeners
contextId = context && context._leaflet_id;
objKey = types[i] + '_idx';
if (contextId && events[objKey]) {
listeners = events[objKey][contextId] || [];
} else {
listeners = events[types[i]] || [];
}
for (j = listeners.length - 1; j >= 0; j--) {
if (
(!fn || listeners[j].action === fn) &&
(!context || (listeners[j].context === context))
) {
if ((!fn || listeners[j].action === fn) && (!context || (listeners[j].context === context))) {
listeners.splice(j, 1);
}
}
if (contextId && listeners.length === 0) {
objLenKey = objKey + '_len';
delete events[objKey][contextId];
events[objLenKey] = (events[objLenKey] || 1) - 1;
}
}
}
@ -80,15 +115,36 @@ L.Mixin.Events = {
return this;
}
var event = L.extend({
var event = L.Util.extend({
type: type,
target: this
}, data);
var listeners = this[key][type].slice();
var listeners, i, len, eventsObj, contextId;
for (var i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
if (this[key][type]) {
listeners = this[key][type].slice();
for (i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
}
}
// fire event for the context-indexed listeners as well
eventsObj = this[key][type + '_idx'];
if (eventsObj) {
for (contextId in eventsObj) {
if (eventsObj.hasOwnProperty(contextId)) {
listeners = eventsObj[contextId];
if (listeners) {
for (i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
}
}
}
}
}
return this;