marionette-rails 1.0.0.beta5 → 1.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +1,192 @@
1
1
  /*!
2
- * Backbone.Marionette, v1.0.0-beta5
2
+ * Backbone.Marionette, v1.0.0-beta6
3
3
  * Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
4
4
  * Distributed under MIT license
5
5
  * http://github.com/marionettejs/backbone.marionette
6
6
  */
7
7
  /*!
8
+ * Includes BabySitter
9
+ * https://github.com/marionettejs/backbone.babysitter/
8
10
  * Includes Wreqr
9
11
  * https://github.com/marionettejs/backbone.wreqr/
10
12
  * Includes EventBinder
11
13
  * https://github.com/marionettejs/backbone.eventbinder/
12
14
  */
15
+ // Backbone.BabySitter, v0.0.3
16
+ // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
17
+ // Distributed under MIT license
18
+ // http://github.com/marionettejs/backbone.babysitter
19
+ // Backbone.ChildViewContainer
20
+ // ---------------------------
21
+ //
22
+ // Provide a container to store, retrieve and
23
+ // shut down child views.
24
+
25
+ Backbone.ChildViewContainer = (function(Backbone, _){
26
+
27
+ // Container Constructor
28
+ // ---------------------
29
+
30
+ var Container = function(options){
31
+ this._views = {};
32
+ this._indexByModel = {};
33
+ this._indexByCollection = {};
34
+ this._indexByCustom = {};
35
+ this._updateLength();
36
+ };
37
+
38
+ // Container Methods
39
+ // -----------------
40
+
41
+ _.extend(Container.prototype, {
42
+
43
+ // Add a view to this container. Stores the view
44
+ // by `cid` and makes it searchable by the model
45
+ // and/or collection of the view. Optionally specify
46
+ // a custom key to store an retrieve the view.
47
+ add: function(view, customIndex){
48
+ var viewCid = view.cid;
49
+
50
+ // store the view
51
+ this._views[viewCid] = view;
52
+
53
+ // index it by model
54
+ if (view.model){
55
+ this._indexByModel[view.model.cid] = viewCid;
56
+ }
57
+
58
+ // index it by collection
59
+ if (view.collection){
60
+ this._indexByCollection[view.collection.cid] = viewCid;
61
+ }
62
+
63
+ // index by custom
64
+ if (customIndex){
65
+ this._indexByCustom[customIndex] = viewCid;
66
+ }
67
+
68
+ this._updateLength();
69
+ },
70
+
71
+ // Find a view by the model that was attached to
72
+ // it. Uses the model's `cid` to find it, and
73
+ // retrieves the view by it's `cid` from the result
74
+ findByModel: function(model){
75
+ var viewCid = this._indexByModel[model.cid];
76
+ return this.findByCid(viewCid);
77
+ },
78
+
79
+ // Find a view by the collection that was attached to
80
+ // it. Uses the collection's `cid` to find it, and
81
+ // retrieves the view by it's `cid` from the result
82
+ findByCollection: function(col){
83
+ var viewCid = this._indexByCollection[col.cid];
84
+ return this.findByCid(viewCid);
85
+ },
86
+
87
+ // Find a view by a custom indexer.
88
+ findByCustom: function(index){
89
+ var viewCid = this._indexByCustom[index];
90
+ return this.findByCid(viewCid);
91
+ },
92
+
93
+ // Find by index. This is not guaranteed to be a
94
+ // stable index.
95
+ findByIndex: function(index){
96
+ return _.values(this._views)[index];
97
+ },
98
+
99
+ // retrieve a view by it's `cid` directly
100
+ findByCid: function(cid){
101
+ return this._views[cid];
102
+ },
103
+
104
+ // Remove a view
105
+ remove: function(view){
106
+ var viewCid = view.cid;
107
+
108
+ // delete model index
109
+ if (view.model){
110
+ delete this._indexByModel[view.model.cid];
111
+ }
112
+
113
+ // delete collection index
114
+ if (view.collection){
115
+ delete this._indexByCollection[view.collection.cid];
116
+ }
117
+
118
+ // delete custom index
119
+ var cust;
120
+
121
+ for (var key in this._indexByCustom){
122
+ if (this._indexByCustom.hasOwnProperty(key)){
123
+ if (this._indexByCustom[key] === viewCid){
124
+ cust = key;
125
+ break;
126
+ }
127
+ }
128
+ }
129
+
130
+ if (cust){
131
+ delete this._indexByCustom[cust];
132
+ }
133
+
134
+ // remove the view from the container
135
+ delete this._views[viewCid];
136
+
137
+ // update the length
138
+ this._updateLength();
139
+ },
140
+
141
+ // Call a method on every view in the container,
142
+ // passing parameters to the call method one at a
143
+ // time, like `function.call`.
144
+ call: function(method, args){
145
+ args = Array.prototype.slice.call(arguments, 1);
146
+ this.apply(method, args);
147
+ },
148
+
149
+ // Apply a method on every view in the container,
150
+ // passing parameters to the call method one at a
151
+ // time, like `function.apply`.
152
+ apply: function(method, args){
153
+ var view;
154
+ _.each(this._views, function(view, key){
155
+ if (_.isFunction(view[method])){
156
+ view[method].apply(view, args);
157
+ }
158
+ });
159
+ },
160
+
161
+ // Update the `.length` attribute on this container
162
+ _updateLength: function(){
163
+ this.length = _.size(this._views);
164
+ }
165
+
166
+ });
167
+
168
+ // Borrowing this code from Backbone.Collection:
169
+ // http://backbonejs.org/docs/backbone.html#section-106
170
+ //
171
+ // Mix in methods from Underscore, for iteration, and other
172
+ // collection related features.
173
+ var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
174
+ 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
175
+ 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
176
+ 'last', 'without', 'isEmpty'];
177
+
178
+ _.each(methods, function(method) {
179
+ Container.prototype[method] = function() {
180
+ var views = _.values(this._views);
181
+ var args = [views].concat(_.toArray(arguments));
182
+ return _[method].apply(_, args);
183
+ };
184
+ });
185
+
186
+ // return the public API
187
+ return Container;
188
+ })(Backbone, _);
189
+
13
190
  // Backbone.EventBinder, v0.1.0
14
191
  // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
15
192
  // Distributed under MIT license
@@ -340,7 +517,7 @@ Marionette.triggerMethod = function(){
340
517
 
341
518
  if (_.isFunction(this[methodName])){
342
519
  args.shift();
343
- this[methodName].apply(this, args);
520
+ return this[methodName].apply(this, args);
344
521
  }
345
522
  };
346
523
 
@@ -562,12 +739,13 @@ Marionette.Renderer = {
562
739
  // modules and routers, and as a mediator for workflow
563
740
  // and coordination of other objects, views, and more.
564
741
  Marionette.Controller = function(options){
742
+ this.triggerMethod = Marionette.triggerMethod;
565
743
  this.options = options || {};
566
744
 
567
745
  Marionette.addEventBinder(this);
568
746
 
569
747
  if (_.isFunction(this.initialize)){
570
- this.initialize(options);
748
+ this.initialize(this.options);
571
749
  }
572
750
  };
573
751
 
@@ -577,7 +755,13 @@ Marionette.Controller.extend = Marionette.extend;
577
755
  // --------------
578
756
 
579
757
  // Ensure it can trigger events with Backbone.Events
580
- _.extend(Marionette.Controller.prototype, Backbone.Events);
758
+ _.extend(Marionette.Controller.prototype, Backbone.Events, {
759
+ close: function(){
760
+ this.unbindAll();
761
+ this.triggerMethod("close");
762
+ this.unbind();
763
+ }
764
+ });
581
765
 
582
766
  // Region
583
767
  // ------
@@ -964,6 +1148,7 @@ Marionette.ItemView = Marionette.View.extend({
964
1148
  Marionette.CollectionView = Marionette.View.extend({
965
1149
  constructor: function(options){
966
1150
  this.initChildViewStorage();
1151
+
967
1152
  Marionette.View.prototype.constructor.apply(this, arguments);
968
1153
  this.initialEvents();
969
1154
  this.onShowCallbacks = new Marionette.Callbacks();
@@ -1106,7 +1291,7 @@ Marionette.CollectionView = Marionette.View.extend({
1106
1291
 
1107
1292
  // Store the child view itself so we can properly
1108
1293
  // remove and/or close it later
1109
- this.storeChild(item, view);
1294
+ this.children.add(view);
1110
1295
  this.triggerMethod("item:added", view);
1111
1296
 
1112
1297
  // Forward all child item view events through the parent,
@@ -1150,15 +1335,20 @@ Marionette.CollectionView = Marionette.View.extend({
1150
1335
 
1151
1336
  // Remove the child view and close it
1152
1337
  removeItemView: function(item){
1153
- var view = this.children[item.cid];
1338
+ var view = this.children.findByModel(item);
1339
+
1154
1340
  if (view){
1155
1341
  var childBinding = this.childBindings[view.cid];
1156
1342
  if (childBinding) {
1157
1343
  this.unbindFrom(childBinding);
1158
1344
  delete this.childBindings[view.cid];
1159
1345
  }
1160
- view.close();
1161
- delete this.children[item.cid];
1346
+
1347
+ if (view.close){
1348
+ view.close();
1349
+ }
1350
+
1351
+ this.children.remove(view);
1162
1352
  }
1163
1353
 
1164
1354
  if (!this.collection || this.collection.length === 0){
@@ -1175,16 +1365,10 @@ Marionette.CollectionView = Marionette.View.extend({
1175
1365
  collectionView.$el.append(itemView.el);
1176
1366
  },
1177
1367
 
1178
- // Store references to all of the child `itemView`
1179
- // instances so they can be managed and cleaned up, later.
1180
- storeChild: function(item, view){
1181
- this.children[item.cid] = view;
1182
- },
1183
-
1184
1368
  // Internal method to set up the `children` object for
1185
1369
  // storing all of the child views
1186
1370
  initChildViewStorage: function(){
1187
- this.children = {};
1371
+ this.children = new Backbone.ChildViewContainer();
1188
1372
  },
1189
1373
 
1190
1374
  // Handle cleanup and other closing needs for
@@ -1202,11 +1386,9 @@ Marionette.CollectionView = Marionette.View.extend({
1202
1386
  // is holding on to, if any
1203
1387
  closeChildren: function(){
1204
1388
  var that = this;
1205
- if (this.children){
1206
- _.each(_.clone(this.children), function(childView){
1207
- that.removeItemView(childView.model);
1208
- });
1209
- }
1389
+ this.children.apply("close");
1390
+ // re-initialize to clean up after ourselves
1391
+ this.initChildViewStorage();
1210
1392
  }
1211
1393
  });
1212
1394
 
@@ -1480,13 +1662,11 @@ Marionette.Layout = Marionette.ItemView.extend({
1480
1662
  Marionette.AppRouter = Backbone.Router.extend({
1481
1663
 
1482
1664
  constructor: function(options){
1483
- Backbone.Router.prototype.constructor.call(this, options);
1665
+ Backbone.Router.prototype.constructor.apply(this, arguments);
1666
+ this.options = options;
1484
1667
 
1485
1668
  if (this.appRoutes){
1486
- var controller = this.controller;
1487
- if (options && options.controller) {
1488
- controller = options.controller;
1489
- }
1669
+ var controller = Marionette.getOption(this, "controller");
1490
1670
  this.processAppRoutes(controller, this.appRoutes);
1491
1671
  }
1492
1672
  },
@@ -1649,12 +1829,19 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
1649
1829
 
1650
1830
  // Start the module, and run all of it's initializers
1651
1831
  start: function(options){
1652
- // Prevent re-start the module
1832
+ // Prevent re-starting a module that is already started
1653
1833
  if (this._isInitialized){ return; }
1654
1834
 
1655
1835
  // start the sub-modules (depth-first hierarchy)
1656
1836
  _.each(this.submodules, function(mod){
1657
- if (mod.config.options.startWithParent){
1837
+ // check to see if we should start the sub-module with this parent
1838
+ var startWithParent = true;
1839
+ if (mod.config && mod.config.options){
1840
+ startWithParent = mod.config.options.startWithParent;
1841
+ }
1842
+
1843
+ // start the sub-module
1844
+ if (startWithParent){
1658
1845
  mod.start(options);
1659
1846
  }
1660
1847
  });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marionette-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta5
4
+ version: 1.0.0.beta6
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors: