Skip to content

Commit

Permalink
Merge pull request Leaflet#2149 from danzel/ios7-2122
Browse files Browse the repository at this point in the history
Work around iOS7 memory trouble
  • Loading branch information
mourner committed Nov 4, 2013
2 parents 6c85f43 + fa35aba commit 77bd10c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
44 changes: 44 additions & 0 deletions spec/suites/core/EventsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,29 @@ describe('Events', function() {
expect(spy2.called).to.be(false);
});

it('removes listeners with context == this and a stamp originally added without one', function () {
var obj = new Klass(),
obj2 = new Klass(),
spy1 = sinon.spy(),
spy2 = sinon.spy(),
spy3 = sinon.spy();

obj.addEventListener('test', spy1, obj);
L.Util.stamp(obj);
obj.addEventListener('test', spy2, obj);
obj.addEventListener('test', spy3, obj2); // So that there is a contextId based listener, otherwise removeEventListener will do correct behaviour anyway

obj.removeEventListener('test', spy1, obj);
obj.removeEventListener('test', spy2, obj);
obj.removeEventListener('test', spy3, obj2);

obj.fireEvent('test');

expect(spy1.called).to.be(false);
expect(spy2.called).to.be(false);
expect(spy3.called).to.be(false);
});

it('doesnt lose track of listeners when removing non existent ones', function () {
var obj = new Klass(),
spy = sinon.spy(),
Expand All @@ -212,6 +235,27 @@ describe('Events', function() {
expect(spy.called).to.be(false);
});

it('correctly removes all listeners if given no fn', function () {
var obj = new Klass(),
spy = sinon.spy(),
foo = {},
foo2 = {},
foo3 = {};

obj.addEventListener('test', spy, foo2);
obj.addEventListener('test', spy, foo3);

obj.removeEventListener('test'); // Removes both of the above listeners

expect(obj.hasEventListeners('test')).to.be(false);

//Add and remove a listener
obj.addEventListener('test', spy, foo2);
obj.removeEventListener('test', spy, foo2);

expect(obj.hasEventListeners('test')).to.be(false);
});

it('makes sure an event is not triggered if a listener is removed during dispatch',function() {
var obj = new Klass(),
spy = sinon.spy();
Expand Down
13 changes: 7 additions & 6 deletions src/core/Events.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ L.Mixin.Events = {
if (L.Util.invokeEach(types, this.addEventListener, this, fn, context)) { return this; }

var events = this[eventsKey] = this[eventsKey] || {},
contextId = context && L.stamp(context),
contextId = context && context !== this && L.stamp(context),
i, len, event, type, indexKey, indexLenKey, typeIndex;

// types can be a string of space-separated words
Expand All @@ -27,7 +27,7 @@ L.Mixin.Events = {
};
type = types[i];

if (context) {
if (contextId) {
// store listeners of a particular context in a separate hash (if it has an id)
// gives a major performance boost when removing thousands of map layers

Expand Down Expand Up @@ -74,7 +74,7 @@ L.Mixin.Events = {
if (L.Util.invokeEach(types, this.removeEventListener, this, fn, context)) { return this; }

var events = this[eventsKey],
contextId = context && L.stamp(context),
contextId = context && context !== this && L.stamp(context),
i, len, type, listeners, j, indexKey, indexLenKey, typeIndex, removed;

types = L.Util.splitWords(types);
Expand All @@ -90,9 +90,10 @@ L.Mixin.Events = {
// clear all listeners for a type if function isn't specified
delete events[type];
delete events[indexKey];
delete events[indexLenKey];

} else {
listeners = context && typeIndex ? typeIndex[contextId] : events[type];
listeners = contextId && typeIndex ? typeIndex[contextId] : events[type];

if (listeners) {
for (j = listeners.length - 1; j >= 0; j--) {
Expand Down Expand Up @@ -135,7 +136,7 @@ L.Mixin.Events = {
listeners = events[type].slice();

for (i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
listeners[i].action.call(listeners[i].context, event);
}
}

Expand All @@ -147,7 +148,7 @@ L.Mixin.Events = {

if (listeners) {
for (i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
listeners[i].action.call(listeners[i].context, event);
}
}
}
Expand Down

0 comments on commit 77bd10c

Please sign in to comment.