marionette-rails 1.0.0.beta6 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/vendor/assets/javascripts/backbone.marionette.js +266 -103
- metadata +1 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* Backbone.Marionette, v1.0.0-
|
2
|
+
* Backbone.Marionette, v1.0.0-rc1
|
3
3
|
* Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
4
4
|
* Distributed under MIT license
|
5
5
|
* http://github.com/marionettejs/backbone.marionette
|
@@ -12,7 +12,7 @@
|
|
12
12
|
* Includes EventBinder
|
13
13
|
* https://github.com/marionettejs/backbone.eventbinder/
|
14
14
|
*/
|
15
|
-
// Backbone.BabySitter, v0.0.
|
15
|
+
// Backbone.BabySitter, v0.0.4
|
16
16
|
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
17
17
|
// Distributed under MIT license
|
18
18
|
// http://github.com/marionettejs/backbone.babysitter
|
@@ -27,12 +27,14 @@ Backbone.ChildViewContainer = (function(Backbone, _){
|
|
27
27
|
// Container Constructor
|
28
28
|
// ---------------------
|
29
29
|
|
30
|
-
var Container = function(
|
30
|
+
var Container = function(initialViews){
|
31
31
|
this._views = {};
|
32
32
|
this._indexByModel = {};
|
33
33
|
this._indexByCollection = {};
|
34
34
|
this._indexByCustom = {};
|
35
35
|
this._updateLength();
|
36
|
+
|
37
|
+
this._addInitialViews(initialViews);
|
36
38
|
};
|
37
39
|
|
38
40
|
// Container Methods
|
@@ -151,18 +153,35 @@ Backbone.ChildViewContainer = (function(Backbone, _){
|
|
151
153
|
// time, like `function.apply`.
|
152
154
|
apply: function(method, args){
|
153
155
|
var view;
|
156
|
+
|
157
|
+
// fix for IE < 9
|
158
|
+
args = args || [];
|
159
|
+
|
154
160
|
_.each(this._views, function(view, key){
|
155
161
|
if (_.isFunction(view[method])){
|
156
162
|
view[method].apply(view, args);
|
157
163
|
}
|
158
164
|
});
|
165
|
+
|
159
166
|
},
|
160
167
|
|
161
168
|
// Update the `.length` attribute on this container
|
162
169
|
_updateLength: function(){
|
163
170
|
this.length = _.size(this._views);
|
164
|
-
}
|
171
|
+
},
|
172
|
+
|
173
|
+
// set up an initial list of views
|
174
|
+
_addInitialViews: function(views){
|
175
|
+
if (!views){ return; }
|
176
|
+
|
177
|
+
var view, i,
|
178
|
+
length = views.length;
|
165
179
|
|
180
|
+
for (i=0; i<length; i++){
|
181
|
+
view = views[i];
|
182
|
+
this.add(view);
|
183
|
+
}
|
184
|
+
}
|
166
185
|
});
|
167
186
|
|
168
187
|
// Borrowing this code from Backbone.Collection:
|
@@ -173,7 +192,7 @@ Backbone.ChildViewContainer = (function(Backbone, _){
|
|
173
192
|
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
|
174
193
|
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
|
175
194
|
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
|
176
|
-
'last', 'without', 'isEmpty'];
|
195
|
+
'last', 'without', 'isEmpty', 'pluck'];
|
177
196
|
|
178
197
|
_.each(methods, function(method) {
|
179
198
|
Container.prototype[method] = function() {
|
@@ -187,7 +206,7 @@ Backbone.ChildViewContainer = (function(Backbone, _){
|
|
187
206
|
return Container;
|
188
207
|
})(Backbone, _);
|
189
208
|
|
190
|
-
// Backbone.EventBinder,
|
209
|
+
// Backbone.EventBinder, v1.0.2
|
191
210
|
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
192
211
|
// Distributed under MIT license
|
193
212
|
// http://github.com/marionettejs/backbone.eventbinder
|
@@ -257,6 +276,10 @@ Backbone.EventBinder = (function(Backbone, _){
|
|
257
276
|
// Use whatever best logic necessary to determine the type
|
258
277
|
// of the supplied object
|
259
278
|
function getHandlerForObject(obj) {
|
279
|
+
if (_.isUndefined(obj) || _.isNull(obj)) {
|
280
|
+
throw new Error("Can't bindTo undefined");
|
281
|
+
}
|
282
|
+
|
260
283
|
if (obj.jquery) { return handlerMap.jquery; }
|
261
284
|
|
262
285
|
return handlerMap["default"];
|
@@ -280,7 +303,8 @@ Backbone.EventBinder = (function(Backbone, _){
|
|
280
303
|
var obj = arguments[0];
|
281
304
|
var handlers = getHandlerForObject(obj);
|
282
305
|
|
283
|
-
var
|
306
|
+
var args = Array.prototype.slice.apply(arguments);
|
307
|
+
var binding = handlers.bindTo.apply(this, args);
|
284
308
|
|
285
309
|
this._eventBindings.push(binding);
|
286
310
|
|
@@ -290,7 +314,9 @@ Backbone.EventBinder = (function(Backbone, _){
|
|
290
314
|
// Unbind from a single binding object. Binding objects are
|
291
315
|
// returned from the `bindTo` method call.
|
292
316
|
unbindFrom: function(binding) {
|
293
|
-
|
317
|
+
var args = Array.prototype.slice.apply(arguments);
|
318
|
+
handlerMap[binding.type].unbindFrom.apply(this, args);
|
319
|
+
|
294
320
|
this._eventBindings = _.reject(this._eventBindings, function(bind){return bind === binding;});
|
295
321
|
},
|
296
322
|
|
@@ -306,7 +332,7 @@ Backbone.EventBinder = (function(Backbone, _){
|
|
306
332
|
return EventBinder;
|
307
333
|
})(Backbone, _);
|
308
334
|
|
309
|
-
// Backbone.Wreqr, v0.
|
335
|
+
// Backbone.Wreqr, v0.1.0
|
310
336
|
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
311
337
|
// Distributed under MIT license
|
312
338
|
// http://github.com/marionettejs/backbone.wreqr
|
@@ -314,9 +340,16 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
314
340
|
"option strict";
|
315
341
|
var Wreqr = {};
|
316
342
|
|
343
|
+
// Handlers
|
344
|
+
// --------
|
345
|
+
// A registry of functions to call, given a name
|
346
|
+
|
317
347
|
Wreqr.Handlers = (function(Backbone, _){
|
318
348
|
"option strict";
|
319
349
|
|
350
|
+
// Constructor
|
351
|
+
// -----------
|
352
|
+
|
320
353
|
var Handlers = function(){
|
321
354
|
"use strict";
|
322
355
|
this._handlers = {};
|
@@ -324,7 +357,13 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
324
357
|
|
325
358
|
Handlers.extend = Backbone.Model.extend;
|
326
359
|
|
360
|
+
// Instance Members
|
361
|
+
// ----------------
|
362
|
+
|
327
363
|
_.extend(Handlers.prototype, {
|
364
|
+
|
365
|
+
// Add a handler for the given name, with an
|
366
|
+
// optional context to run the handler within
|
328
367
|
addHandler: function(name, handler, context){
|
329
368
|
var config = {
|
330
369
|
callback: handler,
|
@@ -334,6 +373,9 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
334
373
|
this._handlers[name] = config;
|
335
374
|
},
|
336
375
|
|
376
|
+
// Get the currently registered handler for
|
377
|
+
// the specified name. Throws an exception if
|
378
|
+
// no handler is found.
|
337
379
|
getHandler: function(name){
|
338
380
|
var config = this._handlers[name];
|
339
381
|
|
@@ -342,14 +384,17 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
342
384
|
}
|
343
385
|
|
344
386
|
return function(){
|
345
|
-
|
387
|
+
var args = Array.prototype.slice.apply(arguments);
|
388
|
+
return config.callback.apply(config.context, args);
|
346
389
|
};
|
347
390
|
},
|
348
391
|
|
392
|
+
// Remove a handler for the specified name
|
349
393
|
removeHandler: function(name){
|
350
394
|
delete this._handlers[name];
|
351
395
|
},
|
352
396
|
|
397
|
+
// Remove all handlers from this registry
|
353
398
|
removeAllHandlers: function(){
|
354
399
|
this._handlers = {};
|
355
400
|
}
|
@@ -367,8 +412,11 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
367
412
|
"option strict";
|
368
413
|
|
369
414
|
return Wreqr.Handlers.extend({
|
370
|
-
execute: function(
|
371
|
-
|
415
|
+
execute: function(){
|
416
|
+
var name = arguments[0];
|
417
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
418
|
+
|
419
|
+
this.getHandler(name).apply(this, args);
|
372
420
|
}
|
373
421
|
});
|
374
422
|
|
@@ -383,8 +431,11 @@ Backbone.Wreqr = (function(Backbone, Marionette, _){
|
|
383
431
|
"option strict";
|
384
432
|
|
385
433
|
return Wreqr.Handlers.extend({
|
386
|
-
request: function(
|
387
|
-
|
434
|
+
request: function(){
|
435
|
+
var name = arguments[0];
|
436
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
437
|
+
|
438
|
+
return this.getHandler(name).apply(this, args);
|
388
439
|
}
|
389
440
|
});
|
390
441
|
|
@@ -513,7 +564,7 @@ Marionette.triggerMethod = function(){
|
|
513
564
|
methodName += capLetter + segment.slice(1);
|
514
565
|
}
|
515
566
|
|
516
|
-
this.trigger.apply(this,
|
567
|
+
this.trigger.apply(this, args);
|
517
568
|
|
518
569
|
if (_.isFunction(this[methodName])){
|
519
570
|
args.shift();
|
@@ -526,17 +577,7 @@ Marionette.triggerMethod = function(){
|
|
526
577
|
// -----------
|
527
578
|
// Import the event binder from it's new home
|
528
579
|
// https://github.com/marionettejs/backbone.eventbinder
|
529
|
-
Marionette.EventBinder = Backbone.EventBinder.extend(
|
530
|
-
|
531
|
-
augment: function(target){
|
532
|
-
var eventBinder = new Marionette.EventBinder();
|
533
|
-
target.eventBinder = eventBinder;
|
534
|
-
target.bindTo = _.bind(eventBinder.bindTo, eventBinder);
|
535
|
-
target.unbindFrom = _.bind(eventBinder.unbindFrom, eventBinder);
|
536
|
-
target.unbindAll = _.bind(eventBinder.unbindAll, eventBinder);
|
537
|
-
}
|
538
|
-
|
539
|
-
});
|
580
|
+
Marionette.EventBinder = Backbone.EventBinder.extend();
|
540
581
|
|
541
582
|
// Add the EventBinder methods to the view directly,
|
542
583
|
// but keep them bound to the EventBinder instance so they work properly.
|
@@ -547,7 +588,15 @@ Marionette.EventBinder = Backbone.EventBinder.extend({
|
|
547
588
|
Marionette.addEventBinder = function(target){
|
548
589
|
var eventBinder = new Marionette.EventBinder();
|
549
590
|
target.eventBinder = eventBinder;
|
550
|
-
|
591
|
+
|
592
|
+
target.bindTo = function(source, event, callback, context){
|
593
|
+
// check the context of the bindTo and set it to the object
|
594
|
+
// that is having the eventBinder attached to it, if no context
|
595
|
+
// has been specified in the .bindTo call
|
596
|
+
context = context || target;
|
597
|
+
eventBinder.bindTo(source, event, callback, context);
|
598
|
+
};
|
599
|
+
|
551
600
|
target.unbindFrom = _.bind(eventBinder.unbindFrom, eventBinder);
|
552
601
|
target.unbindAll = _.bind(eventBinder.unbindAll, eventBinder);
|
553
602
|
};
|
@@ -563,11 +612,70 @@ Marionette.EventAggregator = Backbone.Wreqr.EventAggregator.extend({
|
|
563
612
|
|
564
613
|
constructor: function(){
|
565
614
|
Marionette.addEventBinder(this);
|
566
|
-
|
615
|
+
|
616
|
+
var args = Array.prototype.slice.apply(arguments);
|
617
|
+
Backbone.Wreqr.EventAggregator.prototype.constructor.apply(this, args);
|
567
618
|
}
|
568
619
|
|
569
620
|
});
|
570
621
|
|
622
|
+
// Marionette.bindEntityEvents
|
623
|
+
// ---------------------------
|
624
|
+
//
|
625
|
+
// This method is used to bind a backbone "entity" (collection/model)
|
626
|
+
// to methods on a target object.
|
627
|
+
//
|
628
|
+
// The first paremter, `target`, must have a `bindTo` method from the
|
629
|
+
// EventBinder object.
|
630
|
+
//
|
631
|
+
// The second parameter is the entity (Backbone.Model or Backbone.Collection)
|
632
|
+
// to bind the events from.
|
633
|
+
//
|
634
|
+
// The third parameter is a hash of { "event:name": "eventHandler" }
|
635
|
+
// configuration. Multiple handlers can be separated by a space. A
|
636
|
+
// function can be supplied instead of a string handler name.
|
637
|
+
Marionette.bindEntityEvents = (function(){
|
638
|
+
|
639
|
+
// Bind the event to handlers specified as a string of
|
640
|
+
// handler names on the target object
|
641
|
+
function bindFromStrings(target, entity, evt, methods){
|
642
|
+
var methodNames = methods.split(/\s+/);
|
643
|
+
|
644
|
+
_.each(methodNames,function(methodName) {
|
645
|
+
|
646
|
+
var method = target[methodName];
|
647
|
+
if(!method) {
|
648
|
+
throw new Error("Method '"+ methodName +"' was configured as an event handler, but does not exist.");
|
649
|
+
}
|
650
|
+
|
651
|
+
target.bindTo(entity, evt, method, target);
|
652
|
+
});
|
653
|
+
}
|
654
|
+
|
655
|
+
// Bind the event to a supplied callback function
|
656
|
+
function bindToFunction(target, entity, evt, method){
|
657
|
+
target.bindTo(entity, evt, method, target);
|
658
|
+
}
|
659
|
+
|
660
|
+
// Export the bindEntityEvents method
|
661
|
+
return function(target, entity, bindings){
|
662
|
+
if (!entity || !bindings) { return; }
|
663
|
+
|
664
|
+
_.each(bindings, function(methods, evt){
|
665
|
+
|
666
|
+
// allow for a function as the handler,
|
667
|
+
// or a list of event names as a string
|
668
|
+
if (_.isFunction(methods)){
|
669
|
+
bindToFunction(target, entity, evt, methods);
|
670
|
+
} else {
|
671
|
+
bindFromStrings(target, entity, evt, methods);
|
672
|
+
}
|
673
|
+
|
674
|
+
});
|
675
|
+
};
|
676
|
+
})();
|
677
|
+
|
678
|
+
|
571
679
|
// Callbacks
|
572
680
|
// ---------
|
573
681
|
|
@@ -653,11 +761,12 @@ _.extend(Marionette.TemplateCache, {
|
|
653
761
|
// `clear("#t1", "#t2", "...")`
|
654
762
|
clear: function(){
|
655
763
|
var i;
|
656
|
-
var
|
764
|
+
var args = Array.prototype.slice.apply(arguments);
|
765
|
+
var length = args.length;
|
657
766
|
|
658
767
|
if (length > 0){
|
659
768
|
for(i=0; i<length; i++){
|
660
|
-
delete this.templateCaches[
|
769
|
+
delete this.templateCaches[args[i]];
|
661
770
|
}
|
662
771
|
} else {
|
663
772
|
this.templateCaches = {};
|
@@ -783,7 +892,8 @@ Marionette.Region = function(options){
|
|
783
892
|
}
|
784
893
|
|
785
894
|
if (this.initialize){
|
786
|
-
|
895
|
+
var args = Array.prototype.slice.apply(arguments);
|
896
|
+
this.initialize.apply(this, args);
|
787
897
|
}
|
788
898
|
};
|
789
899
|
|
@@ -940,10 +1050,11 @@ Marionette.View = Backbone.View.extend({
|
|
940
1050
|
_.bindAll(this, "render");
|
941
1051
|
Marionette.addEventBinder(this);
|
942
1052
|
|
943
|
-
|
1053
|
+
var args = Array.prototype.slice.apply(arguments);
|
1054
|
+
Backbone.View.prototype.constructor.apply(this, args);
|
944
1055
|
|
945
|
-
|
946
|
-
|
1056
|
+
Marionette.bindEntityEvents(this, this.model, Marionette.getOption(this, "modelEvents"));
|
1057
|
+
Marionette.bindEntityEvents(this, this.collection, Marionette.getOption(this, "collectionEvents"));
|
947
1058
|
|
948
1059
|
this.bindTo(this, "show", this.onShowCalled, this);
|
949
1060
|
},
|
@@ -1023,13 +1134,17 @@ Marionette.View = Backbone.View.extend({
|
|
1023
1134
|
close: function(){
|
1024
1135
|
if (this.isClosed) { return; }
|
1025
1136
|
|
1026
|
-
this.triggerMethod("before:close");
|
1137
|
+
var shouldClose = this.triggerMethod("before:close");
|
1138
|
+
if (shouldClose === false){
|
1139
|
+
return;
|
1140
|
+
}
|
1027
1141
|
|
1028
1142
|
this.remove();
|
1029
|
-
this.unbindAll();
|
1030
1143
|
|
1031
1144
|
this.triggerMethod("close");
|
1032
1145
|
this.isClosed = true;
|
1146
|
+
|
1147
|
+
this.unbindAll();
|
1033
1148
|
},
|
1034
1149
|
|
1035
1150
|
// This method binds the elements specified in the "ui" hash inside the view's code with
|
@@ -1051,22 +1166,6 @@ Marionette.View = Backbone.View.extend({
|
|
1051
1166
|
var selector = that.uiBindings[key];
|
1052
1167
|
that.ui[key] = that.$(selector);
|
1053
1168
|
});
|
1054
|
-
},
|
1055
|
-
|
1056
|
-
// This method is used to bind a backbone "entity" (collection/model) to methods on the view.
|
1057
|
-
bindBackboneEntityTo: function(entity, bindings){
|
1058
|
-
if (!entity || !bindings) { return; }
|
1059
|
-
|
1060
|
-
var view = this;
|
1061
|
-
_.each(bindings, function(methodName, evt){
|
1062
|
-
|
1063
|
-
var method = view[methodName];
|
1064
|
-
if(!method) {
|
1065
|
-
throw new Error("View method '"+ methodName +"' was configured as an event handler, but does not exist.");
|
1066
|
-
}
|
1067
|
-
|
1068
|
-
view.bindTo(entity, evt, method, view);
|
1069
|
-
});
|
1070
1169
|
}
|
1071
1170
|
});
|
1072
1171
|
|
@@ -1078,11 +1177,35 @@ Marionette.View = Backbone.View.extend({
|
|
1078
1177
|
// and calling several methods on extended views, such as `onRender`.
|
1079
1178
|
Marionette.ItemView = Marionette.View.extend({
|
1080
1179
|
constructor: function(){
|
1081
|
-
|
1180
|
+
var args = Array.prototype.slice.apply(arguments);
|
1181
|
+
Marionette.View.prototype.constructor.apply(this, args);
|
1082
1182
|
|
1083
1183
|
if (this.initialEvents){
|
1084
1184
|
this.initialEvents();
|
1085
1185
|
}
|
1186
|
+
|
1187
|
+
this.bindTo(this, "show", this._handleShow, this);
|
1188
|
+
this.bindTo(this, "render", this._handleRender, this);
|
1189
|
+
},
|
1190
|
+
|
1191
|
+
// internal event handler to track when the view has been rendered
|
1192
|
+
_handleShow: function(){
|
1193
|
+
this._isShown = true;
|
1194
|
+
this.triggerDOMRefresh();
|
1195
|
+
},
|
1196
|
+
|
1197
|
+
// internal event handler to track when the view has been shown in the DOM,
|
1198
|
+
// using a Marionette.Region (or by other means of triggering "show")
|
1199
|
+
_handleRender: function(){
|
1200
|
+
this._isRendered = true;
|
1201
|
+
this.triggerDOMRefresh();
|
1202
|
+
},
|
1203
|
+
|
1204
|
+
// Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
|
1205
|
+
triggerDOMRefresh: function(){
|
1206
|
+
if (this._isShown && this._isRendered){
|
1207
|
+
this.triggerMethod("dom:refresh");
|
1208
|
+
}
|
1086
1209
|
},
|
1087
1210
|
|
1088
1211
|
// Serialize the model or collection for the view. If a model is
|
@@ -1135,7 +1258,10 @@ Marionette.ItemView = Marionette.View.extend({
|
|
1135
1258
|
if (this.isClosed){ return; }
|
1136
1259
|
|
1137
1260
|
this.triggerMethod('item:before:close');
|
1138
|
-
|
1261
|
+
|
1262
|
+
var args = Array.prototype.slice.apply(arguments);
|
1263
|
+
Marionette.View.prototype.close.apply(this, args);
|
1264
|
+
|
1139
1265
|
this.triggerMethod('item:closed');
|
1140
1266
|
}
|
1141
1267
|
});
|
@@ -1146,16 +1272,19 @@ Marionette.ItemView = Marionette.View.extend({
|
|
1146
1272
|
// A view that iterates over a Backbone.Collection
|
1147
1273
|
// and renders an individual ItemView for each model.
|
1148
1274
|
Marionette.CollectionView = Marionette.View.extend({
|
1275
|
+
// used as the prefix for item view events
|
1276
|
+
// that are forwarded through the collectionview
|
1277
|
+
itemViewEventPrefix: "itemview",
|
1278
|
+
|
1279
|
+
// constructor
|
1149
1280
|
constructor: function(options){
|
1150
1281
|
this.initChildViewStorage();
|
1151
1282
|
|
1152
|
-
|
1283
|
+
var args = Array.prototype.slice.apply(arguments);
|
1284
|
+
Marionette.View.prototype.constructor.apply(this, args);
|
1285
|
+
|
1153
1286
|
this.initialEvents();
|
1154
1287
|
this.onShowCallbacks = new Marionette.Callbacks();
|
1155
|
-
|
1156
|
-
if (options && options.itemViewOptions) {
|
1157
|
-
this.itemViewOptions = options.itemViewOptions;
|
1158
|
-
}
|
1159
1288
|
},
|
1160
1289
|
|
1161
1290
|
// Configured the initial events that the collection view
|
@@ -1279,45 +1408,54 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1279
1408
|
var that = this;
|
1280
1409
|
|
1281
1410
|
// get the itemViewOptions if any were specified
|
1282
|
-
var itemViewOptions;
|
1283
|
-
if (_.isFunction(
|
1284
|
-
itemViewOptions =
|
1285
|
-
} else {
|
1286
|
-
itemViewOptions = this.itemViewOptions;
|
1411
|
+
var itemViewOptions = Marionette.getOption(this, "itemViewOptions");
|
1412
|
+
if (_.isFunction(itemViewOptions)){
|
1413
|
+
itemViewOptions = itemViewOptions.call(this, item);
|
1287
1414
|
}
|
1288
1415
|
|
1289
1416
|
// build the view
|
1290
1417
|
var view = this.buildItemView(item, ItemView, itemViewOptions);
|
1418
|
+
|
1419
|
+
// set up the child view event forwarding
|
1420
|
+
this.addChildViewEventForwarding(view);
|
1291
1421
|
|
1292
1422
|
// Store the child view itself so we can properly
|
1293
1423
|
// remove and/or close it later
|
1294
1424
|
this.children.add(view);
|
1425
|
+
|
1426
|
+
// Render it and show it
|
1427
|
+
var renderResult = this.renderItemView(view, index);
|
1428
|
+
|
1429
|
+
// let the world know this view was added
|
1295
1430
|
this.triggerMethod("item:added", view);
|
1296
1431
|
|
1432
|
+
// call onShow for child item views
|
1433
|
+
if (view.onShow){
|
1434
|
+
this.onShowCallbacks.add(view.onShow, view);
|
1435
|
+
}
|
1436
|
+
|
1437
|
+
return renderResult;
|
1438
|
+
},
|
1439
|
+
|
1440
|
+
// Set up the child view event forwarding. Uses an "itemview:"
|
1441
|
+
// prefix in front of all forwarded events.
|
1442
|
+
addChildViewEventForwarding: function(view){
|
1443
|
+
var prefix = Marionette.getOption(this, "itemViewEventPrefix");
|
1444
|
+
|
1297
1445
|
// Forward all child item view events through the parent,
|
1298
1446
|
// prepending "itemview:" to the event name
|
1299
1447
|
var childBinding = this.bindTo(view, "all", function(){
|
1300
1448
|
var args = slice.call(arguments);
|
1301
|
-
args[0] = "
|
1449
|
+
args[0] = prefix + ":" + args[0];
|
1302
1450
|
args.splice(1, 0, view);
|
1303
1451
|
|
1304
|
-
|
1305
|
-
});
|
1452
|
+
this.triggerMethod.apply(this, args);
|
1453
|
+
}, this);
|
1306
1454
|
|
1307
1455
|
// Store all child event bindings so we can unbind
|
1308
1456
|
// them when removing / closing the child view
|
1309
|
-
this.
|
1310
|
-
this.
|
1311
|
-
|
1312
|
-
// Render it and show it
|
1313
|
-
var renderResult = this.renderItemView(view, index);
|
1314
|
-
|
1315
|
-
// call onShow for child item views
|
1316
|
-
if (view.onShow){
|
1317
|
-
this.onShowCallbacks.add(view.onShow, view);
|
1318
|
-
}
|
1319
|
-
|
1320
|
-
return renderResult;
|
1457
|
+
this._childBindings = this._childBindings || {};
|
1458
|
+
this._childBindings[view.cid] = childBinding;
|
1321
1459
|
},
|
1322
1460
|
|
1323
1461
|
// render the item view
|
@@ -1338,10 +1476,10 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1338
1476
|
var view = this.children.findByModel(item);
|
1339
1477
|
|
1340
1478
|
if (view){
|
1341
|
-
var childBinding = this.
|
1479
|
+
var childBinding = this._childBindings[view.cid];
|
1342
1480
|
if (childBinding) {
|
1343
1481
|
this.unbindFrom(childBinding);
|
1344
|
-
delete this.
|
1482
|
+
delete this._childBindings[view.cid];
|
1345
1483
|
}
|
1346
1484
|
|
1347
1485
|
if (view.close){
|
@@ -1379,7 +1517,9 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1379
1517
|
this.triggerMethod("collection:before:close");
|
1380
1518
|
this.closeChildren();
|
1381
1519
|
this.triggerMethod("collection:closed");
|
1382
|
-
|
1520
|
+
|
1521
|
+
var args = Array.prototype.slice.apply(arguments);
|
1522
|
+
Marionette.View.prototype.close.apply(this, args);
|
1383
1523
|
},
|
1384
1524
|
|
1385
1525
|
// Close the child views that this collection view
|
@@ -1401,7 +1541,9 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
1401
1541
|
// an item view as `modelView`, for the top leaf
|
1402
1542
|
Marionette.CompositeView = Marionette.CollectionView.extend({
|
1403
1543
|
constructor: function(options){
|
1404
|
-
|
1544
|
+
var args = Array.prototype.slice.apply(arguments);
|
1545
|
+
Marionette.CollectionView.apply(this, args);
|
1546
|
+
|
1405
1547
|
this.itemView = this.getItemView();
|
1406
1548
|
},
|
1407
1549
|
|
@@ -1470,7 +1612,9 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
1470
1612
|
|
1471
1613
|
// Render the collection for the composite view
|
1472
1614
|
renderCollection: function(){
|
1473
|
-
|
1615
|
+
var args = Array.prototype.slice.apply(arguments);
|
1616
|
+
Marionette.CollectionView.prototype.render.apply(this, args);
|
1617
|
+
|
1474
1618
|
this.triggerMethod("composite:collection:rendered");
|
1475
1619
|
},
|
1476
1620
|
|
@@ -1547,7 +1691,9 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1547
1691
|
constructor: function () {
|
1548
1692
|
this._firstRender = true;
|
1549
1693
|
this.initializeRegions();
|
1550
|
-
|
1694
|
+
|
1695
|
+
var args = Array.prototype.slice.apply(arguments);
|
1696
|
+
Backbone.Marionette.ItemView.apply(this, args);
|
1551
1697
|
},
|
1552
1698
|
|
1553
1699
|
// Layout's render will use the existing region objects the
|
@@ -1567,7 +1713,9 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1567
1713
|
this.reInitializeRegions();
|
1568
1714
|
}
|
1569
1715
|
|
1570
|
-
var
|
1716
|
+
var args = Array.prototype.slice.apply(arguments);
|
1717
|
+
var result = Marionette.ItemView.prototype.render.apply(this, args);
|
1718
|
+
|
1571
1719
|
return result;
|
1572
1720
|
},
|
1573
1721
|
|
@@ -1577,7 +1725,9 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1577
1725
|
|
1578
1726
|
this.closeRegions();
|
1579
1727
|
this.destroyRegions();
|
1580
|
-
|
1728
|
+
|
1729
|
+
var args = Array.prototype.slice.apply(arguments);
|
1730
|
+
Backbone.Marionette.ItemView.prototype.close.apply(this, args);
|
1581
1731
|
},
|
1582
1732
|
|
1583
1733
|
// Initialize the regions that have been defined in a
|
@@ -1662,7 +1812,9 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
1662
1812
|
Marionette.AppRouter = Backbone.Router.extend({
|
1663
1813
|
|
1664
1814
|
constructor: function(options){
|
1665
|
-
|
1815
|
+
var args = Array.prototype.slice.apply(arguments);
|
1816
|
+
Backbone.Router.prototype.constructor.apply(this, args);
|
1817
|
+
|
1666
1818
|
this.options = options;
|
1667
1819
|
|
1668
1820
|
if (this.appRoutes){
|
@@ -1728,12 +1880,14 @@ Marionette.Application = function(options){
|
|
1728
1880
|
_.extend(Marionette.Application.prototype, Backbone.Events, {
|
1729
1881
|
// Command execution, facilitated by Backbone.Wreqr.Commands
|
1730
1882
|
execute: function(){
|
1731
|
-
|
1883
|
+
var args = Array.prototype.slice.apply(arguments);
|
1884
|
+
this.commands.execute.apply(this.commands, args);
|
1732
1885
|
},
|
1733
1886
|
|
1734
1887
|
// Request/response, facilitated by Backbone.Wreqr.RequestResponse
|
1735
1888
|
request: function(){
|
1736
|
-
|
1889
|
+
var args = Array.prototype.slice.apply(arguments);
|
1890
|
+
return this.reqres.request.apply(this.reqres, args);
|
1737
1891
|
},
|
1738
1892
|
|
1739
1893
|
// Add an initializer that is either run at when the `start`
|
@@ -1808,6 +1962,7 @@ Marionette.Module = function(moduleName, app){
|
|
1808
1962
|
|
1809
1963
|
// extend this module with an event binder
|
1810
1964
|
Marionette.addEventBinder(this);
|
1965
|
+
this.triggerMethod = Marionette.triggerMethod;
|
1811
1966
|
};
|
1812
1967
|
|
1813
1968
|
// Extend the Module prototype with events / bindTo, so that the module
|
@@ -1847,8 +2002,12 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1847
2002
|
});
|
1848
2003
|
|
1849
2004
|
// run the callbacks to "start" the current module
|
2005
|
+
this.triggerMethod("before:start", options);
|
2006
|
+
|
1850
2007
|
this._initializerCallbacks.run(options, this);
|
1851
2008
|
this._isInitialized = true;
|
2009
|
+
|
2010
|
+
this.triggerMethod("start", options);
|
1852
2011
|
},
|
1853
2012
|
|
1854
2013
|
// Stop this module by running its finalizers and then stop all of
|
@@ -1858,6 +2017,8 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1858
2017
|
if (!this._isInitialized){ return; }
|
1859
2018
|
this._isInitialized = false;
|
1860
2019
|
|
2020
|
+
Marionette.triggerMethod.call(this, "before:stop");
|
2021
|
+
|
1861
2022
|
// stop the sub-modules; depth-first, to make sure the
|
1862
2023
|
// sub-modules are stopped / finalized before parents
|
1863
2024
|
_.each(this.submodules, function(mod){ mod.stop(); });
|
@@ -1868,6 +2029,8 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1868
2029
|
// reset the initializers and finalizers
|
1869
2030
|
this._initializerCallbacks.reset();
|
1870
2031
|
this._finalizerCallbacks.reset();
|
2032
|
+
|
2033
|
+
Marionette.triggerMethod.call(this, "stop");
|
1871
2034
|
},
|
1872
2035
|
|
1873
2036
|
// Configure the module with a definition function and any custom args
|
@@ -1883,11 +2046,11 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1883
2046
|
|
1884
2047
|
// build the correct list of arguments for the module definition
|
1885
2048
|
var args = _.flatten([
|
1886
|
-
this,
|
1887
|
-
this.config.app,
|
1888
|
-
Backbone,
|
1889
|
-
Marionette,
|
1890
|
-
$, _,
|
2049
|
+
this,
|
2050
|
+
this.config.app,
|
2051
|
+
Backbone,
|
2052
|
+
Marionette,
|
2053
|
+
$, _,
|
1891
2054
|
customArgs
|
1892
2055
|
]);
|
1893
2056
|
|
@@ -1906,7 +2069,7 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1906
2069
|
// Function level methods to create modules
|
1907
2070
|
_.extend(Marionette.Module, {
|
1908
2071
|
|
1909
|
-
// Create a module, hanging off the app parameter as the parent object.
|
2072
|
+
// Create a module, hanging off the app parameter as the parent object.
|
1910
2073
|
create: function(app, moduleNames, moduleDefinition){
|
1911
2074
|
var that = this;
|
1912
2075
|
var parentModule = app;
|
@@ -1929,7 +2092,7 @@ _.extend(Marionette.Module, {
|
|
1929
2092
|
if (isLastModuleInChain){
|
1930
2093
|
module.config.options = that._getModuleOptions(module, parentModule, moduleDefinition);
|
1931
2094
|
|
1932
|
-
// Only add a module definition and initializer when this is the last
|
2095
|
+
// Only add a module definition and initializer when this is the last
|
1933
2096
|
// module in a "parent.child.grandchild" hierarchy of module names and
|
1934
2097
|
// when the module call has a definition function supplied
|
1935
2098
|
if (module.config.options.hasDefinition){
|
@@ -1953,14 +2116,14 @@ _.extend(Marionette.Module, {
|
|
1953
2116
|
return parentModule;
|
1954
2117
|
},
|
1955
2118
|
|
1956
|
-
// Only add the initializer if it is set to start with parent (the app),
|
2119
|
+
// Only add the initializer if it is set to start with parent (the app),
|
1957
2120
|
// and if it has not yet been added
|
1958
2121
|
_configureStartWithApp: function(app, module){
|
1959
2122
|
// skip this if we have already configured the module to start w/ the app
|
1960
2123
|
if (module.config.startWithAppIsConfigured){
|
1961
2124
|
return;
|
1962
2125
|
}
|
1963
|
-
|
2126
|
+
|
1964
2127
|
// start the module when the app starts
|
1965
2128
|
app.addInitializer(function(options){
|
1966
2129
|
// but only if the module is configured to start w/ parent
|
@@ -1979,7 +2142,7 @@ _.extend(Marionette.Module, {
|
|
1979
2142
|
// Get an existing module of this name if we have one
|
1980
2143
|
var module = parentModule[moduleName];
|
1981
2144
|
|
1982
|
-
if (!module){
|
2145
|
+
if (!module){
|
1983
2146
|
// Create a new module if we don't have one
|
1984
2147
|
module = new Marionette.Module(moduleName, app);
|
1985
2148
|
parentModule[moduleName] = module;
|
@@ -1998,7 +2161,7 @@ _.extend(Marionette.Module, {
|
|
1998
2161
|
}
|
1999
2162
|
|
2000
2163
|
// set up initial options for the module
|
2001
|
-
var options = {
|
2164
|
+
var options = {
|
2002
2165
|
startWithParent: startWithParent,
|
2003
2166
|
hasDefinition: !!moduleDefinition
|
2004
2167
|
};
|
@@ -2013,12 +2176,12 @@ _.extend(Marionette.Module, {
|
|
2013
2176
|
|
2014
2177
|
} else {
|
2015
2178
|
|
2016
|
-
// the definition is an object.
|
2179
|
+
// the definition is an object.
|
2017
2180
|
|
2018
2181
|
// grab the "define" attribute
|
2019
2182
|
options.hasDefinition = !!moduleDefinition.define;
|
2020
2183
|
options.definition = moduleDefinition.define;
|
2021
|
-
|
2184
|
+
|
2022
2185
|
// grab the "startWithParent" attribute if one exists
|
2023
2186
|
if (moduleDefinition.hasOwnProperty("startWithParent")){
|
2024
2187
|
options.startWithParent = moduleDefinition.startWithParent;
|