From e41e8a886a284d3601a97e16599209529b50c29c Mon Sep 17 00:00:00 2001 From: iirvine Date: Fri, 12 Apr 2013 15:21:48 -0700 Subject: [PATCH] initial implementation of events#once --- spec/suites/core/EventsSpec.js | 62 ++++++++++++++++++++++++++++++++++ src/core/Events.js | 23 +++++++++++++ 2 files changed, 85 insertions(+) diff --git a/spec/suites/core/EventsSpec.js b/spec/suites/core/EventsSpec.js index fc0976d0..48af81d1 100644 --- a/spec/suites/core/EventsSpec.js +++ b/spec/suites/core/EventsSpec.js @@ -245,4 +245,66 @@ describe('Events', function() { expect(spy3.called).to.be(true); }); }); + + describe('#once', function(){ + it('removes event listeners after first fire', function() { + var obj = new Klass(), + spy = new sinon.spy(); + + obj.once('test', spy); + obj.fire('test'); + + expect(spy.called).to.be(true); + + obj.fire('test'); + + expect(spy.callCount).to.be.lessThan(2); + }); + + it('works with object hash', function() { + var obj = new Klass(), + spy = new sinon.spy(), + otherSpy = new sinon.spy(); + + obj.once({ + test: spy, + otherTest: otherSpy + }); + + 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('only removes the fired event handler', function(){ + var obj = new Klass(), + spy = new sinon.spy(), + otherSpy = new sinon.spy(); + + obj.once({ + test: spy, + otherTest: otherSpy + }); + + 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); + }); + }); }); diff --git a/src/core/Events.js b/src/core/Events.js index 27910eae..6f3de7dd 100644 --- a/src/core/Events.js +++ b/src/core/Events.js @@ -148,6 +148,29 @@ L.Mixin.Events = { } return this; + }, + + once: function(types, fn, context) { + handlerFor = function(fn, type, context) { + var handler = function() { + this.removeEventListener(type, fn, context); + this.removeEventListener(type, handler, context); + } + return handler; + } + + 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; + } + + this.addEventListener(types, fn, context); + return this.addEventListener(types, handlerFor(fn, types, context), context); } };