Created
November 29, 2015 22:15
-
-
Save paulfalgout/27ca9265f81c7e62390a to your computer and use it in GitHub Desktop.
Mn v3 ES6 build example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"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