Marionette.Module = function(moduleName, app){
this.moduleName = moduleName;
this._setupInitializersAndFinalizers();
this.startWithParent = true;
this.triggerMethod = Marionette.triggerMethod;
_.extend(Marionette.Module.prototype, Backbone.Events, {
addInitializer: function(callback){
this._initializerCallbacks.add(callback);
addFinalizer: function(callback){
this._finalizerCallbacks.add(callback);
start: function(options){
if (this._isInitialized){ return; }
_.each(this.submodules, function(mod){
if (mod.startWithParent){
this.triggerMethod("before:start", options);
this._initializerCallbacks.run(options, this);
this._isInitialized = true;
this.triggerMethod("start", options);
if (!this._isInitialized){ return; }
this._isInitialized = false;
Marionette.triggerMethod.call(this, "before:stop");
_.each(this.submodules, function(mod){ mod.stop(); });
this._finalizerCallbacks.run(undefined,this);
this._initializerCallbacks.reset();
this._finalizerCallbacks.reset();
Marionette.triggerMethod.call(this, "stop");
addDefinition: function(moduleDefinition, customArgs){
this._runModuleDefinition(moduleDefinition, customArgs);
_runModuleDefinition: function(definition, customArgs){
if (!definition){ return; }
definition.apply(this, args);
_setupInitializersAndFinalizers: function(){
this._initializerCallbacks = new Marionette.Callbacks();
this._finalizerCallbacks = new Marionette.Callbacks();
_.extend(Marionette.Module, {
create: function(app, moduleNames, moduleDefinition){
var customArgs = slice(arguments);
moduleNames = moduleNames.split(".");
var length = moduleNames.length;
var moduleDefinitions = [];
moduleDefinitions[length-1] = moduleDefinition;
_.each(moduleNames, function(moduleName, i){
var parentModule = module;
module = this._getModule(parentModule, moduleName, app);
this._addModuleDefinition(parentModule, module, moduleDefinitions[i], customArgs);
_getModule: function(parentModule, moduleName, app, def, args){
var module = parentModule[moduleName];
module = new Marionette.Module(moduleName, app);
parentModule[moduleName] = module;
parentModule.submodules[moduleName] = module;
_addModuleDefinition: function(parentModule, module, def, args){
} else if (_.isObject(def)){
startWithParent = def.startWithParent;
module.addDefinition(fn, args);
module.startWithParent = module.startWithParent && startWithParent;
if (module.startWithParent && !module.startWithParentIsConfigured){
module.startWithParentIsConfigured = true;
parentModule.addInitializer(function(options){
if (module.startWithParent){