marionette-rails 0.9.13 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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