mirror of
https://github.com/Leaflet/Leaflet.git
synced 2025-08-16 16:45:22 +00:00
This commit is contained in:

committed by
Vladimir Agafonkin

parent
450ef3ec77
commit
8047b0b7a9
@ -35,6 +35,62 @@ describe('Events', function () {
|
|||||||
// expect(spy6.callCount).to.be(1);
|
// expect(spy6.callCount).to.be(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('fires all listeners in the order they are added', function () {
|
||||||
|
var obj = new L.Evented(),
|
||||||
|
ctx1 = new L.Class(),
|
||||||
|
ctx2 = new L.Class(),
|
||||||
|
count = {one: 0, two: 0, three: 0, four: 0};
|
||||||
|
|
||||||
|
function listener1(e) {
|
||||||
|
count.one++;
|
||||||
|
expect(count.two).to.eql(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function listener2(e) {
|
||||||
|
count.two++;
|
||||||
|
expect(count.one).to.eql(1);
|
||||||
|
expect(count.three).to.eql(0);
|
||||||
|
if (count.two === 1) {
|
||||||
|
expect(this).to.eql(ctx2);
|
||||||
|
} else if (count.two === 2) {
|
||||||
|
expect(this).to.eql(ctx1);
|
||||||
|
} else {
|
||||||
|
expect(this).to.eql(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listener3(e) {
|
||||||
|
count.three++;
|
||||||
|
expect(count.two).to.eql(3);
|
||||||
|
expect(count.four).to.eql(0);
|
||||||
|
if (count.three === 1) {
|
||||||
|
expect(this).to.eql(ctx1);
|
||||||
|
} else if (count.three === 2) {
|
||||||
|
expect(this).to.eql(ctx2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listener4(e) {
|
||||||
|
count.four++;
|
||||||
|
expect(count.three).to.eql(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.on('test', listener1, ctx1);
|
||||||
|
obj.on('test', listener2, ctx2);
|
||||||
|
obj.on('test', listener2, ctx1); // Same listener but with different context.
|
||||||
|
obj.on('test', listener2); // Same listener but without context.
|
||||||
|
obj.on('test', listener3, ctx1);
|
||||||
|
obj.on('test', listener3, ctx2);
|
||||||
|
obj.on('test', listener4, ctx2);
|
||||||
|
|
||||||
|
obj.fireEvent('test');
|
||||||
|
|
||||||
|
expect(count.one).to.be(1);
|
||||||
|
expect(count.two).to.be(3);
|
||||||
|
expect(count.three).to.be(2);
|
||||||
|
expect(count.four).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('provides event object to listeners and executes them in the right context', function () {
|
it('provides event object to listeners and executes them in the right context', function () {
|
||||||
var obj = new L.Evented(),
|
var obj = new L.Evented(),
|
||||||
obj2 = new L.Evented(),
|
obj2 = new L.Evented(),
|
||||||
|
@ -96,30 +96,22 @@ L.Evented = L.Class.extend({
|
|||||||
var typeListeners = this._events[type];
|
var typeListeners = this._events[type];
|
||||||
if (!typeListeners) {
|
if (!typeListeners) {
|
||||||
typeListeners = {
|
typeListeners = {
|
||||||
listeners: {},
|
listeners: [],
|
||||||
count: 0
|
count: 0
|
||||||
};
|
};
|
||||||
this._events[type] = typeListeners;
|
this._events[type] = typeListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
var contextId = context && context !== this && L.stamp(context),
|
if (context === this) {
|
||||||
newListener = {fn: fn, ctx: context};
|
// Less memory footprint.
|
||||||
|
context = undefined;
|
||||||
if (!contextId) {
|
|
||||||
contextId = 'no_context';
|
|
||||||
newListener.ctx = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn array for context
|
|
||||||
var listeners = typeListeners.listeners[contextId];
|
|
||||||
if (!listeners) {
|
|
||||||
listeners = [];
|
|
||||||
typeListeners.listeners[contextId] = listeners;
|
|
||||||
}
|
}
|
||||||
|
var newListener = {fn: fn, ctx: context},
|
||||||
|
listeners = typeListeners.listeners;
|
||||||
|
|
||||||
// check if fn already there
|
// check if fn already there
|
||||||
for (var i = 0, len = listeners.length; i < len; i++) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,68 +122,55 @@ L.Evented = L.Class.extend({
|
|||||||
|
|
||||||
_off: function (type, fn, context) {
|
_off: function (type, fn, context) {
|
||||||
var typeListeners,
|
var typeListeners,
|
||||||
contextId,
|
|
||||||
listeners,
|
listeners,
|
||||||
i,
|
i,
|
||||||
len;
|
len;
|
||||||
|
|
||||||
if (!this._events) { return; }
|
if (!this._events) { return; }
|
||||||
|
|
||||||
if (!fn) {
|
|
||||||
// Set all removed listeners to noop so they are not called if remove happens in fire
|
|
||||||
typeListeners = this._events[type];
|
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];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
typeListeners = this._events[type];
|
|
||||||
if (!typeListeners) {
|
if (!typeListeners) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
contextId = context && context !== this && L.stamp(context);
|
listeners = typeListeners.listeners;
|
||||||
if (!contextId) {
|
|
||||||
contextId = 'no_context';
|
if (!fn) {
|
||||||
|
// Set all removed listeners to noop so they are not called if remove happens in fire
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (context === this) {
|
||||||
|
context = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners = typeListeners.listeners[contextId];
|
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
|
|
||||||
// find fn and remove it
|
// find fn and remove it
|
||||||
for (i = 0, len = listeners.length; i < len; i++) {
|
for (i = 0, len = listeners.length; i < len; i++) {
|
||||||
var l = listeners[i];
|
var l = listeners[i];
|
||||||
|
if (l.ctx !== context) { continue; }
|
||||||
if (l.fn === fn) {
|
if (l.fn === fn) {
|
||||||
|
|
||||||
// set the removed listener to noop so that's not called if remove happens in fire
|
// set the removed listener to noop so that's not called if remove happens in fire
|
||||||
l.fn = L.Util.falseFn;
|
l.fn = L.Util.falseFn;
|
||||||
typeListeners.count--;
|
typeListeners.count--;
|
||||||
|
|
||||||
if (len > 1) {
|
if (this._isFiring) {
|
||||||
if (!this._isFiring) {
|
|
||||||
listeners.splice(i, 1);
|
|
||||||
} else {
|
|
||||||
/* copy array in case events are being fired */
|
/* copy array in case events are being fired */
|
||||||
typeListeners.listeners[contextId] = listeners.slice();
|
listeners = listeners.slice();
|
||||||
typeListeners.listeners[contextId].splice(i, 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete typeListeners.listeners[contextId];
|
|
||||||
}
|
}
|
||||||
|
listeners.splice(i, 1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (listeners.length === 0) {
|
|
||||||
delete typeListeners.listeners[contextId];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -210,17 +189,11 @@ L.Evented = L.Class.extend({
|
|||||||
|
|
||||||
if (typeListeners) {
|
if (typeListeners) {
|
||||||
this._isFiring = true;
|
this._isFiring = true;
|
||||||
|
var listeners = typeListeners.listeners;
|
||||||
// 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++) {
|
for (var i = 0, len = listeners.length; i < len; i++) {
|
||||||
var l = listeners[i];
|
var l = listeners[i];
|
||||||
l.fn.call(l.ctx || this, event);
|
l.fn.call(l.ctx || this, event);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this._isFiring = false;
|
this._isFiring = false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user