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 ) {