marionette-rails 0.9.13 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- // Backbone.Marionette, v0.9.13
1
+ // Backbone.Marionette, v0.10.0
2
2
  // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
3
3
  // Distributed under MIT license
4
4
  // http://github.com/derickbailey/backbone.marionette
@@ -440,7 +440,14 @@ Marionette.CollectionView = Marionette.View.extend({
440
440
 
441
441
  // Build an `itemView` for every model in the collection.
442
442
  buildItemView: function(item, ItemView){
443
- var itemViewOptions = _.result(this, "itemViewOptions");
443
+ var itemViewOptions;
444
+
445
+ if (_.isFunction(this.itemViewOptions)){
446
+ itemViewOptions = this.itemViewOptions(item);
447
+ } else {
448
+ itemViewOptions = this.itemViewOptions;
449
+ }
450
+
444
451
  var options = _.extend({model: item}, itemViewOptions);
445
452
  var view = new ItemView(options);
446
453
  return view;
@@ -1010,10 +1017,10 @@ Marionette.Module = function(moduleName, app, customArgs){
1010
1017
  this._setupInitializersAndFinalizers();
1011
1018
 
1012
1019
  // store the configuration for this module
1013
- this._config = {};
1014
- this._config.app = app;
1015
- this._config.customArgs = customArgs;
1016
- this._config.definitions = [];
1020
+ this.config = {};
1021
+ this.config.app = app;
1022
+ this.config.customArgs = customArgs;
1023
+ this.config.definitions = [];
1017
1024
 
1018
1025
  // extend this module with an event binder
1019
1026
  var eventBinder = new Marionette.EventBinder();
@@ -1042,16 +1049,16 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
1042
1049
  // Prevent re-start the module
1043
1050
  if (this._isInitialized){ return; }
1044
1051
 
1045
- this._runModuleDefinition();
1052
+ // start the sub-modules (depth-first hierarchy)
1053
+ _.each(this.submodules, function(mod){
1054
+ if (mod.config.options.startWithParent){
1055
+ mod.start(options);
1056
+ }
1057
+ });
1058
+
1059
+ // run the callbacks to "start" the current module
1046
1060
  this._initializerCallbacks.run(options, this);
1047
1061
  this._isInitialized = true;
1048
-
1049
- // start the sub-modules
1050
- if (this.submodules){
1051
- _.each(this.submodules, function(mod){
1052
- mod.start(options);
1053
- });
1054
- }
1055
1062
  },
1056
1063
 
1057
1064
  // Stop this module by running its finalizers and then stop all of
@@ -1061,44 +1068,40 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
1061
1068
  if (!this._isInitialized){ return; }
1062
1069
  this._isInitialized = false;
1063
1070
 
1071
+ // stop the sub-modules; depth-first, to make sure the
1072
+ // sub-modules are stopped / finalized before parents
1073
+ _.each(this.submodules, function(mod){ mod.stop(); });
1074
+
1064
1075
  // run the finalizers
1065
1076
  this._finalizerCallbacks.run();
1066
- // then reset the initializers and finalizers
1067
- this._setupInitializersAndFinalizers();
1068
1077
 
1069
- // stop the sub-modules
1070
- _.each(this.submodules, function(mod){ mod.stop(); });
1078
+ // reset the initializers and finalizers
1079
+ this._initializerCallbacks.reset();
1080
+ this._finalizerCallbacks.reset();
1071
1081
  },
1072
1082
 
1073
1083
  // Configure the module with a definition function and any custom args
1074
1084
  // that are to be passed in to the definition function
1075
1085
  addDefinition: function(moduleDefinition){
1076
- this._config.definitions.push(moduleDefinition);
1086
+ this._runModuleDefinition(moduleDefinition);
1077
1087
  },
1078
1088
 
1079
1089
  // Internal method: run the module definition function with the correct
1080
1090
  // arguments
1081
- _runModuleDefinition: function(){
1082
- if (this._config.definitions.length === 0) { return; }
1091
+ _runModuleDefinition: function(definition){
1092
+ if (!definition){ return; }
1083
1093
 
1084
1094
  // build the correct list of arguments for the module definition
1085
1095
  var args = _.flatten([
1086
1096
  this,
1087
- this._config.app,
1097
+ this.config.app,
1088
1098
  Backbone,
1089
1099
  Marionette,
1090
1100
  $, _,
1091
- this._config.customArgs
1101
+ this.config.customArgs
1092
1102
  ]);
1093
1103
 
1094
- // run the module definition function with the correct args
1095
- var definitionCount = this._config.definitions.length-1;
1096
- for(var i=0; i <= definitionCount; i++){
1097
-
1098
- var definition = this._config.definitions[i];
1099
- definition.apply(this, args);
1100
-
1101
- }
1104
+ definition.apply(this, args);
1102
1105
  },
1103
1106
 
1104
1107
  // Internal method: set up new copies of initializers and finalizers.
@@ -1128,22 +1131,22 @@ _.extend(Marionette.Module, {
1128
1131
  var length = moduleNames.length;
1129
1132
  _.each(moduleNames, function(moduleName, i){
1130
1133
  var isLastModuleInChain = (i === length-1);
1134
+ var isFirstModuleInChain = (i === 0);
1131
1135
 
1132
- // Get an existing module of this name if we have one
1133
- var module = parentModule[moduleName];
1134
- if (!module){
1135
- // Create a new module if we don't have one
1136
- module = new Marionette.Module(moduleName, app, customArgs);
1137
- parentModule[moduleName] = module;
1138
- // store the module on the parent
1139
- parentModule.submodules[moduleName] = module;
1136
+ var module = that._getModuleDefinition(parentModule, moduleName, app, customArgs);
1137
+ module.config.options = that._getModuleOptions(parentModule, moduleDefinition);
1138
+
1139
+ // if it's the first module in the chain, configure it
1140
+ // for auto-start, as specified by the options
1141
+ if (isFirstModuleInChain){
1142
+ that._configureAutoStart(app, module);
1140
1143
  }
1141
1144
 
1142
1145
  // Only add a module definition and initializer when this is
1143
1146
  // the last module in a "parent.child.grandchild" hierarchy of
1144
1147
  // module names
1145
- if (isLastModuleInChain ){
1146
- that._createModuleDefinition(module, moduleDefinition, app);
1148
+ if (isLastModuleInChain && module.config.options.hasDefinition){
1149
+ module.addDefinition(module.config.options.definition);
1147
1150
  }
1148
1151
 
1149
1152
  // Reset the parent module so that the next child
@@ -1155,28 +1158,46 @@ _.extend(Marionette.Module, {
1155
1158
  return parentModule;
1156
1159
  },
1157
1160
 
1158
- _createModuleDefinition: function(module, moduleDefinition, app){
1159
- var moduleOptions = this._getModuleDefinitionOptions(moduleDefinition);
1160
-
1161
- // add the module definition
1162
- if (moduleOptions.definition){
1163
- module.addDefinition(moduleOptions.definition);
1164
- }
1165
-
1166
- if (moduleOptions.startWithApp){
1161
+ _configureAutoStart: function(app, module){
1162
+ // Only add the initializer if it's the first module, and
1163
+ // if it is set to auto-start, and if it has not yet been added
1164
+ if (module.config.options.startWithParent && !module.config.autoStartConfigured){
1167
1165
  // start the module when the app starts
1168
1166
  app.addInitializer(function(options){
1169
1167
  module.start(options);
1170
1168
  });
1171
1169
  }
1170
+
1171
+ // prevent this module from being configured for
1172
+ // auto start again. the first time the module
1173
+ // is defined, determines it's auto-start
1174
+ module.config.autoStartConfigured = true;
1175
+ },
1176
+
1177
+ _getModuleDefinition: function(parentModule, moduleName, app, customArgs){
1178
+ // Get an existing module of this name if we have one
1179
+ var module = parentModule[moduleName];
1180
+
1181
+ if (!module){
1182
+ // Create a new module if we don't have one
1183
+ module = new Marionette.Module(moduleName, app, customArgs);
1184
+ parentModule[moduleName] = module;
1185
+ // store the module on the parent
1186
+ parentModule.submodules[moduleName] = module;
1187
+ }
1188
+
1189
+ return module;
1172
1190
  },
1173
1191
 
1174
- _getModuleDefinitionOptions: function(moduleDefinition){
1192
+ _getModuleOptions: function(parentModule, moduleDefinition){
1175
1193
  // default to starting the module with the app
1176
- var options = { startWithApp: true };
1194
+ var options = {
1195
+ startWithParent: true,
1196
+ hasDefinition: !!moduleDefinition
1197
+ };
1177
1198
 
1178
1199
  // short circuit if we don't have a module definition
1179
- if (!moduleDefinition){ return options; }
1200
+ if (!options.hasDefinition){ return options; }
1180
1201
 
1181
1202
  if (_.isFunction(moduleDefinition)){
1182
1203
  // if the definition is a function, assign it directly
@@ -1185,12 +1206,15 @@ _.extend(Marionette.Module, {
1185
1206
 
1186
1207
  } else {
1187
1208
 
1188
- // the definition is an object. grab the "define" attribute
1189
- // and the "startWithApp" attribute, as set the options
1190
- // appropriately
1209
+ // the definition is an object.
1210
+
1211
+ // grab the "define" attribute
1212
+ options.hasDefinition = !!moduleDefinition.define;
1191
1213
  options.definition = moduleDefinition.define;
1192
- if (moduleDefinition.hasOwnProperty("startWithApp")){
1193
- options.startWithApp = moduleDefinition.startWithApp;
1214
+
1215
+ // grab the "startWithParent" attribute if one exists
1216
+ if (moduleDefinition.hasOwnProperty("startWithParent")){
1217
+ options.startWithParent = moduleDefinition.startWithParent;
1194
1218
  }
1195
1219
  }
1196
1220
 
@@ -1322,8 +1346,8 @@ Marionette.Renderer = {
1322
1346
  // and executing them at a later point in time, using jQuery's
1323
1347
  // `Deferred` object.
1324
1348
  Marionette.Callbacks = function(){
1325
- this.deferred = $.Deferred();
1326
- this.promise = this.deferred.promise();
1349
+ this._deferred = $.Deferred();
1350
+ this._callbacks = [];
1327
1351
  };
1328
1352
 
1329
1353
  _.extend(Marionette.Callbacks.prototype, {
@@ -1332,7 +1356,9 @@ _.extend(Marionette.Callbacks.prototype, {
1332
1356
  // guaranteed to execute, even if they are added after the
1333
1357
  // `run` method is called.
1334
1358
  add: function(callback, contextOverride){
1335
- this.promise.done(function(context, options){
1359
+ this._callbacks.push({cb: callback, ctx: contextOverride});
1360
+
1361
+ this._deferred.done(function(context, options){
1336
1362
  if (contextOverride){ context = contextOverride; }
1337
1363
  callback.call(context, options);
1338
1364
  });
@@ -1342,7 +1368,17 @@ _.extend(Marionette.Callbacks.prototype, {
1342
1368
  // Additional callbacks can be added after this has been run
1343
1369
  // and they will still be executed.
1344
1370
  run: function(options, context){
1345
- this.deferred.resolve(context, options);
1371
+ this._deferred.resolve(context, options);
1372
+ },
1373
+
1374
+ // Resets the list of callbacks to be run, allowing the same list
1375
+ // to be run multiple times - whenever the `run` method is called.
1376
+ reset: function(){
1377
+ var that = this;
1378
+ this._deferred = $.Deferred();
1379
+ _.each(this._callbacks, function(cb){
1380
+ that.add(cb.cb, cb.ctx);
1381
+ });
1346
1382
  }
1347
1383
  });
1348
1384
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 9
8
- - 13
9
- version: 0.9.13
7
+ - 10
8
+ - 0
9
+ version: 0.10.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Godfrey Chan