Allow L.Mixin.Events.addEventListener() to accept a map in which the string keys represent one or more space-separated event types and the values represent a handler function to be called for the event(s).
Allow L.Mixin.Events.removeEventListener() to accept one or more space-separated event types. Omitting the fn parameter will remove all event handlers for the supplied event type(s). Also allow L.Mixin.Events.removeEventListener() to accept a map where the string keys represent one or more space-separated event types and the values represent handler functions previously attached for the event(s). Add unit tests for the above changes.
This commit is contained in:
parent
8d619899b0
commit
95ed9cdda2
@ -13,49 +13,89 @@ describe('Events', function() {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
spy3 = jasmine.createSpy();
|
||||
spy3 = jasmine.createSpy(),
|
||||
spy4 = jasmine.createSpy(),
|
||||
spy5 = jasmine.createSpy();
|
||||
spy6 = jasmine.createSpy();
|
||||
|
||||
obj.addEventListener('test', spy);
|
||||
obj.addEventListener('test', spy2);
|
||||
obj.addEventListener('other', spy3);
|
||||
obj.addEventListener({ test: spy4, other: spy5 });
|
||||
obj.addEventListener({'test other': spy6 })
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
expect(spy2).not.toHaveBeenCalled();
|
||||
expect(spy3).not.toHaveBeenCalled();
|
||||
expect(spy4).not.toHaveBeenCalled();
|
||||
expect(spy5).not.toHaveBeenCalled();
|
||||
expect(spy6).not.toHaveBeenCalled();
|
||||
|
||||
obj.fireEvent('test');
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
expect(spy2).toHaveBeenCalled();
|
||||
expect(spy3).not.toHaveBeenCalled();
|
||||
expect(spy4).toHaveBeenCalled();
|
||||
expect(spy5).not.toHaveBeenCalled();
|
||||
expect(spy6).toHaveBeenCalled();
|
||||
expect(spy6.calls.length).toEqual(1);
|
||||
});
|
||||
|
||||
|
||||
it('should provide event object to listeners and execute them in the right context', function() {
|
||||
var obj = new Klass(),
|
||||
obj2 = new Klass(),
|
||||
obj3 = new Klass(),
|
||||
obj4 = new Klass(),
|
||||
foo = {};
|
||||
|
||||
function listener1(e) {
|
||||
expect(e.type).toEqual('test');
|
||||
expect(e.target).toEqual(obj);
|
||||
expect(this).toEqual(obj);
|
||||
expect(e.bar).toEqual(3);
|
||||
};
|
||||
expect(e.baz).toEqual(1);
|
||||
}
|
||||
|
||||
function listener2(e) {
|
||||
expect(e.type).toEqual('test');
|
||||
expect(e.target).toEqual(obj2);
|
||||
expect(this).toEqual(foo);
|
||||
};
|
||||
expect(e.baz).toEqual(2);
|
||||
}
|
||||
|
||||
function listener3(e) {
|
||||
expect(e.type).toEqual('test');
|
||||
expect(e.target).toEqual(obj3);
|
||||
expect(this).toEqual(obj3);
|
||||
expect(e.baz).toEqual(3);
|
||||
}
|
||||
|
||||
function listener4(e) {
|
||||
expect(e.type).toEqual('test');
|
||||
expect(e.target).toEqual(obj4);
|
||||
expect(this).toEqual(foo);
|
||||
expect(e.baz).toEqual(4);
|
||||
}
|
||||
|
||||
obj.addEventListener('test', listener1);
|
||||
obj2.addEventListener('test', listener2, foo);
|
||||
obj3.addEventListener({ test: listener3 });
|
||||
obj4.addEventListener({ test: listener4 }, foo);
|
||||
|
||||
obj.fireEvent('test', {bar: 3});
|
||||
obj.fireEvent('test', {baz: 1});
|
||||
obj2.fireEvent('test', {baz: 2});
|
||||
obj3.fireEvent('test', {baz: 3});
|
||||
obj4.fireEvent('test', {baz: 4});
|
||||
});
|
||||
|
||||
it('should not call listeners removed through #removeEventListener', function() {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy();
|
||||
spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
spy3 = jasmine.createSpy(),
|
||||
spy4 = jasmine.createSpy(),
|
||||
spy5 = jasmine.createSpy();
|
||||
|
||||
obj.addEventListener('test', spy);
|
||||
obj.removeEventListener('test', spy);
|
||||
@ -63,6 +103,28 @@ describe('Events', function() {
|
||||
obj.fireEvent('test');
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
|
||||
obj.addEventListener('test2', spy2);
|
||||
obj.addEventListener('test2', spy3);
|
||||
obj.removeEventListener('test2');
|
||||
|
||||
obj.fireEvent('test2');
|
||||
|
||||
expect(spy2).not.toHaveBeenCalled();
|
||||
expect(spy3).not.toHaveBeenCalled();
|
||||
|
||||
obj.addEventListener('test3', spy4);
|
||||
obj.addEventListener('test4', spy5);
|
||||
obj.removeEventListener({
|
||||
test3: spy4,
|
||||
test4: spy5
|
||||
});
|
||||
|
||||
obj.fireEvent('test3');
|
||||
obj.fireEvent('test4');
|
||||
|
||||
expect(spy4).not.toHaveBeenCalled();
|
||||
expect(spy5).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -5,13 +5,37 @@
|
||||
L.Mixin = {};
|
||||
|
||||
L.Mixin.Events = {
|
||||
addEventListener: function (/*String*/ type, /*Function*/ fn, /*(optional) Object*/ context) {
|
||||
addEventListener: function (/*String or Object*/ types, /*(optional) Function or Object*/ fn, /*(optional) Object*/ context) {
|
||||
var events = this._leaflet_events = this._leaflet_events || {};
|
||||
events[type] = events[type] || [];
|
||||
events[type].push({
|
||||
|
||||
// Types can be a map of types/handlers
|
||||
if (typeof types === 'object') {
|
||||
context = context || fn;
|
||||
fn = undefined;
|
||||
|
||||
for (var type in types) {
|
||||
if (types.hasOwnProperty(type)) {
|
||||
this.addEventListener(type, types[type], context);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!fn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
types = (types || '').replace(/^\s+/, '').replace(/\s+$/, '').split(' ');
|
||||
|
||||
for (var i = 0, ilen = types.length; i < ilen; i++) {
|
||||
events[types[i]] = events[types[i]] || [];
|
||||
events[types[i]].push({
|
||||
action: fn,
|
||||
context: context || this
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
@ -20,20 +44,44 @@ L.Mixin.Events = {
|
||||
return (k in this) && (type in this[k]) && (this[k][type].length > 0);
|
||||
},
|
||||
|
||||
removeEventListener: function (/*String*/ type, /*Function*/ fn, /*(optional) Object*/ context) {
|
||||
if (!this.hasEventListeners(type)) {
|
||||
removeEventListener: function (/*String or Object*/ types, /*(optional) Function*/ fn, /*(optional) Object*/ context) {
|
||||
var events = this._leaflet_events;
|
||||
|
||||
if (typeof types === 'object') {
|
||||
context = context || fn;
|
||||
fn = undefined;
|
||||
|
||||
for (var type in types) {
|
||||
if (types.hasOwnProperty(type)) {
|
||||
this.off(type, types[type], context);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
for (var i = 0, events = this._leaflet_events, len = events[type].length; i < len; i++) {
|
||||
types = (types || '').replace(/^\s+/, '').replace(/\s+$/, '').split(' ');
|
||||
|
||||
for (var i = 0, ilen = types.length; i < ilen; i++) {
|
||||
var eventType = events[types[i]] || [];
|
||||
|
||||
if (!this.hasEventListeners(types[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove matching events
|
||||
var j = eventType.length;
|
||||
|
||||
while (j--) {
|
||||
if (
|
||||
(events[type][i].action === fn) &&
|
||||
(!context || (events[type][i].context === context))
|
||||
(!fn || eventType[j].action === fn) &&
|
||||
(!context || (eventType[j].context === context))
|
||||
) {
|
||||
events[type].splice(i, 1);
|
||||
return this;
|
||||
eventType.splice(j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user