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.
276 lines
6.6 KiB
276 lines
6.6 KiB
10 years ago
|
(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;
|
||
|
|
||
|
}));
|