mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-05 13:21:10 -05:00
203 lines
5 KiB
JavaScript
203 lines
5 KiB
JavaScript
|
/**
|
||
|
* |-------------------|
|
||
|
* | Backbone-Mediator |
|
||
|
* |-------------------|
|
||
|
* Backbone-Mediator is freely distributable under the MIT license.
|
||
|
*
|
||
|
* <a href="https://github.com/chalbert/Backbone-Mediator">More details & documentation</a>
|
||
|
*
|
||
|
* @author Nicolas Gilbert
|
||
|
*
|
||
|
* @requires _
|
||
|
* @requires Backbone
|
||
|
*/
|
||
|
(function(factory){
|
||
|
'use strict';
|
||
|
|
||
|
if (typeof define === 'function' && define.amd) {
|
||
|
define(['underscore', 'backbone'], factory);
|
||
|
} else {
|
||
|
factory(_, Backbone);
|
||
|
}
|
||
|
|
||
|
})(function (_, Backbone){
|
||
|
'use strict';
|
||
|
|
||
|
/**
|
||
|
* @static
|
||
|
*/
|
||
|
var channels = {},
|
||
|
Subscriber,
|
||
|
/** @borrows Backbone.View#delegateEvents */
|
||
|
delegateEvents = Backbone.View.prototype.delegateEvents,
|
||
|
/** @borrows Backbone.View#delegateEvents */
|
||
|
undelegateEvents = Backbone.View.prototype.undelegateEvents;
|
||
|
|
||
|
/**
|
||
|
* @class
|
||
|
*/
|
||
|
Backbone.Mediator = {
|
||
|
|
||
|
/**
|
||
|
* Subscribe to a channel
|
||
|
*
|
||
|
* @param channel
|
||
|
*/
|
||
|
subscribe: function(channel, subscription, context, once) {
|
||
|
if (!channels[channel]) channels[channel] = [];
|
||
|
channels[channel].push({fn: subscription, context: context || this, once: once});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger all callbacks for a channel
|
||
|
*
|
||
|
* @param channel
|
||
|
* @params N Extra parametter to pass to handler
|
||
|
*/
|
||
|
publish: function(channel) {
|
||
|
if (!channels[channel]) return;
|
||
|
|
||
|
var args = [].slice.call(arguments, 1),
|
||
|
subscription;
|
||
|
|
||
|
for (var i = 0; i < channels[channel].length; i++) {
|
||
|
subscription = channels[channel][i];
|
||
|
subscription.fn.apply(subscription.context, args);
|
||
|
if (subscription.once) {
|
||
|
Backbone.Mediator.unsubscribe(channel, subscription.fn, subscription.context);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Cancel subscription
|
||
|
*
|
||
|
* @param channel
|
||
|
* @param fn
|
||
|
* @param context
|
||
|
*/
|
||
|
|
||
|
unsubscribe: function(channel, fn, context){
|
||
|
if (!channels[channel]) return;
|
||
|
|
||
|
var subscription;
|
||
|
for (var i = 0; i < channels[channel].length; i++) {
|
||
|
subscription = channels[channel][i];
|
||
|
if (subscription.fn === fn && subscription.context === context) {
|
||
|
channels[channel].splice(i, 1);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Subscribing to one event only
|
||
|
*
|
||
|
* @param channel
|
||
|
* @param subscription
|
||
|
* @param context
|
||
|
*/
|
||
|
subscribeOnce: function (channel, subscription, context) {
|
||
|
Backbone.Mediator.subscribe(channel, subscription, context, true);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
Backbone.Mediator.channels = channels;
|
||
|
|
||
|
/**
|
||
|
* Allow to define convention-based subscriptions
|
||
|
* as an 'subscriptions' hash on a view. Subscriptions
|
||
|
* can then be easily setup and cleaned.
|
||
|
*
|
||
|
* @class
|
||
|
*/
|
||
|
|
||
|
|
||
|
Subscriber = {
|
||
|
|
||
|
/**
|
||
|
* Extend delegateEvents() to set subscriptions
|
||
|
*/
|
||
|
delegateEvents: function(){
|
||
|
delegateEvents.apply(this, arguments);
|
||
|
this.setSubscriptions();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Extend undelegateEvents() to unset subscriptions
|
||
|
*/
|
||
|
undelegateEvents: function(){
|
||
|
undelegateEvents.apply(this, arguments);
|
||
|
this.unsetSubscriptions();
|
||
|
},
|
||
|
|
||
|
/** @property {Object} List of subscriptions, to be defined */
|
||
|
subscriptions: {},
|
||
|
|
||
|
/**
|
||
|
* Subscribe to each subscription
|
||
|
* @param {Object} [subscriptions] An optional hash of subscription to add
|
||
|
*/
|
||
|
|
||
|
setSubscriptions: function(subscriptions){
|
||
|
if (subscriptions) _.extend(this.subscriptions || {}, subscriptions);
|
||
|
subscriptions = subscriptions || this.subscriptions;
|
||
|
if (!subscriptions || _.isEmpty(subscriptions)) return;
|
||
|
// Just to be sure we don't set duplicate
|
||
|
this.unsetSubscriptions(subscriptions);
|
||
|
|
||
|
_.each(subscriptions, function(subscription, channel){
|
||
|
var once;
|
||
|
if (subscription.$once) {
|
||
|
subscription = subscription.$once;
|
||
|
once = true;
|
||
|
}
|
||
|
if (_.isString(subscription)) {
|
||
|
subscription = this[subscription];
|
||
|
}
|
||
|
Backbone.Mediator.subscribe(channel, subscription, this, once);
|
||
|
}, this);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Unsubscribe to each subscription
|
||
|
* @param {Object} [subscriptions] An optional hash of subscription to remove
|
||
|
*/
|
||
|
unsetSubscriptions: function(subscriptions){
|
||
|
subscriptions = subscriptions || this.subscriptions;
|
||
|
if (!subscriptions || _.isEmpty(subscriptions)) return;
|
||
|
_.each(subscriptions, function(subscription, channel){
|
||
|
if (_.isString(subscription)) {
|
||
|
subscription = this[subscription];
|
||
|
}
|
||
|
Backbone.Mediator.unsubscribe(channel, subscription.$once || subscription, this);
|
||
|
}, this);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @lends Backbone.View.prototype
|
||
|
*/
|
||
|
_.extend(Backbone.View.prototype, Subscriber);
|
||
|
|
||
|
/**
|
||
|
* @lends Backbone.Mediator
|
||
|
*/
|
||
|
_.extend(Backbone.Mediator, {
|
||
|
/**
|
||
|
* Shortcut for publish
|
||
|
* @function
|
||
|
*/
|
||
|
pub: Backbone.Mediator.publish,
|
||
|
/**
|
||
|
* Shortcut for subscribe
|
||
|
* @function
|
||
|
*/
|
||
|
sub: Backbone.Mediator.subscribe
|
||
|
});
|
||
|
|
||
|
return Backbone;
|
||
|
|
||
|
});
|