From a469a387a16398253dcd74d0872edbdb1d0e215f Mon Sep 17 00:00:00 2001 From: iirvine Date: Sat, 13 Apr 2013 22:11:01 -0700 Subject: [PATCH] back to first implementation to fix event leak --- spec/suites/core/EventsSpec.js | 90 ++++------------------------------ src/core/Events.js | 44 +++++++---------- 2 files changed, 27 insertions(+), 107 deletions(-) diff --git a/spec/suites/core/EventsSpec.js b/spec/suites/core/EventsSpec.js index b9706fb3..f8554eb1 100644 --- a/spec/suites/core/EventsSpec.js +++ b/spec/suites/core/EventsSpec.js @@ -247,7 +247,7 @@ describe('Events', function() { }); describe('#once', function() { - it('removes event listeners after first fire', function() { + it('removes event listeners after first trigger', function() { var obj = new Klass(), spy = new sinon.spy(); @@ -261,7 +261,7 @@ describe('Events', function() { expect(spy.callCount).to.be.lessThan(2); }); - it('works with object hash', function() { + it('works with an object hash', function() { var obj = new Klass(), spy = new sinon.spy(), otherSpy = new sinon.spy(); @@ -284,88 +284,16 @@ describe('Events', function() { expect(otherSpy.callCount).to.be.lessThan(2); }); - it('only removes the fired event handler', function() { - var obj = new Klass(), - spy = new sinon.spy(), - otherSpy = new sinon.spy(); + it("doesn't call listeners to events that have been removed", function () { + var obj = new Klass(), + spy = new sinon.spy(); - obj.once({ - test: spy, - otherTest: otherSpy - }); + obj.once('test', spy, obj); + obj.off('test', spy, obj); - obj.fire('test'); + obj.fire('test'); - expect(spy.called).to.be(true); - expect(otherSpy.called).to.be(false); - - obj.fire('otherTest'); - - expect(otherSpy.called).to.be(true); - - expect(spy.callCount).to.be.lessThan(2); - expect(otherSpy.callCount).to.be.lessThan(2); - }); - - it('can be passed multiple types', function() { - var obj = new Klass(), - spy = new sinon.spy(), - otherSpy = new sinon.spy(); - - obj.once('test otherTest', spy, obj); - obj.fire('otherTest'); - - expect(spy.called).to.be(true); - - obj.fire('test'); - - expect(spy.callCount).to.be.lessThan(2); - }); - - it('provides event object to listeners and executes with the correct context', function() { - var obj = new Klass(), - obj2 = new Klass(), - obj3 = new Klass(), - obj4 = new Klass(), - foo = new Klass(); - - function listener1(e) { - expect(e.type).to.eql('test'); - expect(e.target).to.eql(obj); - expect(this).to.eql(obj); - expect(e.baz).to.eql(1); - } - - function listener2(e) { - expect(e.type).to.eql('test'); - expect(e.target).to.eql(obj2); - expect(this).to.eql(foo); - expect(e.baz).to.eql(2); - } - - function listener3(e) { - expect(e.type).to.eql('test'); - expect(e.target).to.eql(obj3); - expect(this).to.eql(obj3); - expect(e.baz).to.eql(3); - } - - function listener4(e) { - expect(e.type).to.eql('test'); - expect(e.target).to.eql(obj4); - expect(this).to.eql(foo); - expect(e.baz).to.eql(4); - } - - obj.once('test', listener1); - obj2.once('test', listener2, foo); - obj3.once({ test: listener3 }); - obj4.once({ test: listener4 }, foo); - - obj.fireEvent('test', {baz: 1}); - obj2.fireEvent('test', {baz: 2}); - obj3.fireEvent('test', {baz: 3}); - obj4.fireEvent('test', {baz: 4}); + expect(spy.called).to.be(false); }); }); }); diff --git a/src/core/Events.js b/src/core/Events.js index 93cde26b..4d017b49 100644 --- a/src/core/Events.js +++ b/src/core/Events.js @@ -148,34 +148,26 @@ L.Mixin.Events = { }, once: function(types, fn, context) { - var once = function(fn) { - var done = false; - return function() { - if (done) return; - fn.apply(this, arguments); - fn = null; - done = true; - } - } + handlerFor = function (fn, type, context) { + var handler = function () { + this.removeEventListener(type, fn, context); + this.removeEventListener(type, handler, context); + } + return handler; + } - var handlerFor = L.bind(function(type, fn, context) { - var handler = once(function() { - this.removeEventListener(types, handler); - fn.apply(context || this, arguments); - }); - return handler; - }, this); + if (typeof types === 'object') { + for (type in types) { + if (types.hasOwnProperty(type)) { + this.addEventListener(type, types[type], fn); + this.addEventListener(type, handlerFor(types[type], type, fn), fn); + } + } + return this; + } - if (typeof types === 'object') { - for (type in types) { - if (types.hasOwnProperty(type)) { - this.addEventListener(type, handlerFor(type, types[type], fn), fn); - } - } - return this; - } - - return this.addEventListener(types, handlerFor(types,fn,context), context); + this.addEventListener(types, fn, context); + return this.addEventListener(types, handlerFor(fn, types, context), context); } };