diff --git a/lib/postal.js b/lib/postal.js index 98328c9..b424bd0 100644 --- a/lib/postal.js +++ b/lib/postal.js @@ -11,7 +11,7 @@ // Node, or CommonJS-Like environments module.exports = function (_) { _ = _ || require("underscore"); - return factory(_); + return factory(_, this); }; } else if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module. @@ -25,6 +25,7 @@ }(this, function (_, global, undefined) { var postal; + var prevPostal = global.postal; var ConsecutiveDistinctPredicate = function () { @@ -424,6 +425,14 @@ return result; }, + noConflict: function () { + if (typeof window === "undefined") { + throw new Error("noConflict can only be used in browser clients which aren't using AMD modules"); + } + global.postal = prevPostal; + return this; + }, + utils: { getSubscribersFor: function () { var channel = arguments[0], diff --git a/lib/postal.min.js b/lib/postal.min.js index 406da7e..fce34ce 100644 --- a/lib/postal.min.js +++ b/lib/postal.min.js @@ -5,4 +5,4 @@ * Url: http://github.com/postaljs/postal.js * License(s): MIT, GPL */ -(function(t,n){"object"==typeof module&&module.exports?module.exports=function(t){return t=t||require("underscore"),n(t)}:"function"==typeof define&&define.amd?define(["underscore"],function(i){return n(i,t)}):t.postal=n(t._,t)})(this,function(t,n){var i,s=function(){var n;return function(i){var s=!1;return t.isString(i)?(s=i===n,n=i):(s=t.isEqual(i,n),n=t.clone(i)),!s}},e=function(){var n=[];return function(i){var s=!t.any(n,function(n){return t.isObject(i)||t.isArray(i)?t.isEqual(i,n):i===n});return s&&n.push(i),s}},c=function(t){this.channel=t||i.configuration.DEFAULT_CHANNEL};c.prototype.subscribe=function(){return 1===arguments.length?new r(this.channel,arguments[0].topic,arguments[0].callback):new r(this.channel,arguments[0],arguments[1])},c.prototype.publish=function(){var t=1===arguments.length?"[object String]"===Object.prototype.toString.call(arguments[0])?{topic:arguments[0]}:arguments[0]:{topic:arguments[0],data:arguments[1]};return t.channel=this.channel,i.configuration.bus.publish(t)};var r=function(t,n,s){if(3!==arguments.length)throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");if(0===n.length)throw new Error("Topics cannot be empty");this.channel=t,this.topic=n,this.callback=s,this.constraints=[],this.context=null,i.configuration.bus.publish({channel:i.configuration.SYSTEM_CHANNEL,topic:"subscription.created",data:{event:"subscription.created",channel:t,topic:n}}),i.configuration.bus.subscribe(this)};r.prototype={unsubscribe:function(){this.inactive||(this.inactive=!0,i.configuration.bus.unsubscribe(this),i.configuration.bus.publish({channel:i.configuration.SYSTEM_CHANNEL,topic:"subscription.removed",data:{event:"subscription.removed",channel:this.channel,topic:this.topic}}))},defer:function(){var t=this,n=this.callback;return this.callback=function(i,s){setTimeout(function(){n.call(t.context,i,s)},0)},this},disposeAfter:function(n){if(t.isNaN(n)||0>=n)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var i=this,s=this.callback,e=t.after(n,t.bind(function(){this.unsubscribe()},this));return this.callback=function(){s.apply(i.context,arguments),e()},this},distinctUntilChanged:function(){return this.withConstraint(new s),this},distinct:function(){return this.withConstraint(new e),this},once:function(){return this.disposeAfter(1),this},withConstraint:function(n){if(!t.isFunction(n))throw"Predicate constraint must be a function";return this.constraints.push(n),this},withConstraints:function(n){var i=this;return t.isArray(n)&&t.each(n,function(t){i.withConstraint(t)}),i},withContext:function(t){return this.context=t,this},withDebounce:function(n,i){if(t.isNaN(n))throw"Milliseconds must be a number";var s=this.callback;return this.callback=t.debounce(s,n,!!i),this},withDelay:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";var i=this,s=this.callback;return this.callback=function(t,e){setTimeout(function(){s.call(i.context,t,e)},n)},this},withThrottle:function(n,i){if(i=i||{},t.isNaN(n))throw"Milliseconds must be a number";var s=this.callback;return this.callback=t.throttle(s,n,i),this},subscribe:function(t){return this.callback=t,this}};var o={cache:{},regex:{},compare:function(n,i){var s,e,c,r=this.cache[i]&&this.cache[i][n];return"undefined"!=typeof r?r:((e=this.regex[n])||(s="^"+t.map(n.split("."),function(t){var n="";return c&&(n="#"!==c?"\\.\\b":"\\b"),n+="#"===t?"[\\s\\S]*":"*"===t?"[^.]+":t,c=t,n}).join("")+"$",e=this.regex[n]=new RegExp(s)),this.cache[i]=this.cache[i]||{},this.cache[i][n]=r=e.test(i),r)},reset:function(){this.cache={},this.regex={}}},a=function(n,s){!n.inactive&&i.configuration.resolver.compare(n.topic,s.topic)&&t.all(n.constraints,function(t){return t.call(n.context,s.data,s)})&&"function"==typeof n.callback&&n.callback.call(n.context,s.data,s)},u=0,h=[],l=function(){for(;h.length;)f.unsubscribe(h.shift())},f={addWireTap:function(t){var n=this;return n.wireTaps.push(t),function(){var i=n.wireTaps.indexOf(t);-1!==i&&n.wireTaps.splice(i,1)}},publish:function(n){return++u,n.timeStamp=new Date,t.each(this.wireTaps,function(t){t(n.data,n)}),this.subscriptions[n.channel]&&t.each(this.subscriptions[n.channel],function(t){for(var i,s=0,e=t.length;e>s;)(i=t[s++])&&a(i,n)}),0===--u&&l(),n},reset:function(){this.subscriptions&&(t.each(this.subscriptions,function(n){t.each(n,function(t){for(;t.length;)t.pop().unsubscribe()})}),this.subscriptions={})},subscribe:function(t){var n,i=this.subscriptions[t.channel];return i||(i=this.subscriptions[t.channel]={}),n=this.subscriptions[t.channel][t.topic],n||(n=this.subscriptions[t.channel][t.topic]=[]),n.push(t),t},subscriptions:{},wireTaps:[],unsubscribe:function(t){if(u)return void h.push(t);if(this.subscriptions[t.channel][t.topic])for(var n=this.subscriptions[t.channel][t.topic].length,i=0;n>i;){if(this.subscriptions[t.channel][t.topic][i]===t){this.subscriptions[t.channel][t.topic].splice(i,1);break}i+=1}}};if(i={configuration:{bus:f,resolver:o,DEFAULT_CHANNEL:"/",SYSTEM_CHANNEL:"postal"},ChannelDefinition:c,SubscriptionDefinition:r,channel:function(t){return new c(t)},subscribe:function(t){return new r(t.channel||i.configuration.DEFAULT_CHANNEL,t.topic,t.callback)},publish:function(t){return t.channel=t.channel||i.configuration.DEFAULT_CHANNEL,i.configuration.bus.publish(t)},addWireTap:function(t){return this.configuration.bus.addWireTap(t)},linkChannels:function(n,s){var e=[];return n=t.isArray(n)?n:[n],s=t.isArray(s)?s:[s],t.each(n,function(n){var c=n.topic||"#";t.each(s,function(s){var r=s.channel||i.configuration.DEFAULT_CHANNEL;e.push(i.subscribe({channel:n.channel||i.configuration.DEFAULT_CHANNEL,topic:c,callback:function(n,e){var c=t.clone(e);c.topic=t.isFunction(s.topic)?s.topic(e.topic):s.topic||e.topic,c.channel=r,c.data=n,i.publish(c)}}))})}),e},utils:{getSubscribersFor:function(){var t=arguments[0],n=arguments[1];return 1===arguments.length&&(t=arguments[0].channel||i.configuration.DEFAULT_CHANNEL,n=arguments[0].topic),i.configuration.bus.subscriptions[t]&&Object.prototype.hasOwnProperty.call(i.configuration.bus.subscriptions[t],n)?i.configuration.bus.subscriptions[t][n]:[]},reset:function(){i.configuration.bus.reset(),i.configuration.resolver.reset()}}},f.subscriptions[i.configuration.SYSTEM_CHANNEL]={},n&&Object.prototype.hasOwnProperty.call(n,"__postalReady__")&&t.isArray(n.__postalReady__))for(;n.__postalReady__.length;)n.__postalReady__.shift().onReady(i);return i}); \ No newline at end of file +(function(n,t){"object"==typeof module&&module.exports?module.exports=function(n){return n=n||require("underscore"),t(n,this)}:"function"==typeof define&&define.amd?define(["underscore"],function(i){return t(i,n)}):n.postal=t(n._,n)})(this,function(n,t){var i,e=t.postal,s=function(){var t;return function(i){var e=!1;return n.isString(i)?(e=i===t,t=i):(e=n.isEqual(i,t),t=n.clone(i)),!e}},c=function(){var t=[];return function(i){var e=!n.any(t,function(t){return n.isObject(i)||n.isArray(i)?n.isEqual(i,t):i===t});return e&&t.push(i),e}},r=function(n){this.channel=n||i.configuration.DEFAULT_CHANNEL};r.prototype.subscribe=function(){return 1===arguments.length?new o(this.channel,arguments[0].topic,arguments[0].callback):new o(this.channel,arguments[0],arguments[1])},r.prototype.publish=function(){var n=1===arguments.length?"[object String]"===Object.prototype.toString.call(arguments[0])?{topic:arguments[0]}:arguments[0]:{topic:arguments[0],data:arguments[1]};return n.channel=this.channel,i.configuration.bus.publish(n)};var o=function(n,t,e){if(3!==arguments.length)throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");if(0===t.length)throw new Error("Topics cannot be empty");this.channel=n,this.topic=t,this.callback=e,this.constraints=[],this.context=null,i.configuration.bus.publish({channel:i.configuration.SYSTEM_CHANNEL,topic:"subscription.created",data:{event:"subscription.created",channel:n,topic:t}}),i.configuration.bus.subscribe(this)};o.prototype={unsubscribe:function(){this.inactive||(this.inactive=!0,i.configuration.bus.unsubscribe(this),i.configuration.bus.publish({channel:i.configuration.SYSTEM_CHANNEL,topic:"subscription.removed",data:{event:"subscription.removed",channel:this.channel,topic:this.topic}}))},defer:function(){var n=this,t=this.callback;return this.callback=function(i,e){setTimeout(function(){t.call(n.context,i,e)},0)},this},disposeAfter:function(t){if(n.isNaN(t)||0>=t)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var i=this,e=this.callback,s=n.after(t,n.bind(function(){this.unsubscribe()},this));return this.callback=function(){e.apply(i.context,arguments),s()},this},distinctUntilChanged:function(){return this.withConstraint(new s),this},distinct:function(){return this.withConstraint(new c),this},once:function(){return this.disposeAfter(1),this},withConstraint:function(t){if(!n.isFunction(t))throw"Predicate constraint must be a function";return this.constraints.push(t),this},withConstraints:function(t){var i=this;return n.isArray(t)&&n.each(t,function(n){i.withConstraint(n)}),i},withContext:function(n){return this.context=n,this},withDebounce:function(t,i){if(n.isNaN(t))throw"Milliseconds must be a number";var e=this.callback;return this.callback=n.debounce(e,t,!!i),this},withDelay:function(t){if(n.isNaN(t))throw"Milliseconds must be a number";var i=this,e=this.callback;return this.callback=function(n,s){setTimeout(function(){e.call(i.context,n,s)},t)},this},withThrottle:function(t,i){if(i=i||{},n.isNaN(t))throw"Milliseconds must be a number";var e=this.callback;return this.callback=n.throttle(e,t,i),this},subscribe:function(n){return this.callback=n,this}};var a={cache:{},regex:{},compare:function(t,i){var e,s,c,r=this.cache[i]&&this.cache[i][t];return"undefined"!=typeof r?r:((s=this.regex[t])||(e="^"+n.map(t.split("."),function(n){var t="";return c&&(t="#"!==c?"\\.\\b":"\\b"),t+="#"===n?"[\\s\\S]*":"*"===n?"[^.]+":n,c=n,t}).join("")+"$",s=this.regex[t]=new RegExp(e)),this.cache[i]=this.cache[i]||{},this.cache[i][t]=r=s.test(i),r)},reset:function(){this.cache={},this.regex={}}},u=function(t,e){!t.inactive&&i.configuration.resolver.compare(t.topic,e.topic)&&n.all(t.constraints,function(n){return n.call(t.context,e.data,e)})&&"function"==typeof t.callback&&t.callback.call(t.context,e.data,e)},h=0,l=[],f=function(){for(;l.length;)p.unsubscribe(l.shift())},p={addWireTap:function(n){var t=this;return t.wireTaps.push(n),function(){var i=t.wireTaps.indexOf(n);-1!==i&&t.wireTaps.splice(i,1)}},publish:function(t){return++h,t.timeStamp=new Date,n.each(this.wireTaps,function(n){n(t.data,t)}),this.subscriptions[t.channel]&&n.each(this.subscriptions[t.channel],function(n){for(var i,e=0,s=n.length;s>e;)(i=n[e++])&&u(i,t)}),0===--h&&f(),t},reset:function(){this.subscriptions&&(n.each(this.subscriptions,function(t){n.each(t,function(n){for(;n.length;)n.pop().unsubscribe()})}),this.subscriptions={})},subscribe:function(n){var t,i=this.subscriptions[n.channel];return i||(i=this.subscriptions[n.channel]={}),t=this.subscriptions[n.channel][n.topic],t||(t=this.subscriptions[n.channel][n.topic]=[]),t.push(n),n},subscriptions:{},wireTaps:[],unsubscribe:function(n){if(h)return void l.push(n);if(this.subscriptions[n.channel][n.topic])for(var t=this.subscriptions[n.channel][n.topic].length,i=0;t>i;){if(this.subscriptions[n.channel][n.topic][i]===n){this.subscriptions[n.channel][n.topic].splice(i,1);break}i+=1}}};if(i={configuration:{bus:p,resolver:a,DEFAULT_CHANNEL:"/",SYSTEM_CHANNEL:"postal"},ChannelDefinition:r,SubscriptionDefinition:o,channel:function(n){return new r(n)},subscribe:function(n){return new o(n.channel||i.configuration.DEFAULT_CHANNEL,n.topic,n.callback)},publish:function(n){return n.channel=n.channel||i.configuration.DEFAULT_CHANNEL,i.configuration.bus.publish(n)},addWireTap:function(n){return this.configuration.bus.addWireTap(n)},linkChannels:function(t,e){var s=[];return t=n.isArray(t)?t:[t],e=n.isArray(e)?e:[e],n.each(t,function(t){var c=t.topic||"#";n.each(e,function(e){var r=e.channel||i.configuration.DEFAULT_CHANNEL;s.push(i.subscribe({channel:t.channel||i.configuration.DEFAULT_CHANNEL,topic:c,callback:function(t,s){var c=n.clone(s);c.topic=n.isFunction(e.topic)?e.topic(s.topic):e.topic||s.topic,c.channel=r,c.data=t,i.publish(c)}}))})}),s},noConflict:function(){if("undefined"==typeof window)throw new Error("noConflict can only be used in browser clients which aren't using AMD modules");return t.postal=e,this},utils:{getSubscribersFor:function(){var n=arguments[0],t=arguments[1];return 1===arguments.length&&(n=arguments[0].channel||i.configuration.DEFAULT_CHANNEL,t=arguments[0].topic),i.configuration.bus.subscriptions[n]&&Object.prototype.hasOwnProperty.call(i.configuration.bus.subscriptions[n],t)?i.configuration.bus.subscriptions[n][t]:[]},reset:function(){i.configuration.bus.reset(),i.configuration.resolver.reset()}}},p.subscriptions[i.configuration.SYSTEM_CHANNEL]={},t&&Object.prototype.hasOwnProperty.call(t,"__postalReady__")&&n.isArray(t.__postalReady__))for(;t.__postalReady__.length;)t.__postalReady__.shift().onReady(i);return i}); \ No newline at end of file diff --git a/spec/index.html b/spec/index.html index d69f864..a258525 100644 --- a/spec/index.html +++ b/spec/index.html @@ -6,6 +6,10 @@
+ diff --git a/spec/postaljs.spec.js b/spec/postaljs.spec.js index 7b75bf5..d76bf7e 100644 --- a/spec/postaljs.spec.js +++ b/spec/postaljs.spec.js @@ -1,5 +1,5 @@ /* global describe, postal, it, after, before, expect */ -(function() { +(function(global) { var postal = typeof window === "undefined" ? require("../lib/postal.js")() : window.postal; var expect = typeof window === "undefined" ? require("expect.js") : window.expect; var _ = typeof window === "undefined" ? require("underscore") : window._; @@ -9,6 +9,25 @@ var caughtSubscribeEvent = false; var caughtUnsubscribeEvent = false; + describe("noConflict", function() { + it("should return control to the previous postal value", function() { + if(typeof window === "undefined" || (typeof window !== "undefined" && typeof require === "function" && define.amd)) { + var err = false; + try { + postal.noConflict(); + } catch(e) { + err = true; + } + expect(err).to.be( true ); + } else { + var _postal = global.postal; // hang on to postal value + postal.noConflict(); // return previous postal + expect( global.postal.foo ).to.be( "bar" ); + global.postal = _postal; // return postal back as it was + } + }); + }); + describe("subscription creation", function(){ describe( "When creating basic subscription", function () { var systemSubscription = {}; @@ -694,4 +713,4 @@ } ); } ); }); -}()); \ No newline at end of file +}(this)); \ No newline at end of file diff --git a/src/Api.js b/src/Api.js index dfdc4b6..2197518 100644 --- a/src/Api.js +++ b/src/Api.js @@ -1,4 +1,4 @@ -/* global localBus, bindingsResolver, ChannelDefinition, SubscriptionDefinition, postal */ +/* global localBus, bindingsResolver, ChannelDefinition, SubscriptionDefinition, postal, prevPostal, global */ /*jshint -W020 */ postal = { configuration : { @@ -54,6 +54,14 @@ postal = { return result; }, + noConflict: function() { + if(typeof window === "undefined") { + throw new Error("noConflict can only be used in browser clients which aren't using AMD modules"); + } + global.postal = prevPostal; + return this; + }, + utils : { getSubscribersFor : function () { var channel = arguments[ 0 ], diff --git a/src/LocalBus.js b/src/LocalBus.js index c143985..5f4e085 100644 --- a/src/LocalBus.js +++ b/src/LocalBus.js @@ -88,7 +88,7 @@ var localBus = { unSubQueue.push( config ); return; } - if ( this.subscriptions[config.channel][config.topic] ) { + if ( this.subscriptions[config.channel] && this.subscriptions[config.channel][config.topic] ) { var len = this.subscriptions[config.channel][config.topic].length, idx = 0; while ( idx < len ) { diff --git a/src/postal.js b/src/postal.js index 0f6d4c1..8de1af6 100644 --- a/src/postal.js +++ b/src/postal.js @@ -4,7 +4,7 @@ // Node, or CommonJS-Like environments module.exports = function ( _ ) { _ = _ || require( "underscore" ); - return factory( _ ); + return factory( _, this ); }; } else if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. @@ -18,6 +18,7 @@ }( this, function ( _, global, undefined ) { var postal; + var prevPostal = global.postal; //import("ConsecutiveDistinctPredicate.js"); //import("DistinctPredicate.js");