Skip to content

Instantly share code, notes, and snippets.

@paulfalgout
Created November 29, 2015 22:15
Show Gist options
  • Save paulfalgout/27ca9265f81c7e62390a to your computer and use it in GitHub Desktop.
Save paulfalgout/27ca9265f81c7e62390a to your computer and use it in GitHub Desktop.
Mn v3 ES6 build example
// MarionetteJS (Backbone.Marionette)
// ----------------------------------
// v2.4.1
//
// Copyright (c)2015 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://marionettejs.com
/*!
* Includes BabySitter
* https://github.com/marionettejs/backbone.babysitter/
*
* Includes Radio
* https://github.com/marionettejs/backbone.radio/
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('backbone'), require('underscore'), require('backbone.babysitter'), require('backbone.radio')) :
typeof define === 'function' && define.amd ? define(['backbone', 'underscore', 'backbone.babysitter', 'backbone.radio'], factory) :
global.Marionette = global.Mn = factory(global.Backbone,global._,global.Backbone.ChildViewContainer,global.Backbone.Radio);
}(this, function (Backbone,_,ChildViewContainer,Radio) { 'use strict';
Backbone = 'default' in Backbone ? Backbone['default'] : Backbone;
_ = 'default' in _ ? _['default'] : _;
ChildViewContainer = 'default' in ChildViewContainer ? ChildViewContainer['default'] : ChildViewContainer;
Radio = 'default' in Radio ? Radio['default'] : Radio;
// Backbone.BabySitter
// -------------------
// v0.1.10
//
// Copyright (c)2015 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://github.com/marionettejs/backbone.babysitter
(function(Backbone, _) {
"use strict";
var previousChildViewContainer = Backbone.ChildViewContainer;
// BabySitter.ChildViewContainer
// -----------------------------
//
// Provide a container to store, retrieve and
// shut down child views.
Backbone.ChildViewContainer = function(Backbone, _) {
// Container Constructor
// ---------------------
var Container = function(views) {
this._views = {};
this._indexByModel = {};
this._indexByCustom = {};
this._updateLength();
_.each(views, this.add, this);
};
// Container Methods
// -----------------
_.extend(Container.prototype, {
// Add a view to this container. Stores the view
// by `cid` and makes it searchable by the model
// cid (and model itself). Optionally specify
// a custom key to store an retrieve the view.
add: function(view, customIndex) {
var viewCid = view.cid;
// store the view
this._views[viewCid] = view;
// index it by model
if (view.model) {
this._indexByModel[view.model.cid] = viewCid;
}
// index by custom
if (customIndex) {
this._indexByCustom[customIndex] = viewCid;
}
this._updateLength();
return this;
},
// Find a view by the model that was attached to
// it. Uses the model's `cid` to find it.
findByModel: function(model) {
return this.findByModelCid(model.cid);
},
// Find a view by the `cid` of the model that was attached to
// it. Uses the model's `cid` to find the view `cid` and
// retrieve the view using it.
findByModelCid: function(modelCid) {
var viewCid = this._indexByModel[modelCid];
return this.findByCid(viewCid);
},
// Find a view by a custom indexer.
findByCustom: function(index) {
var viewCid = this._indexByCustom[index];
return this.findByCid(viewCid);
},
// Find by index. This is not guaranteed to be a
// stable index.
findByIndex: function(index) {
return _.values(this._views)[index];
},
// retrieve a view by its `cid` directly
findByCid: function(cid) {
return this._views[cid];
},
// Remove a view
remove: function(view) {
var viewCid = view.cid;
// delete model index
if (view.model) {
delete this._indexByModel[view.model.cid];
}
// delete custom index
_.any(this._indexByCustom, function(cid, key) {
if (cid === viewCid) {
delete this._indexByCustom[key];
return true;
}
}, this);
// remove the view from the container
delete this._views[viewCid];
// update the length
this._updateLength();
return this;
},
// Call a method on every view in the container,
// passing parameters to the call method one at a
// time, like `function.call`.
call: function(method) {
this.apply(method, _.tail(arguments));
},
// Apply a method on every view in the container,
// passing parameters to the call method one at a
// time, like `function.apply`.
apply: function(method, args) {
_.each(this._views, function(view) {
if (_.isFunction(view[method])) {
view[method].apply(view, args || []);
}
});
},
// Update the `.length` attribute on this container
_updateLength: function() {
this.length = _.size(this._views);
}
});
// Borrowing this code from Backbone.Collection:
// http://backbonejs.org/docs/backbone.html#section-106
//
// Mix in methods from Underscore, for iteration, and other
// collection related features.
var methods = [ "forEach", "each", "map", "find", "detect", "filter", "select", "reject", "every", "all", "some", "any", "include", "contains", "invoke", "toArray", "first", "initial", "rest", "last", "without", "isEmpty", "pluck", "reduce" ];
_.each(methods, function(method) {
Container.prototype[method] = function() {
var views = _.values(this._views);
var args = [ views ].concat(_.toArray(arguments));
return _[method].apply(_, args);
};
});
// return the public API
return Container;
}(Backbone, _);
Backbone.ChildViewContainer.VERSION = "0.1.10";
Backbone.ChildViewContainer.noConflict = function() {
Backbone.ChildViewContainer = previousChildViewContainer;
return this;
};
return Backbone.ChildViewContainer;
})(Backbone, _);// Backbone.Radio v1.0.2
(function(_, Backbone) {
"use strict";
var previousRadio = Backbone.Radio;
var Radio = Backbone.Radio = {};
Radio.VERSION = "1.0.2";
// This allows you to run multiple instances of Radio on the same
// webapp. After loading the new version, call `noConflict()` to
// get a reference to it. At the same time the old version will be
// returned to Backbone.Radio.
Radio.noConflict = function() {
Backbone.Radio = previousRadio;
return this;
};
// Whether or not we're in DEBUG mode or not. DEBUG mode helps you
// get around the issues of lack of warnings when events are mis-typed.
Radio.DEBUG = false;
// Format debug text.
Radio._debugText = function(warning, eventName, channelName) {
return warning + (channelName ? " on the " + channelName + " channel" : "") + ': "' + eventName + '"';
};
// This is the method that's called when an unregistered event was called.
// By default, it logs warning to the console. By overriding this you could
// make it throw an Error, for instance. This would make firing a nonexistent event
// have the same consequence as firing a nonexistent method on an Object.
Radio.debugLog = function(warning, eventName, channelName) {
if (Radio.DEBUG && console && console.warn) {
console.warn(Radio._debugText(warning, eventName, channelName));
}
};
var eventSplitter = /\s+/;
// An internal method used to handle Radio's method overloading for Requests.
// It's borrowed from Backbone.Events. It differs from Backbone's overload
// API (which is used in Backbone.Events) in that it doesn't support space-separated
// event names.
Radio._eventsApi = function(obj, action, name, rest) {
if (!name) {
return false;
}
var results = {};
// Handle event maps.
if (typeof name === "object") {
for (var key in name) {
var result = obj[action].apply(obj, [ key, name[key] ].concat(rest));
eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;
}
return results;
}
// Handle space separated event names.
if (eventSplitter.test(name)) {
var names = name.split(eventSplitter);
for (var i = 0, l = names.length; i < l; i++) {
results[names[i]] = obj[action].apply(obj, [ names[i] ].concat(rest));
}
return results;
}
return false;
};
// An optimized way to execute callbacks.
Radio._callHandler = function(callback, context, args) {
var a1 = args[0], a2 = args[1], a3 = args[2];
switch (args.length) {
case 0:
return callback.call(context);
case 1:
return callback.call(context, a1);
case 2:
return callback.call(context, a1, a2);
case 3:
return callback.call(context, a1, a2, a3);
default:
return callback.apply(context, args);
}
};
// A helper used by `off` methods to the handler from the store
function removeHandler(store, name, callback, context) {
var event = store[name];
if ((!callback || (callback === event.callback || callback === event.callback._callback)) && (!context || context === event.context)) {
delete store[name];
return true;
}
}
function removeHandlers(store, name, callback, context) {
store || (store = {});
var names = name ? [ name ] : _.keys(store);
var matched = false;
for (var i = 0, length = names.length; i < length; i++) {
name = names[i];
// If there's no event by this name, log it and continue
// with the loop
if (!store[name]) {
continue;
}
if (removeHandler(store, name, callback, context)) {
matched = true;
}
}
return matched;
}
/*
* tune-in
* -------
* Get console logs of a channel's activity
*
*/
var _logs = {};
// This is to produce an identical function in both tuneIn and tuneOut,
// so that Backbone.Events unregisters it.
function _partial(channelName) {
return _logs[channelName] || (_logs[channelName] = _.partial(Radio.log, channelName));
}
_.extend(Radio, {
// Log information about the channel and event
log: function log(channelName, eventName) {
var args = _.rest(arguments, 2);
console.log("[" + channelName + '] "' + eventName + '"', args);
},
// Logs all events on this channel to the console. It sets an
// internal value on the channel telling it we're listening,
// then sets a listener on the Backbone.Events
tuneIn: function tuneIn(channelName) {
var channel = Radio.channel(channelName);
channel._tunedIn = true;
channel.on("all", _partial(channelName));
return this;
},
// Stop logging all of the activities on this channel to the console
tuneOut: function tuneOut(channelName) {
var channel = Radio.channel(channelName);
channel._tunedIn = false;
channel.off("all", _partial(channelName));
delete _logs[channelName];
return this;
}
});
/*
* Backbone.Radio.Requests
* -----------------------
* A messaging system for requesting data.
*
*/
function makeCallback(callback) {
return _.isFunction(callback) ? callback : function() {
return callback;
};
}
Radio.Requests = {
// Make a request
request: function request(name) {
var args = _.rest(arguments);
var results = Radio._eventsApi(this, "request", name, args);
if (results) {
return results;
}
var channelName = this.channelName;
var requests = this._requests;
// Check if we should log the request, and if so, do it
if (channelName && this._tunedIn) {
Radio.log.apply(this, [ channelName, name ].concat(args));
}
// If the request isn't handled, log it in DEBUG mode and exit
if (requests && (requests[name] || requests["default"])) {
var handler = requests[name] || requests["default"];
args = requests[name] ? args : arguments;
return Radio._callHandler(handler.callback, handler.context, args);
} else {
Radio.debugLog("An unhandled request was fired", name, channelName);
}
},
// Set up a handler for a request
reply: function reply(name, callback, context) {
if (Radio._eventsApi(this, "reply", name, [ callback, context ])) {
return this;
}
this._requests || (this._requests = {});
if (this._requests[name]) {
Radio.debugLog("A request was overwritten", name, this.channelName);
}
this._requests[name] = {
callback: makeCallback(callback),
context: context || this
};
return this;
},
// Set up a handler that can only be requested once
replyOnce: function replyOnce(name, callback, context) {
if (Radio._eventsApi(this, "replyOnce", name, [ callback, context ])) {
return this;
}
var self = this;
var once = _.once(function() {
self.stopReplying(name);
return makeCallback(callback).apply(this, arguments);
});
return this.reply(name, once, context);
},
// Remove handler(s)
stopReplying: function stopReplying(name, callback, context) {
if (Radio._eventsApi(this, "stopReplying", name)) {
return this;
}
// Remove everything if there are no arguments passed
if (!name && !callback && !context) {
delete this._requests;
} else if (!removeHandlers(this._requests, name, callback, context)) {
Radio.debugLog("Attempted to remove the unregistered request", name, this.channelName);
}
return this;
}
};
/*
* Backbone.Radio.channel
* ----------------------
* Get a reference to a channel by name.
*
*/
Radio._channels = {};
Radio.channel = function(channelName) {
if (!channelName) {
throw new Error("You must provide a name for the channel.");
}
if (Radio._channels[channelName]) {
return Radio._channels[channelName];
} else {
return Radio._channels[channelName] = new Radio.Channel(channelName);
}
};
/*
* Backbone.Radio.Channel
* ----------------------
* A Channel is an object that extends from Backbone.Events,
* and Radio.Requests.
*
*/
Radio.Channel = function(channelName) {
this.channelName = channelName;
};
_.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {
// Remove all handlers from the messaging systems of this channel
reset: function reset() {
this.off();
this.stopListening();
this.stopReplying();
return this;
}
});
/*
* Top-level API
* -------------
* Supplies the 'top-level API' for working with Channels directly
* from Backbone.Radio.
*
*/
var channel, args, systems = [ Backbone.Events, Radio.Commands, Radio.Requests ];
_.each(systems, function(system) {
_.each(system, function(method, methodName) {
Radio[methodName] = function(channelName) {
args = _.rest(arguments);
channel = this.channel(channelName);
return channel[methodName].apply(channel, args);
};
});
});
Radio.reset = function(channelName) {
var channels = !channelName ? this._channels : [ this._channels[channelName] ];
_.invoke(channels, "reset");
};
var backbone_radio = Radio;
return backbone_radio;
})(_, Backbone);
// Attach bundled libraries to expected local vars
Radio = Backbone.Radio;
ChildViewContainer = Backbone.ChildViewContainer;
// Similar to `_.result`, this is a simple helper
// If a function is provided we call it with context
// otherwise just return the value. If the value is
// undefined return a default value
var _getValue = function _getValue(value, context, params) {
if (_.isFunction(value)) {
value = params ? value.apply(context, params) : value.call(context);
}
return value;
};
var version = "2.4.1";
// Borrow the Backbone `extend` method so we can use it as needed
var extend = Backbone.Model.extend;
var errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number'];
var MarionetteError = extend.call(Error, {
urlRoot: 'http://marionettejs.com/docs/v' + version + '/',
constructor: function MarionetteError(message, options) {
if (_.isObject(message)) {
options = message;
message = options.message;
} else if (!options) {
options = {};
}
var error = Error.call(this, message);
_.extend(this, _.pick(error, errorProps), _.pick(options, errorProps));
this.captureStackTrace();
if (options.url) {
this.url = this.urlRoot + options.url;
}
},
captureStackTrace: function captureStackTrace() {
if (Error.captureStackTrace) {
Error.captureStackTrace(this, MarionetteError);
}
},
toString: function toString() {
return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : '');
}
});
MarionetteError.extend = extend;
// Bind the event to handlers specified as a string of
// handler names on the target object
function bindFromStrings(target, entity, evt, methods) {
var methodNames = methods.split(/\s+/);
_.each(methodNames, function (methodName) {
var method = target[methodName];
if (!method) {
throw new MarionetteError('Method "' + methodName + '" was configured as an event handler, but does not exist.');
}
target.listenTo(entity, evt, method);
});
}
// Bind the event to a supplied callback function
function bindToFunction(target, entity, evt, method) {
target.listenTo(entity, evt, method);
}
// Bind the event to handlers specified as a string of
// handler names on the target object
function unbindFromStrings(target, entity, evt, methods) {
var methodNames = methods.split(/\s+/);
_.each(methodNames, function (methodName) {
var method = target[methodName];
target.stopListening(entity, evt, method);
});
}
// Bind the event to a supplied callback function
function unbindToFunction(target, entity, evt, method) {
target.stopListening(entity, evt, method);
}
// generic looping function
function iterateEvents(target, entity, bindings, functionCallback, stringCallback) {
if (!entity || !bindings) {
return;
}
// type-check bindings
if (!_.isObject(bindings)) {
throw new MarionetteError({
message: 'Bindings must be an object or function.',
url: 'marionette.functions.html#marionettebindentityevents'
});
}
// allow the bindings to be a function
bindings = _getValue(bindings, target);
// iterate the bindings and bind them
_.each(bindings, function (methods, evt) {
// allow for a function as the handler,
// or a list of event names as a string
if (_.isFunction(methods)) {
functionCallback(target, entity, evt, methods);
} else {
stringCallback(target, entity, evt, methods);
}
});
}
function bindEntityEvents(target, entity, bindings) {
iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);
}
function unbindEntityEvents(target, entity, bindings) {
iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings);
}
// Proxy `bindEntityEvents`
function proxyBindEntityEvents(entity, bindings) {
return bindEntityEvents(this, entity, bindings);
}
// Proxy `unbindEntityEvents`
function proxyUnbindEntityEvents(entity, bindings) {
return unbindEntityEvents(this, entity, bindings);
}
//Proxy Radio message handling to enable declarative interactions with radio channels
var radioAPI = {
'radioEvents': {
startMethod: 'on',
stopMethod: 'off'
},
'radioRequests': {
startMethod: 'reply',
stopMethod: 'stopReplying'
}
};
function proxyRadioHandlers() {
unproxyRadioHandlers.apply(this);
_.each(radioAPI, function (commands, radioType) {
var hash = _.result(this, radioType);
if (!hash) {
return;
}
_.each(hash, function (handler, radioMessage) {
handler = normalizeHandler.call(this, handler);
var messageComponents = radioMessage.split(' ');
var channel = messageComponents[0];
var messageName = messageComponents[1];
proxyRadioHandler.call(this, channel, radioType, messageName, handler);
}, this);
}, this);
}
function proxyRadioHandler(channel, radioType, messageName, handler) {
var method = radioAPI[radioType].startMethod;
this._radioChannels = this._radioChannels || [];
if (!_.contains(this._radioChannels, channel)) {
this._radioChannels.push(channel);
}
Radio[method](channel, messageName, handler, this);
}
function unproxyRadioHandlers() {
_.each(this._radioChannels, function (channel) {
_.each(radioAPI, function (commands) {
Radio[commands.stopMethod](channel, null, null, this);
}, this);
}, this);
}
function normalizeHandler(handler) {
if (!_.isFunction(handler)) {
handler = this[handler];
}
return handler;
}
// Determine if `el` is a child of the document
var isNodeAttached = function isNodeAttached(el) {
return Backbone.$.contains(document.documentElement, el);
};
// Merge `keys` from `options` onto `this`
var mergeOptions = function mergeOptions(options, keys) {
if (!options) {
return;
}
_.extend(this, _.pick(options, keys));
};
var getOption = function getOption(target, optionName) {
if (!target || !optionName) {
return;
}
if (target.options && target.options[optionName] !== undefined) {
return target.options[optionName];
} else {
return target[optionName];
}
};
// Proxy `Marionette.getOption`
var proxyGetOption = function proxyGetOption(optionName) {
return getOption(this, optionName);
};
// Marionette.normalizeMethods
// ----------------------
// Pass in a mapping of events => functions or function names
// and return a mapping of events => functions
var normalizeMethods = function normalizeMethods(hash) {
return _.reduce(hash, function (normalizedHash, method, name) {
if (!_.isFunction(method)) {
method = this[method];
}
if (method) {
normalizedHash[name] = method;
}
return normalizedHash;
}, {}, this);
};
var normalizeUIString = function normalizeUIString(uiString, ui) {
return uiString.replace(/@ui\.[a-zA-Z_$0-9]*/g, function (r) {
return ui[r.slice(4)];
});
};
// allows for the use of the @ui. syntax within
// a given key for triggers and events
// swaps the @ui with the associated selector.
// Returns a new, non-mutated, parsed events hash.
var normalizeUIKeys = function normalizeUIKeys(hash, ui) {
return _.reduce(hash, function (memo, val, key) {
var normalizedKey = normalizeUIString(key, ui);
memo[normalizedKey] = val;
return memo;
}, {});
};
// allows for the use of the @ui. syntax within
// a given value for regions
// swaps the @ui with the associated selector
var normalizeUIValues = function normalizeUIValues(hash, ui, properties) {
_.each(hash, function (val, key) {
if (_.isString(val)) {
hash[key] = normalizeUIString(val, ui);
} else if (_.isObject(val) && _.isArray(properties)) {
_.extend(val, normalizeUIValues(_.pick(val, properties), ui));
/* Value is an object, and we got an array of embedded property names to normalize. */
_.each(properties, function (property) {
var propertyVal = val[property];
if (_.isString(propertyVal)) {
val[property] = normalizeUIString(propertyVal, ui);
}
});
}
});
return hash;
};
var deprecate = function deprecate(message, test) {
if (_.isObject(message)) {
message = message.prev + ' is going to be removed in the future. ' + 'Please use ' + message.next + ' instead.' + (message.url ? ' See: ' + message.url : '');
}
if (!Marionette.DEV_MODE) {
return;
}
if ((test === undefined || !test) && !deprecate._cache[message]) {
deprecate._warn('Deprecation warning: ' + message);
deprecate._cache[message] = true;
}
};
deprecate._console = typeof console !== 'undefined' ? console : {};
deprecate._warn = function () {
var warn = deprecate._console.warn || deprecate._console.log || function () {};
return warn.apply(deprecate._console, arguments);
};
deprecate._cache = {};
var _triggerMethod = (function () {
// split the event name on the ":"
var splitter = /(^|:)(\w)/gi;
// take the event section ("section1:section2:section3")
// and turn it in to uppercase name
function getEventName(match, prefix, eventName) {
return eventName.toUpperCase();
}
return function (context, args) {
var event = args[0];
// get the method name from the event name
var methodName = 'on' + event.replace(splitter, getEventName);
var method = getOption(context, methodName);
var result;
// call the onMethodName if it exists
if (_.isFunction(method)) {
// pass all args, except the event name
result = method.apply(context, _.rest(args));
}
// trigger the event
context.trigger.apply(context, args);
return result;
};
})();
// Trigger an event and/or a corresponding method name. Examples:
//
// `this.triggerMethod("foo")` will trigger the "foo" event and
// call the "onFoo" method.
//
// `this.triggerMethod("foo:bar")` will trigger the "foo:bar" event and
// call the "onFooBar" method.
function triggerMethod(event) {
return _triggerMethod(this, arguments);
}
// triggerMethodOn invokes triggerMethod on a specific context
//
// e.g. `Marionette.triggerMethodOn(view, 'show')`
// will trigger a "show" event or invoke onShow the view.
function triggerMethodOn(context) {
var fnc = _.isFunction(context.triggerMethod) ? context.triggerMethod : triggerMethod;
return fnc.apply(context, _.rest(arguments));
}
// triggerMethodMany invokes triggerMethod on many targets from a source
// it's useful for standardizing a pattern where we propogate an event from a source
// to many targets.
//
// For each target we want to follow the pattern
// target.triggerMethod(event, target, source, ...other args)
// e.g childview.triggerMethod('attach', childView, region, ...args)
function triggerMethodMany(targets, source, eventName) {
var args = _.drop(arguments, 3);
_.each(targets, function (target) {
triggerMethodOn.apply(target, [target, eventName, target, source].concat(args));
});
}
var FEATURES = {};
function isEnabled(name) {
return !!FEATURES[name];
}
function setEnabled(name, state) {
return FEATURES[name] = state;
}
// A Base Class that other Classes should descend from.
// Object borrows many conventions and utilities from Backbone.
var MarionetteObject = function MarionetteObject(options) {
this.options = _.extend({}, _.result(this, 'options'), options);
proxyRadioHandlers.apply(this);
this.cid = _.uniqueId(this.cidPrefix);
this.initialize.apply(this, arguments);
};
MarionetteObject.extend = extend;
// Object Methods
// --------------
// Ensure it can trigger events with Backbone.Events
_.extend(MarionetteObject.prototype, Backbone.Events, {
cidPrefix: 'mno',
// for parity with Marionette.AbstractView lifecyle
_isDestroyed: false,
isDestroyed: function isDestroyed() {
return this._isDestroyed();
},
//this is a noop method intended to be overridden by classes that extend from this base
initialize: function initialize() {},
destroy: function destroy(options) {
if (this._isDestroyed) {
return this;
}
options = options || {};
this.triggerMethod('before:destroy', options);
// mark as destroyed before doing the actual destroy, to
// prevent infinite loops within "destroy" event handlers
this._isDestroyed = true;
this.triggerMethod('destroy', options);
unproxyRadioHandlers.apply(this);
this.stopListening();
return this;
},
// Import the `triggerMethod` to trigger events with corresponding
// methods if the method exists
triggerMethod: triggerMethod,
// A handy way to merge options onto the instance
mergeOptions: mergeOptions,
// Proxy `getOption` to enable getting options from this or this.options by name.
getOption: proxyGetOption,
// Proxy `bindEntityEvents` to enable binding view's events from another entity.
bindEntityEvents: proxyBindEntityEvents,
// Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.
unbindEntityEvents: proxyUnbindEntityEvents
});
// Monitor a view's state, and after it has been rendered and shown
// in the DOM, trigger a "dom:refresh" event every time it is
// re-rendered.
function MonitorDOMRefresh(view) {
if (view._isDomRefreshMonitored) {
return;
}
view._isDomRefreshMonitored = true;
// track when the view has been shown in the DOM,
// using a Marionette.Region (or by other means of triggering "show")
function handleShow() {
view._isShown = true;
triggerDOMRefresh();
}
// track when the view has been rendered
function handleRender() {
view._isRendered = true;
triggerDOMRefresh();
}
// Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
function triggerDOMRefresh() {
if (view._isShown && view._isRendered && isNodeAttached(view.el)) {
triggerMethodOn(view, 'dom:refresh', view);
}
}
view.on({
show: handleShow,
render: handleRender
});
}
// Manage the visual regions of your composite application. See
// http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
var Region = MarionetteObject.extend({
cidPrefix: 'mnr',
constructor: function constructor(options) {
// set options temporarily so that we can get `el`.
// options will be overriden by Object.constructor
this.options = options || {};
this.el = this.getOption('el');
// Handle when this.el is passed in as a $ wrapped element.
this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el;
if (!this.el) {
throw new MarionetteError({
name: 'NoElError',
message: 'An "el" must be specified for a region.'
});
}
this.$el = this.getEl(this.el);
MarionetteObject.call(this, options);
},
// Displays a backbone view instance inside of the region.
// Handles calling the `render` method for you. Reads content
// directly from the `el` attribute. Also calls an optional
// `onShow` and `onDestroy` method on your view, just after showing
// or just before destroying the view, respectively.
// The `preventDestroy` option can be used to prevent a view from
// the old view being destroyed on show.
// The `forceShow` option can be used to force a view to be
// re-rendered if it's already shown in the region.
show: function show(view, options) {
if (!this._ensureElement()) {
return;
}
this._ensureViewIsIntact(view);
MonitorDOMRefresh(view);
var showOptions = options || {};
var isDifferentView = view !== this.currentView;
var forceShow = !!showOptions.forceShow;
var replaceElement = !!showOptions.replaceElement;
// We are only changing the view if there is a current view to change to begin with
var changingView = this.currentView;
var isChangingView = !!changingView;
// Only destroy the current view if we don't want to `preventDestroy` and if
// the view given in the first argument is different than `currentView`
var _shouldDestroyView = this.shouldDestroyView(view, options);
// Only show the view given in the first argument if it is different than
// the current view or if we want to re-show the view. Note that if
// `_shouldDestroyView` is true, then `_shouldShowView` is also necessarily true.
var _shouldShowView = isDifferentView || forceShow;
// only replace the region's element with the view's element if explicitly set
var _shouldReplaceElement = replaceElement;
if (isChangingView) {
this.triggerMethod('before:swapOut', changingView, this, options);
}
if (this.currentView && isDifferentView) {
delete this.currentView._parent;
}
if (_shouldDestroyView) {
this.empty();
// A `destroy` event is attached to the clean up manually removed views.
// We need to detach this event when a new view is going to be shown as it
// is no longer relevant.
} else if (isChangingView && _shouldShowView) {
this.currentView.off('destroy', this.empty, this);
}
if (_shouldShowView) {
// We need to listen for if a view is destroyed
// in a way other than through the region.
// If this happens we need to remove the reference
// to the currentView since once a view has been destroyed
// we can not reuse it.
view.once('destroy', this.empty, this);
// make this region the view's parent,
// It's important that this parent binding happens before rendering
// so that any events the child may trigger during render can also be
// triggered on the child's ancestor views
view._parent = this;
this._renderView(view, options);
if (isChangingView) {
this.triggerMethod('before:swapIn', view, this, options);
}
this.triggerMethod('before:show', view, this, options);
triggerMethodOn(view, 'before:show', view, this, options);
// An array of views that we're about to display
var attachedRegion = isNodeAttached(this.el);
// The views that we're about to attach to the document
// It's important that we prevent _getNestedViews from being executed unnecessarily
// as it's a potentially-slow method
var displayedViews = [];
var attachOptions = _.extend({
triggerBeforeAttach: this.triggerBeforeAttach,
triggerAttach: this.triggerAttach
}, showOptions);
if (attachedRegion && attachOptions.triggerBeforeAttach) {
displayedViews = this._displayedViews(view);
this._triggerAttach(displayedViews, 'before:');
}
this.attachHtml(view, _shouldReplaceElement);
this.currentView = view;
if (attachedRegion && attachOptions.triggerAttach) {
displayedViews = this._displayedViews(view);
this._triggerAttach(displayedViews);
}
if (isChangingView) {
this.triggerMethod('swapOut', changingView, this, options);
this.triggerMethod('swapIn', view, this, options);
}
this.triggerMethod('show', view, this, options);
triggerMethodOn(view, 'show', view, this, options);
}
return this;
},
shouldDestroyView: function shouldDestroyView(view, options) {
var showOptions = options || {};
var isDifferentView = view !== this.currentView;
var preventDestroy = !!showOptions.preventDestroy;
return isDifferentView && !preventDestroy;
},
_renderView: function _renderView(view, options) {
if (!view.supportsRenderLifecycle) {
triggerMethodOn(view, 'before:render', view);
}
this.renderView(view, options);
if (!view.supportsRenderLifecycle) {
triggerMethodOn(view, 'render', view);
}
},
renderView: function renderView(view, options) {
view.render();
},
triggerBeforeAttach: true,
triggerAttach: true,
_triggerAttach: function _triggerAttach(views, prefix) {
var eventName = (prefix || '') + 'attach';
triggerMethodMany(views, this, eventName);
},
_displayedViews: function _displayedViews(view) {
return _.union([view], _.result(view, '_getNestedViews') || []);
},
_ensureElement: function _ensureElement() {
if (!_.isObject(this.el)) {
this.$el = this.getEl(this.el);
this.el = this.$el[0];
}
if (!this.$el || this.$el.length === 0) {
if (this.getOption('allowMissingEl')) {
return false;
} else {
throw new MarionetteError('An "el" ' + this.$el.selector + ' must exist in DOM');
}
}
return true;
},
_ensureViewIsIntact: function _ensureViewIsIntact(view) {
if (!view) {
throw new MarionetteError({
name: 'ViewNotValid',
message: 'The view passed is undefined and therefore invalid. You must pass a view instance to show.'
});
}
if (view._isDestroyed) {
throw new MarionetteError({
name: 'ViewDestroyedError',
message: 'View (cid: "' + view.cid + '") has already been destroyed and cannot be used.'
});
}
},
// Override this method to change how the region finds the DOM
// element that it manages. Return a jQuery selector object scoped
// to a provided parent el or the document if none exists.
getEl: function getEl(el) {
return Backbone.$(el, _getValue(this.options.parentEl, this));
},
// Replace the region's DOM element with the view's DOM element.
_replaceEl: function _replaceEl(view) {
// empty el so we don't save any non-destroyed views
this.$el.contents().detach();
// always restore the el to ensure the regions el is
// present before replacing
this._restoreEl();
var parent = this.el.parentNode;
parent.replaceChild(view.el, this.el);
this.replaced = true;
},
// Restore the region's element in the DOM.
_restoreEl: function _restoreEl() {
if (!this.currentView) {
return;
}
var view = this.currentView;
var parent = view.el.parentNode;
if (!parent) {
return;
}
parent.replaceChild(this.el, view.el);
this.replaced = false;
},
// Override this method to change how the new view is
// appended to the `$el` that the region is managing
attachHtml: function attachHtml(view, shouldReplace) {
if (shouldReplace) {
// replace the region's node with the view's node
this._replaceEl(view);
} else {
// empty the node and append new view
this.$el.contents().detach();
this.el.appendChild(view.el);
}
},
// Destroy the current view, if there is one. If there is no
// current view, it does nothing and returns immediately.
empty: function empty(options) {
var view = this.currentView;
var emptyOptions = options || {};
var preventDestroy = !!emptyOptions.preventDestroy;
// If there is no view in the region
// we should not remove anything
if (!view) {
return this;
}
view.off('destroy', this.empty, this);
this.triggerMethod('before:empty', view);
if (this.replaced) {
this._restoreEl();
}
if (!preventDestroy) {
this._destroyView();
}
this.triggerMethod('empty', view);
// Remove region pointer to the currentView
delete this.currentView;
if (preventDestroy) {
this.$el.contents().detach();
}
return this;
},
// call 'destroy' or 'remove', depending on which is found
// on the view (if showing a raw Backbone view or a Marionette View)
_destroyView: function _destroyView() {
var view = this.currentView;
if (view._isDestroyed) {
return;
}
if (!view.supportsDestroyLifecycle) {
triggerMethodOn(view, 'before:destroy', view);
}
if (view.destroy) {
view.destroy();
} else {
view.remove();
// appending _isDestroyed to raw Backbone View allows regions
// to throw a ViewDestroyedError for this view
view._isDestroyed = true;
}
if (!view.supportsDestroyLifecycle) {
triggerMethodOn(view, 'destroy', view);
}
},
// Attach an existing view to the region. This
// will not call `render` or `onShow` for the new view,
// and will not replace the current HTML for the `el`
// of the region.
attachView: function attachView(view) {
if (this.currentView) {
delete this.currentView._parent;
}
view._parent = this;
this.currentView = view;
return this;
},
// Checks whether a view is currently present within
// the region. Returns `true` if there is and `false` if
// no view is present.
hasView: function hasView() {
return !!this.currentView;
},
// Reset the region by destroying any existing view and
// clearing out the cached `$el`. The next time a view
// is shown via this region, the region will re-query the
// DOM for the region's `el`.
reset: function reset() {
this.empty();
if (this.$el) {
this.el = this.$el.selector;
}
delete this.$el;
return this;
}
});
// A container for a Marionette application.
var Application = MarionetteObject.extend({
cidPrefix: 'mna',
constructor: function constructor(options) {
options = options || {};
this._initRegion(options);
MarionetteObject.prototype.constructor.apply(this, arguments);
},
regionClass: Region,
_initRegion: function _initRegion(options) {
var region = options.region || this.region;
var RegionClass = options.regionClass || this.regionClass;
// if the region is a string expect an el or selector
// and instantiate a region
if (_.isString(region)) {
this._region = new RegionClass({
el: region
});
return;
}
this._region = region;
},
getRegion: function getRegion() {
return this._region;
},
showView: function showView(view, options) {
var region = this.getRegion();
return region.show.apply(region, arguments);
},
getView: function getView() {
return this.getRegion().currentView;
},
// kick off all of the application's processes.
start: function start(options) {
this.triggerMethod('before:start', options);
this.triggerMethod('start', options);
}
});
var AppRouter = Backbone.Router.extend({
constructor: function constructor(options) {
this.options = options || {};
Backbone.Router.apply(this, arguments);
var appRoutes = this.getOption('appRoutes');
var controller = this._getController();
this.processAppRoutes(controller, appRoutes);
this.on('route', this._processOnRoute, this);
},
// Similar to route method on a Backbone Router but
// method is called on the controller
appRoute: function appRoute(route, methodName) {
var controller = this._getController();
this._addAppRoute(controller, route, methodName);
},
// process the route event and trigger the onRoute
// method call, if it exists
_processOnRoute: function _processOnRoute(routeName, routeArgs) {
// make sure an onRoute before trying to call it
if (_.isFunction(this.onRoute)) {
// find the path that matches the current route
var routePath = _.invert(this.getOption('appRoutes'))[routeName];
this.onRoute(routeName, routePath, routeArgs);
}
},
// Internal method to process the `appRoutes` for the
// router, and turn them in to routes that trigger the
// specified method on the specified `controller`.
processAppRoutes: function processAppRoutes(controller, appRoutes) {
if (!appRoutes) {
return;
}
var routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes
_.each(routeNames, function (route) {
this._addAppRoute(controller, route, appRoutes[route]);
}, this);
},
_getController: function _getController() {
return this.getOption('controller');
},
_addAppRoute: function _addAppRoute(controller, route, methodName) {
var method = controller[methodName];
if (!method) {
throw new MarionetteError('Method "' + methodName + '" was not found on the controller');
}
this.route(route, methodName, _.bind(method, controller));
},
mergeOptions: mergeOptions,
// Proxy `getOption` to enable getting options from this or this.options by name.
getOption: proxyGetOption,
triggerMethod: triggerMethod,
bindEntityEvents: proxyBindEntityEvents,
unbindEntityEvents: proxyUnbindEntityEvents
});
// Manage templates stored in `<script>` blocks,
// caching them for faster access.
var TemplateCache = function TemplateCache(templateId) {
this.templateId = templateId;
};
// TemplateCache object-level methods. Manage the template
// caches from these method calls instead of creating
// your own TemplateCache instances
_.extend(TemplateCache, {
templateCaches: {},
// Get the specified template by id. Either
// retrieves the cached version, or loads it
// from the DOM.
get: function get(templateId, options) {
var cachedTemplate = this.templateCaches[templateId];
if (!cachedTemplate) {
cachedTemplate = new TemplateCache(templateId);
this.templateCaches[templateId] = cachedTemplate;
}
return cachedTemplate.load(options);
},
// Clear templates from the cache. If no arguments
// are specified, clears all templates:
// `clear()`
//
// If arguments are specified, clears each of the
// specified templates from the cache:
// `clear("#t1", "#t2", "...")`
clear: function clear() {
var i;
var args = _.toArray(arguments);
var length = args.length;
if (length > 0) {
for (i = 0; i < length; i++) {
delete this.templateCaches[args[i]];
}
} else {
this.templateCaches = {};
}
}
});
// TemplateCache instance methods, allowing each
// template cache object to manage its own state
// and know whether or not it has been loaded
_.extend(TemplateCache.prototype, {
// Internal method to load the template
load: function load(options) {
// Guard clause to prevent loading this template more than once
if (this.compiledTemplate) {
return this.compiledTemplate;
}
// Load the template and compile it
var template = this.loadTemplate(this.templateId, options);
this.compiledTemplate = this.compileTemplate(template, options);
return this.compiledTemplate;
},
// Load a template from the DOM, by default. Override
// this method to provide your own template retrieval
// For asynchronous loading with AMD/RequireJS, consider
// using a template-loader plugin as described here:
// https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs
loadTemplate: function loadTemplate(templateId, options) {
var $template = Backbone.$(templateId);
if (!$template.length) {
throw new MarionetteError({
name: 'NoTemplateError',
message: 'Could not find template: "' + templateId + '"'
});
}
return $template.html();
},
// Pre-compile the template before caching it. Override
// this method if you do not need to pre-compile a template
// (JST / RequireJS for example) or if you want to change
// the template engine used (Handebars, etc).
compileTemplate: function compileTemplate(rawTemplate, options) {
return _.template(rawTemplate, options);
}
});
// Render a template with data by passing in the template
// selector and the data to render.
var Renderer = {
// Render a template with data. The `template` parameter is
// passed to the `TemplateCache` object to retrieve the
// template function. Override this method to provide your own
// custom rendering and template handling for all of Marionette.
render: function render(template, data) {
if (!template) {
throw new MarionetteError({
name: 'TemplateNotFoundError',
message: 'Cannot render the template since its false, null or undefined.'
});
}
var templateFunc = _.isFunction(template) ? template : TemplateCache.get(template);
return templateFunc(data);
}
};
// Borrow event splitter from Backbone
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
function Behaviors(view, behaviors) {
if (!_.isObject(view.behaviors)) {
return {};
}
// Behaviors defined on a view can be a flat object literal
// or it can be a function that returns an object.
behaviors = Behaviors.parseBehaviors(view, behaviors);
// Wraps several of the view's methods
// calling the methods first on each behavior
// and then eventually calling the method on the view.
Behaviors.wrap(view, behaviors, _.keys(methods));
return behaviors;
}
var methods = {
behaviorTriggers: function behaviorTriggers(unusedBehaviorTriggers, behaviors) {
var triggerBuilder = new BehaviorTriggersBuilder(this, behaviors);
return triggerBuilder.buildBehaviorTriggers();
},
behaviorEvents: function behaviorEvents(unusedBehaviorEvents, behaviors) {
var _behaviorsEvents = {};
_.each(behaviors, function (b, i) {
var _events = {};
var behaviorEvents = _.clone(_.result(b, 'events')) || {};
// Normalize behavior events hash to allow
// a user to use the @ui. syntax.
behaviorEvents = normalizeUIKeys(behaviorEvents, getBehaviorsUI(b));
var j = 0;
_.each(behaviorEvents, function (behaviorHandler, key) {
var match = key.match(delegateEventSplitter);
// Set event name to be namespaced using the view cid,
// the behavior index, and the behavior event index
// to generate a non colliding event namespace
// http://api.jquery.com/event.namespace/
var eventName = match[1] + '.' + [this.cid, i, j++, ' '].join('');
var selector = match[2];
var eventKey = eventName + selector;
var handler = _.isFunction(behaviorHandler) ? behaviorHandler : b[behaviorHandler];
_events[eventKey] = _.bind(handler, b);
}, this);
_behaviorsEvents = _.extend(_behaviorsEvents, _events);
}, this);
return _behaviorsEvents;
}
};
_.extend(Behaviors, {
// Placeholder method to be extended by the user.
// The method should define the object that stores the behaviors.
// i.e.
//
// ```js
// Marionette.Behaviors.behaviorsLookup: function() {
// return App.Behaviors
// }
// ```
behaviorsLookup: function behaviorsLookup() {
throw new MarionetteError({
message: 'You must define where your behaviors are stored.',
url: 'marionette.behaviors.md#behaviorslookup'
});
},
// Takes care of getting the behavior class
// given options and a key.
// If a user passes in options.behaviorClass
// default to using that.
// If a user passes in a Behavior Class directly, use that
// Otherwise delegate the lookup to the users `behaviorsLookup` implementation.
getBehaviorClass: function getBehaviorClass(options, key) {
if (options.behaviorClass) {
return options.behaviorClass;
//treat functions as a Behavior constructor
} else if (_.isFunction(options)) {
return options;
}
// behaviorsLookup can be either a flat object or a method
return _getValue(Behaviors.behaviorsLookup, this, [options, key])[key];
},
// Iterate over the behaviors object, for each behavior
// instantiate it and get its grouped behaviors.
// This accepts a list of behaviors in either an object or array form
parseBehaviors: function parseBehaviors(view, behaviors) {
return _.chain(behaviors).map(function (options, key) {
var BehaviorClass = Behaviors.getBehaviorClass(options, key);
//if we're passed a class directly instead of an object
var _options = options === BehaviorClass ? {} : options;
var behavior = new BehaviorClass(_options, view);
var nestedBehaviors = Behaviors.parseBehaviors(view, _.result(behavior, 'behaviors'));
return [behavior].concat(nestedBehaviors);
}).flatten().value();
},
// Wrap view internal methods so that they delegate to behaviors. For example,
// `onDestroy` should trigger destroy on all of the behaviors and then destroy itself.
// i.e.
//
// `view.delegateEvents = _.partial(methods.delegateEvents, view.delegateEvents, behaviors);`
wrap: function wrap(view, behaviors, methodNames) {
_.each(methodNames, function (methodName) {
view[methodName] = _.partial(methods[methodName], view[methodName], behaviors);
});
}
});
// Class to build handlers for `triggers` on behaviors
// for views
function BehaviorTriggersBuilder(view, behaviors) {
this._view = view;
this._behaviors = behaviors;
this._triggers = {};
}
_.extend(BehaviorTriggersBuilder.prototype, {
// Main method to build the triggers hash with event keys and handlers
buildBehaviorTriggers: function buildBehaviorTriggers() {
_.each(this._behaviors, this._buildTriggerHandlersForBehavior, this);
return this._triggers;
},
// Internal method to build all trigger handlers for a given behavior
_buildTriggerHandlersForBehavior: function _buildTriggerHandlersForBehavior(behavior, i) {
var triggersHash = _.clone(_.result(behavior, 'triggers')) || {};
triggersHash = normalizeUIKeys(triggersHash, getBehaviorsUI(behavior));
_.each(triggersHash, _.bind(this._setHandlerForBehavior, this, behavior, i));
},
// Internal method to create and assign the trigger handler for a given
// behavior
_setHandlerForBehavior: function _setHandlerForBehavior(behavior, i, eventName, trigger) {
// Unique identifier for the `this._triggers` hash
var triggerKey = trigger.replace(/^\S+/, function (triggerName) {
return triggerName + '.' + 'behaviortriggers' + i;
});
this._triggers[triggerKey] = this._view._buildViewTrigger(eventName);
}
});
function getBehaviorsUI(behavior) {
return behavior._uiBindings || behavior.ui;
}
var ViewMixin = {
supportsRenderLifecycle: true,
supportsDestroyLifecycle: true,
_isDestroyed: false,
isDestroyed: function isDestroyed() {
return !!this._isDestroyed;
},
_isRendered: false,
isRendered: function isRendered() {
return !!this._isRendered;
},
_initBehaviors: function _initBehaviors() {
var behaviors = _getValue(this.getOption('behaviors'), this);
this._behaviors = Behaviors(this, behaviors);
},
// Get the template for this view
// instance. You can set a `template` attribute in the view
// definition or pass a `template: "whatever"` parameter in
// to the constructor options.
getTemplate: function getTemplate() {
return this.getOption('template');
},
// Internal method to render the template with the serialized data
// and template context via the `Marionette.Renderer` object.
_renderTemplate: function _renderTemplate() {
var template = this.getTemplate();
// Allow template-less views
if (template === false) {
return;
}
// Add in entity data and template context
var data = this.mixinTemplateContext(this.serializeData());
// Render and add to el
var html = Renderer.render(template, data, this);
this.attachElContent(html);
},
// Prepares the special `model` property of a view
// for being displayed in the template. By default
// we simply clone the attributes. Override this if
// you need a custom transformation for your view's model
serializeModel: function serializeModel() {
if (!this.model) {
return {};
}
return _.clone(this.model.attributes);
},
// Mix in template context methods. Looks for a
// `templateContext` attribute, which can either be an
// object literal, or a function that returns an object
// literal. All methods and attributes from this object
// are copies to the object passed in.
mixinTemplateContext: function mixinTemplateContext(target) {
target = target || {};
var templateContext = this.getOption('templateContext');
templateContext = _getValue(templateContext, this);
return _.extend(target, templateContext);
},
// normalize the keys of passed hash with the views `ui` selectors.
// `{"@ui.foo": "bar"}`
normalizeUIKeys: function normalizeUIKeys$$(hash) {
var uiBindings = _.result(this, '_uiBindings');
return normalizeUIKeys(hash, uiBindings || _.result(this, 'ui'));
},
// normalize the values of passed hash with the views `ui` selectors.
// `{foo: "@ui.bar"}`
normalizeUIValues: function normalizeUIValues$$(hash, properties) {
var ui = _.result(this, 'ui');
var uiBindings = _.result(this, '_uiBindings');
return normalizeUIValues(hash, uiBindings || ui, properties);
},
// Configure `triggers` to forward DOM events to view
// events. `triggers: {"click .foo": "do:foo"}`
configureTriggers: function configureTriggers() {
if (!this.triggers) {
return;
}
// Allow `triggers` to be configured as a function
var triggers = this.normalizeUIKeys(_.result(this, 'triggers'));
// Configure the triggers, prevent default
// action and stop propagation of DOM events
return _.reduce(triggers, function (events, value, key) {
events[key] = this._buildViewTrigger(value);
return events;
}, {}, this);
},
// Overriding Backbone.View's `delegateEvents` to handle
// `events` and `triggers`
delegateEvents: function delegateEvents(eventsArg) {
// proxy behavior $el to the view's $el.
_.invoke(this._behaviors, 'proxyViewProperties', this);
var events = _getValue(eventsArg || this.events, this);
// normalize ui keys
events = this.normalizeUIKeys(events);
if (typeof eventsArg === 'undefined') {
this.events = events;
}
var combinedEvents = {};
// look up if this view has behavior events
var behaviorEvents = _.result(this, 'behaviorEvents') || {};
var triggers = this.configureTriggers();
var behaviorTriggers = _.result(this, 'behaviorTriggers') || {};
// behavior events will be overriden by view events and or triggers
_.extend(combinedEvents, behaviorEvents, events, triggers, behaviorTriggers);
Backbone.View.prototype.delegateEvents.call(this, combinedEvents);
return this;
},
// Handle `modelEvents`, and `collectionEvents` configuration
delegateEntityEvents: function delegateEntityEvents() {
this.undelegateEntityEvents();
this.bindEntityEvents(this.model, this.getOption('modelEvents'));
this.bindEntityEvents(this.collection, this.getOption('collectionEvents'));
_.each(this._behaviors, function (behavior) {
behavior.bindEntityEvents(this.model, behavior.getOption('modelEvents'));
behavior.bindEntityEvents(this.collection, behavior.getOption('collectionEvents'));
}, this);
return this;
},
// Handle unbinding `modelEvents`, and `collectionEvents` configuration
undelegateEntityEvents: function undelegateEntityEvents() {
this.unbindEntityEvents(this.model, this.getOption('modelEvents'));
this.unbindEntityEvents(this.collection, this.getOption('collectionEvents'));
_.each(this._behaviors, function (behavior) {
behavior.unbindEntityEvents(this.model, behavior.getOption('modelEvents'));
behavior.unbindEntityEvents(this.collection, behavior.getOption('collectionEvents'));
}, this);
return this;
},
// Internal helper method to verify whether the view hasn't been destroyed
_ensureViewIsIntact: function _ensureViewIsIntact() {
if (this._isDestroyed) {
throw new MarionetteError({
name: 'ViewDestroyedError',
message: 'View (cid: "' + this.cid + '") has already been destroyed and cannot be used.'
});
}
},
// Handle destroying the view and its children.
destroy: function destroy() {
if (this._isDestroyed) {
return this;
}
var args = _.toArray(arguments);
this.triggerMethod.apply(this, ['before:destroy'].concat(args));
// update lifecycle flags
this._isDestroyed = true;
this._isRendered = false;
// unbind UI elements
this.unbindUIElements();
// remove the view from the DOM
// https://github.com/jashkenas/backbone/blob/1.2.3/backbone.js#L1235
this._removeElement();
// remove children after the remove to prevent extra paints
this._removeChildren();
// Call destroy on each behavior after
// destroying the view.
// This unbinds event listeners
// that behaviors have registered for.
_.invoke(this._behaviors, 'destroy', args);
this.triggerMethod.apply(this, ['destroy'].concat(args));
this.stopListening();
return this;
},
bindUIElements: function bindUIElements() {
this._bindUIElements();
_.invoke(this._behaviors, this._bindUIElements);
},
// This method binds the elements specified in the "ui" hash inside the view's code with
// the associated jQuery selectors.
_bindUIElements: function _bindUIElements() {
if (!this.ui) {
return;
}
// store the ui hash in _uiBindings so they can be reset later
// and so re-rendering the view will be able to find the bindings
if (!this._uiBindings) {
this._uiBindings = this.ui;
}
// get the bindings result, as a function or otherwise
var bindings = _.result(this, '_uiBindings');
// empty the ui so we don't have anything to start with
this._ui = {};
// bind each of the selectors
_.each(bindings, function (selector, key) {
this._ui[key] = this.$(selector);
}, this);
this.ui = this._ui;
},
// This method unbinds the elements specified in the "ui" hash
unbindUIElements: function unbindUIElements() {
this._unbindUIElements();
_.invoke(this._behaviors, this._unbindUIElements);
},
_unbindUIElements: function _unbindUIElements() {
if (!this.ui || !this._uiBindings) {
return;
}
// delete all of the existing ui bindings
_.each(this.ui, function ($el, name) {
delete this.ui[name];
}, this);
// reset the ui element to the original bindings configuration
this.ui = this._uiBindings;
delete this._uiBindings;
delete this._ui;
},
getUI: function getUI(name) {
this._ensureViewIsIntact();
return this._ui[name];
},
// Internal method to create an event handler for a given `triggerDef` like
// 'click:foo'
_buildViewTrigger: function _buildViewTrigger(triggerDef) {
var options = _.defaults({}, triggerDef, {
preventDefault: true,
stopPropagation: true
});
var eventName = _.isObject(triggerDef) ? options.event : triggerDef;
return function (e) {
if (e) {
if (e.preventDefault && options.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation && options.stopPropagation) {
e.stopPropagation();
}
}
var args = {
view: this,
model: this.model,
collection: this.collection
};
this.triggerMethod(eventName, args);
};
},
// used as the prefix for child view events
// that are forwarded through the layoutview
childViewEventPrefix: 'childview',
// import the `triggerMethod` to trigger events with corresponding
// methods if the method exists
triggerMethod: function triggerMethod() {
var ret = _triggerMethod(this, arguments);
this._triggerEventOnBehaviors(arguments);
this._triggerEventOnParentLayout(arguments[0], _.rest(arguments));
return ret;
},
_triggerEventOnBehaviors: function _triggerEventOnBehaviors(args) {
var triggerMethod = _triggerMethod;
var behaviors = this._behaviors;
// Use good ol' for as this is a very hot function
for (var i = 0, length = behaviors && behaviors.length; i < length; i++) {
triggerMethod(behaviors[i], args);
}
},
_triggerEventOnParentLayout: function _triggerEventOnParentLayout(eventName, args) {
var layoutView = this._parentItemView();
if (!layoutView) {
return;
}
// invoke triggerMethod on parent view
var eventPrefix = getOption(layoutView, 'childViewEventPrefix');
var prefixedEventName = eventPrefix + ':' + eventName;
var callArgs = [this].concat(args);
_triggerMethod(layoutView, [prefixedEventName].concat(callArgs));
// call the parent view's childEvents handler
var childEvents = getOption(layoutView, 'childEvents');
// since childEvents can be an object or a function use Marionette._getValue
// to handle the abstaction for us.
childEvents = _getValue(childEvents, layoutView);
var normalizedChildEvents = layoutView.normalizeMethods(childEvents);
if (!!normalizedChildEvents && _.isFunction(normalizedChildEvents[eventName])) {
normalizedChildEvents[eventName].apply(layoutView, callArgs);
}
},
// Returns an array of every nested view within this view
_getNestedViews: function _getNestedViews() {
var children = this._getImmediateChildren();
if (!children.length) {
return children;
}
return _.reduce(children, function (memo, view) {
if (!view._getNestedViews) {
return memo;
}
return memo.concat(view._getNestedViews());
}, children);
},
// Walk the _parent tree until we find a view (if one exists).
// Returns the parent view hierarchically closest to this view.
_parentItemView: function _parentItemView() {
var parent = this._parent;
while (parent) {
if (parent instanceof View) {
return parent;
}
parent = parent._parent;
}
},
// Imports the "normalizeMethods" to transform hashes of
// events=>function references/names to a hash of events=>function references
normalizeMethods: normalizeMethods,
// A handy way to merge passed-in options onto the instance
mergeOptions: mergeOptions,
// Proxy `getOption` to enable getting options from this or this.options by name.
getOption: proxyGetOption,
// Proxy `bindEntityEvents` to enable binding view's events from another entity.
bindEntityEvents: proxyBindEntityEvents,
// Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.
unbindEntityEvents: proxyUnbindEntityEvents
};
var RegionsMixin = {
regionClass: Region,
// Internal method to initialize the regions that have been defined in a
// `regions` attribute on this View.
_initRegions: function _initRegions(options) {
// init regions hash
this.regions = this.regions || {};
this._regions = {};
this.addRegions(this.getOption('regions'));
},
// Internal method to re-initialize all of the regions by updating
// the `el` that they point to
_reInitRegions: function _reInitRegions() {
_.invoke(this._regions, 'reset');
},
// Add a single region, by name, to the View
addRegion: function addRegion(name, definition) {
var regions = {};
regions[name] = definition;
return this.addRegions(regions)[name];
},
// Add multiple regions as a {name: definition, name2: def2} object literal or
// a function that evaluates to such literal
addRegions: function addRegions(regions) {
// Enable regions to be a function
regions = _getValue(regions, this, arguments);
// If there's nothing to add, stop here.
if (_.isEmpty(regions)) {
return;
}
// Normalize region selectors hash to allow
// a user to use the @ui. syntax.
regions = this.normalizeUIValues(regions, ['selector', 'el']);
// Add the regions definitions to the regions property
this.regions = _.extend({}, this.regions, regions);
return this._addRegions(regions);
},
// internal method to build and add regions
_addRegions: function _addRegions(regionDefinitions) {
regionDefinitions = _getValue(regionDefinitions, this, arguments);
return _.reduce(regionDefinitions, function (regions, definition, name) {
regions[name] = this._buildRegion(definition);
this._addRegion(regions[name], name);
return regions;
}, {}, this);
},
// return the region instance from the definition
_buildRegion: function _buildRegion(definition) {
if (definition instanceof Region) {
return definition;
}
return this._buildRegionFromDefinition(definition);
},
_buildRegionFromDefinition: function _buildRegionFromDefinition(definition) {
if (_.isString(definition)) {
return this._buildRegionFromObject({ el: definition });
}
if (_.isFunction(definition)) {
return this._buildRegionFromRegionClass(definition);
}
if (_.isObject(definition)) {
return this._buildRegionFromObject(definition);
}
throw new MarionetteError({
message: 'Improper region configuration type.',
url: 'marionette.region.html#region-configuration-types'
});
},
_buildRegionFromObject: function _buildRegionFromObject(definition) {
var RegionClass = definition.regionClass || this.getOption('regionClass');
var options = _.omit(definition, 'regionClass');
_.defaults(options, {
el: definition.selector,
parentEl: _.partial(_.result, this, 'el')
});
return new RegionClass(options);
},
// Build the region directly from a given `RegionClass`
_buildRegionFromRegionClass: function _buildRegionFromRegionClass(RegionClass) {
return new RegionClass({
parentEl: _.partial(_.result, this, 'el')
});
},
_addRegion: function _addRegion(region, name) {
this.triggerMethod('before:add:region', name, region);
region._parent = this;
this._regions[name] = region;
this.triggerMethod('add:region', name, region);
},
// Remove a single region from the View, by name
removeRegion: function removeRegion(name) {
var region = this._regions[name];
this._removeRegion(region, name);
return region;
},
// Remove all regions from the View
removeRegions: function removeRegions() {
var regions = this.getRegions();
_.each(this._regions, this._removeRegion, this);
return regions;
},
_removeRegion: function _removeRegion(region, name) {
this.triggerMethod('before:remove:region', name, region);
region.empty();
region.stopListening();
delete this.regions[name];
delete this._regions[name];
this.triggerMethod('remove:region', name, region);
},
// Empty all regions in the region manager, but
// leave them attached
emptyRegions: function emptyRegions() {
var regions = this.getRegions();
_.invoke(regions, 'empty');
return regions;
},
// Checks to see if view contains region
// Accepts the region name
// hasRegion('main')
hasRegion: function hasRegion(name) {
return !!this.getRegion(name);
},
// Provides access to regions
// Accepts the region name
// getRegion('main')
getRegion: function getRegion(name) {
return this._regions[name];
},
// Get all regions
getRegions: function getRegions() {
return _.clone(this._regions);
},
showChildView: function showChildView(name, view, options) {
var region = this.getRegion(name);
return region.show.apply(region, _.rest(arguments));
},
getChildView: function getChildView(name) {
return this.getRegion(name).currentView;
},
_getImmediateChildren: function _getImmediateChildren() {
return _.chain(this.getRegions()).pluck('currentView').compact().value();
}
};
// The standard view. Includes view events, automatic rendering
// of Underscore templates, nested views, and more.
var View = Backbone.View.extend({
constructor: function constructor(options) {
this.render = _.bind(this.render, this);
this.options = _.extend({}, _.result(this, 'options'), options);
MonitorDOMRefresh(this);
this._initBehaviors();
this._initRegions();
Backbone.View.prototype.constructor.call(this, this.options);
this.delegateEntityEvents();
},
// Serialize the view's model *or* collection, if
// it exists, for the template
serializeData: function serializeData() {
if (!this.model && !this.collection) {
return {};
}
// If we have a model, we serialize that
if (this.model) {
return this.serializeModel();
}
// Otherwise, we serialize the collection,
// making it available under the `items` property
return {
items: this.serializeCollection()
};
},
// Serialize a collection by cloning each of
// its model's attributes
serializeCollection: function serializeCollection() {
if (!this.collection) {
return {};
}
return this.collection.map(function (model) {
return _.clone(model.attributes);
});
},
// Render the view, defaulting to underscore.js templates.
// You can override this in your view definition to provide
// a very specific rendering for your view. In general, though,
// you should override the `Marionette.Renderer` object to
// change how Marionette renders views.
// Subsequent renders after the first will re-render all nested
// views.
render: function render() {
this._ensureViewIsIntact();
this.triggerMethod('before:render', this);
// If this is not the first render call, then we need to
// re-initialize the `el` for each region
if (this._isRendered) {
this._reInitRegions();
}
this._renderTemplate();
this._isRendered = true;
this.bindUIElements();
this.triggerMethod('render', this);
return this;
},
// Attaches the content of a given view.
// This method can be overridden to optimize rendering,
// or to render in a non standard way.
//
// For example, using `innerHTML` instead of `$el.html`
//
// ```js
// attachElContent: function(html) {
// this.el.innerHTML = html;
// return this;
// }
// ```
attachElContent: function attachElContent(html) {
this.$el.html(html);
return this;
},
// called by ViewMixin destroy
_removeChildren: function _removeChildren() {
this.removeRegions();
}
});
_.extend(View.prototype, ViewMixin);
_.extend(View.prototype, RegionsMixin);
// A view that iterates over a Backbone.Collection
// and renders an individual child view for each model.
var CollectionView = Backbone.View.extend({
// flag for maintaining the sorted order of the collection
sort: true,
// constructor
// option to pass `{sort: false}` to prevent the `CollectionView` from
// maintaining the sorted order of the collection.
// This will fallback onto appending childView's to the end.
//
// option to pass `{comparator: compFunction()}` to allow the `CollectionView`
// to use a custom sort order for the collection.
constructor: function constructor(options) {
this.render = _.bind(this.render, this);
this.options = _.extend({}, _.result(this, 'options'), options);
MonitorDOMRefresh(this);
this.on({
'before:show': this._onBeforeShowCalled,
'show': this._onShowCalled,
'before:attach': this._onBeforeAttachCalled,
'attach': this._onAttachCalled
});
this._initBehaviors();
this.once('render', this._initialEvents);
this._initChildViewStorage();
this.initRenderBuffer();
Backbone.View.prototype.constructor.call(this, this.options);
this.delegateEntityEvents();
},
// Instead of inserting elements one by one into the page,
// it's much more performant to insert elements into a document
// fragment and then insert that document fragment into the page
initRenderBuffer: function initRenderBuffer() {
this._bufferedChildren = [];
},
startBuffering: function startBuffering() {
this.initRenderBuffer();
this.isBuffering = true;
},
endBuffering: function endBuffering() {
// Only trigger attach if already shown and attached, otherwise Region#show() handles this.
var canTriggerAttach = this._isShown && isNodeAttached(this.el);
var nestedViews;
this.isBuffering = false;
if (this._isShown) {
triggerMethodMany(this._bufferedChildren, this, 'before:show');
}
if (canTriggerAttach && this._triggerBeforeAttach) {
nestedViews = this._getNestedViews();
triggerMethodMany(nestedViews, this, 'before:attach');
}
this.attachBuffer(this, this._createBuffer());
if (canTriggerAttach && this._triggerAttach) {
nestedViews = this._getNestedViews();
triggerMethodMany(nestedViews, this, 'attach');
}
if (this._isShown) {
triggerMethodMany(this._bufferedChildren, this, 'show');
}
this.initRenderBuffer();
},
// Configured the initial events that the collection view
// binds to.
_initialEvents: function _initialEvents() {
if (this.collection) {
this.listenTo(this.collection, 'add', this._onCollectionAdd);
this.listenTo(this.collection, 'remove', this._onCollectionRemove);
this.listenTo(this.collection, 'reset', this.render);
if (this.getOption('sort')) {
this.listenTo(this.collection, 'sort', this._sortViews);
}
}
},
// Handle a child added to the collection
_onCollectionAdd: function _onCollectionAdd(child, collection, opts) {
// `index` is present when adding with `at` since BB 1.2; indexOf fallback for < 1.2
var index = opts.at !== undefined && (opts.index || collection.indexOf(child));
// When filtered or when there is no initial index, calculate index.
if (this.getOption('filter') || index === false) {
index = _.indexOf(this._filteredSortedModels(index), child);
}
if (this._shouldAddChild(child, index)) {
this.destroyEmptyView();
var ChildView = this._getChildView(child);
this.addChild(child, ChildView, index);
}
},
// get the child view by model it holds, and remove it
_onCollectionRemove: function _onCollectionRemove(model) {
var view = this.children.findByModel(model);
this.removeChildView(view);
this.checkEmpty();
},
_onBeforeShowCalled: function _onBeforeShowCalled() {
// Reset attach event flags at the top of the Region#show() event lifecycle; if the Region's
// show() options permit onBeforeAttach/onAttach events, these flags will be set true again.
this._triggerBeforeAttach = this._triggerAttach = false;
this.children.each(function (childView) {
triggerMethodOn(childView, 'before:show', childView);
});
},
_onShowCalled: function _onShowCalled() {
this.children.each(function (childView) {
triggerMethodOn(childView, 'show', childView);
});
},
// If during Region#show() onBeforeAttach was fired, continue firing it for child views
_onBeforeAttachCalled: function _onBeforeAttachCalled() {
this._triggerBeforeAttach = true;
},
// If during Region#show() onAttach was fired, continue firing it for child views
_onAttachCalled: function _onAttachCalled() {
this._triggerAttach = true;
},
// Render children views. Override this method to
// provide your own implementation of a render function for
// the collection view.
render: function render() {
this._ensureViewIsIntact();
this.triggerMethod('before:render', this);
this._renderChildren();
this._isRendered = true;
this.triggerMethod('render', this);
return this;
},
// An efficient rendering used for filtering. Instead of modifying
// the whole DOM for the collection view, we are only adding or
// removing the related childrenViews.
setFilter: function setFilter(filter, options) {
options = options || {};
var viewCanBeRendered = this._isRendered && !this._isDestroyed;
// The same filter or a `prevent` option won't render the filter.
// Nevertheless, a `prevent` option will modify the value.
if (!viewCanBeRendered || this.filter === filter) {
return;
}
if (!options.preventRender) {
this.triggerMethod('before:apply:filter', this);
this._resolveDeltasForFiltering(filter);
this.triggerMethod('apply:filter', this);
} else {
this.filter = filter;
}
},
// `removeFilter` is actually an alias for removing filters.
removeFilter: function removeFilter(options) {
this.setFilter(null, options);
},
// Calculate the deltas to remove/add the related childrenViews,
// so you don't need to rebuild the whole DOM.
_resolveDeltasForFiltering: function _resolveDeltasForFiltering(filter) {
var previousModels = this._filteredSortedModels();
this.filter = filter;
var models = this._filteredSortedModels();
var currentIds = _.pluck(models, 'cid');
var modelMustBeShown;
// We resolve the deltas in a different way because we have
// to respect the sorting algorithm.
_.each(models, function (model, index) {
if (!this.children.findByModel(model)) {
this._onCollectionAdd(model, this.collection, { at: index });
}
}, this);
_.each(previousModels, function (model) {
modelMustBeShown = _.contains(currentIds, model.cid);
if (this.children.findByModel(model) && !modelMustBeShown) {
this._onCollectionRemove(model);
}
}, this);
},
// Reorder DOM after sorting. When your element's rendering
// do not use their index, you can pass reorderOnSort: true
// to only reorder the DOM after a sort instead of rendering
// all the collectionView
reorder: function reorder() {
var children = this.children;
var models = this._filteredSortedModels();
var anyModelsAdded = _.some(models, function (model) {
return !children.findByModel(model);
});
// If there are any new models added due to filtering
// We need to add child views
// So render as normal
if (anyModelsAdded) {
this.render();
} else {
// get the DOM nodes in the same order as the models
var elsToReorder = _.map(models, function (model, index) {
var view = children.findByModel(model);
view._index = index;
return view.el;
});
// find the views that were children before but arent in this new ordering
var filteredOutViews = children.filter(function (view) {
return !_.contains(elsToReorder, view.el);
});
this.triggerMethod('before:reorder');
// since append moves elements that are already in the DOM,
// appending the elements will effectively reorder them
this._appendReorderedChildren(elsToReorder);
// remove any views that have been filtered out
_.each(filteredOutViews, this.removeChildView, this);
this.checkEmpty();
this.triggerMethod('reorder');
}
},
// Render view after sorting. Override this method to
// change how the view renders after a `sort` on the collection.
resortView: function resortView() {
if (getOption(this, 'reorderOnSort')) {
this.reorder();
} else {
this._renderChildren();
}
},
// Internal method. This checks for any changes in the order of the collection.
// If the index of any view doesn't match, it will render.
_sortViews: function _sortViews() {
var models = this._filteredSortedModels();
// check for any changes in sort order of views
var orderChanged = _.find(models, function (item, index) {
var view = this.children.findByModel(item);
return !view || view._index !== index;
}, this);
if (orderChanged) {
this.resortView();
}
},
// Internal reference to what index a `emptyView` is.
_emptyViewIndex: -1,
// Internal method. Separated so that CompositeView can append to the childViewContainer
// if necessary
_appendReorderedChildren: function _appendReorderedChildren(children) {
this.$el.append(children);
},
// Internal method. Separated so that CompositeView can have
// more control over events being triggered, around the rendering
// process
_renderChildren: function _renderChildren() {
this.destroyEmptyView();
this.destroyChildren({ checkEmpty: false });
var models = this._filteredSortedModels();
if (this.isEmpty(this.collection, { processedModels: models })) {
this.showEmptyView();
} else {
this.triggerMethod('before:render:children', this);
this.startBuffering();
this.showCollection(models);
this.endBuffering();
this.triggerMethod('render:children', this);
}
},
// Internal method to loop through collection and show each child view.
showCollection: function showCollection(models) {
_.each(models, function (child, index) {
var ChildView = this._getChildView(child);
this.addChild(child, ChildView, index);
}, this);
},
// Allow the collection to be sorted by a custom view comparator
_filteredSortedModels: function _filteredSortedModels(addedAt) {
if (!this.collection) {
return [];
}
var viewComparator = this.getViewComparator();
var models = this.collection.models;
addedAt = Math.min(Math.max(addedAt, 0), models.length - 1);
if (viewComparator) {
var addedModel;
// Preserve `at` location, even for a sorted view
if (addedAt) {
addedModel = models[addedAt];
models = models.slice(0, addedAt).concat(models.slice(addedAt + 1));
}
models = this._sortModelsBy(models, viewComparator);
if (addedModel) {
models.splice(addedAt, 0, addedModel);
}
}
// Filter after sorting in case the filter uses the index
models = this._filterModels(models);
return models;
},
// Filter an array of models, if a filter exists
_filterModels: function _filterModels(models) {
if (this.getOption('filter')) {
models = _.filter(models, function (model, index) {
return this._shouldAddChild(model, index);
}, this);
}
return models;
},
_sortModelsBy: function _sortModelsBy(models, comparator) {
if (typeof comparator === 'string') {
return _.sortBy(models, function (model) {
return model.get(comparator);
}, this);
} else if (comparator.length === 1) {
return _.sortBy(models, comparator, this);
} else {
return models.sort(_.bind(comparator, this));
}
},
// Internal method to show an empty view in place of
// a collection of child views, when the collection is empty
showEmptyView: function showEmptyView() {
var EmptyView = this.getEmptyView();
if (EmptyView && !this._showingEmptyView) {
this._showingEmptyView = true;
var model = new Backbone.Model();
var emptyViewOptions = this.getOption('emptyViewOptions') || this.getOption('childViewOptions');
if (_.isFunction(emptyViewOptions)) {
emptyViewOptions = emptyViewOptions.call(this, model, this._emptyViewIndex);
}
var view = this.buildChildView(model, EmptyView, emptyViewOptions);
this.triggerMethod('before:render:empty', view);
this._addChildView(view, 0);
this.triggerMethod('render:empty', view);
view._parent = this;
}
},
// Internal method to destroy an existing emptyView instance
// if one exists. Called when a collection view has been
// rendered empty, and then a child is added to the collection.
destroyEmptyView: function destroyEmptyView() {
if (this._showingEmptyView) {
this.triggerMethod('before:remove:empty');
this.destroyChildren();
delete this._showingEmptyView;
this.triggerMethod('remove:empty');
}
},
// Retrieve the empty view class
getEmptyView: function getEmptyView() {
return this.getOption('emptyView');
},
// Retrieve the `childView` class, either from `this.options.childView`
// or from the `childView` in the object definition. The "options"
// takes precedence.
// The `childView` property can be either a view class or a function that
// returns a view class. If it is a function, it will receive the model that
// will be passed to the view instance (created from the returned view class)
_getChildView: function _getChildView(child) {
var childView = this.getOption('childView');
if (!childView) {
throw new MarionetteError({
name: 'NoChildViewError',
message: 'A "childView" must be specified'
});
}
// first check if the `childView` is a view class (the common case)
// then check if it's a function (which we assume that returns a view class)
if (childView.prototype instanceof Backbone.View || childView === Backbone.View) {
return childView;
} else if (_.isFunction(childView)) {
return childView.call(this, child);
} else {
throw new MarionetteError({
name: 'InvalidChildViewError',
message: '"childView" must be a view class or a function that returns a view class'
});
}
},
// Render the child's view and add it to the
// HTML for the collection view at a given index.
// This will also update the indices of later views in the collection
// in order to keep the children in sync with the collection.
addChild: function addChild(child, ChildView, index) {
var childViewOptions = this.getOption('childViewOptions');
childViewOptions = _getValue(childViewOptions, this, [child, index]);
var view = this.buildChildView(child, ChildView, childViewOptions);
// increment indices of views after this one
this._updateIndices(view, true, index);
this.triggerMethod('before:add:child', view);
this._addChildView(view, index);
this.triggerMethod('add:child', view);
view._parent = this;
return view;
},
// Internal method. This decrements or increments the indices of views after the
// added/removed view to keep in sync with the collection.
_updateIndices: function _updateIndices(view, increment, index) {
if (!this.getOption('sort')) {
return;
}
if (increment) {
// assign the index to the view
view._index = index;
}
// update the indexes of views after this one
this.children.each(function (laterView) {
if (laterView._index >= view._index) {
laterView._index += increment ? 1 : -1;
}
});
},
// Internal Method. Add the view to children and render it at
// the given index.
_addChildView: function _addChildView(view, index) {
// Only trigger attach if already shown, attached, and not buffering, otherwise endBuffer() or
// Region#show() handles this.
var canTriggerAttach = this._isShown && !this.isBuffering && isNodeAttached(this.el);
var triggerBeforeShow = this._isShown && !this.isBuffering;
var triggerBeforeAttach = canTriggerAttach && this._triggerBeforeAttach;
var triggerAttach = canTriggerAttach && this._triggerAttach;
// set up the child view event forwarding
this.proxyChildEvents(view);
// Store the child view itself so we can properly remove and/or destroy it later
this.children.add(view);
this._renderChildView(view, index, triggerBeforeShow, triggerBeforeAttach);
if (triggerAttach) {
var nestedViews = this._getViewAndNested(view);
triggerMethodMany(nestedViews, this, 'attach');
}
if (this._isShown && !this.isBuffering) {
triggerMethodOn(view, 'show', view);
}
},
// render the child view
_renderChildView: function _renderChildView(view, index, triggerBeforeShow, triggerBeforeAttach) {
if (!view.supportsRenderLifecycle) {
triggerMethodOn(view, 'before:render', view);
}
view.render();
if (!view.supportsRenderLifecycle) {
triggerMethodOn(view, 'render', view);
}
if (triggerBeforeShow) {
triggerMethodOn(view, 'before:show', view);
}
if (triggerBeforeAttach) {
var nestedViews = this._getViewAndNested(view);
triggerMethodMany(nestedViews, this, 'before:attach');
}
this.attachHtml(this, view, index);
return view;
},
// Build a `childView` for a model in the collection.
buildChildView: function buildChildView(child, ChildViewClass, childViewOptions) {
var options = _.extend({ model: child }, childViewOptions);
var childView = new ChildViewClass(options);
MonitorDOMRefresh(childView);
return childView;
},
// Remove the child view and destroy it.
// This function also updates the indices of
// later views in the collection in order to keep
// the children in sync with the collection.
removeChildView: function removeChildView(view) {
if (!view) {
return view;
}
this.triggerMethod('before:remove:child', view);
if (!view.supportsDestroyLifecycle) {
triggerMethodOn(view, 'before:destroy', view);
}
// call 'destroy' or 'remove', depending on which is found
if (view.destroy) {
view.destroy();
} else {
view.remove();
}
if (!view.supportsDestroyLifecycle) {
triggerMethodOn(view, 'destroy', view);
}
delete view._parent;
this.stopListening(view);
this.children.remove(view);
this.triggerMethod('remove:child', view);
// decrement the index of views after this one
this._updateIndices(view, false);
return view;
},
// check if the collection is empty
// or optionally whether an array of pre-processed models is empty
isEmpty: function isEmpty(collection, options) {
var models;
if (_.result(options, 'processedModels')) {
models = options.processedModels;
} else {
models = this.collection ? this.collection.models : [];
models = this._filterModels(models);
}
return models.length === 0;
},
// If empty, show the empty view
checkEmpty: function checkEmpty() {
if (this.isEmpty(this.collection)) {
this.showEmptyView();
}
},
// You might need to override this if you've overridden attachHtml
attachBuffer: function attachBuffer(collectionView, buffer) {
collectionView.$el.append(buffer);
},
// Create a fragment buffer from the currently buffered children
_createBuffer: function _createBuffer() {
var elBuffer = document.createDocumentFragment();
_.each(this._bufferedChildren, function (b) {
elBuffer.appendChild(b.el);
});
return elBuffer;
},
// Append the HTML to the collection's `el`.
// Override this method to do something other
// than `.append`.
attachHtml: function attachHtml(collectionView, childView, index) {
if (collectionView.isBuffering) {
// buffering happens on reset events and initial renders
// in order to reduce the number of inserts into the
// document, which are expensive.
collectionView._bufferedChildren.splice(index, 0, childView);
} else {
// If we've already rendered the main collection, append
// the new child into the correct order if we need to. Otherwise
// append to the end.
if (!collectionView._insertBefore(childView, index)) {
collectionView._insertAfter(childView);
}
}
},
// Internal method. Check whether we need to insert the view into
// the correct position.
_insertBefore: function _insertBefore(childView, index) {
var currentView;
var findPosition = this.getOption('sort') && index < this.children.length - 1;
if (findPosition) {
// Find the view after this one
currentView = this.children.find(function (view) {
return view._index === index + 1;
});
}
if (currentView) {
currentView.$el.before(childView.el);
return true;
}
return false;
},
// Internal method. Append a view to the end of the $el
_insertAfter: function _insertAfter(childView) {
this.$el.append(childView.el);
},
// Internal method to set up the `children` object for
// storing all of the child views
_initChildViewStorage: function _initChildViewStorage() {
this.children = new ChildViewContainer();
},
// called by ViewMixin destroy
_removeChildren: function _removeChildren() {
this.destroyChildren({ checkEmpty: false });
},
// Destroy the child views that this collection view
// is holding on to, if any
destroyChildren: function destroyChildren(options) {
this.triggerMethod('before:destroy:children');
var destroyOptions = options || {};
var shouldCheckEmpty = true;
var childViews = this.children.map(_.identity);
if (typeof destroyOptions.checkEmpty !== 'undefined') {
shouldCheckEmpty = destroyOptions.checkEmpty;
}
this.children.each(this.removeChildView, this);
if (shouldCheckEmpty) {
this.checkEmpty();
}
this.triggerMethod('destroy:children');
return childViews;
},
// Return true if the given child should be shown
// Return false otherwise
// The filter will be passed (child, index, collection)
// Where
// 'child' is the given model
// 'index' is the index of that model in the collection
// 'collection' is the collection referenced by this CollectionView
_shouldAddChild: function _shouldAddChild(child, index) {
var filter = this.getOption('filter');
return !_.isFunction(filter) || filter.call(this, child, index, this.collection);
},
// Set up the child view event forwarding. Uses a "childview:"
// prefix in front of all forwarded events.
proxyChildEvents: function proxyChildEvents(view) {
var prefix = this.getOption('childViewEventPrefix');
// Forward all child view events through the parent,
// prepending "childview:" to the event name
this.listenTo(view, 'all', function () {
var args = _.toArray(arguments);
var rootEvent = args[0];
var childViewEvents = this.normalizeMethods(_.result(this, 'childViewEvents'));
args[0] = prefix + ':' + rootEvent;
args.splice(1, 0, view);
// call collectionView childViewEvent if defined
if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[rootEvent])) {
childViewEvents[rootEvent].apply(this, args.slice(1));
}
this.triggerMethod.apply(this, args);
});
},
_getImmediateChildren: function _getImmediateChildren() {
return _.values(this.children._views);
},
_getViewAndNested: function _getViewAndNested(view) {
// This will not fail on Backbone.View which does not have #_getNestedViews.
return [view].concat(_.result(view, '_getNestedViews') || []);
},
getViewComparator: function getViewComparator() {
return this.getOption('viewComparator');
}
});
_.extend(CollectionView.prototype, ViewMixin);
// Used for rendering a branch-leaf, hierarchical structure.
// Extends directly from CollectionView and also renders an
// a child view as `modelView`, for the top leaf
var CompositeView = CollectionView.extend({
// Setting up the inheritance chain which allows changes to
// Marionette.CollectionView.prototype.constructor which allows overriding
// option to pass '{sort: false}' to prevent the CompositeView from
// maintaining the sorted order of the collection.
// This will fallback onto appending childView's to the end.
constructor: function constructor() {
deprecate('CompositeView is deprecated. Convert to View at your earliest convenience');
CollectionView.prototype.constructor.apply(this, arguments);
},
// Configured the initial events that the composite view
// binds to. Override this method to prevent the initial
// events, or to add your own initial events.
_initialEvents: function _initialEvents() {
// Bind only after composite view is rendered to avoid adding child views
// to nonexistent childViewContainer
if (this.collection) {
this.listenTo(this.collection, 'add', this._onCollectionAdd);
this.listenTo(this.collection, 'remove', this._onCollectionRemove);
this.listenTo(this.collection, 'reset', this.renderChildren);
if (this.getOption('sort')) {
this.listenTo(this.collection, 'sort', this._sortViews);
}
}
},
// Retrieve the `childView` to be used when rendering each of
// the items in the collection. The default is to return
// `this.childView` or Marionette.CompositeView if no `childView`
// has been defined. As happens in CollectionView, `childView` can
// be a function (which should return a view class).
_getChildView: function _getChildView(child) {
var childView = this.getOption('childView');
// for CompositeView, if `childView` is not specified, we'll get the same
// composite view class rendered for each child in the collection
// then check if the `childView` is a view class (the common case)
// finally check if it's a function (which we assume that returns a view class)
if (!childView) {
return this.constructor;
} else if (childView.prototype instanceof Backbone.View || childView === Backbone.View) {
return childView;
} else if (_.isFunction(childView)) {
return childView.call(this, child);
} else {
throw new MarionetteError({
name: 'InvalidChildViewError',
message: '"childView" must be a view class or a function that returns a view class'
});
}
},
// Return the serialized model
serializeData: function serializeData() {
return this.serializeModel();
},
// Renders the model and the collection.
render: function render() {
this._ensureViewIsIntact();
this._isRendering = true;
this.resetChildViewContainer();
this.triggerMethod('before:render', this);
this._renderTemplate();
this.bindUIElements();
this.renderChildren();
this._isRendering = false;
this._isRendered = true;
this.triggerMethod('render', this);
return this;
},
renderChildren: function renderChildren() {
if (this._isRendered || this._isRendering) {
CollectionView.prototype._renderChildren.call(this);
}
},
// Attaches the content of the root.
// This method can be overridden to optimize rendering,
// or to render in a non standard way.
//
// For example, using `innerHTML` instead of `$el.html`
//
// ```js
// attachElContent: function(html) {
// this.el.innerHTML = html;
// return this;
// }
// ```
attachElContent: function attachElContent(html) {
this.$el.html(html);
return this;
},
// You might need to override this if you've overridden attachHtml
attachBuffer: function attachBuffer(compositeView, buffer) {
var $container = this.getChildViewContainer(compositeView);
$container.append(buffer);
},
// Internal method. Append a view to the end of the $el.
// Overidden from CollectionView to ensure view is appended to
// childViewContainer
_insertAfter: function _insertAfter(childView) {
var $container = this.getChildViewContainer(this, childView);
$container.append(childView.el);
},
// Internal method. Append reordered childView'.
// Overidden from CollectionView to ensure reordered views
// are appended to childViewContainer
_appendReorderedChildren: function _appendReorderedChildren(children) {
var $container = this.getChildViewContainer(this);
$container.append(children);
},
// Internal method to ensure an `$childViewContainer` exists, for the
// `attachHtml` method to use.
getChildViewContainer: function getChildViewContainer(containerView, childView) {
if (!!containerView.$childViewContainer) {
return containerView.$childViewContainer;
}
var container;
var childViewContainer = getOption(containerView, 'childViewContainer');
if (childViewContainer) {
var selector = _getValue(childViewContainer, containerView);
if (selector.charAt(0) === '@' && containerView.ui) {
container = containerView.ui[selector.substr(4)];
} else {
container = containerView.$(selector);
}
if (container.length <= 0) {
throw new MarionetteError({
name: 'ChildViewContainerMissingError',
message: 'The specified "childViewContainer" was not found: ' + containerView.childViewContainer
});
}
} else {
container = containerView.$el;
}
containerView.$childViewContainer = container;
return container;
},
// Internal method to reset the `$childViewContainer` on render
resetChildViewContainer: function resetChildViewContainer() {
if (this.$childViewContainer) {
this.$childViewContainer = undefined;
}
}
});
var Behavior = MarionetteObject.extend({
cidPrefix: 'mnb',
constructor: function constructor(options, view) {
// Setup reference to the view.
// this comes in handle when a behavior
// wants to directly talk up the chain
// to the view.
this.view = view;
this.defaults = _.result(this, 'defaults') || {};
this.options = _.extend({}, this.defaults, options);
// Construct an internal UI hash using
// the behaviors UI hash and then the view UI hash.
// This allows the user to use UI hash elements
// defined in the parent view as well as those
// defined in the given behavior.
// This order will help the reuse and share of a behavior
// between multiple views, while letting a view override a
// selector under an UI key.
this.ui = _.extend({}, _.result(this, 'ui'), _.result(view, 'ui'));
MarionetteObject.apply(this, arguments);
},
// proxy behavior $ method to the view
// this is useful for doing jquery DOM lookups
// scoped to behaviors view.
$: function $() {
return this.view.$.apply(this.view, arguments);
},
// Stops the behavior from listening to events.
// Overrides Object#destroy to prevent additional events from being triggered.
destroy: function destroy() {
this.stopListening();
return this;
},
proxyViewProperties: function proxyViewProperties(view) {
this.$el = view.$el;
this.el = view.el;
}
});
var previousMarionette = Backbone.Marionette;
var Marionette = Backbone.Marionette = {};
// This allows you to run multiple instances of Marionette on the same
// webapp. After loading the new version, call `noConflict()` to
// get a reference to it. At the same time the old version will be
// returned to Backbone.Marionette.
Marionette.noConflict = function () {
Backbone.Marionette = previousMarionette;
return this;
};
// Utilities
Marionette.bindEntityEvents = bindEntityEvents;
Marionette.unbindEntityEvents = unbindEntityEvents;
Marionette.proxyBindEntityEvents = proxyBindEntityEvents;
Marionette.proxyUnbindEntityEvents = proxyUnbindEntityEvents;
Marionette.proxyRadioHandlers = proxyRadioHandlers;
Marionette.unproxyRadioHandlers = unproxyRadioHandlers;
Marionette.extend = extend;
Marionette.isNodeAttached = isNodeAttached;
Marionette.mergeOptions = mergeOptions;
Marionette.getOption = getOption;
Marionette.proxyGetOption = proxyGetOption;
Marionette.normalizeMethods = normalizeMethods;
Marionette.normalizeUIString = normalizeUIString;
Marionette.normalizeUIKeys = normalizeUIKeys;
Marionette.normalizeUIValues = normalizeUIValues;
Marionette.deprecate = deprecate;
Marionette.triggerMethod = triggerMethod;
Marionette.triggerMethodOn = triggerMethodOn;
Marionette.triggerMethodMany = triggerMethodMany;
Marionette.isEnabled = isEnabled;
Marionette.setEnabled = setEnabled;
// Classes
Marionette.Application = Application;
Marionette.AppRouter = AppRouter;
Marionette.MonitorDOMRefresh = MonitorDOMRefresh;
Marionette.Renderer = Renderer;
Marionette.TemplateCache = TemplateCache;
Marionette.View = View;
Marionette.CollectionView = CollectionView;
Marionette.CompositeView = CompositeView;
Marionette.Behavior = Behavior;
Marionette.Behaviors = Behaviors;
Marionette.Region = Region;
Marionette.Error = MarionetteError;
Marionette.Object = MarionetteObject;
// Configuration
Marionette.DEV_MODE = false;
Marionette.FEATURES = FEATURES;
Marionette.VERSION = version;
return Marionette;
}));
//# sourceMappingURL=backbone.marionette.js.map
{"version":3,"file":"backbone.marionette.js","sources":["src/utils/_getValue.js","package.json","src/utils/extend.js","src/error.js","src/bind-entity-events.js","src/radio-helpers.js","src/utils/isNodeAttached.js","src/utils/mergeOptions.js","src/utils/getOption.js","src/utils/proxyGetOption.js","src/utils/normalizeMethods.js","src/utils/normalizeUIString.js","src/utils/normalizeUIKeys.js","src/utils/normalizeUIValues.js","src/utils/deprecate.js","src/trigger-method.js","src/features.js","src/object.js","src/dom-refresh.js","src/region.js","src/application.js","src/app-router.js","src/template-cache.js","src/renderer.js","src/behaviors.js","src/view-mixin.js","src/regions-mixin.js","src/view.js","src/collection-view.js","src/composite-view.js","src/behavior.js","src/backbone.marionette.js"],"sourcesContent":["import _ from 'underscore';\n\n// Similar to `_.result`, this is a simple helper\n// If a function is provided we call it with context\n// otherwise just return the value. If the value is\n// undefined return a default value\nvar _getValue = function(value, context, params) {\n if (_.isFunction(value)) {\n value = params ? value.apply(context, params) : value.call(context);\n }\n return value;\n};\n\nexport default _getValue;\n","{\n \"name\": \"backbone.marionette\",\n \"description\": \"The Backbone Framework\",\n \"version\": \"2.4.1\",\n \"homepage\": \"https://github.com/marionettejs/backbone.marionette\",\n \"main\": \"lib/core/backbone.marionette.js\",\n \"keywords\": [\n \"backbone\",\n \"plugin\",\n \"marionette\",\n \"composite\",\n \"architecture\",\n \"single\",\n \"page\",\n \"app\",\n \"client\",\n \"browser\"\n ],\n \"license\": \"MIT\",\n \"scripts\": {\n \"build\": \"gulp build\",\n \"coverage\": \"gulp coverage\",\n \"coveralls\": \"gulp coveralls\",\n \"test\": \"gulp\"\n },\n \"author\": {\n \"name\": \"Derick Bailey\",\n \"email\": \"[email protected]\",\n \"url\": \"http://derickbailey.com/\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/marionettejs/backbone.marionette/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/marionettejs/backbone.marionette.git\"\n },\n \"github\": \"https://github.com/marionettejs/backbone.marionette\",\n \"dependencies\": {\n \"backbone.babysitter\": \"^0.1.0\",\n \"backbone.radio\": \"^1.0.0\",\n \"backbone\": \"1.2.1 - 1.2.3\",\n \"underscore\": \"1.7 - 1.8.3\"\n },\n \"devDependencies\": {\n \"babel-core\": \"^5.0.0\",\n \"babel-eslint\": \"^4.1.3\",\n \"babelify\": \"^6.4.0\",\n \"browserify\": \"^12.0.1\",\n \"chai\": \"^3.4.0\",\n \"chai-jq\": \"0.0.8\",\n \"dox\": \"git://github.com/jasonLaster/dox.git#marked\",\n \"glob\": \"^5.0.15\",\n \"gulp\": \"^3.9.0\",\n \"gulp-coveralls\": \"^0.1.4\",\n \"gulp-eslint\": \"^1.0.0\",\n \"gulp-file\": \"^0.2.0\",\n \"gulp-filter\": \"^3.0.1\",\n \"gulp-header\": \"^1.7.1\",\n \"gulp-istanbul\": \"^0.10.2\",\n \"gulp-jscs\": \"^3.0.2\",\n \"gulp-lintspaces\": \"^0.3.1\",\n \"gulp-livereload\": \"^3.8.1\",\n \"gulp-mocha\": \"^2.1.3\",\n \"gulp-plumber\": \"^1.0.1\",\n \"gulp-preprocess\": \"^1.2.0\",\n \"gulp-rename\": \"^1.2.2\",\n \"gulp-sourcemaps\": \"^1.6.0\",\n \"gulp-tap\": \"^0.1.3\",\n \"gulp-uglify\": \"^1.4.2\",\n \"gulp-unwrapper\": \"^0.1.0\",\n \"gulp-yaml-validate\": \"^1.0.2\",\n \"isparta\": \"^3.1.0\",\n \"jquery\": \"^2.1.4\",\n \"jsdom\": \"^7.0.2\",\n \"rollup\": \"^0.21.1\",\n \"rollup-plugin-babel\": \"^1.0.0\",\n \"rollup-plugin-json\": \"^2.0.0\",\n \"sinon\": \"^1.17.2\",\n \"sinon-chai\": \"^2.8.0\",\n \"vinyl-buffer\": \"^1.0.0\",\n \"vinyl-source-stream\": \"^1.1.0\"\n }\n}\n","// Marionette.extend\n// -----------------\n\nimport Backbone from 'backbone';\n\n// Borrow the Backbone `extend` method so we can use it as needed\nvar extend = Backbone.Model.extend;\n\nexport default extend;\n","// Error\n// -----\n\nimport _ from 'underscore';\nimport extend from './utils/extend';\nimport {version} from '../package.json';\n\nvar errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number'];\n\nvar MarionetteError = extend.call(Error, {\n urlRoot: 'http://marionettejs.com/docs/v' + version + '/',\n\n constructor: function MarionetteError(message, options) {\n if (_.isObject(message)) {\n options = message;\n message = options.message;\n } else if (!options) {\n options = {};\n }\n\n var error = Error.call(this, message);\n _.extend(this, _.pick(error, errorProps), _.pick(options, errorProps));\n\n this.captureStackTrace();\n\n if (options.url) {\n this.url = this.urlRoot + options.url;\n }\n },\n\n captureStackTrace: function() {\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, MarionetteError);\n }\n },\n\n toString: function() {\n return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : '');\n }\n});\n\nMarionetteError.extend = extend;\n\nexport default MarionetteError;\n","// Bind Entity Events & Unbind Entity Events\n// -----------------------------------------\n//\n// These methods are used to bind/unbind a backbone \"entity\" (e.g. collection/model)\n// to methods on a target object.\n//\n// The first parameter, `target`, must have the Backbone.Events module mixed in.\n//\n// The second parameter is the `entity` (Backbone.Model, Backbone.Collection or\n// any object that has Backbone.Events mixed in) to bind the events from.\n//\n// The third parameter is a hash of { \"event:name\": \"eventHandler\" }\n// configuration. Multiple handlers can be separated by a space. A\n// function can be supplied instead of a string handler name.\n\nimport _ from 'underscore';\nimport _getValue from './utils/_getValue';\nimport MarionetteError from './error';\n\n// Bind the event to handlers specified as a string of\n// handler names on the target object\nfunction bindFromStrings(target, entity, evt, methods) {\n var methodNames = methods.split(/\\s+/);\n\n _.each(methodNames, function(methodName) {\n\n var method = target[methodName];\n if (!method) {\n throw new MarionetteError('Method \"' + methodName +\n '\" was configured as an event handler, but does not exist.');\n }\n\n target.listenTo(entity, evt, method);\n });\n}\n\n// Bind the event to a supplied callback function\nfunction bindToFunction(target, entity, evt, method) {\n target.listenTo(entity, evt, method);\n}\n\n// Bind the event to handlers specified as a string of\n// handler names on the target object\nfunction unbindFromStrings(target, entity, evt, methods) {\n var methodNames = methods.split(/\\s+/);\n\n _.each(methodNames, function(methodName) {\n var method = target[methodName];\n target.stopListening(entity, evt, method);\n });\n}\n\n// Bind the event to a supplied callback function\nfunction unbindToFunction(target, entity, evt, method) {\n target.stopListening(entity, evt, method);\n}\n\n// generic looping function\nfunction iterateEvents(target, entity, bindings, functionCallback, stringCallback) {\n if (!entity || !bindings) { return; }\n\n // type-check bindings\n if (!_.isObject(bindings)) {\n throw new MarionetteError({\n message: 'Bindings must be an object or function.',\n url: 'marionette.functions.html#marionettebindentityevents'\n });\n }\n\n // allow the bindings to be a function\n bindings = _getValue(bindings, target);\n\n // iterate the bindings and bind them\n _.each(bindings, function(methods, evt) {\n\n // allow for a function as the handler,\n // or a list of event names as a string\n if (_.isFunction(methods)) {\n functionCallback(target, entity, evt, methods);\n } else {\n stringCallback(target, entity, evt, methods);\n }\n\n });\n}\n\nfunction bindEntityEvents(target, entity, bindings) {\n iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);\n}\n\nfunction unbindEntityEvents(target, entity, bindings) {\n iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings);\n}\n\n// Proxy `bindEntityEvents`\nfunction proxyBindEntityEvents(entity, bindings) {\n return bindEntityEvents(this, entity, bindings);\n}\n\n// Proxy `unbindEntityEvents`\nfunction proxyUnbindEntityEvents(entity, bindings) {\n return unbindEntityEvents(this, entity, bindings);\n}\n\n// Export Public API\nexport {\n bindEntityEvents,\n unbindEntityEvents,\n proxyBindEntityEvents,\n proxyUnbindEntityEvents\n};\n","import Backbone from 'backbone';\nimport _ from 'underscore';\nimport Radio from 'backbone.radio';\n\n//Proxy Radio message handling to enable declarative interactions with radio channels\nvar radioAPI = {\n 'radioEvents': {\n startMethod: 'on',\n stopMethod: 'off'\n },\n 'radioRequests': {\n startMethod: 'reply',\n stopMethod: 'stopReplying'\n }\n};\n\nfunction proxyRadioHandlers() {\n unproxyRadioHandlers.apply(this);\n _.each(radioAPI, function(commands, radioType) {\n var hash = _.result(this, radioType);\n if (!hash) {\n return;\n }\n _.each(hash, function(handler, radioMessage) {\n handler = normalizeHandler.call(this, handler);\n var messageComponents = radioMessage.split(' ');\n var channel = messageComponents[0];\n var messageName = messageComponents[1];\n proxyRadioHandler.call(this, channel, radioType, messageName, handler);\n }, this);\n }, this);\n}\n\nfunction proxyRadioHandler(channel, radioType, messageName, handler) {\n var method = radioAPI[radioType].startMethod;\n this._radioChannels = this._radioChannels || [];\n if (!_.contains(this._radioChannels, channel)) {\n this._radioChannels.push(channel);\n }\n\n Radio[method](channel, messageName, handler, this);\n}\n\nfunction unproxyRadioHandlers() {\n _.each(this._radioChannels, function(channel) {\n _.each(radioAPI, function(commands) {\n Radio[commands.stopMethod](channel, null, null, this);\n }, this);\n }, this);\n}\n\nfunction normalizeHandler(handler) {\n if (!_.isFunction(handler)) {\n handler = this[handler];\n }\n return handler;\n}\n\nexport {\n proxyRadioHandlers,\n unproxyRadioHandlers\n};\n","// Marionette.isNodeAttached\n// -------------------------\n\nimport Backbone from 'backbone';\n\n// Determine if `el` is a child of the document\nvar isNodeAttached = function(el) {\n return Backbone.$.contains(document.documentElement, el);\n};\n\nexport default isNodeAttached;\n","import _ from 'underscore';\n\n// Merge `keys` from `options` onto `this`\nvar mergeOptions = function(options, keys) {\n if (!options) { return; }\n _.extend(this, _.pick(options, keys));\n};\n\nexport default mergeOptions;\n","// Marionette.getOption\n// --------------------\n\n// Retrieve an object, function or other value from a target\n// object or its `options`, with `options` taking precedence.\nvar getOption = function(target, optionName) {\n if (!target || !optionName) { return; }\n if (target.options && (target.options[optionName] !== undefined)) {\n return target.options[optionName];\n } else {\n return target[optionName];\n }\n};\n\nexport default getOption;\n","import getOption from './getOption';\n\n// Proxy `Marionette.getOption`\nvar proxyGetOption = function(optionName) {\n return getOption(this, optionName);\n};\n\nexport default proxyGetOption;\n","import _ from 'underscore';\n\n// Marionette.normalizeMethods\n// ----------------------\n\n// Pass in a mapping of events => functions or function names\n// and return a mapping of events => functions\nvar normalizeMethods = function(hash) {\n return _.reduce(hash, function(normalizedHash, method, name) {\n if (!_.isFunction(method)) {\n method = this[method];\n }\n if (method) {\n normalizedHash[name] = method;\n }\n return normalizedHash;\n }, {}, this);\n};\n\nexport default normalizeMethods;\n","// utility method for parsing @ui. syntax strings\n// into associated selector\nvar normalizeUIString = function(uiString, ui) {\n return uiString.replace(/@ui\\.[a-zA-Z_$0-9]*/g, function(r) {\n return ui[r.slice(4)];\n });\n};\n\nexport default normalizeUIString;\n","import _ from 'underscore';\nimport normalizeUIString from './normalizeUIString';\n\n// allows for the use of the @ui. syntax within\n// a given key for triggers and events\n// swaps the @ui with the associated selector.\n// Returns a new, non-mutated, parsed events hash.\nvar normalizeUIKeys = function(hash, ui) {\n return _.reduce(hash, function(memo, val, key) {\n var normalizedKey = normalizeUIString(key, ui);\n memo[normalizedKey] = val;\n return memo;\n }, {});\n};\n\nexport default normalizeUIKeys;\n","import _ from 'underscore';\nimport normalizeUIString from './normalizeUIString';\n\n// allows for the use of the @ui. syntax within\n// a given value for regions\n// swaps the @ui with the associated selector\nvar normalizeUIValues = function(hash, ui, properties) {\n _.each(hash, function(val, key) {\n if (_.isString(val)) {\n hash[key] = normalizeUIString(val, ui);\n } else if (_.isObject(val) && _.isArray(properties)) {\n _.extend(val, normalizeUIValues(_.pick(val, properties), ui));\n /* Value is an object, and we got an array of embedded property names to normalize. */\n _.each(properties, function(property) {\n var propertyVal = val[property];\n if (_.isString(propertyVal)) {\n val[property] = normalizeUIString(propertyVal, ui);\n }\n });\n }\n });\n return hash;\n};\n\nexport default normalizeUIValues;\n","/* global console */\n\nimport _ from 'underscore';\n\nimport Marionette from '../backbone.marionette';\n\nvar deprecate = function(message, test) {\n if (_.isObject(message)) {\n message = (\n message.prev + ' is going to be removed in the future. ' +\n 'Please use ' + message.next + ' instead.' +\n (message.url ? ' See: ' + message.url : '')\n );\n }\n\n if (!Marionette.DEV_MODE) {\n return;\n }\n\n if ((test === undefined || !test) && !deprecate._cache[message]) {\n deprecate._warn('Deprecation warning: ' + message);\n deprecate._cache[message] = true;\n }\n};\n\ndeprecate._console = typeof console !== 'undefined' ? console : {};\ndeprecate._warn = function() {\n var warn = deprecate._console.warn || deprecate._console.log || function() {};\n return warn.apply(deprecate._console, arguments);\n};\ndeprecate._cache = {};\n\nexport default deprecate;\n","/* jshint maxstatements: 14, maxcomplexity: 7 */\n\n// Trigger Method\n// --------------\n\nimport _ from 'underscore';\nimport getOption from './utils/getOption';\n\nvar _triggerMethod = (function() {\n // split the event name on the \":\"\n var splitter = /(^|:)(\\w)/gi;\n\n // take the event section (\"section1:section2:section3\")\n // and turn it in to uppercase name\n function getEventName(match, prefix, eventName) {\n return eventName.toUpperCase();\n }\n\n return function(context, args) {\n var event = args[0];\n\n // get the method name from the event name\n var methodName = 'on' + event.replace(splitter, getEventName);\n var method = getOption(context, methodName);\n var result;\n\n // call the onMethodName if it exists\n if (_.isFunction(method)) {\n // pass all args, except the event name\n result = method.apply(context, _.rest(args));\n }\n\n // trigger the event\n context.trigger.apply(context, args);\n\n return result;\n };\n})();\n\n// Trigger an event and/or a corresponding method name. Examples:\n//\n// `this.triggerMethod(\"foo\")` will trigger the \"foo\" event and\n// call the \"onFoo\" method.\n//\n// `this.triggerMethod(\"foo:bar\")` will trigger the \"foo:bar\" event and\n// call the \"onFooBar\" method.\nfunction triggerMethod(event) {\n return _triggerMethod(this, arguments);\n}\n\n// triggerMethodOn invokes triggerMethod on a specific context\n//\n// e.g. `Marionette.triggerMethodOn(view, 'show')`\n// will trigger a \"show\" event or invoke onShow the view.\nfunction triggerMethodOn(context) {\n var fnc = _.isFunction(context.triggerMethod) ?\n context.triggerMethod :\n triggerMethod;\n\n return fnc.apply(context, _.rest(arguments));\n}\n\n// triggerMethodMany invokes triggerMethod on many targets from a source\n// it's useful for standardizing a pattern where we propogate an event from a source\n// to many targets.\n//\n// For each target we want to follow the pattern\n// target.triggerMethod(event, target, source, ...other args)\n// e.g childview.triggerMethod('attach', childView, region, ...args)\nfunction triggerMethodMany(targets, source, eventName) {\n var args = _.drop(arguments, 3);\n\n _.each(targets, function(target) {\n triggerMethodOn.apply(target, [target, eventName, target, source].concat(args));\n });\n}\n\nexport {\n _triggerMethod,\n triggerMethod,\n triggerMethodOn,\n triggerMethodMany\n};\n","// Add Feature flags here\n// e.g. 'class' => false\nvar FEATURES = {\n};\n\nfunction isEnabled(name) {\n return !!FEATURES[name];\n}\n\nfunction setEnabled(name, state) {\n return FEATURES[name] = state;\n}\n\nexport {\n FEATURES,\n setEnabled,\n isEnabled\n};\n","// Object\n// ------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport extend from './utils/extend';\nimport proxyGetOption from './utils/proxyGetOption';\nimport mergeOptions from './utils/mergeOptions';\nimport { triggerMethod } from './trigger-method';\nimport {\n proxyBindEntityEvents,\n proxyUnbindEntityEvents } from './bind-entity-events';\n\nimport {\n proxyRadioHandlers,\n unproxyRadioHandlers } from './radio-helpers';\n\n// A Base Class that other Classes should descend from.\n// Object borrows many conventions and utilities from Backbone.\nvar MarionetteObject = function(options) {\n this.options = _.extend({}, _.result(this, 'options'), options);\n proxyRadioHandlers.apply(this);\n this.cid = _.uniqueId(this.cidPrefix);\n this.initialize.apply(this, arguments);\n};\n\nMarionetteObject.extend = extend;\n\n// Object Methods\n// --------------\n\n// Ensure it can trigger events with Backbone.Events\n_.extend(MarionetteObject.prototype, Backbone.Events, {\n cidPrefix: 'mno',\n\n // for parity with Marionette.AbstractView lifecyle\n _isDestroyed: false,\n\n isDestroyed: function() {\n return this._isDestroyed();\n },\n\n //this is a noop method intended to be overridden by classes that extend from this base\n initialize: function() {},\n\n destroy: function(options) {\n if (this._isDestroyed) { return this; }\n\n options = options || {};\n\n this.triggerMethod('before:destroy', options);\n\n // mark as destroyed before doing the actual destroy, to\n // prevent infinite loops within \"destroy\" event handlers\n this._isDestroyed = true;\n this.triggerMethod('destroy', options);\n unproxyRadioHandlers.apply(this);\n this.stopListening();\n\n return this;\n },\n\n // Import the `triggerMethod` to trigger events with corresponding\n // methods if the method exists\n triggerMethod: triggerMethod,\n\n // A handy way to merge options onto the instance\n mergeOptions: mergeOptions,\n\n // Proxy `getOption` to enable getting options from this or this.options by name.\n getOption: proxyGetOption,\n\n // Proxy `bindEntityEvents` to enable binding view's events from another entity.\n bindEntityEvents: proxyBindEntityEvents,\n\n // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.\n unbindEntityEvents: proxyUnbindEntityEvents\n\n});\n\nexport default MarionetteObject;\n","// DOM Refresh\n// -----------\n\nimport _ from 'underscore';\nimport isNodeAttached from './utils/isNodeAttached';\nimport {triggerMethodOn} from './trigger-method';\n\n// Monitor a view's state, and after it has been rendered and shown\n// in the DOM, trigger a \"dom:refresh\" event every time it is\n// re-rendered.\n\nfunction MonitorDOMRefresh(view) {\n if (view._isDomRefreshMonitored) { return; }\n view._isDomRefreshMonitored = true;\n\n // track when the view has been shown in the DOM,\n // using a Marionette.Region (or by other means of triggering \"show\")\n function handleShow() {\n view._isShown = true;\n triggerDOMRefresh();\n }\n\n // track when the view has been rendered\n function handleRender() {\n view._isRendered = true;\n triggerDOMRefresh();\n }\n\n // Trigger the \"dom:refresh\" event and corresponding \"onDomRefresh\" method\n function triggerDOMRefresh() {\n if (view._isShown && view._isRendered && isNodeAttached(view.el)) {\n triggerMethodOn(view, 'dom:refresh', view);\n }\n }\n\n view.on({\n show: handleShow,\n render: handleRender\n });\n}\n\nexport default MonitorDOMRefresh;\n","// Region\n// ------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport isNodeAttached from './utils/isNodeAttached';\nimport MNObject from './object';\nimport _getValue from './utils/_getValue';\nimport MarionetteError from './error';\nimport MonitorDOMRefresh from './dom-refresh';\nimport { triggerMethodOn, triggerMethodMany } from './trigger-method';\n\n// Manage the visual regions of your composite application. See\n// http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/\n\nvar Region = MNObject.extend({\n cidPrefix: 'mnr',\n\n constructor: function(options) {\n\n // set options temporarily so that we can get `el`.\n // options will be overriden by Object.constructor\n this.options = options || {};\n this.el = this.getOption('el');\n\n // Handle when this.el is passed in as a $ wrapped element.\n this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el;\n\n if (!this.el) {\n throw new MarionetteError({\n name: 'NoElError',\n message: 'An \"el\" must be specified for a region.'\n });\n }\n\n this.$el = this.getEl(this.el);\n MNObject.call(this, options);\n },\n\n // Displays a backbone view instance inside of the region.\n // Handles calling the `render` method for you. Reads content\n // directly from the `el` attribute. Also calls an optional\n // `onShow` and `onDestroy` method on your view, just after showing\n // or just before destroying the view, respectively.\n // The `preventDestroy` option can be used to prevent a view from\n // the old view being destroyed on show.\n // The `forceShow` option can be used to force a view to be\n // re-rendered if it's already shown in the region.\n show: function(view, options) {\n if (!this._ensureElement()) {\n return;\n }\n\n this._ensureViewIsIntact(view);\n MonitorDOMRefresh(view);\n\n var showOptions = options || {};\n var isDifferentView = view !== this.currentView;\n var forceShow = !!showOptions.forceShow;\n var replaceElement = !!showOptions.replaceElement;\n\n // We are only changing the view if there is a current view to change to begin with\n var changingView = this.currentView;\n var isChangingView = !!changingView;\n\n // Only destroy the current view if we don't want to `preventDestroy` and if\n // the view given in the first argument is different than `currentView`\n var _shouldDestroyView = this.shouldDestroyView(view, options);\n\n // Only show the view given in the first argument if it is different than\n // the current view or if we want to re-show the view. Note that if\n // `_shouldDestroyView` is true, then `_shouldShowView` is also necessarily true.\n var _shouldShowView = isDifferentView || forceShow;\n\n // only replace the region's element with the view's element if explicitly set\n var _shouldReplaceElement = replaceElement;\n\n if (isChangingView) {\n this.triggerMethod('before:swapOut', changingView, this, options);\n }\n\n if (this.currentView && isDifferentView) {\n delete this.currentView._parent;\n }\n\n if (_shouldDestroyView) {\n this.empty();\n\n // A `destroy` event is attached to the clean up manually removed views.\n // We need to detach this event when a new view is going to be shown as it\n // is no longer relevant.\n } else if (isChangingView && _shouldShowView) {\n this.currentView.off('destroy', this.empty, this);\n }\n\n if (_shouldShowView) {\n\n // We need to listen for if a view is destroyed\n // in a way other than through the region.\n // If this happens we need to remove the reference\n // to the currentView since once a view has been destroyed\n // we can not reuse it.\n view.once('destroy', this.empty, this);\n\n // make this region the view's parent,\n // It's important that this parent binding happens before rendering\n // so that any events the child may trigger during render can also be\n // triggered on the child's ancestor views\n view._parent = this;\n this._renderView(view, options);\n\n if (isChangingView) {\n this.triggerMethod('before:swapIn', view, this, options);\n }\n\n this.triggerMethod('before:show', view, this, options);\n triggerMethodOn(view, 'before:show', view, this, options);\n\n // An array of views that we're about to display\n var attachedRegion = isNodeAttached(this.el);\n\n // The views that we're about to attach to the document\n // It's important that we prevent _getNestedViews from being executed unnecessarily\n // as it's a potentially-slow method\n var displayedViews = [];\n\n var attachOptions = _.extend({\n triggerBeforeAttach: this.triggerBeforeAttach,\n triggerAttach: this.triggerAttach\n }, showOptions);\n\n if (attachedRegion && attachOptions.triggerBeforeAttach) {\n displayedViews = this._displayedViews(view);\n this._triggerAttach(displayedViews, 'before:');\n }\n\n this.attachHtml(view, _shouldReplaceElement);\n this.currentView = view;\n\n if (attachedRegion && attachOptions.triggerAttach) {\n displayedViews = this._displayedViews(view);\n this._triggerAttach(displayedViews);\n }\n\n if (isChangingView) {\n this.triggerMethod('swapOut', changingView, this, options);\n this.triggerMethod('swapIn', view, this, options);\n }\n\n this.triggerMethod('show', view, this, options);\n triggerMethodOn(view, 'show', view, this, options);\n }\n\n return this;\n },\n\n shouldDestroyView: function(view, options) {\n var showOptions = options || {};\n var isDifferentView = view !== this.currentView;\n var preventDestroy = !!showOptions.preventDestroy;\n\n return isDifferentView && !preventDestroy;\n },\n\n _renderView: function(view, options) {\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'before:render', view);\n }\n this.renderView(view, options);\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'render', view);\n }\n },\n\n renderView: function(view, options) {\n view.render();\n },\n\n triggerBeforeAttach: true,\n triggerAttach: true,\n\n _triggerAttach: function(views, prefix) {\n var eventName = (prefix || '') + 'attach';\n triggerMethodMany(views, this, eventName);\n },\n\n _displayedViews: function(view) {\n return _.union([view], _.result(view, '_getNestedViews') || []);\n },\n\n _ensureElement: function() {\n if (!_.isObject(this.el)) {\n this.$el = this.getEl(this.el);\n this.el = this.$el[0];\n }\n\n if (!this.$el || this.$el.length === 0) {\n if (this.getOption('allowMissingEl')) {\n return false;\n } else {\n throw new MarionetteError('An \"el\" ' + this.$el.selector + ' must exist in DOM');\n }\n }\n return true;\n },\n\n _ensureViewIsIntact: function(view) {\n if (!view) {\n throw new MarionetteError({\n name: 'ViewNotValid',\n message: 'The view passed is undefined and therefore invalid. You must pass a view instance to show.'\n });\n }\n\n if (view._isDestroyed) {\n throw new MarionetteError({\n name: 'ViewDestroyedError',\n message: 'View (cid: \"' + view.cid + '\") has already been destroyed and cannot be used.'\n });\n }\n },\n\n // Override this method to change how the region finds the DOM\n // element that it manages. Return a jQuery selector object scoped\n // to a provided parent el or the document if none exists.\n getEl: function(el) {\n return Backbone.$(el, _getValue(this.options.parentEl, this));\n },\n\n // Replace the region's DOM element with the view's DOM element.\n _replaceEl: function(view) {\n // empty el so we don't save any non-destroyed views\n this.$el.contents().detach();\n\n // always restore the el to ensure the regions el is\n // present before replacing\n this._restoreEl();\n\n var parent = this.el.parentNode;\n\n parent.replaceChild(view.el, this.el);\n this.replaced = true;\n },\n\n // Restore the region's element in the DOM.\n _restoreEl: function() {\n if (!this.currentView) {\n return;\n }\n\n var view = this.currentView;\n var parent = view.el.parentNode;\n\n if (!parent) {\n return;\n }\n\n parent.replaceChild(this.el, view.el);\n this.replaced = false;\n },\n\n // Override this method to change how the new view is\n // appended to the `$el` that the region is managing\n attachHtml: function(view, shouldReplace) {\n if (shouldReplace) {\n // replace the region's node with the view's node\n this._replaceEl(view);\n } else {\n // empty the node and append new view\n this.$el.contents().detach();\n\n this.el.appendChild(view.el);\n }\n },\n\n // Destroy the current view, if there is one. If there is no\n // current view, it does nothing and returns immediately.\n empty: function(options) {\n var view = this.currentView;\n\n var emptyOptions = options || {};\n var preventDestroy = !!emptyOptions.preventDestroy;\n\n // If there is no view in the region\n // we should not remove anything\n if (!view) { return this; }\n\n view.off('destroy', this.empty, this);\n this.triggerMethod('before:empty', view);\n\n if (this.replaced) {\n this._restoreEl();\n }\n\n if (!preventDestroy) {\n this._destroyView();\n }\n this.triggerMethod('empty', view);\n\n // Remove region pointer to the currentView\n delete this.currentView;\n\n if (preventDestroy) {\n this.$el.contents().detach();\n }\n\n return this;\n },\n\n // call 'destroy' or 'remove', depending on which is found\n // on the view (if showing a raw Backbone view or a Marionette View)\n _destroyView: function() {\n var view = this.currentView;\n if (view._isDestroyed) { return; }\n\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'before:destroy', view);\n }\n if (view.destroy) {\n view.destroy();\n } else {\n view.remove();\n\n // appending _isDestroyed to raw Backbone View allows regions\n // to throw a ViewDestroyedError for this view\n view._isDestroyed = true;\n }\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'destroy', view);\n }\n },\n\n // Attach an existing view to the region. This\n // will not call `render` or `onShow` for the new view,\n // and will not replace the current HTML for the `el`\n // of the region.\n attachView: function(view) {\n if (this.currentView) {\n delete this.currentView._parent;\n }\n view._parent = this;\n this.currentView = view;\n return this;\n },\n\n // Checks whether a view is currently present within\n // the region. Returns `true` if there is and `false` if\n // no view is present.\n hasView: function() {\n return !!this.currentView;\n },\n\n // Reset the region by destroying any existing view and\n // clearing out the cached `$el`. The next time a view\n // is shown via this region, the region will re-query the\n // DOM for the region's `el`.\n reset: function() {\n this.empty();\n\n if (this.$el) {\n this.el = this.$el.selector;\n }\n\n delete this.$el;\n return this;\n }\n\n});\n\nexport default Region;\n","// Application\n// -----------\nimport _ from 'underscore';\nimport MarionetteObject from './object';\nimport Region from './region';\n\n// A container for a Marionette application.\nvar Application = MarionetteObject.extend({\n cidPrefix: 'mna',\n\n constructor: function(options) {\n options = options || {};\n\n this._initRegion(options);\n\n MarionetteObject.prototype.constructor.apply(this, arguments);\n },\n\n regionClass: Region,\n\n _initRegion: function(options) {\n var region = options.region || this.region;\n var RegionClass = options.regionClass || this.regionClass;\n\n // if the region is a string expect an el or selector\n // and instantiate a region\n if (_.isString(region)) {\n this._region = new RegionClass({\n el: region\n });\n return;\n }\n\n this._region = region;\n },\n\n getRegion: function() {\n return this._region;\n },\n\n showView: function(view, options) {\n var region = this.getRegion();\n return region.show.apply(region, arguments);\n },\n\n getView: function() {\n return this.getRegion().currentView;\n },\n\n // kick off all of the application's processes.\n start: function(options) {\n this.triggerMethod('before:start', options);\n this.triggerMethod('start', options);\n }\n\n});\n\nexport default Application;\n","// App Router\n// ----------\n\n// Reduce the boilerplate code of handling route events\n// and then calling a single method on another object,\n// called a controller.\n// Have your routers configured to call the method on\n// your controller, directly.\n//\n// Configure an AppRouter with `appRoutes`.\n//\n// App routers can only take one `controller` object.\n// It is recommended that you divide your controller\n// objects in to smaller pieces of related functionality\n// and have multiple routers / controllers, instead of\n// just one giant router and controller.\n//\n// You can also add standard routes to an AppRouter.\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport MarionetteError from './error';\nimport mergeOptions from './utils/mergeOptions';\nimport proxyGetOption from './utils/proxyGetOption';\nimport { proxyBindEntityEvents, proxyUnbindEntityEvents } from './bind-entity-events';\nimport { triggerMethod } from './trigger-method';\n\nvar AppRouter = Backbone.Router.extend({\n\n constructor: function(options) {\n this.options = options || {};\n\n Backbone.Router.apply(this, arguments);\n\n var appRoutes = this.getOption('appRoutes');\n var controller = this._getController();\n this.processAppRoutes(controller, appRoutes);\n this.on('route', this._processOnRoute, this);\n },\n\n // Similar to route method on a Backbone Router but\n // method is called on the controller\n appRoute: function(route, methodName) {\n var controller = this._getController();\n this._addAppRoute(controller, route, methodName);\n },\n\n // process the route event and trigger the onRoute\n // method call, if it exists\n _processOnRoute: function(routeName, routeArgs) {\n // make sure an onRoute before trying to call it\n if (_.isFunction(this.onRoute)) {\n // find the path that matches the current route\n var routePath = _.invert(this.getOption('appRoutes'))[routeName];\n this.onRoute(routeName, routePath, routeArgs);\n }\n },\n\n // Internal method to process the `appRoutes` for the\n // router, and turn them in to routes that trigger the\n // specified method on the specified `controller`.\n processAppRoutes: function(controller, appRoutes) {\n if (!appRoutes) { return; }\n\n var routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes\n\n _.each(routeNames, function(route) {\n this._addAppRoute(controller, route, appRoutes[route]);\n }, this);\n },\n\n _getController: function() {\n return this.getOption('controller');\n },\n\n _addAppRoute: function(controller, route, methodName) {\n var method = controller[methodName];\n\n if (!method) {\n throw new MarionetteError('Method \"' + methodName + '\" was not found on the controller');\n }\n\n this.route(route, methodName, _.bind(method, controller));\n },\n\n mergeOptions: mergeOptions,\n\n // Proxy `getOption` to enable getting options from this or this.options by name.\n getOption: proxyGetOption,\n\n triggerMethod: triggerMethod,\n\n bindEntityEvents: proxyBindEntityEvents,\n\n unbindEntityEvents: proxyUnbindEntityEvents\n});\n\nexport default AppRouter;\n","// Template Cache\n// --------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport MarionetteError from './error';\n\n// Manage templates stored in `<script>` blocks,\n// caching them for faster access.\nvar TemplateCache = function(templateId) {\n this.templateId = templateId;\n};\n\n// TemplateCache object-level methods. Manage the template\n// caches from these method calls instead of creating\n// your own TemplateCache instances\n_.extend(TemplateCache, {\n templateCaches: {},\n\n // Get the specified template by id. Either\n // retrieves the cached version, or loads it\n // from the DOM.\n get: function(templateId, options) {\n var cachedTemplate = this.templateCaches[templateId];\n\n if (!cachedTemplate) {\n cachedTemplate = new TemplateCache(templateId);\n this.templateCaches[templateId] = cachedTemplate;\n }\n\n return cachedTemplate.load(options);\n },\n\n // Clear templates from the cache. If no arguments\n // are specified, clears all templates:\n // `clear()`\n //\n // If arguments are specified, clears each of the\n // specified templates from the cache:\n // `clear(\"#t1\", \"#t2\", \"...\")`\n clear: function() {\n var i;\n var args = _.toArray(arguments);\n var length = args.length;\n\n if (length > 0) {\n for (i = 0; i < length; i++) {\n delete this.templateCaches[args[i]];\n }\n } else {\n this.templateCaches = {};\n }\n }\n});\n\n// TemplateCache instance methods, allowing each\n// template cache object to manage its own state\n// and know whether or not it has been loaded\n_.extend(TemplateCache.prototype, {\n\n // Internal method to load the template\n load: function(options) {\n // Guard clause to prevent loading this template more than once\n if (this.compiledTemplate) {\n return this.compiledTemplate;\n }\n\n // Load the template and compile it\n var template = this.loadTemplate(this.templateId, options);\n this.compiledTemplate = this.compileTemplate(template, options);\n\n return this.compiledTemplate;\n },\n\n // Load a template from the DOM, by default. Override\n // this method to provide your own template retrieval\n // For asynchronous loading with AMD/RequireJS, consider\n // using a template-loader plugin as described here:\n // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs\n loadTemplate: function(templateId, options) {\n var $template = Backbone.$(templateId);\n\n if (!$template.length) {\n throw new MarionetteError({\n name: 'NoTemplateError',\n message: 'Could not find template: \"' + templateId + '\"'\n });\n }\n return $template.html();\n },\n\n // Pre-compile the template before caching it. Override\n // this method if you do not need to pre-compile a template\n // (JST / RequireJS for example) or if you want to change\n // the template engine used (Handebars, etc).\n compileTemplate: function(rawTemplate, options) {\n return _.template(rawTemplate, options);\n }\n});\n\nexport default TemplateCache;\n","// Renderer\n// --------\n\nimport _ from 'underscore';\nimport MarionetteError from './error';\nimport TemplateCache from './template-cache';\n\n// Render a template with data by passing in the template\n// selector and the data to render.\nvar Renderer = {\n\n // Render a template with data. The `template` parameter is\n // passed to the `TemplateCache` object to retrieve the\n // template function. Override this method to provide your own\n // custom rendering and template handling for all of Marionette.\n render: function(template, data) {\n if (!template) {\n throw new MarionetteError({\n name: 'TemplateNotFoundError',\n message: 'Cannot render the template since its false, null or undefined.'\n });\n }\n\n var templateFunc = _.isFunction(template) ? template : TemplateCache.get(template);\n\n return templateFunc(data);\n }\n};\n\nexport default Renderer;\n","// Behaviors\n// ---------\n\n// Behaviors is a utility class that takes care of\n// gluing your behavior instances to their given View.\n// The most important part of this class is that you\n// **MUST** override the class level behaviorsLookup\n// method for things to work properly.\n\nimport _ from 'underscore';\nimport _getValue from './utils/_getValue';\nimport normalizeUIKeys from './utils/normalizeUIKeys';\nimport MarionetteError from './error';\n\n// Borrow event splitter from Backbone\nvar delegateEventSplitter = /^(\\S+)\\s*(.*)$/;\n\nfunction Behaviors(view, behaviors) {\n\n if (!_.isObject(view.behaviors)) {\n return {};\n }\n\n // Behaviors defined on a view can be a flat object literal\n // or it can be a function that returns an object.\n behaviors = Behaviors.parseBehaviors(view, behaviors);\n\n // Wraps several of the view's methods\n // calling the methods first on each behavior\n // and then eventually calling the method on the view.\n Behaviors.wrap(view, behaviors, _.keys(methods));\n return behaviors;\n}\n\nvar methods = {\n behaviorTriggers: function(unusedBehaviorTriggers, behaviors) {\n var triggerBuilder = new BehaviorTriggersBuilder(this, behaviors);\n return triggerBuilder.buildBehaviorTriggers();\n },\n\n behaviorEvents: function(unusedBehaviorEvents, behaviors) {\n var _behaviorsEvents = {};\n\n _.each(behaviors, function(b, i) {\n var _events = {};\n var behaviorEvents = _.clone(_.result(b, 'events')) || {};\n\n // Normalize behavior events hash to allow\n // a user to use the @ui. syntax.\n behaviorEvents = normalizeUIKeys(behaviorEvents, getBehaviorsUI(b));\n\n var j = 0;\n _.each(behaviorEvents, function(behaviorHandler, key) {\n var match = key.match(delegateEventSplitter);\n\n // Set event name to be namespaced using the view cid,\n // the behavior index, and the behavior event index\n // to generate a non colliding event namespace\n // http://api.jquery.com/event.namespace/\n var eventName = match[1] + '.' + [this.cid, i, j++, ' '].join('');\n var selector = match[2];\n\n var eventKey = eventName + selector;\n var handler = _.isFunction(behaviorHandler) ? behaviorHandler : b[behaviorHandler];\n\n _events[eventKey] = _.bind(handler, b);\n }, this);\n\n _behaviorsEvents = _.extend(_behaviorsEvents, _events);\n }, this);\n\n return _behaviorsEvents;\n }\n};\n\n_.extend(Behaviors, {\n\n // Placeholder method to be extended by the user.\n // The method should define the object that stores the behaviors.\n // i.e.\n //\n // ```js\n // Marionette.Behaviors.behaviorsLookup: function() {\n // return App.Behaviors\n // }\n // ```\n behaviorsLookup: function() {\n throw new MarionetteError({\n message: 'You must define where your behaviors are stored.',\n url: 'marionette.behaviors.md#behaviorslookup'\n });\n },\n\n // Takes care of getting the behavior class\n // given options and a key.\n // If a user passes in options.behaviorClass\n // default to using that.\n // If a user passes in a Behavior Class directly, use that\n // Otherwise delegate the lookup to the users `behaviorsLookup` implementation.\n getBehaviorClass: function(options, key) {\n if (options.behaviorClass) {\n return options.behaviorClass;\n //treat functions as a Behavior constructor\n } else if (_.isFunction(options)) {\n return options;\n }\n\n // behaviorsLookup can be either a flat object or a method\n return _getValue(Behaviors.behaviorsLookup, this, [options, key])[key];\n },\n\n // Iterate over the behaviors object, for each behavior\n // instantiate it and get its grouped behaviors.\n // This accepts a list of behaviors in either an object or array form\n parseBehaviors: function(view, behaviors) {\n return _.chain(behaviors).map(function(options, key) {\n var BehaviorClass = Behaviors.getBehaviorClass(options, key);\n //if we're passed a class directly instead of an object\n var _options = options === BehaviorClass ? {} : options;\n var behavior = new BehaviorClass(_options, view);\n var nestedBehaviors = Behaviors.parseBehaviors(view, _.result(behavior, 'behaviors'));\n\n return [behavior].concat(nestedBehaviors);\n }).flatten().value();\n },\n\n // Wrap view internal methods so that they delegate to behaviors. For example,\n // `onDestroy` should trigger destroy on all of the behaviors and then destroy itself.\n // i.e.\n //\n // `view.delegateEvents = _.partial(methods.delegateEvents, view.delegateEvents, behaviors);`\n wrap: function(view, behaviors, methodNames) {\n _.each(methodNames, function(methodName) {\n view[methodName] = _.partial(methods[methodName], view[methodName], behaviors);\n });\n }\n});\n\n// Class to build handlers for `triggers` on behaviors\n// for views\nfunction BehaviorTriggersBuilder(view, behaviors) {\n this._view = view;\n this._behaviors = behaviors;\n this._triggers = {};\n}\n\n_.extend(BehaviorTriggersBuilder.prototype, {\n // Main method to build the triggers hash with event keys and handlers\n buildBehaviorTriggers: function() {\n _.each(this._behaviors, this._buildTriggerHandlersForBehavior, this);\n return this._triggers;\n },\n\n // Internal method to build all trigger handlers for a given behavior\n _buildTriggerHandlersForBehavior: function(behavior, i) {\n var triggersHash = _.clone(_.result(behavior, 'triggers')) || {};\n\n triggersHash = normalizeUIKeys(triggersHash, getBehaviorsUI(behavior));\n\n _.each(triggersHash, _.bind(this._setHandlerForBehavior, this, behavior, i));\n },\n\n // Internal method to create and assign the trigger handler for a given\n // behavior\n _setHandlerForBehavior: function(behavior, i, eventName, trigger) {\n // Unique identifier for the `this._triggers` hash\n var triggerKey = trigger.replace(/^\\S+/, function(triggerName) {\n return triggerName + '.' + 'behaviortriggers' + i;\n });\n\n this._triggers[triggerKey] = this._view._buildViewTrigger(eventName);\n }\n});\n\nfunction getBehaviorsUI(behavior) {\n return behavior._uiBindings || behavior.ui;\n}\n\nexport default Behaviors;\n","// ViewMixin\n// ---------\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport Behaviors from './behaviors';\nimport _getValue from './utils/_getValue';\nimport getOption from './utils/getOption';\nimport normalizeMethods from './utils/normalizeMethods';\nimport normalizeUIKeys from './utils/normalizeUIKeys';\nimport normalizeUIValues from './utils/normalizeUIValues';\nimport mergeOptions from './utils/mergeOptions';\nimport proxyGetOption from './utils/proxyGetOption';\nimport MarionetteError from './error';\nimport Renderer from './renderer';\nimport View from './view';\nimport { proxyBindEntityEvents, proxyUnbindEntityEvents } from './bind-entity-events';\nimport { _triggerMethod } from './trigger-method';\n\nexport default {\n supportsRenderLifecycle: true,\n supportsDestroyLifecycle: true,\n\n _isDestroyed: false,\n\n isDestroyed: function() {\n return !!this._isDestroyed;\n },\n\n _isRendered: false,\n\n isRendered: function() {\n return !!this._isRendered;\n },\n\n _initBehaviors: function() {\n var behaviors = _getValue(this.getOption('behaviors'), this);\n this._behaviors = Behaviors(this, behaviors);\n },\n\n // Get the template for this view\n // instance. You can set a `template` attribute in the view\n // definition or pass a `template: \"whatever\"` parameter in\n // to the constructor options.\n getTemplate: function() {\n return this.getOption('template');\n },\n\n // Internal method to render the template with the serialized data\n // and template context via the `Marionette.Renderer` object.\n _renderTemplate: function() {\n var template = this.getTemplate();\n\n // Allow template-less views\n if (template === false) {\n return;\n }\n\n // Add in entity data and template context\n var data = this.mixinTemplateContext(this.serializeData());\n\n // Render and add to el\n var html = Renderer.render(template, data, this);\n this.attachElContent(html);\n },\n\n // Prepares the special `model` property of a view\n // for being displayed in the template. By default\n // we simply clone the attributes. Override this if\n // you need a custom transformation for your view's model\n serializeModel: function() {\n if (!this.model) { return {}; }\n return _.clone(this.model.attributes);\n },\n\n // Mix in template context methods. Looks for a\n // `templateContext` attribute, which can either be an\n // object literal, or a function that returns an object\n // literal. All methods and attributes from this object\n // are copies to the object passed in.\n mixinTemplateContext: function(target) {\n target = target || {};\n var templateContext = this.getOption('templateContext');\n templateContext = _getValue(templateContext, this);\n return _.extend(target, templateContext);\n },\n\n // normalize the keys of passed hash with the views `ui` selectors.\n // `{\"@ui.foo\": \"bar\"}`\n normalizeUIKeys: function(hash) {\n var uiBindings = _.result(this, '_uiBindings');\n return normalizeUIKeys(hash, uiBindings || _.result(this, 'ui'));\n },\n\n // normalize the values of passed hash with the views `ui` selectors.\n // `{foo: \"@ui.bar\"}`\n normalizeUIValues: function(hash, properties) {\n var ui = _.result(this, 'ui');\n var uiBindings = _.result(this, '_uiBindings');\n return normalizeUIValues(hash, uiBindings || ui, properties);\n },\n\n // Configure `triggers` to forward DOM events to view\n // events. `triggers: {\"click .foo\": \"do:foo\"}`\n configureTriggers: function() {\n if (!this.triggers) { return; }\n\n // Allow `triggers` to be configured as a function\n var triggers = this.normalizeUIKeys(_.result(this, 'triggers'));\n\n // Configure the triggers, prevent default\n // action and stop propagation of DOM events\n return _.reduce(triggers, function(events, value, key) {\n events[key] = this._buildViewTrigger(value);\n return events;\n }, {}, this);\n },\n\n // Overriding Backbone.View's `delegateEvents` to handle\n // `events` and `triggers`\n delegateEvents: function(eventsArg) {\n // proxy behavior $el to the view's $el.\n _.invoke(this._behaviors, 'proxyViewProperties', this);\n\n var events = _getValue(eventsArg || this.events, this);\n\n // normalize ui keys\n events = this.normalizeUIKeys(events);\n if (typeof eventsArg === 'undefined') {this.events = events;}\n\n var combinedEvents = {};\n\n // look up if this view has behavior events\n var behaviorEvents = _.result(this, 'behaviorEvents') || {};\n var triggers = this.configureTriggers();\n var behaviorTriggers = _.result(this, 'behaviorTriggers') || {};\n\n // behavior events will be overriden by view events and or triggers\n _.extend(combinedEvents, behaviorEvents, events, triggers, behaviorTriggers);\n\n Backbone.View.prototype.delegateEvents.call(this, combinedEvents);\n\n return this;\n },\n\n // Handle `modelEvents`, and `collectionEvents` configuration\n delegateEntityEvents: function() {\n this.undelegateEntityEvents();\n\n this.bindEntityEvents(this.model, this.getOption('modelEvents'));\n this.bindEntityEvents(this.collection, this.getOption('collectionEvents'));\n\n _.each(this._behaviors, function(behavior) {\n behavior.bindEntityEvents(this.model, behavior.getOption('modelEvents'));\n behavior.bindEntityEvents(this.collection, behavior.getOption('collectionEvents'));\n }, this);\n\n return this;\n },\n\n // Handle unbinding `modelEvents`, and `collectionEvents` configuration\n undelegateEntityEvents: function() {\n this.unbindEntityEvents(this.model, this.getOption('modelEvents'));\n this.unbindEntityEvents(this.collection, this.getOption('collectionEvents'));\n\n _.each(this._behaviors, function(behavior) {\n behavior.unbindEntityEvents(this.model, behavior.getOption('modelEvents'));\n behavior.unbindEntityEvents(this.collection, behavior.getOption('collectionEvents'));\n }, this);\n\n return this;\n },\n\n // Internal helper method to verify whether the view hasn't been destroyed\n _ensureViewIsIntact: function() {\n if (this._isDestroyed) {\n throw new MarionetteError({\n name: 'ViewDestroyedError',\n message: 'View (cid: \"' + this.cid + '\") has already been destroyed and cannot be used.'\n });\n }\n },\n\n // Handle destroying the view and its children.\n destroy: function() {\n if (this._isDestroyed) { return this; }\n\n var args = _.toArray(arguments);\n\n this.triggerMethod.apply(this, ['before:destroy'].concat(args));\n\n // update lifecycle flags\n this._isDestroyed = true;\n this._isRendered = false;\n\n // unbind UI elements\n this.unbindUIElements();\n\n // remove the view from the DOM\n // https://github.com/jashkenas/backbone/blob/1.2.3/backbone.js#L1235\n this._removeElement();\n\n // remove children after the remove to prevent extra paints\n this._removeChildren();\n // Call destroy on each behavior after\n // destroying the view.\n // This unbinds event listeners\n // that behaviors have registered for.\n _.invoke(this._behaviors, 'destroy', args);\n\n this.triggerMethod.apply(this, ['destroy'].concat(args));\n\n this.stopListening();\n\n return this;\n },\n\n bindUIElements: function() {\n this._bindUIElements();\n _.invoke(this._behaviors, this._bindUIElements);\n },\n\n // This method binds the elements specified in the \"ui\" hash inside the view's code with\n // the associated jQuery selectors.\n _bindUIElements: function() {\n if (!this.ui) { return; }\n\n // store the ui hash in _uiBindings so they can be reset later\n // and so re-rendering the view will be able to find the bindings\n if (!this._uiBindings) {\n this._uiBindings = this.ui;\n }\n\n // get the bindings result, as a function or otherwise\n var bindings = _.result(this, '_uiBindings');\n\n // empty the ui so we don't have anything to start with\n this._ui = {};\n\n // bind each of the selectors\n _.each(bindings, function(selector, key) {\n this._ui[key] = this.$(selector);\n }, this);\n\n this.ui = this._ui;\n },\n\n // This method unbinds the elements specified in the \"ui\" hash\n unbindUIElements: function() {\n this._unbindUIElements();\n _.invoke(this._behaviors, this._unbindUIElements);\n },\n\n _unbindUIElements: function() {\n if (!this.ui || !this._uiBindings) { return; }\n\n // delete all of the existing ui bindings\n _.each(this.ui, function($el, name) {\n delete this.ui[name];\n }, this);\n\n // reset the ui element to the original bindings configuration\n this.ui = this._uiBindings;\n delete this._uiBindings;\n delete this._ui;\n },\n\n getUI: function(name) {\n this._ensureViewIsIntact();\n\n return this._ui[name];\n },\n\n // Internal method to create an event handler for a given `triggerDef` like\n // 'click:foo'\n _buildViewTrigger: function(triggerDef) {\n var options = _.defaults({}, triggerDef, {\n preventDefault: true,\n stopPropagation: true\n });\n\n var eventName = _.isObject(triggerDef) ? options.event : triggerDef;\n\n return function(e) {\n if (e) {\n if (e.preventDefault && options.preventDefault) {\n e.preventDefault();\n }\n\n if (e.stopPropagation && options.stopPropagation) {\n e.stopPropagation();\n }\n }\n\n var args = {\n view: this,\n model: this.model,\n collection: this.collection\n };\n\n this.triggerMethod(eventName, args);\n };\n },\n\n // used as the prefix for child view events\n // that are forwarded through the layoutview\n childViewEventPrefix: 'childview',\n\n // import the `triggerMethod` to trigger events with corresponding\n // methods if the method exists\n triggerMethod: function() {\n var ret = _triggerMethod(this, arguments);\n\n this._triggerEventOnBehaviors(arguments);\n this._triggerEventOnParentLayout(arguments[0], _.rest(arguments));\n\n return ret;\n },\n\n _triggerEventOnBehaviors: function(args) {\n var triggerMethod = _triggerMethod;\n var behaviors = this._behaviors;\n // Use good ol' for as this is a very hot function\n for (var i = 0, length = behaviors && behaviors.length; i < length; i++) {\n triggerMethod(behaviors[i], args);\n }\n },\n\n _triggerEventOnParentLayout: function(eventName, args) {\n var layoutView = this._parentItemView();\n if (!layoutView) {\n return;\n }\n\n // invoke triggerMethod on parent view\n var eventPrefix = getOption(layoutView, 'childViewEventPrefix');\n var prefixedEventName = eventPrefix + ':' + eventName;\n var callArgs = [this].concat(args);\n\n _triggerMethod(layoutView, [prefixedEventName].concat(callArgs));\n\n // call the parent view's childEvents handler\n var childEvents = getOption(layoutView, 'childEvents');\n\n // since childEvents can be an object or a function use Marionette._getValue\n // to handle the abstaction for us.\n childEvents = _getValue(childEvents, layoutView);\n var normalizedChildEvents = layoutView.normalizeMethods(childEvents);\n\n if (!!normalizedChildEvents && _.isFunction(normalizedChildEvents[eventName])) {\n normalizedChildEvents[eventName].apply(layoutView, callArgs);\n }\n },\n\n // Returns an array of every nested view within this view\n _getNestedViews: function() {\n var children = this._getImmediateChildren();\n\n if (!children.length) { return children; }\n\n return _.reduce(children, function(memo, view) {\n if (!view._getNestedViews) { return memo; }\n return memo.concat(view._getNestedViews());\n }, children);\n },\n\n // Walk the _parent tree until we find a view (if one exists).\n // Returns the parent view hierarchically closest to this view.\n _parentItemView: function() {\n var parent = this._parent;\n\n while (parent) {\n if (parent instanceof View) {\n return parent;\n }\n parent = parent._parent;\n }\n },\n\n // Imports the \"normalizeMethods\" to transform hashes of\n // events=>function references/names to a hash of events=>function references\n normalizeMethods: normalizeMethods,\n\n // A handy way to merge passed-in options onto the instance\n mergeOptions: mergeOptions,\n\n // Proxy `getOption` to enable getting options from this or this.options by name.\n getOption: proxyGetOption,\n\n // Proxy `bindEntityEvents` to enable binding view's events from another entity.\n bindEntityEvents: proxyBindEntityEvents,\n\n // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.\n unbindEntityEvents: proxyUnbindEntityEvents\n};\n","import _ from 'underscore';\nimport Region from './region';\nimport _getValue from './utils/_getValue';\nimport MarionetteError from './error';\n\nexport default {\n regionClass: Region,\n\n // Internal method to initialize the regions that have been defined in a\n // `regions` attribute on this View.\n _initRegions: function(options) {\n\n // init regions hash\n this.regions = this.regions || {};\n this._regions = {};\n\n this.addRegions(this.getOption('regions'));\n },\n\n // Internal method to re-initialize all of the regions by updating\n // the `el` that they point to\n _reInitRegions: function() {\n _.invoke(this._regions, 'reset');\n },\n\n // Add a single region, by name, to the View\n addRegion: function(name, definition) {\n var regions = {};\n regions[name] = definition;\n return this.addRegions(regions)[name];\n },\n\n // Add multiple regions as a {name: definition, name2: def2} object literal or\n // a function that evaluates to such literal\n addRegions: function(regions) {\n\n // Enable regions to be a function\n regions = _getValue(regions, this, arguments);\n\n // If there's nothing to add, stop here.\n if (_.isEmpty(regions)) {\n return;\n }\n\n // Normalize region selectors hash to allow\n // a user to use the @ui. syntax.\n regions = this.normalizeUIValues(regions, ['selector', 'el']);\n\n // Add the regions definitions to the regions property\n this.regions = _.extend({}, this.regions, regions);\n\n return this._addRegions(regions);\n },\n\n // internal method to build and add regions\n _addRegions: function(regionDefinitions) {\n regionDefinitions = _getValue(regionDefinitions, this, arguments);\n\n return _.reduce(regionDefinitions, function(regions, definition, name) {\n regions[name] = this._buildRegion(definition);\n this._addRegion(regions[name], name);\n return regions;\n }, {}, this);\n },\n\n // return the region instance from the definition\n _buildRegion: function(definition) {\n if (definition instanceof Region) {\n return definition;\n }\n\n return this._buildRegionFromDefinition(definition);\n },\n\n _buildRegionFromDefinition: function(definition) {\n if (_.isString(definition)) {\n return this._buildRegionFromObject({el: definition});\n }\n\n if (_.isFunction(definition)) {\n return this._buildRegionFromRegionClass(definition);\n }\n\n if (_.isObject(definition)) {\n return this._buildRegionFromObject(definition);\n }\n\n throw new MarionetteError({\n message: 'Improper region configuration type.',\n url: 'marionette.region.html#region-configuration-types'\n });\n },\n\n _buildRegionFromObject: function(definition) {\n var RegionClass = definition.regionClass || this.getOption('regionClass');\n\n var options = _.omit(definition, 'regionClass');\n\n _.defaults(options, {\n el: definition.selector,\n parentEl: _.partial(_.result, this, 'el')\n });\n\n return new RegionClass(options);\n },\n\n // Build the region directly from a given `RegionClass`\n _buildRegionFromRegionClass: function(RegionClass) {\n return new RegionClass({\n parentEl: _.partial(_.result, this, 'el')\n });\n },\n\n _addRegion: function(region, name) {\n this.triggerMethod('before:add:region', name, region);\n\n region._parent = this;\n\n this._regions[name] = region;\n\n this.triggerMethod('add:region', name, region);\n },\n\n // Remove a single region from the View, by name\n removeRegion: function(name) {\n var region = this._regions[name];\n\n this._removeRegion(region, name);\n\n return region;\n },\n\n // Remove all regions from the View\n removeRegions: function() {\n var regions = this.getRegions();\n\n _.each(this._regions, this._removeRegion, this);\n\n return regions;\n },\n\n _removeRegion: function(region, name) {\n this.triggerMethod('before:remove:region', name, region);\n\n region.empty();\n region.stopListening();\n\n delete this.regions[name];\n delete this._regions[name];\n\n this.triggerMethod('remove:region', name, region);\n },\n\n // Empty all regions in the region manager, but\n // leave them attached\n emptyRegions: function() {\n var regions = this.getRegions();\n _.invoke(regions, 'empty');\n return regions;\n },\n\n // Checks to see if view contains region\n // Accepts the region name\n // hasRegion('main')\n hasRegion: function(name) {\n return !!this.getRegion(name);\n },\n\n // Provides access to regions\n // Accepts the region name\n // getRegion('main')\n getRegion: function(name) {\n return this._regions[name];\n },\n\n // Get all regions\n getRegions: function() {\n return _.clone(this._regions);\n },\n\n showChildView: function(name, view, options) {\n var region = this.getRegion(name);\n return region.show.apply(region, _.rest(arguments));\n },\n\n getChildView: function(name) {\n return this.getRegion(name).currentView;\n },\n\n _getImmediateChildren: function() {\n return _.chain(this.getRegions())\n .pluck('currentView')\n .compact()\n .value();\n }\n\n};\n","// View\n// ---------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport ViewMixin from './view-mixin';\nimport RegionsMixin from './regions-mixin';\nimport MonitorDOMRefresh from './dom-refresh';\nimport _getValue from './utils/_getValue';\n\n// The standard view. Includes view events, automatic rendering\n// of Underscore templates, nested views, and more.\nvar View = Backbone.View.extend({\n\n constructor: function(options) {\n this.render = _.bind(this.render, this);\n\n this.options = _.extend({}, _.result(this, 'options'), options);\n\n MonitorDOMRefresh(this);\n\n this._initBehaviors();\n this._initRegions();\n\n Backbone.View.prototype.constructor.call(this, this.options);\n\n this.delegateEntityEvents();\n },\n\n // Serialize the view's model *or* collection, if\n // it exists, for the template\n serializeData: function() {\n if (!this.model && !this.collection) {\n return {};\n }\n\n // If we have a model, we serialize that\n if (this.model) {\n return this.serializeModel();\n }\n\n // Otherwise, we serialize the collection,\n // making it available under the `items` property\n return {\n items: this.serializeCollection()\n };\n },\n\n // Serialize a collection by cloning each of\n // its model's attributes\n serializeCollection: function() {\n if (!this.collection) { return {}; }\n return this.collection.map(function(model) { return _.clone(model.attributes); });\n },\n\n // Render the view, defaulting to underscore.js templates.\n // You can override this in your view definition to provide\n // a very specific rendering for your view. In general, though,\n // you should override the `Marionette.Renderer` object to\n // change how Marionette renders views.\n // Subsequent renders after the first will re-render all nested\n // views.\n render: function() {\n this._ensureViewIsIntact();\n\n this.triggerMethod('before:render', this);\n\n // If this is not the first render call, then we need to\n // re-initialize the `el` for each region\n if (this._isRendered) {\n this._reInitRegions();\n }\n\n this._renderTemplate();\n this._isRendered = true;\n this.bindUIElements();\n\n this.triggerMethod('render', this);\n\n return this;\n },\n\n // Attaches the content of a given view.\n // This method can be overridden to optimize rendering,\n // or to render in a non standard way.\n //\n // For example, using `innerHTML` instead of `$el.html`\n //\n // ```js\n // attachElContent: function(html) {\n // this.el.innerHTML = html;\n // return this;\n // }\n // ```\n attachElContent: function(html) {\n this.$el.html(html);\n\n return this;\n },\n\n // called by ViewMixin destroy\n _removeChildren: function() {\n this.removeRegions();\n }\n});\n\n_.extend(View.prototype, ViewMixin);\n\n_.extend(View.prototype, RegionsMixin);\n\nexport default View;\n","// Collection View\n// ---------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport ChildViewContainer from 'backbone.babysitter';\nimport isNodeAttached from './utils/isNodeAttached';\nimport _getValue from './utils/_getValue';\nimport getOption from './utils/getOption';\nimport MarionetteError from './error';\nimport ViewMixin from './view-mixin';\nimport MonitorDOMRefresh from './dom-refresh';\nimport { triggerMethodMany, triggerMethodOn } from './trigger-method';\n\n// A view that iterates over a Backbone.Collection\n// and renders an individual child view for each model.\nvar CollectionView = Backbone.View.extend({\n\n // flag for maintaining the sorted order of the collection\n sort: true,\n\n // constructor\n // option to pass `{sort: false}` to prevent the `CollectionView` from\n // maintaining the sorted order of the collection.\n // This will fallback onto appending childView's to the end.\n //\n // option to pass `{comparator: compFunction()}` to allow the `CollectionView`\n // to use a custom sort order for the collection.\n constructor: function(options) {\n this.render = _.bind(this.render, this);\n\n this.options = _.extend({}, _.result(this, 'options'), options);\n\n MonitorDOMRefresh(this);\n\n this.on({\n 'before:show': this._onBeforeShowCalled,\n 'show': this._onShowCalled,\n 'before:attach': this._onBeforeAttachCalled,\n 'attach': this._onAttachCalled\n });\n\n this._initBehaviors();\n this.once('render', this._initialEvents);\n this._initChildViewStorage();\n this.initRenderBuffer();\n\n Backbone.View.prototype.constructor.call(this, this.options);\n\n this.delegateEntityEvents();\n },\n\n // Instead of inserting elements one by one into the page,\n // it's much more performant to insert elements into a document\n // fragment and then insert that document fragment into the page\n initRenderBuffer: function() {\n this._bufferedChildren = [];\n },\n\n startBuffering: function() {\n this.initRenderBuffer();\n this.isBuffering = true;\n },\n\n endBuffering: function() {\n // Only trigger attach if already shown and attached, otherwise Region#show() handles this.\n var canTriggerAttach = this._isShown && isNodeAttached(this.el);\n var nestedViews;\n\n this.isBuffering = false;\n\n if (this._isShown) {\n triggerMethodMany(this._bufferedChildren, this, 'before:show');\n }\n if (canTriggerAttach && this._triggerBeforeAttach) {\n nestedViews = this._getNestedViews();\n triggerMethodMany(nestedViews, this, 'before:attach');\n }\n\n this.attachBuffer(this, this._createBuffer());\n\n if (canTriggerAttach && this._triggerAttach) {\n nestedViews = this._getNestedViews();\n triggerMethodMany(nestedViews, this, 'attach');\n }\n if (this._isShown) {\n triggerMethodMany(this._bufferedChildren, this, 'show');\n }\n\n this.initRenderBuffer();\n },\n\n // Configured the initial events that the collection view\n // binds to.\n _initialEvents: function() {\n if (this.collection) {\n this.listenTo(this.collection, 'add', this._onCollectionAdd);\n this.listenTo(this.collection, 'remove', this._onCollectionRemove);\n this.listenTo(this.collection, 'reset', this.render);\n\n if (this.getOption('sort')) {\n this.listenTo(this.collection, 'sort', this._sortViews);\n }\n }\n },\n\n // Handle a child added to the collection\n _onCollectionAdd: function(child, collection, opts) {\n // `index` is present when adding with `at` since BB 1.2; indexOf fallback for < 1.2\n var index = opts.at !== undefined && (opts.index || collection.indexOf(child));\n\n // When filtered or when there is no initial index, calculate index.\n if (this.getOption('filter') || index === false) {\n index = _.indexOf(this._filteredSortedModels(index), child);\n }\n\n if (this._shouldAddChild(child, index)) {\n this.destroyEmptyView();\n var ChildView = this._getChildView(child);\n this.addChild(child, ChildView, index);\n }\n },\n\n // get the child view by model it holds, and remove it\n _onCollectionRemove: function(model) {\n var view = this.children.findByModel(model);\n this.removeChildView(view);\n this.checkEmpty();\n },\n\n _onBeforeShowCalled: function() {\n // Reset attach event flags at the top of the Region#show() event lifecycle; if the Region's\n // show() options permit onBeforeAttach/onAttach events, these flags will be set true again.\n this._triggerBeforeAttach = this._triggerAttach = false;\n this.children.each(function(childView) {\n triggerMethodOn(childView, 'before:show', childView);\n });\n },\n\n _onShowCalled: function() {\n this.children.each(function(childView) {\n triggerMethodOn(childView, 'show', childView);\n });\n },\n\n // If during Region#show() onBeforeAttach was fired, continue firing it for child views\n _onBeforeAttachCalled: function() {\n this._triggerBeforeAttach = true;\n },\n\n // If during Region#show() onAttach was fired, continue firing it for child views\n _onAttachCalled: function() {\n this._triggerAttach = true;\n },\n\n // Render children views. Override this method to\n // provide your own implementation of a render function for\n // the collection view.\n render: function() {\n this._ensureViewIsIntact();\n this.triggerMethod('before:render', this);\n this._renderChildren();\n this._isRendered = true;\n this.triggerMethod('render', this);\n return this;\n },\n\n // An efficient rendering used for filtering. Instead of modifying\n // the whole DOM for the collection view, we are only adding or\n // removing the related childrenViews.\n setFilter: function(filter, options) {\n options = options || {};\n var viewCanBeRendered = this._isRendered && !this._isDestroyed;\n // The same filter or a `prevent` option won't render the filter.\n // Nevertheless, a `prevent` option will modify the value.\n if (!viewCanBeRendered || this.filter === filter) {\n return;\n }\n if (!options.preventRender) {\n this.triggerMethod('before:apply:filter', this);\n this._resolveDeltasForFiltering(filter);\n this.triggerMethod('apply:filter', this);\n } else {\n this.filter = filter;\n }\n },\n\n // `removeFilter` is actually an alias for removing filters.\n removeFilter: function(options) {\n this.setFilter(null, options);\n },\n\n // Calculate the deltas to remove/add the related childrenViews,\n // so you don't need to rebuild the whole DOM.\n _resolveDeltasForFiltering: function(filter) {\n var previousModels = this._filteredSortedModels();\n this.filter = filter;\n var models = this._filteredSortedModels();\n var currentIds = _.pluck(models, 'cid');\n var modelMustBeShown;\n // We resolve the deltas in a different way because we have\n // to respect the sorting algorithm.\n _.each(models, function(model, index) {\n if (!this.children.findByModel(model)) {\n this._onCollectionAdd(model, this.collection, {at: index});\n }\n }, this);\n _.each(previousModels, function(model) {\n modelMustBeShown = _.contains(currentIds, model.cid);\n if (this.children.findByModel(model) && !modelMustBeShown) {\n this._onCollectionRemove(model);\n }\n }, this);\n },\n\n // Reorder DOM after sorting. When your element's rendering\n // do not use their index, you can pass reorderOnSort: true\n // to only reorder the DOM after a sort instead of rendering\n // all the collectionView\n reorder: function() {\n var children = this.children;\n var models = this._filteredSortedModels();\n var anyModelsAdded = _.some(models, function(model) {\n return !children.findByModel(model);\n });\n\n // If there are any new models added due to filtering\n // We need to add child views\n // So render as normal\n if (anyModelsAdded) {\n this.render();\n } else {\n // get the DOM nodes in the same order as the models\n var elsToReorder = _.map(models, function(model, index) {\n var view = children.findByModel(model);\n view._index = index;\n return view.el;\n });\n\n // find the views that were children before but arent in this new ordering\n var filteredOutViews = children.filter(function(view) {\n return !_.contains(elsToReorder, view.el);\n });\n\n this.triggerMethod('before:reorder');\n\n // since append moves elements that are already in the DOM,\n // appending the elements will effectively reorder them\n this._appendReorderedChildren(elsToReorder);\n\n // remove any views that have been filtered out\n _.each(filteredOutViews, this.removeChildView, this);\n this.checkEmpty();\n\n this.triggerMethod('reorder');\n }\n },\n\n // Render view after sorting. Override this method to\n // change how the view renders after a `sort` on the collection.\n resortView: function() {\n if (getOption(this, 'reorderOnSort')) {\n this.reorder();\n } else {\n this._renderChildren();\n }\n },\n\n // Internal method. This checks for any changes in the order of the collection.\n // If the index of any view doesn't match, it will render.\n _sortViews: function() {\n var models = this._filteredSortedModels();\n\n // check for any changes in sort order of views\n var orderChanged = _.find(models, function(item, index) {\n var view = this.children.findByModel(item);\n return !view || view._index !== index;\n }, this);\n\n if (orderChanged) {\n this.resortView();\n }\n },\n\n // Internal reference to what index a `emptyView` is.\n _emptyViewIndex: -1,\n\n // Internal method. Separated so that CompositeView can append to the childViewContainer\n // if necessary\n _appendReorderedChildren: function(children) {\n this.$el.append(children);\n },\n\n // Internal method. Separated so that CompositeView can have\n // more control over events being triggered, around the rendering\n // process\n _renderChildren: function() {\n this.destroyEmptyView();\n this.destroyChildren({checkEmpty: false});\n\n var models = this._filteredSortedModels();\n if (this.isEmpty(this.collection, {processedModels: models})) {\n this.showEmptyView();\n } else {\n this.triggerMethod('before:render:children', this);\n this.startBuffering();\n this.showCollection(models);\n this.endBuffering();\n this.triggerMethod('render:children', this);\n }\n },\n\n // Internal method to loop through collection and show each child view.\n showCollection: function(models) {\n _.each(models, function(child, index) {\n var ChildView = this._getChildView(child);\n this.addChild(child, ChildView, index);\n }, this);\n },\n\n // Allow the collection to be sorted by a custom view comparator\n _filteredSortedModels: function(addedAt) {\n if (!this.collection) { return []; }\n\n var viewComparator = this.getViewComparator();\n var models = this.collection.models;\n addedAt = Math.min(Math.max(addedAt, 0), models.length - 1);\n\n if (viewComparator) {\n var addedModel;\n // Preserve `at` location, even for a sorted view\n if (addedAt) {\n addedModel = models[addedAt];\n models = models.slice(0, addedAt).concat(models.slice(addedAt + 1));\n }\n models = this._sortModelsBy(models, viewComparator);\n if (addedModel) {\n models.splice(addedAt, 0, addedModel);\n }\n }\n\n // Filter after sorting in case the filter uses the index\n models = this._filterModels(models);\n\n return models;\n },\n\n // Filter an array of models, if a filter exists\n _filterModels: function(models) {\n if (this.getOption('filter')) {\n models = _.filter(models, function(model, index) {\n return this._shouldAddChild(model, index);\n }, this);\n }\n return models;\n },\n\n _sortModelsBy: function(models, comparator) {\n if (typeof comparator === 'string') {\n return _.sortBy(models, function(model) {\n return model.get(comparator);\n }, this);\n } else if (comparator.length === 1) {\n return _.sortBy(models, comparator, this);\n } else {\n return models.sort(_.bind(comparator, this));\n }\n },\n\n // Internal method to show an empty view in place of\n // a collection of child views, when the collection is empty\n showEmptyView: function() {\n var EmptyView = this.getEmptyView();\n\n if (EmptyView && !this._showingEmptyView) {\n this._showingEmptyView = true;\n\n var model = new Backbone.Model();\n var emptyViewOptions =\n this.getOption('emptyViewOptions') || this.getOption('childViewOptions');\n if (_.isFunction(emptyViewOptions)) {\n emptyViewOptions = emptyViewOptions.call(this, model, this._emptyViewIndex);\n }\n\n var view = this.buildChildView(model, EmptyView, emptyViewOptions);\n\n this.triggerMethod('before:render:empty', view);\n this._addChildView(view, 0);\n this.triggerMethod('render:empty', view);\n\n view._parent = this;\n }\n },\n\n // Internal method to destroy an existing emptyView instance\n // if one exists. Called when a collection view has been\n // rendered empty, and then a child is added to the collection.\n destroyEmptyView: function() {\n if (this._showingEmptyView) {\n this.triggerMethod('before:remove:empty');\n\n this.destroyChildren();\n delete this._showingEmptyView;\n\n this.triggerMethod('remove:empty');\n }\n },\n\n // Retrieve the empty view class\n getEmptyView: function() {\n return this.getOption('emptyView');\n },\n\n // Retrieve the `childView` class, either from `this.options.childView`\n // or from the `childView` in the object definition. The \"options\"\n // takes precedence.\n // The `childView` property can be either a view class or a function that\n // returns a view class. If it is a function, it will receive the model that\n // will be passed to the view instance (created from the returned view class)\n _getChildView: function(child) {\n var childView = this.getOption('childView');\n\n if (!childView) {\n throw new MarionetteError({\n name: 'NoChildViewError',\n message: 'A \"childView\" must be specified'\n });\n }\n\n // first check if the `childView` is a view class (the common case)\n // then check if it's a function (which we assume that returns a view class)\n if (childView.prototype instanceof Backbone.View || childView === Backbone.View) {\n return childView;\n } else if (_.isFunction(childView)) {\n return childView.call(this, child);\n } else {\n throw new MarionetteError({\n name: 'InvalidChildViewError',\n message: '\"childView\" must be a view class or a function that returns a view class'\n });\n }\n },\n\n // Render the child's view and add it to the\n // HTML for the collection view at a given index.\n // This will also update the indices of later views in the collection\n // in order to keep the children in sync with the collection.\n addChild: function(child, ChildView, index) {\n var childViewOptions = this.getOption('childViewOptions');\n childViewOptions = _getValue(childViewOptions, this, [child, index]);\n\n var view = this.buildChildView(child, ChildView, childViewOptions);\n\n // increment indices of views after this one\n this._updateIndices(view, true, index);\n\n this.triggerMethod('before:add:child', view);\n this._addChildView(view, index);\n this.triggerMethod('add:child', view);\n\n view._parent = this;\n\n return view;\n },\n\n // Internal method. This decrements or increments the indices of views after the\n // added/removed view to keep in sync with the collection.\n _updateIndices: function(view, increment, index) {\n if (!this.getOption('sort')) {\n return;\n }\n\n if (increment) {\n // assign the index to the view\n view._index = index;\n }\n\n // update the indexes of views after this one\n this.children.each(function(laterView) {\n if (laterView._index >= view._index) {\n laterView._index += increment ? 1 : -1;\n }\n });\n },\n\n // Internal Method. Add the view to children and render it at\n // the given index.\n _addChildView: function(view, index) {\n // Only trigger attach if already shown, attached, and not buffering, otherwise endBuffer() or\n // Region#show() handles this.\n var canTriggerAttach = this._isShown && !this.isBuffering && isNodeAttached(this.el);\n var triggerBeforeShow = this._isShown && !this.isBuffering;\n\n var triggerBeforeAttach = canTriggerAttach && this._triggerBeforeAttach;\n var triggerAttach = canTriggerAttach && this._triggerAttach;\n\n // set up the child view event forwarding\n this.proxyChildEvents(view);\n\n // Store the child view itself so we can properly remove and/or destroy it later\n this.children.add(view);\n this._renderChildView(view, index, triggerBeforeShow, triggerBeforeAttach);\n\n if (triggerAttach) {\n var nestedViews = this._getViewAndNested(view);\n triggerMethodMany(nestedViews, this, 'attach');\n }\n if (this._isShown && !this.isBuffering) {\n triggerMethodOn(view, 'show', view);\n }\n },\n\n // render the child view\n _renderChildView: function(view, index, triggerBeforeShow, triggerBeforeAttach) {\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'before:render', view);\n }\n view.render();\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'render', view);\n }\n if (triggerBeforeShow) {\n triggerMethodOn(view, 'before:show', view);\n }\n if (triggerBeforeAttach) {\n var nestedViews = this._getViewAndNested(view);\n triggerMethodMany(nestedViews, this, 'before:attach');\n }\n this.attachHtml(this, view, index);\n return view;\n },\n\n // Build a `childView` for a model in the collection.\n buildChildView: function(child, ChildViewClass, childViewOptions) {\n var options = _.extend({model: child}, childViewOptions);\n var childView = new ChildViewClass(options);\n MonitorDOMRefresh(childView);\n return childView;\n },\n\n // Remove the child view and destroy it.\n // This function also updates the indices of\n // later views in the collection in order to keep\n // the children in sync with the collection.\n removeChildView: function(view) {\n if (!view) { return view; }\n\n this.triggerMethod('before:remove:child', view);\n\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'before:destroy', view);\n }\n // call 'destroy' or 'remove', depending on which is found\n if (view.destroy) {\n view.destroy();\n } else {\n view.remove();\n }\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'destroy', view);\n }\n\n delete view._parent;\n this.stopListening(view);\n this.children.remove(view);\n this.triggerMethod('remove:child', view);\n\n // decrement the index of views after this one\n this._updateIndices(view, false);\n\n return view;\n },\n\n // check if the collection is empty\n // or optionally whether an array of pre-processed models is empty\n isEmpty: function(collection, options) {\n var models;\n if (_.result(options, 'processedModels')) {\n models = options.processedModels;\n } else {\n models = this.collection ? this.collection.models : [];\n models = this._filterModels(models);\n }\n return models.length === 0;\n },\n\n // If empty, show the empty view\n checkEmpty: function() {\n if (this.isEmpty(this.collection)) {\n this.showEmptyView();\n }\n },\n\n // You might need to override this if you've overridden attachHtml\n attachBuffer: function(collectionView, buffer) {\n collectionView.$el.append(buffer);\n },\n\n // Create a fragment buffer from the currently buffered children\n _createBuffer: function() {\n var elBuffer = document.createDocumentFragment();\n _.each(this._bufferedChildren, function(b) {\n elBuffer.appendChild(b.el);\n });\n return elBuffer;\n },\n\n // Append the HTML to the collection's `el`.\n // Override this method to do something other\n // than `.append`.\n attachHtml: function(collectionView, childView, index) {\n if (collectionView.isBuffering) {\n // buffering happens on reset events and initial renders\n // in order to reduce the number of inserts into the\n // document, which are expensive.\n collectionView._bufferedChildren.splice(index, 0, childView);\n } else {\n // If we've already rendered the main collection, append\n // the new child into the correct order if we need to. Otherwise\n // append to the end.\n if (!collectionView._insertBefore(childView, index)) {\n collectionView._insertAfter(childView);\n }\n }\n },\n\n // Internal method. Check whether we need to insert the view into\n // the correct position.\n _insertBefore: function(childView, index) {\n var currentView;\n var findPosition = this.getOption('sort') && (index < this.children.length - 1);\n if (findPosition) {\n // Find the view after this one\n currentView = this.children.find(function(view) {\n return view._index === index + 1;\n });\n }\n\n if (currentView) {\n currentView.$el.before(childView.el);\n return true;\n }\n\n return false;\n },\n\n // Internal method. Append a view to the end of the $el\n _insertAfter: function(childView) {\n this.$el.append(childView.el);\n },\n\n // Internal method to set up the `children` object for\n // storing all of the child views\n _initChildViewStorage: function() {\n this.children = new ChildViewContainer();\n },\n\n // called by ViewMixin destroy\n _removeChildren: function() {\n this.destroyChildren({checkEmpty: false});\n },\n\n // Destroy the child views that this collection view\n // is holding on to, if any\n destroyChildren: function(options) {\n this.triggerMethod('before:destroy:children');\n var destroyOptions = options || {};\n var shouldCheckEmpty = true;\n var childViews = this.children.map(_.identity);\n\n if (typeof destroyOptions.checkEmpty !== 'undefined') {\n shouldCheckEmpty = destroyOptions.checkEmpty;\n }\n\n this.children.each(this.removeChildView, this);\n\n if (shouldCheckEmpty) {\n this.checkEmpty();\n }\n\n this.triggerMethod('destroy:children');\n return childViews;\n },\n\n // Return true if the given child should be shown\n // Return false otherwise\n // The filter will be passed (child, index, collection)\n // Where\n // 'child' is the given model\n // 'index' is the index of that model in the collection\n // 'collection' is the collection referenced by this CollectionView\n _shouldAddChild: function(child, index) {\n var filter = this.getOption('filter');\n return !_.isFunction(filter) || filter.call(this, child, index, this.collection);\n },\n\n // Set up the child view event forwarding. Uses a \"childview:\"\n // prefix in front of all forwarded events.\n proxyChildEvents: function(view) {\n var prefix = this.getOption('childViewEventPrefix');\n\n // Forward all child view events through the parent,\n // prepending \"childview:\" to the event name\n this.listenTo(view, 'all', function() {\n var args = _.toArray(arguments);\n var rootEvent = args[0];\n var childViewEvents = this.normalizeMethods(_.result(this, 'childViewEvents'));\n\n args[0] = prefix + ':' + rootEvent;\n args.splice(1, 0, view);\n\n // call collectionView childViewEvent if defined\n if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[rootEvent])) {\n childViewEvents[rootEvent].apply(this, args.slice(1));\n }\n\n this.triggerMethod.apply(this, args);\n });\n },\n\n _getImmediateChildren: function() {\n return _.values(this.children._views);\n },\n\n _getViewAndNested: function(view) {\n // This will not fail on Backbone.View which does not have #_getNestedViews.\n return [view].concat(_.result(view, '_getNestedViews') || []);\n },\n\n getViewComparator: function() {\n return this.getOption('viewComparator');\n }\n});\n\n_.extend(CollectionView.prototype, ViewMixin);\n\nexport default CollectionView;\n","// Composite View\n// --------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport deprecate from './utils/deprecate';\nimport _getValue from './utils/_getValue';\nimport getOption from './utils/getOption';\nimport MarionetteError from './error';\nimport CollectionView from './collection-view';\n\n// Used for rendering a branch-leaf, hierarchical structure.\n// Extends directly from CollectionView and also renders an\n// a child view as `modelView`, for the top leaf\nvar CompositeView = CollectionView.extend({\n\n // Setting up the inheritance chain which allows changes to\n // Marionette.CollectionView.prototype.constructor which allows overriding\n // option to pass '{sort: false}' to prevent the CompositeView from\n // maintaining the sorted order of the collection.\n // This will fallback onto appending childView's to the end.\n constructor: function() {\n deprecate('CompositeView is deprecated. Convert to View at your earliest convenience');\n CollectionView.prototype.constructor.apply(this, arguments);\n },\n\n // Configured the initial events that the composite view\n // binds to. Override this method to prevent the initial\n // events, or to add your own initial events.\n _initialEvents: function() {\n\n // Bind only after composite view is rendered to avoid adding child views\n // to nonexistent childViewContainer\n\n if (this.collection) {\n this.listenTo(this.collection, 'add', this._onCollectionAdd);\n this.listenTo(this.collection, 'remove', this._onCollectionRemove);\n this.listenTo(this.collection, 'reset', this.renderChildren);\n\n if (this.getOption('sort')) {\n this.listenTo(this.collection, 'sort', this._sortViews);\n }\n }\n },\n\n // Retrieve the `childView` to be used when rendering each of\n // the items in the collection. The default is to return\n // `this.childView` or Marionette.CompositeView if no `childView`\n // has been defined. As happens in CollectionView, `childView` can\n // be a function (which should return a view class).\n _getChildView: function(child) {\n var childView = this.getOption('childView');\n\n // for CompositeView, if `childView` is not specified, we'll get the same\n // composite view class rendered for each child in the collection\n // then check if the `childView` is a view class (the common case)\n // finally check if it's a function (which we assume that returns a view class)\n if (!childView) {\n return this.constructor;\n } else if (childView.prototype instanceof Backbone.View || childView === Backbone.View) {\n return childView;\n } else if (_.isFunction(childView)) {\n return childView.call(this, child);\n } else {\n throw new MarionetteError({\n name: 'InvalidChildViewError',\n message: '\"childView\" must be a view class or a function that returns a view class'\n });\n }\n\n },\n\n // Return the serialized model\n serializeData: function() {\n return this.serializeModel();\n },\n\n // Renders the model and the collection.\n render: function() {\n this._ensureViewIsIntact();\n this._isRendering = true;\n this.resetChildViewContainer();\n\n this.triggerMethod('before:render', this);\n\n this._renderTemplate();\n this.bindUIElements();\n this.renderChildren();\n\n this._isRendering = false;\n this._isRendered = true;\n this.triggerMethod('render', this);\n return this;\n },\n\n renderChildren: function() {\n if (this._isRendered || this._isRendering) {\n CollectionView.prototype._renderChildren.call(this);\n }\n },\n\n // Attaches the content of the root.\n // This method can be overridden to optimize rendering,\n // or to render in a non standard way.\n //\n // For example, using `innerHTML` instead of `$el.html`\n //\n // ```js\n // attachElContent: function(html) {\n // this.el.innerHTML = html;\n // return this;\n // }\n // ```\n attachElContent: function(html) {\n this.$el.html(html);\n\n return this;\n },\n\n // You might need to override this if you've overridden attachHtml\n attachBuffer: function(compositeView, buffer) {\n var $container = this.getChildViewContainer(compositeView);\n $container.append(buffer);\n },\n\n // Internal method. Append a view to the end of the $el.\n // Overidden from CollectionView to ensure view is appended to\n // childViewContainer\n _insertAfter: function(childView) {\n var $container = this.getChildViewContainer(this, childView);\n $container.append(childView.el);\n },\n\n // Internal method. Append reordered childView'.\n // Overidden from CollectionView to ensure reordered views\n // are appended to childViewContainer\n _appendReorderedChildren: function(children) {\n var $container = this.getChildViewContainer(this);\n $container.append(children);\n },\n\n // Internal method to ensure an `$childViewContainer` exists, for the\n // `attachHtml` method to use.\n getChildViewContainer: function(containerView, childView) {\n if (!!containerView.$childViewContainer) {\n return containerView.$childViewContainer;\n }\n\n var container;\n var childViewContainer = getOption(containerView, 'childViewContainer');\n if (childViewContainer) {\n\n var selector = _getValue(childViewContainer, containerView);\n\n if (selector.charAt(0) === '@' && containerView.ui) {\n container = containerView.ui[selector.substr(4)];\n } else {\n container = containerView.$(selector);\n }\n\n if (container.length <= 0) {\n throw new MarionetteError({\n name: 'ChildViewContainerMissingError',\n message: 'The specified \"childViewContainer\" was not found: ' + containerView.childViewContainer\n });\n }\n\n } else {\n container = containerView.$el;\n }\n\n containerView.$childViewContainer = container;\n return container;\n },\n\n // Internal method to reset the `$childViewContainer` on render\n resetChildViewContainer: function() {\n if (this.$childViewContainer) {\n this.$childViewContainer = undefined;\n }\n }\n});\n\nexport default CompositeView;\n","// Behavior\n// --------\n\n// A Behavior is an isolated set of DOM /\n// user interactions that can be mixed into any View.\n// Behaviors allow you to blackbox View specific interactions\n// into portable logical chunks, keeping your views simple and your code DRY.\n\nimport _ from 'underscore';\nimport MNObject from './object';\n\nvar Behavior = MNObject.extend({\n cidPrefix: 'mnb',\n\n constructor: function(options, view) {\n // Setup reference to the view.\n // this comes in handle when a behavior\n // wants to directly talk up the chain\n // to the view.\n this.view = view;\n this.defaults = _.result(this, 'defaults') || {};\n this.options = _.extend({}, this.defaults, options);\n // Construct an internal UI hash using\n // the behaviors UI hash and then the view UI hash.\n // This allows the user to use UI hash elements\n // defined in the parent view as well as those\n // defined in the given behavior.\n // This order will help the reuse and share of a behavior\n // between multiple views, while letting a view override a\n // selector under an UI key.\n this.ui = _.extend({}, _.result(this, 'ui'), _.result(view, 'ui'));\n\n MNObject.apply(this, arguments);\n },\n\n // proxy behavior $ method to the view\n // this is useful for doing jquery DOM lookups\n // scoped to behaviors view.\n $: function() {\n return this.view.$.apply(this.view, arguments);\n },\n\n // Stops the behavior from listening to events.\n // Overrides Object#destroy to prevent additional events from being triggered.\n destroy: function() {\n this.stopListening();\n\n return this;\n },\n\n proxyViewProperties: function(view) {\n this.$el = view.$el;\n this.el = view.el;\n }\n});\n\nexport default Behavior;\n","import Backbone from 'backbone';\nimport {version} from '../package.json';\n\nimport extend from './utils/extend';\nimport isNodeAttached from './utils/isNodeAttached';\nimport mergeOptions from './utils/mergeOptions';\nimport getOption from './utils/getOption';\nimport proxyGetOption from './utils/proxyGetOption';\nimport normalizeMethods from './utils/normalizeMethods';\nimport normalizeUIString from './utils/normalizeUIString';\nimport normalizeUIKeys from './utils/normalizeUIKeys';\nimport normalizeUIValues from './utils/normalizeUIValues';\nimport deprecate from './utils/deprecate';\n\nimport MonitorDOMRefresh from './dom-refresh';\nimport MarionetteObject from './object';\nimport Renderer from './renderer';\nimport TemplateCache from './template-cache';\nimport View from './view';\nimport CollectionView from './collection-view';\nimport CompositeView from './composite-view';\nimport Behavior from './behavior';\nimport Behaviors from './behaviors';\nimport Region from './region';\nimport Application from './application';\nimport AppRouter from './app-router';\nimport MarionetteError from './error';\n\nimport {\n FEATURES,\n isEnabled,\n setEnabled\n} from './features';\n\nimport {\n bindEntityEvents,\n unbindEntityEvents,\n proxyBindEntityEvents,\n proxyUnbindEntityEvents\n} from './bind-entity-events';\n\nimport {\n proxyRadioHandlers,\n unproxyRadioHandlers\n} from './radio-helpers';\n\nimport {\n triggerMethod,\n triggerMethodOn,\n triggerMethodMany\n} from './trigger-method';\n\nvar previousMarionette = Backbone.Marionette;\nvar Marionette = Backbone.Marionette = {};\n\n// This allows you to run multiple instances of Marionette on the same\n// webapp. After loading the new version, call `noConflict()` to\n// get a reference to it. At the same time the old version will be\n// returned to Backbone.Marionette.\nMarionette.noConflict = function() {\n Backbone.Marionette = previousMarionette;\n return this;\n};\n\n// Utilities\nMarionette.bindEntityEvents = bindEntityEvents;\nMarionette.unbindEntityEvents = unbindEntityEvents;\nMarionette.proxyBindEntityEvents = proxyBindEntityEvents;\nMarionette.proxyUnbindEntityEvents = proxyUnbindEntityEvents;\nMarionette.proxyRadioHandlers = proxyRadioHandlers;\nMarionette.unproxyRadioHandlers = unproxyRadioHandlers;\nMarionette.extend = extend;\nMarionette.isNodeAttached = isNodeAttached;\nMarionette.mergeOptions = mergeOptions;\nMarionette.getOption = getOption;\nMarionette.proxyGetOption = proxyGetOption;\nMarionette.normalizeMethods = normalizeMethods;\nMarionette.normalizeUIString = normalizeUIString;\nMarionette.normalizeUIKeys = normalizeUIKeys;\nMarionette.normalizeUIValues = normalizeUIValues;\nMarionette.deprecate = deprecate;\nMarionette.triggerMethod = triggerMethod;\nMarionette.triggerMethodOn = triggerMethodOn;\nMarionette.triggerMethodMany = triggerMethodMany;\nMarionette.isEnabled = isEnabled;\nMarionette.setEnabled = setEnabled;\n\n// Classes\nMarionette.Application = Application;\nMarionette.AppRouter = AppRouter;\nMarionette.MonitorDOMRefresh = MonitorDOMRefresh;\nMarionette.Renderer = Renderer;\nMarionette.TemplateCache = TemplateCache;\nMarionette.View = View;\nMarionette.CollectionView = CollectionView;\nMarionette.CompositeView = CompositeView;\nMarionette.Behavior = Behavior;\nMarionette.Behaviors = Behaviors;\nMarionette.Region = Region;\nMarionette.Error = MarionetteError;\nMarionette.Object = MarionetteObject;\n\n// Configuration\nMarionette.DEV_MODE = false;\nMarionette.FEATURES = FEATURES;\nMarionette.VERSION = version;\n\nexport default Marionette;\n"],"names":["MNObject","normalizeUIKeys","_normalizeUIKeys","normalizeUIValues","_normalizeUIValues"],"mappings":"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","sourceRoot":"/source/"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment