Merge pull request #4838 from Leaflet/fix-recursive-event-fire

Make event firing reentrant
This commit is contained in:
Vladimir Agafonkin 2016-08-25 15:28:39 +02:00 committed by GitHub
commit fb069ba7e8
2 changed files with 46 additions and 4 deletions

View File

@ -341,6 +341,48 @@ describe('Events', function () {
expect(spy.called).to.be(false);
});
it('handles reentrant event firing', function () {
var obj = new L.Evented(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
obj
.addEventListener('test1', function () {
obj.fire('test2');
})
.addEventListener('test2', spy1)
.addEventListener('test1', function () {
obj.removeEventListener('test1', spy2);
})
.addEventListener('test1', spy2);
obj.fireEvent('test1');
expect(spy1.called).to.be(true);
expect(spy2.called).to.be(false);
});
it('can remove an event listener while firing', function () {
var obj = new L.Evented(),
spy = sinon.spy();
var removeSpy = function () {
obj.removeEventListener('test', spy);
};
obj.addEventListener('test', spy);
obj.addEventListener('test', removeSpy);
obj.fire('test');
obj.removeEventListener('test', removeSpy);
// expect(obj.listens('test', L.Util.falseFn)).to.be(false);
// Remove the expect below and comment out the one above, once we've
// gotten rid of _events.count (which makes the expect above pass).
var listeners = obj._events['test'];
expect(listeners.count === listeners.listeners.length).to.be(true);
});
});
describe('#on, #off & #fire', function () {

View File

@ -163,9 +163,9 @@ L.Evented = L.Class.extend({
l.fn = L.Util.falseFn;
typeListeners.count--;
if (this._isFiring) {
if (this._firingCount) {
/* copy array in case events are being fired */
listeners = listeners.slice();
typeListeners.listeners = listeners = listeners.slice();
}
listeners.splice(i, 1);
@ -188,14 +188,14 @@ L.Evented = L.Class.extend({
var typeListeners = this._events[type];
if (typeListeners) {
this._isFiring = true;
this._firingCount = (this._firingCount + 1) || 1;
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;
this._firingCount--;
}
}