You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/UI/JsLibraries/backbone.wreqr.js

276 lines
6.6 KiB

(function (root, factory) {
if (typeof exports === 'object') {
var underscore = require('underscore');
var backbone = require('backbone');
module.exports = factory(underscore, backbone);
} else if (typeof define === 'function' && define.amd) {
define(['underscore', 'backbone'], factory);
}
}(this, function (_, Backbone) {
'use strict';
Backbone.Wreqr = (function(Backbone, Marionette, _){
'use strict';
var Wreqr = {};
// Handlers
// --------
// A registry of functions to call, given a name
Wreqr.Handlers = (function(Backbone, _){
'use strict';
// Constructor
// -----------
var Handlers = function(options){
this.options = options;
this._wreqrHandlers = {};
if (_.isFunction(this.initialize)){
this.initialize(options);
}
};
Handlers.extend = Backbone.Model.extend;
// Instance Members
// ----------------
_.extend(Handlers.prototype, Backbone.Events, {
// Add multiple handlers using an object literal configuration
setHandlers: function(handlers){
_.each(handlers, function(handler, name){
var context = null;
if (_.isObject(handler) && !_.isFunction(handler)){
context = handler.context;
handler = handler.callback;
}
this.setHandler(name, handler, context);
}, this);
},
// Add a handler for the given name, with an
// optional context to run the handler within
setHandler: function(name, handler, context){
var config = {
callback: handler,
context: context
};
this._wreqrHandlers[name] = config;
this.trigger("handler:add", name, handler, context);
},
// Determine whether or not a handler is registered
hasHandler: function(name){
return !! this._wreqrHandlers[name];
},
// Get the currently registered handler for
// the specified name. Throws an exception if
// no handler is found.
getHandler: function(name){
var config = this._wreqrHandlers[name];
if (!config){
throw new Error("Handler not found for '" + name + "'");
}
return function(){
var args = Array.prototype.slice.apply(arguments);
return config.callback.apply(config.context, args);
};
},
// Remove a handler for the specified name
removeHandler: function(name){
delete this._wreqrHandlers[name];
},
// Remove all handlers from this registry
removeAllHandlers: function(){
this._wreqrHandlers = {};
}
});
return Handlers;
})(Backbone, _);
// Wreqr.CommandStorage
// --------------------
//
// Store and retrieve commands for execution.
Wreqr.CommandStorage = (function(){
'use strict';
// Constructor function
var CommandStorage = function(options){
this.options = options;
this._commands = {};
if (_.isFunction(this.initialize)){
this.initialize(options);
}
};
// Instance methods
_.extend(CommandStorage.prototype, Backbone.Events, {
// Get an object literal by command name, that contains
// the `commandName` and the `instances` of all commands
// represented as an array of arguments to process
getCommands: function(commandName){
var commands = this._commands[commandName];
// we don't have it, so add it
if (!commands){
// build the configuration
commands = {
command: commandName,
instances: []
};
// store it
this._commands[commandName] = commands;
}
return commands;
},
// Add a command by name, to the storage and store the
// args for the command
addCommand: function(commandName, args){
var command = this.getCommands(commandName);
command.instances.push(args);
},
// Clear all commands for the given `commandName`
clearCommands: function(commandName){
var command = this.getCommands(commandName);
command.instances = [];
}
});
return CommandStorage;
})();
// Wreqr.Commands
// --------------
//
// A simple command pattern implementation. Register a command
// handler and execute it.
Wreqr.Commands = (function(Wreqr){
'use strict';
return Wreqr.Handlers.extend({
// default storage type
storageType: Wreqr.CommandStorage,
constructor: function(options){
this.options = options || {};
this._initializeStorage(this.options);
this.on("handler:add", this._executeCommands, this);
var args = Array.prototype.slice.call(arguments);
Wreqr.Handlers.prototype.constructor.apply(this, args);
},
// Execute a named command with the supplied args
execute: function(name, args){
name = arguments[0];
args = Array.prototype.slice.call(arguments, 1);
if (this.hasHandler(name)){
this.getHandler(name).apply(this, args);
} else {
this.storage.addCommand(name, args);
}
},
// Internal method to handle bulk execution of stored commands
_executeCommands: function(name, handler, context){
var command = this.storage.getCommands(name);
// loop through and execute all the stored command instances
_.each(command.instances, function(args){
handler.apply(context, args);
});
this.storage.clearCommands(name);
},
// Internal method to initialize storage either from the type's
// `storageType` or the instance `options.storageType`.
_initializeStorage: function(options){
var storage;
var StorageType = options.storageType || this.storageType;
if (_.isFunction(StorageType)){
storage = new StorageType();
} else {
storage = StorageType;
}
this.storage = storage;
}
});
})(Wreqr);
// Wreqr.RequestResponse
// ---------------------
//
// A simple request/response implementation. Register a
// request handler, and return a response from it
Wreqr.RequestResponse = (function(Wreqr){
'use strict';
return Wreqr.Handlers.extend({
request: function(){
var name = arguments[0];
var args = Array.prototype.slice.call(arguments, 1);
return this.getHandler(name).apply(this, args);
}
});
})(Wreqr);
// Event Aggregator
// ----------------
// A pub-sub object that can be used to decouple various parts
// of an application through event-driven architecture.
Wreqr.EventAggregator = (function(Backbone, _){
'use strict';
var EA = function(){};
// Copy the `extend` function used by Backbone's classes
EA.extend = Backbone.Model.extend;
// Copy the basic Backbone.Events on to the event aggregator
_.extend(EA.prototype, Backbone.Events);
return EA;
})(Backbone, _);
return Wreqr;
})(Backbone, Backbone.Marionette, _);
return Backbone.Wreqr;
}));