cleanup and merge #1596, adds Events#once

This commit is contained in:
Vladimir Agafonkin 2013-04-19 17:23:45 +03:00
parent a5e8bc0f49
commit 5647f37ae6
2 changed files with 85 additions and 26 deletions

View File

@ -245,6 +245,7 @@ describe('Events', function() {
expect(spy3.called).to.be(true);
});
});
describe("#clearEventListeners", function() {
it("clears all registered listeners on an object", function() {
var spy = sinon.spy(),
@ -261,4 +262,67 @@ describe('Events', function() {
expect(spy.called).to.be(false);
});
});
describe('#once', function() {
it('removes event listeners after first trigger', function() {
var obj = new Klass(),
spy = sinon.spy();
obj.once('test', spy, obj);
obj.fire('test');
expect(spy.called).to.be(true);
obj.fire('test');
expect(spy.callCount).to.be.lessThan(2);
});
it('works with an object hash', function() {
var obj = new Klass(),
spy = sinon.spy(),
otherSpy = sinon.spy();
obj.once({
'test': spy,
otherTest: otherSpy
}, obj);
obj.fire('test');
obj.fire('otherTest');
expect(spy.called).to.be(true);
expect(otherSpy.called).to.be(true);
obj.fire('test');
obj.fire('otherTest');
expect(spy.callCount).to.be.lessThan(2);
expect(otherSpy.callCount).to.be.lessThan(2);
});
it("doesn't call listeners to events that have been removed", function () {
var obj = new Klass(),
spy = sinon.spy();
obj.once('test', spy, obj);
obj.off('test', spy, obj);
obj.fire('test');
expect(spy.called).to.be(false);
});
it('works if called from a context that doesnt implement #Events', function() {
var obj = new Klass(),
spy = sinon.spy(),
foo = {};
obj.once('test', spy, foo);
obj.fire('test');
expect(spy.called).to.be(true);
});
});
});

View File

@ -10,21 +10,12 @@ L.Mixin.Events = {
addEventListener: function (types, fn, context) { // (String, Function[, Object]) or (Object[, Object])
var type;
// types can be a map of types/handlers
if (typeof types === 'object') {
for (type in types) {
if (types.hasOwnProperty(type)) {
this.addEventListener(type, types[type], fn);
}
}
return this;
}
if (L.Util.invokeEach(types, this.addEventListener, this, fn, context)) { return this; }
var events = this[eventsKey] = this[eventsKey] || {},
contextId = context && L.stamp(context),
i, len, event, indexKey, indexLenKey, typeIndex;
i, len, event, type, indexKey, indexLenKey, typeIndex;
// types can be a string of space-separated words
types = L.Util.splitWords(types);
@ -76,20 +67,11 @@ L.Mixin.Events = {
return this.clearAllEventListeners();
}
var type;
if (typeof types === 'object') {
for (type in types) {
if (types.hasOwnProperty(type)) {
this.removeEventListener(type, types[type], fn);
}
}
return this;
}
if (L.Util.invokeEach(types, this.removeEventListener, this, fn, context)) { return this; }
var events = this[eventsKey],
contextId = context && L.stamp(context),
i, len, listeners, j, indexKey, indexLenKey, typeIndex;
i, len, type, listeners, j, indexKey, indexLenKey, typeIndex;
types = L.Util.splitWords(types);
@ -136,10 +118,7 @@ L.Mixin.Events = {
return this;
}
var event = L.Util.extend({}, data, {
type: type,
target: this
});
var event = L.Util.extend({}, data, { type: type, target: this });
var events = this[eventsKey],
listeners, i, len, typeIndex, contextId;
@ -169,9 +148,25 @@ L.Mixin.Events = {
}
return this;
},
addOneTimeEventListener: function (types, fn, context) {
if (L.Util.invokeEach(types, this.addOneTimeEventListener, this, fn, context)) { return this; }
var handler = L.bind(function () {
this
.removeEventListener(types, fn, context)
.removeEventListener(types, handler, context);
}, this);
return this
.addEventListener(types, fn, context)
.addEventListener(types, handler, context);
}
};
L.Mixin.Events.on = L.Mixin.Events.addEventListener;
L.Mixin.Events.off = L.Mixin.Events.removeEventListener;
L.Mixin.Events.once = L.Mixin.Events.addOneTimeEventListener;
L.Mixin.Events.fire = L.Mixin.Events.fireEvent;