/* 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));