From d3b027bade8497a68eb6202d899d3a2d73b5669c Mon Sep 17 00:00:00 2001 From: Antoine Vandecreme Date: Mon, 21 Mar 2016 11:27:43 -0400 Subject: [PATCH 1/3] Add addOnceHandler method to EventSource. --- src/eventsource.js | 17 ++++++++++++++++- test/modules/events.js | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/eventsource.js b/src/eventsource.js index e305da25..fc2a28aa 100644 --- a/src/eventsource.js +++ b/src/eventsource.js @@ -56,7 +56,22 @@ $.EventSource = function() { /** @lends OpenSeadragon.EventSource.prototype */ $.EventSource.prototype = { - // TODO: Add a method 'one' which automatically unbinds a listener after the first triggered event that matches. + /** + * Add an event handler to be triggered only once for a given event. + * @function + * @param {String} eventName - Name of event to register. + * @param {OpenSeadragon.EventHandler} handler - Function to call when event + * is triggered. + * @param {Object} [userData=null] - Arbitrary object to be passed unchanged + * to the handler. + */ + addOnceHandler: function(eventName, handler, userData) { + var self = this; + this.addHandler(eventName, function onceHandler(event) { + self.removeHandler(eventName, onceHandler); + handler(event); + }, userData); + }, /** * Add an event handler for a given event. diff --git a/test/modules/events.js b/test/modules/events.js index 62caa072..f6cfeb8b 100644 --- a/test/modules/events.js +++ b/test/modules/events.js @@ -949,6 +949,31 @@ viewer.open( '/test/data/testpattern.dzi' ); } ); + // ---------- + test('EventSource: addOnceHandler', function() { + var eventSource = new OpenSeadragon.EventSource(); + var userData = 'data'; + var eventData = { + foo: 1 + }; + var handlerCalledCount = 0; + eventSource.addOnceHandler('test-event', function(event) { + handlerCalledCount++; + strictEqual(event.foo, eventData.foo, + 'Event data should be transmitted to the event.'); + strictEqual(event.userData, userData, + 'User data should be transmitted to the event.'); + }, userData); + strictEqual(0, handlerCalledCount, + 'Handler should not have been called yet.'); + eventSource.raiseEvent('test-event', eventData); + strictEqual(1, handlerCalledCount, + 'Handler should have been called once.'); + eventSource.raiseEvent('test-event', eventData); + strictEqual(1, handlerCalledCount, + 'Handler should still have been called once.'); + }); + // ---------- asyncTest( 'Viewer: tile-drawing event', function () { var tileDrawing = function ( event ) { From fddf0fb938a0371dc09fe27e8211fc5a469025bb Mon Sep 17 00:00:00 2001 From: Antoine Vandecreme Date: Tue, 22 Mar 2016 10:03:52 -0400 Subject: [PATCH 2/3] Use variable instead of function name. --- src/eventsource.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/eventsource.js b/src/eventsource.js index fc2a28aa..6d0d0870 100644 --- a/src/eventsource.js +++ b/src/eventsource.js @@ -67,10 +67,11 @@ $.EventSource.prototype = { */ addOnceHandler: function(eventName, handler, userData) { var self = this; - this.addHandler(eventName, function onceHandler(event) { + var onceHandler = function(event) { self.removeHandler(eventName, onceHandler); handler(event); - }, userData); + }; + this.addHandler(eventName, onceHandler, userData); }, /** From 0f82eed0dbdd85124e23272c732a9c11302e81ed Mon Sep 17 00:00:00 2001 From: Antoine Vandecreme Date: Tue, 22 Mar 2016 13:54:35 -0400 Subject: [PATCH 3/3] Add times parameter to addOnceHandler. --- src/eventsource.js | 14 +++++++++++--- test/modules/events.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/eventsource.js b/src/eventsource.js index 6d0d0870..e3957d7f 100644 --- a/src/eventsource.js +++ b/src/eventsource.js @@ -57,18 +57,26 @@ $.EventSource = function() { $.EventSource.prototype = { /** - * Add an event handler to be triggered only once for a given event. + * Add an event handler to be triggered only once (or a given number of times) + * for a given event. * @function * @param {String} eventName - Name of event to register. * @param {OpenSeadragon.EventHandler} handler - Function to call when event * is triggered. * @param {Object} [userData=null] - Arbitrary object to be passed unchanged * to the handler. + * @param {Number} [times=1] - The number of times to handle the event + * before removing it. */ - addOnceHandler: function(eventName, handler, userData) { + addOnceHandler: function(eventName, handler, userData, times) { var self = this; + times = times || 1; + var count = 0; var onceHandler = function(event) { - self.removeHandler(eventName, onceHandler); + count++; + if (count === times) { + self.removeHandler(eventName, onceHandler); + } handler(event); }; this.addHandler(eventName, onceHandler, userData); diff --git a/test/modules/events.js b/test/modules/events.js index f6cfeb8b..18f50c37 100644 --- a/test/modules/events.js +++ b/test/modules/events.js @@ -974,6 +974,34 @@ 'Handler should still have been called once.'); }); + // ---------- + test('EventSource: addOnceHandler 2 times', function() { + var eventSource = new OpenSeadragon.EventSource(); + var userData = 'data'; + var eventData = { + foo: 1 + }; + var handlerCalledCount = 0; + eventSource.addOnceHandler('test-event', function(event) { + handlerCalledCount++; + strictEqual(event.foo, eventData.foo, + 'Event data should be transmitted to the event.'); + strictEqual(event.userData, userData, + 'User data should be transmitted to the event.'); + }, userData, 2); + strictEqual(0, handlerCalledCount, + 'Handler should not have been called yet.'); + eventSource.raiseEvent('test-event', eventData); + strictEqual(1, handlerCalledCount, + 'Handler should have been called once.'); + eventSource.raiseEvent('test-event', eventData); + strictEqual(2, handlerCalledCount, + 'Handler should have been called twice.'); + eventSource.raiseEvent('test-event', eventData); + strictEqual(2, handlerCalledCount, + 'Handler should still have been called twice.'); + }); + // ---------- asyncTest( 'Viewer: tile-drawing event', function () { var tileDrawing = function ( event ) {