marionette-rails 1.0.0.beta5 → 1.0.0.beta6
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.
- data/vendor/assets/javascripts/backbone.marionette.js +214 -27
- metadata +1 -1
@@ -1,15 +1,192 @@
|
|
1
1
|
/*!
|
2
|
-
* Backbone.Marionette, v1.0.0-
|
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.
|
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
|
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
|
-
|
1161
|
-
|
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
|
-
|
1206
|
-
|
1207
|
-
|
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.
|
1665
|
+
Backbone.Router.prototype.constructor.apply(this, arguments);
|
1666
|
+
this.options = options;
|
1484
1667
|
|
1485
1668
|
if (this.appRoutes){
|
1486
|
-
var controller = this
|
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-
|
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
|
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
|
});
|