| (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; |
| |
| })); |
| |