/*
jQuery pub/sub plugin by Túbal Martín (http://margenn.com)
Inspired by Peter Higgings plugin: https://github.com/phiggins42/bloody-jquery-plugins/blob/8ccf0da40b85fa4ecc30079c8650bac58f7a334c/pubsub.js
*/
(function($) {
// The topics/subscriptions hash
var topics = {};
/**
* @description Publishes some data on a named topic.
* @param {String} topic The topic to publish.
* @param {Array} [args] The data to publish.
* @returns {jQuery} returns jQuery object.
* @example
* $( "#sidebarWidget" ).publish( "/some/topic", [ "a", "b", "c" ] );
*/
$.fn.publish = function ( topic, args ) {
args = args || [],
argsLength = args.length;
if ( topics[topic] ) {
this.each( function( i, obj ) {
// Let's add a reference to the publisher object
args[argsLength] = obj;
$.each( topics[topic], function( j, aElem ) {
aElem.callback.apply( aElem.object, args );
});
});
}
return this;
};
/**
* @description Registers a callback on a named topic.
* @param {String} topic The topic to subscribe to.
* @param {Function} callback The handler. Anytime something is published on a subscribed
* topic, the callback will be called with the published array as ordered arguments.
* @returns {jQuery} returns jQuery object.
* @example
* $( "#header" ).subscribe( "/some/topic", function( a, b, c ) { // handle data } );
*/
$.fn.subscribe = function( topic, callback ) {
topics[topic] = topics[topic] || [];
this.each( function( i, obj ) {
// Array.push() is way slower. See: http://jsperf.com/array-push-el-vs-array-array-length-el
topics[topic][topics[topic].length] = { "object": obj, "callback": callback };
});
return this;
};
/**
* @description Unregisters a previously registered callback for a named topic.
* @param {String} topic The topic to unsubscribe from.
* @returns {jQuery} returns jQuery object.
* @example
* $( "#header" ).unsubscribe( "/some/topic" );
*/
$.fn.unsubscribe = function ( topic ) {
if ( topics[topic] ) {
this.each( function( i, obj ) {
topics[topic] = $.grep( topics[topic], function( aElem, j ) {
return ( obj !== aElem.object );
});
});
if ( topics[topic].length === 0 ) {
delete topics[topic];
}
}
return this;
};
}(jQuery));