hasOwn = Object.prototype.hasOwnProperty,
slice = Array.prototype.slice,
trackCallbacks = $.Callbacks( 'memory' ),
+ trackHandlers = [],
trackQueue = [];
/**
*/
trackSubscribe: function ( topic, callback ) {
var seen = 0;
-
- trackCallbacks.add( function ( trackQueue ) {
+ function handler( trackQueue ) {
var event;
for ( ; seen < trackQueue.length; seen++ ) {
event = trackQueue[ seen ];
callback.call( event, event.topic, event.data );
}
}
+ }
+
+ trackHandlers.push( [ handler, callback ] );
+
+ trackCallbacks.add( handler );
+ },
+
+ /**
+ * Stop handling events for a particular handler
+ *
+ * @param {Function} callback
+ */
+ trackUnsubscribe: function ( callback ) {
+ trackHandlers = $.grep( trackHandlers, function ( fns ) {
+ if ( fns[1] === callback ) {
+ trackCallbacks.remove( fns[0] );
+ // Ensure the tuple is removed to avoid holding on to closures
+ return false;
+ }
+ return true;
} );
},
assert.assertTrue( this.timeStamp >= now, 'thisValue has sane timestamp' );
} );
} );
+
+ QUnit.test( 'trackUnsubscribe', 1, function ( assert ) {
+ var sequence = [];
+ function unsubber( topic, data ) {
+ sequence.push( [ topic, data ] );
+ }
+
+ mw.track( 'unsub', { key: 1 } );
+ mw.trackSubscribe( 'unsub', unsubber );
+ mw.track( 'unsub', { key: 2 } );
+ mw.trackUnsubscribe( unsubber );
+ mw.track( 'unsub', { key: 3 } );
+
+ assert.deepEqual( sequence, [
+ [ 'unsub', { key: 1 } ],
+ [ 'unsub', { key: 2 } ]
+ ], 'Stop when unsubscribing' );
+ } );
}( mediaWiki ) );