Skip to content

Commit

Permalink
Make sure we call event listeners in the order they are registered (fix
Browse files Browse the repository at this point in the history
  • Loading branch information
yohanboniface committed Jul 30, 2016
1 parent c01adbf commit a1e9552
Showing 1 changed file with 31 additions and 58 deletions.
89 changes: 31 additions & 58 deletions src/core/Events.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,102 +96,81 @@ L.Evented = L.Class.extend({
var typeListeners = this._events[type];
if (!typeListeners) {
typeListeners = {
listeners: {},
listeners: [],
count: 0
};
this._events[type] = typeListeners;
}

var contextId = context && context !== this && L.stamp(context),
newListener = {fn: fn, ctx: context};

if (!contextId) {
contextId = 'no_context';
newListener.ctx = undefined;
}

// fn array for context
var listeners = typeListeners.listeners[contextId];
if (!listeners) {
listeners = [];
typeListeners.listeners[contextId] = listeners;
if (context === this) {
// Less memory footprint.
context = undefined;
}
var newListener = {fn: fn, ctx: context},
listeners = typeListeners.listeners;

// check if fn already there
for (var i = 0, len = listeners.length; i < len; i++) {
if (listeners[i].fn === fn) {
if (listeners[i].fn === fn && listeners[i].ctx === context) {
return;
}
}

listeners.push(newListener);
typeListeners.listeners.push(newListener);
typeListeners.count++;
},

_off: function (type, fn, context) {
var typeListeners,
contextId,
listeners,
i,
len;

if (!this._events) { return; }

typeListeners = this._events[type];

if (!typeListeners) {
return;
}

listeners = typeListeners.listeners;

if (!fn) {
// Set all removed listeners to noop so they are not called if remove happens in fire
typeListeners = this._events[type];
if (typeListeners) {
for (contextId in typeListeners.listeners) {
listeners = typeListeners.listeners[contextId];
for (i = 0, len = listeners.length; i < len; i++) {
listeners[i].fn = L.Util.falseFn;
}
}
// clear all listeners for a type if function isn't specified
delete this._events[type];
for (i = 0, len = listeners.length; i < len; i++) {
listeners[i].fn = L.Util.falseFn;
}
// clear all listeners for a type if function isn't specified
delete this._events[type];
return;
}

typeListeners = this._events[type];
if (!typeListeners) {
return;
}

contextId = context && context !== this && L.stamp(context);
if (!contextId) {
contextId = 'no_context';
if (context === this) {
context = undefined;
}

listeners = typeListeners.listeners[contextId];
if (listeners) {

// find fn and remove it
for (i = 0, len = listeners.length; i < len; i++) {
var l = listeners[i];
if (l.ctx !== context) { continue; }
if (l.fn === fn) {

// set the removed listener to noop so that's not called if remove happens in fire
l.fn = L.Util.falseFn;
typeListeners.count--;

if (len > 1) {
if (!this._isFiring) {
listeners.splice(i, 1);
} else {
/* copy array in case events are being fired */
typeListeners.listeners[contextId] = listeners.slice();
typeListeners.listeners[contextId].splice(i, 1);
}
} else {
delete typeListeners.listeners[contextId];
if (this._isFiring) {
/* copy array in case events are being fired */
listeners = listeners.slice();
}
listeners.splice(i, 1);

return;
}
if (listeners.length === 0) {
delete typeListeners.listeners[contextId];
}
}
}
},
Expand All @@ -210,16 +189,10 @@ L.Evented = L.Class.extend({

if (typeListeners) {
this._isFiring = true;

// each context
for (var contextId in typeListeners.listeners) {
var listeners = typeListeners.listeners[contextId];

// each fn in context
for (var i = 0, len = listeners.length; i < len; i++) {
var l = listeners[i];
l.fn.call(l.ctx || this, event);
}
var listeners = typeListeners.listeners;
for (var i = 0, len = listeners.length; i < len; i++) {
var l = listeners[i];
l.fn.call(l.ctx || this, event);
}

this._isFiring = false;
Expand Down

0 comments on commit a1e9552

Please sign in to comment.