marionette-rails 0.10.2 → 1.0.0.beta1
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 +285 -217
- metadata +35 -51
@@ -1,65 +1,65 @@
|
|
1
|
-
// Backbone.Marionette,
|
1
|
+
// Backbone.Marionette, v1.0.0-beta1
|
2
2
|
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
3
3
|
// Distributed under MIT license
|
4
|
-
// http://github.com/
|
5
|
-
Backbone.Marionette = (function(Backbone, _, $){
|
4
|
+
// http://github.com/marionettejs/backbone.marionette
|
5
|
+
Backbone.Marionette = Marionette = (function(Backbone, _, $){
|
6
6
|
var Marionette = {};
|
7
7
|
|
8
|
-
//
|
9
|
-
//
|
10
|
-
|
11
|
-
// The event binder facilitates the binding and unbinding of events
|
12
|
-
// from objects that extend `Backbone.Events`. It makes
|
13
|
-
// unbinding events, even with anonymous callback functions,
|
14
|
-
// easy.
|
15
|
-
//
|
16
|
-
// Inspired by [Johnny Oshika](http://stackoverflow.com/questions/7567404/backbone-js-repopulate-or-recreate-the-view/7607853#7607853)
|
17
|
-
|
18
|
-
Marionette.EventBinder = function(){
|
19
|
-
this._eventBindings = [];
|
20
|
-
};
|
8
|
+
// Helpers
|
9
|
+
// -------
|
21
10
|
|
22
|
-
|
23
|
-
|
24
|
-
// easily, at a later point in time.
|
25
|
-
bindTo: function (obj, eventName, callback, context) {
|
26
|
-
context = context || this;
|
27
|
-
obj.on(eventName, callback, context);
|
28
|
-
|
29
|
-
var binding = {
|
30
|
-
obj: obj,
|
31
|
-
eventName: eventName,
|
32
|
-
callback: callback,
|
33
|
-
context: context
|
34
|
-
};
|
11
|
+
// For slicing `arguments` in functions
|
12
|
+
var slice = Array.prototype.slice;
|
35
13
|
|
36
|
-
|
14
|
+
// Borrow the Backbone `extend` method so we can use it as needed
|
15
|
+
Marionette.extend = Backbone.Model.extend;
|
37
16
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
17
|
+
// Trigger an event and a corresponding method name. Examples:
|
18
|
+
//
|
19
|
+
// `this.triggerMethod("foo")` will trigger the "foo" event and
|
20
|
+
// call the "onFoo" method.
|
21
|
+
//
|
22
|
+
// `this.triggerMethod("foo:bar") will trigger the "foo:bar" event and
|
23
|
+
// call the "onFooBar" method.
|
24
|
+
Marionette.triggerMethod = function(){
|
25
|
+
var args = Array.prototype.slice.apply(arguments);
|
26
|
+
var eventName = args[0];
|
27
|
+
var segments = eventName.split(":");
|
28
|
+
var segment, capLetter, methodName = "on";
|
29
|
+
|
30
|
+
for (var i = 0; i < segments.length; i++){
|
31
|
+
segment = segments[i];
|
32
|
+
capLetter = segment.charAt(0).toUpperCase();
|
33
|
+
methodName += capLetter + segment.slice(1);
|
34
|
+
}
|
47
35
|
|
48
|
-
|
49
|
-
unbindAll: function () {
|
50
|
-
var that = this;
|
36
|
+
this.trigger.apply(this, arguments);
|
51
37
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
_.each(bindings, function (binding, index) {
|
56
|
-
that.unbindFrom(binding);
|
57
|
-
});
|
38
|
+
if (_.isFunction(this[methodName])){
|
39
|
+
args.shift();
|
40
|
+
this[methodName].apply(this, args);
|
58
41
|
}
|
59
|
-
}
|
42
|
+
};
|
60
43
|
|
61
|
-
//
|
62
|
-
|
44
|
+
// EventBinder
|
45
|
+
// -----------
|
46
|
+
// Import the event binder from it's new home
|
47
|
+
// https://github.com/marionettejs/backbone.eventbinder
|
48
|
+
Marionette.EventBinder = Backbone.EventBinder;
|
49
|
+
|
50
|
+
// Add the EventBinder methods to the view directly,
|
51
|
+
// but keep them bound to the EventBinder instance so they work properly.
|
52
|
+
// This allows the event binder's implementation to vary independently
|
53
|
+
// of it being attached to the view... for example the internal structure
|
54
|
+
// used to store the events can change without worry about it interfering
|
55
|
+
// with Marionette's views.
|
56
|
+
Marionette.addEventBinder = function(target){
|
57
|
+
var eventBinder = new Marionette.EventBinder();
|
58
|
+
target.eventBinder = eventBinder;
|
59
|
+
target.bindTo = _.bind(eventBinder.bindTo, eventBinder);
|
60
|
+
target.unbindFrom = _.bind(eventBinder.unbindFrom, eventBinder);
|
61
|
+
target.unbindAll = _.bind(eventBinder.unbindAll, eventBinder);
|
62
|
+
};
|
63
63
|
|
64
64
|
// Marionette.View
|
65
65
|
// ---------------
|
@@ -68,8 +68,8 @@ Marionette.EventBinder.extend = Backbone.View.extend;
|
|
68
68
|
Marionette.View = Backbone.View.extend({
|
69
69
|
|
70
70
|
constructor: function(){
|
71
|
-
|
72
|
-
|
71
|
+
_.bindAll(this, "render");
|
72
|
+
Marionette.addEventBinder(this);
|
73
73
|
|
74
74
|
Backbone.View.prototype.constructor.apply(this, arguments);
|
75
75
|
|
@@ -79,6 +79,10 @@ Marionette.View = Backbone.View.extend({
|
|
79
79
|
this.bindTo(this, "show", this.onShowCalled, this);
|
80
80
|
},
|
81
81
|
|
82
|
+
// import the "triggerMethod" to trigger events with corresponding
|
83
|
+
// methods if the method exists
|
84
|
+
triggerMethod: Marionette.triggerMethod,
|
85
|
+
|
82
86
|
// Get the template for this view
|
83
87
|
// instance. You can set a `template` attribute in the view
|
84
88
|
// definition or pass a `template: "whatever"` parameter in
|
@@ -97,27 +101,6 @@ Marionette.View = Backbone.View.extend({
|
|
97
101
|
return template;
|
98
102
|
},
|
99
103
|
|
100
|
-
// Serialize the model or collection for the view. If a model is
|
101
|
-
// found, `.toJSON()` is called. If a collection is found, `.toJSON()`
|
102
|
-
// is also called, but is used to populate an `items` array in the
|
103
|
-
// resulting data. If both are found, defaults to the model.
|
104
|
-
// You can override the `serializeData` method in your own view
|
105
|
-
// definition, to provide custom serialization for your view's data.
|
106
|
-
serializeData: function(){
|
107
|
-
var data;
|
108
|
-
|
109
|
-
if (this.model) {
|
110
|
-
data = this.model.toJSON();
|
111
|
-
}
|
112
|
-
else if (this.collection) {
|
113
|
-
data = { items: this.collection.toJSON() };
|
114
|
-
}
|
115
|
-
|
116
|
-
data = this.mixinTemplateHelpers(data);
|
117
|
-
|
118
|
-
return data;
|
119
|
-
},
|
120
|
-
|
121
104
|
// Mix in template helper methods. Looks for a
|
122
105
|
// `templateHelpers` attribute, which can either be an
|
123
106
|
// object literal, or a function that returns an object
|
@@ -180,14 +163,15 @@ Marionette.View = Backbone.View.extend({
|
|
180
163
|
// for you. You can specify an `onClose` method in your view to
|
181
164
|
// add custom code that is called after the view is closed.
|
182
165
|
close: function(){
|
183
|
-
if (this.
|
166
|
+
if (this.isClosed) { return; }
|
184
167
|
|
185
|
-
this.
|
168
|
+
this.triggerMethod("before:close");
|
186
169
|
|
187
|
-
|
188
|
-
this.trigger('close');
|
170
|
+
this.remove();
|
189
171
|
this.unbindAll();
|
190
|
-
|
172
|
+
|
173
|
+
this.triggerMethod("close");
|
174
|
+
this.isClosed = true;
|
191
175
|
},
|
192
176
|
|
193
177
|
// This method binds the elements specified in the "ui" hash inside the view's code with
|
@@ -243,15 +227,37 @@ Marionette.ItemView = Marionette.View.extend({
|
|
243
227
|
}
|
244
228
|
},
|
245
229
|
|
230
|
+
// Serialize the model or collection for the view. If a model is
|
231
|
+
// found, `.toJSON()` is called. If a collection is found, `.toJSON()`
|
232
|
+
// is also called, but is used to populate an `items` array in the
|
233
|
+
// resulting data. If both are found, defaults to the model.
|
234
|
+
// You can override the `serializeData` method in your own view
|
235
|
+
// definition, to provide custom serialization for your view's data.
|
236
|
+
serializeData: function(){
|
237
|
+
var data;
|
238
|
+
|
239
|
+
if (this.model) {
|
240
|
+
data = this.model.toJSON();
|
241
|
+
}
|
242
|
+
else if (this.collection) {
|
243
|
+
data = { items: this.collection.toJSON() };
|
244
|
+
}
|
245
|
+
|
246
|
+
data = this.mixinTemplateHelpers(data);
|
247
|
+
|
248
|
+
return data;
|
249
|
+
},
|
250
|
+
|
246
251
|
// Render the view, defaulting to underscore.js templates.
|
247
252
|
// You can override this in your view definition to provide
|
248
253
|
// a very specific rendering for your view. In general, though,
|
249
254
|
// you should override the `Marionette.Renderer` object to
|
250
255
|
// change how Marionette renders views.
|
251
256
|
render: function(){
|
252
|
-
|
253
|
-
|
254
|
-
this.
|
257
|
+
this.isClosed = false;
|
258
|
+
|
259
|
+
this.triggerMethod("before:render", this);
|
260
|
+
this.triggerMethod("item:before:render", this);
|
255
261
|
|
256
262
|
var data = this.serializeData();
|
257
263
|
var template = this.getTemplate();
|
@@ -259,18 +265,20 @@ Marionette.ItemView = Marionette.View.extend({
|
|
259
265
|
this.$el.html(html);
|
260
266
|
this.bindUIElements();
|
261
267
|
|
262
|
-
|
263
|
-
this.
|
264
|
-
|
268
|
+
this.triggerMethod("render", this);
|
269
|
+
this.triggerMethod("item:rendered", this);
|
270
|
+
|
265
271
|
return this;
|
266
272
|
},
|
267
273
|
|
268
274
|
// Override the default close event to add a few
|
269
275
|
// more events that are triggered.
|
270
276
|
close: function(){
|
271
|
-
this.
|
277
|
+
if (this.isClosed){ return; }
|
278
|
+
|
279
|
+
this.triggerMethod('item:before:close');
|
272
280
|
Marionette.View.prototype.close.apply(this, arguments);
|
273
|
-
this.
|
281
|
+
this.triggerMethod('item:closed');
|
274
282
|
}
|
275
283
|
});
|
276
284
|
|
@@ -281,8 +289,8 @@ Marionette.ItemView = Marionette.View.extend({
|
|
281
289
|
// and renders an individual ItemView for each model.
|
282
290
|
Marionette.CollectionView = Marionette.View.extend({
|
283
291
|
constructor: function(){
|
284
|
-
Marionette.View.prototype.constructor.apply(this, arguments);
|
285
292
|
this.initChildViewStorage();
|
293
|
+
Marionette.View.prototype.constructor.apply(this, arguments);
|
286
294
|
this.initialEvents();
|
287
295
|
this.onShowCallbacks = new Marionette.Callbacks();
|
288
296
|
},
|
@@ -302,7 +310,15 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
302
310
|
addChildView: function(item, collection, options){
|
303
311
|
this.closeEmptyView();
|
304
312
|
var ItemView = this.getItemView(item);
|
305
|
-
|
313
|
+
|
314
|
+
var index;
|
315
|
+
if(options && options.index){
|
316
|
+
index = options.index;
|
317
|
+
} else {
|
318
|
+
index = 0;
|
319
|
+
}
|
320
|
+
|
321
|
+
return this.addItemView(item, ItemView, index);
|
306
322
|
},
|
307
323
|
|
308
324
|
// Override from `Marionette.View` to guarantee the `onShow` method
|
@@ -314,23 +330,23 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
314
330
|
// Internal method to trigger the before render callbacks
|
315
331
|
// and events
|
316
332
|
triggerBeforeRender: function(){
|
317
|
-
|
318
|
-
this.
|
319
|
-
this.trigger("collection:before:render", this);
|
333
|
+
this.triggerMethod("before:render", this);
|
334
|
+
this.triggerMethod("collection:before:render", this);
|
320
335
|
},
|
321
336
|
|
322
337
|
// Internal method to trigger the rendered callbacks and
|
323
338
|
// events
|
324
339
|
triggerRendered: function(){
|
325
|
-
|
326
|
-
this.
|
327
|
-
this.trigger("collection:rendered", this);
|
340
|
+
this.triggerMethod("render", this);
|
341
|
+
this.triggerMethod("collection:rendered", this);
|
328
342
|
},
|
329
343
|
|
330
344
|
// Render the collection of items. Override this method to
|
331
345
|
// provide your own implementation of a render function for
|
332
346
|
// the collection view.
|
333
347
|
render: function(){
|
348
|
+
this.isClosed = false;
|
349
|
+
|
334
350
|
this.triggerBeforeRender();
|
335
351
|
this.closeEmptyView();
|
336
352
|
this.closeChildren();
|
@@ -403,8 +419,7 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
403
419
|
// Store the child view itself so we can properly
|
404
420
|
// remove and/or close it later
|
405
421
|
this.storeChild(view);
|
406
|
-
|
407
|
-
this.trigger("item:added", view);
|
422
|
+
this.triggerMethod("item:added", view);
|
408
423
|
|
409
424
|
// Render it and show it
|
410
425
|
var renderResult = this.renderItemView(view, index);
|
@@ -421,7 +436,7 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
421
436
|
args[0] = "itemview:" + args[0];
|
422
437
|
args.splice(1, 0, view);
|
423
438
|
|
424
|
-
that.
|
439
|
+
that.triggerMethod.apply(that, args);
|
425
440
|
});
|
426
441
|
|
427
442
|
// Store all child event bindings so we can unbind
|
@@ -470,7 +485,7 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
470
485
|
this.showEmptyView();
|
471
486
|
}
|
472
487
|
|
473
|
-
this.
|
488
|
+
this.triggerMethod("item:removed", view);
|
474
489
|
},
|
475
490
|
|
476
491
|
// Append the HTML to the collection's `el`.
|
@@ -495,9 +510,11 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
495
510
|
// Handle cleanup and other closing needs for
|
496
511
|
// the collection of views.
|
497
512
|
close: function(){
|
498
|
-
this.
|
513
|
+
if (this.isClosed){ return; }
|
514
|
+
|
515
|
+
this.triggerMethod("collection:before:close");
|
499
516
|
this.closeChildren();
|
500
|
-
this.
|
517
|
+
this.triggerMethod("collection:closed");
|
501
518
|
Marionette.View.prototype.close.apply(this, arguments);
|
502
519
|
},
|
503
520
|
|
@@ -553,31 +570,49 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
553
570
|
return itemView;
|
554
571
|
},
|
555
572
|
|
573
|
+
// Serialize the collection for the view.
|
574
|
+
// You can override the `serializeData` method in your own view
|
575
|
+
// definition, to provide custom serialization for your view's data.
|
576
|
+
serializeData: function(){
|
577
|
+
var data = {};
|
578
|
+
|
579
|
+
if (this.model){
|
580
|
+
data = this.model.toJSON();
|
581
|
+
}
|
582
|
+
|
583
|
+
data = this.mixinTemplateHelpers(data);
|
584
|
+
|
585
|
+
return data;
|
586
|
+
},
|
587
|
+
|
556
588
|
// Renders the model once, and the collection once. Calling
|
557
589
|
// this again will tell the model's view to re-render itself
|
558
590
|
// but the collection will not re-render.
|
559
591
|
render: function(){
|
560
|
-
|
592
|
+
this.isClosed = false;
|
561
593
|
|
562
594
|
this.resetItemViewContainer();
|
563
595
|
|
564
596
|
var html = this.renderModel();
|
565
597
|
this.$el.html(html);
|
566
|
-
|
598
|
+
|
599
|
+
// the ui bindings is done here and not at the end of render since they
|
600
|
+
// will not be available until after the model is rendered, but should be
|
567
601
|
// available before the collection is rendered.
|
568
602
|
this.bindUIElements();
|
569
|
-
|
570
|
-
this.
|
603
|
+
|
604
|
+
this.triggerMethod("composite:model:rendered");
|
605
|
+
this.triggerMethod("render");
|
571
606
|
|
572
607
|
this.renderCollection();
|
573
|
-
this.
|
608
|
+
this.triggerMethod("composite:rendered");
|
574
609
|
return this;
|
575
610
|
},
|
576
611
|
|
577
612
|
// Render the collection for the composite view
|
578
613
|
renderCollection: function(){
|
579
614
|
Marionette.CollectionView.prototype.render.apply(this, arguments);
|
580
|
-
this.
|
615
|
+
this.triggerMethod("composite:collection:rendered");
|
581
616
|
},
|
582
617
|
|
583
618
|
// Render an individual model, if we have one, as
|
@@ -603,23 +638,26 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
603
638
|
// Internal method to ensure an `$itemViewContainer` exists, for the
|
604
639
|
// `appendHtml` method to use.
|
605
640
|
getItemViewContainer: function(containerView){
|
606
|
-
var container;
|
607
641
|
if ("$itemViewContainer" in containerView){
|
608
|
-
|
609
|
-
}
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
642
|
+
return containerView.$itemViewContainer;
|
643
|
+
}
|
644
|
+
|
645
|
+
var container;
|
646
|
+
if (containerView.itemViewContainer){
|
647
|
+
|
648
|
+
var selector = _.result(containerView, "itemViewContainer");
|
649
|
+
container = containerView.$(selector);
|
650
|
+
if (container.length <= 0) {
|
651
|
+
var err = new Error("The specified `itemViewContainer` was not found: " + containerView.itemViewContainer);
|
652
|
+
err.name = "ItemViewContainerMissingError";
|
653
|
+
throw err;
|
620
654
|
}
|
621
|
-
|
655
|
+
|
656
|
+
} else {
|
657
|
+
container = containerView.$el;
|
622
658
|
}
|
659
|
+
|
660
|
+
containerView.$itemViewContainer = container;
|
623
661
|
return container;
|
624
662
|
},
|
625
663
|
|
@@ -634,17 +672,24 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
634
672
|
|
635
673
|
// Region
|
636
674
|
// ------
|
637
|
-
|
675
|
+
//
|
638
676
|
// Manage the visual regions of your composite application. See
|
639
677
|
// http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
|
678
|
+
|
640
679
|
Marionette.Region = function(options){
|
641
680
|
this.options = options || {};
|
642
681
|
|
643
|
-
var
|
644
|
-
|
682
|
+
var el = this.options.el;
|
683
|
+
delete this.options.el;
|
684
|
+
|
685
|
+
Marionette.addEventBinder(this);
|
686
|
+
|
687
|
+
if (el){
|
688
|
+
this.el = el;
|
689
|
+
}
|
645
690
|
|
646
691
|
if (!this.el){
|
647
|
-
var err = new Error("An 'el' must be specified");
|
692
|
+
var err = new Error("An 'el' must be specified for a region.");
|
648
693
|
err.name = "NoElError";
|
649
694
|
throw err;
|
650
695
|
}
|
@@ -654,6 +699,76 @@ Marionette.Region = function(options){
|
|
654
699
|
}
|
655
700
|
};
|
656
701
|
|
702
|
+
|
703
|
+
// Region Type methods
|
704
|
+
// -------------------
|
705
|
+
|
706
|
+
_.extend(Marionette.Region, {
|
707
|
+
|
708
|
+
// Build an instance of a region by passing in a configuration object
|
709
|
+
// and a default region type to use if none is specified in the config.
|
710
|
+
//
|
711
|
+
// The config object should either be a string as a jQuery DOM selector,
|
712
|
+
// a Region type directly, or an object literal that specifies both
|
713
|
+
// a selector and regionType:
|
714
|
+
//
|
715
|
+
// ```js
|
716
|
+
// {
|
717
|
+
// selector: "#foo",
|
718
|
+
// regionType: MyCustomRegion
|
719
|
+
// }
|
720
|
+
// ```
|
721
|
+
//
|
722
|
+
buildRegion: function(regionConfig, defaultRegionType){
|
723
|
+
var regionIsString = (typeof regionConfig === "string");
|
724
|
+
var regionSelectorIsString = (typeof regionConfig.selector === "string");
|
725
|
+
var regionTypeIsUndefined = (typeof regionConfig.regionType === "undefined");
|
726
|
+
var regionIsType = (typeof regionConfig === "function");
|
727
|
+
|
728
|
+
if (!regionIsType && !regionIsString && !regionSelectorIsString) {
|
729
|
+
throw new Error("Region must be specified as a Region type, a selector string or an object with selector property");
|
730
|
+
}
|
731
|
+
|
732
|
+
var selector, RegionType;
|
733
|
+
|
734
|
+
// get the selector for the region
|
735
|
+
|
736
|
+
if (regionIsString) {
|
737
|
+
selector = regionConfig;
|
738
|
+
}
|
739
|
+
|
740
|
+
if (regionConfig.selector) {
|
741
|
+
selector = regionConfig.selector;
|
742
|
+
}
|
743
|
+
|
744
|
+
// get the type for the region
|
745
|
+
|
746
|
+
if (regionIsType){
|
747
|
+
RegionType = regionConfig;
|
748
|
+
}
|
749
|
+
|
750
|
+
if (!regionIsType && regionTypeIsUndefined) {
|
751
|
+
RegionType = defaultRegionType;
|
752
|
+
}
|
753
|
+
|
754
|
+
if (regionConfig.regionType) {
|
755
|
+
RegionType = regionConfig.regionType;
|
756
|
+
}
|
757
|
+
|
758
|
+
// build the region instance
|
759
|
+
|
760
|
+
var regionManager = new RegionType({
|
761
|
+
el: selector
|
762
|
+
});
|
763
|
+
|
764
|
+
return regionManager;
|
765
|
+
}
|
766
|
+
|
767
|
+
});
|
768
|
+
|
769
|
+
// Region Instance Methods
|
770
|
+
// -----------------------
|
771
|
+
|
657
772
|
_.extend(Marionette.Region.prototype, Backbone.Events, {
|
658
773
|
|
659
774
|
// Displays a backbone view instance inside of the region.
|
@@ -700,7 +815,7 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
700
815
|
// current view, it does nothing and returns immediately.
|
701
816
|
close: function(){
|
702
817
|
var view = this.currentView;
|
703
|
-
if (!view){ return; }
|
818
|
+
if (!view || view.isClosed){ return; }
|
704
819
|
|
705
820
|
if (view.close) { view.close(); }
|
706
821
|
this.trigger("view:closed", view);
|
@@ -727,7 +842,7 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
727
842
|
});
|
728
843
|
|
729
844
|
// Copy the `extend` function used by Backbone's classes
|
730
|
-
Marionette.Region.extend =
|
845
|
+
Marionette.Region.extend = Marionette.extend;
|
731
846
|
|
732
847
|
// Layout
|
733
848
|
// ------
|
@@ -768,6 +883,8 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
768
883
|
|
769
884
|
// Handle closing regions, and then close the view itself.
|
770
885
|
close: function () {
|
886
|
+
if (this.isClosed){ return; }
|
887
|
+
|
771
888
|
this.closeRegions();
|
772
889
|
this.destroyRegions();
|
773
890
|
Backbone.Marionette.ItemView.prototype.close.call(this, arguments);
|
@@ -785,35 +902,13 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
785
902
|
}
|
786
903
|
|
787
904
|
var that = this;
|
788
|
-
|
789
|
-
|
790
|
-
var regionSelectorIsString = (typeof region.selector === "string");
|
791
|
-
var regionTypeIsUndefined = (typeof region.regionType === "undefined");
|
792
|
-
|
793
|
-
if (!regionIsString && !regionSelectorIsString) {
|
794
|
-
throw new Error("Region must be specified as a selector string or an object with selector property");
|
795
|
-
}
|
905
|
+
var regions = this.regions || {};
|
906
|
+
_.each(regions, function (region, name) {
|
796
907
|
|
797
|
-
var
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
} else {
|
802
|
-
selector = region.selector;
|
803
|
-
}
|
804
|
-
|
805
|
-
if (regionTypeIsUndefined){
|
806
|
-
RegionType = that.regionType;
|
807
|
-
} else {
|
808
|
-
RegionType = region.regionType;
|
809
|
-
}
|
810
|
-
|
811
|
-
var regionManager = new RegionType({
|
812
|
-
el: selector,
|
813
|
-
getEl: function(selector){
|
814
|
-
return that.$(selector);
|
815
|
-
}
|
816
|
-
});
|
908
|
+
var regionManager = Marionette.Region.buildRegion(region, that.regionType);
|
909
|
+
regionManager.getEl = function(selector){
|
910
|
+
return that.$(selector);
|
911
|
+
};
|
817
912
|
|
818
913
|
that.regionManagers[name] = regionManager;
|
819
914
|
that[name] = regionManager;
|
@@ -864,13 +959,26 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
864
959
|
Marionette.Application = function(options){
|
865
960
|
this.initCallbacks = new Marionette.Callbacks();
|
866
961
|
this.vent = new Marionette.EventAggregator();
|
962
|
+
this.commands = new Backbone.Wreqr.Commands();
|
963
|
+
this.reqres = new Backbone.Wreqr.RequestResponse();
|
867
964
|
this.submodules = {};
|
868
965
|
|
869
|
-
|
870
|
-
|
966
|
+
_.extend(this, options);
|
967
|
+
|
968
|
+
Marionette.addEventBinder(this);
|
871
969
|
};
|
872
970
|
|
873
971
|
_.extend(Marionette.Application.prototype, Backbone.Events, {
|
972
|
+
// Command execution, facilitated by Backbone.Wreqr.Commands
|
973
|
+
execute: function(){
|
974
|
+
this.commands.execute.apply(this.commands, arguments);
|
975
|
+
},
|
976
|
+
|
977
|
+
// Request/response, facilitated by Backbone.Wreqr.RequestResponse
|
978
|
+
request: function(){
|
979
|
+
return this.reqres.request.apply(this.reqres, arguments);
|
980
|
+
},
|
981
|
+
|
874
982
|
// Add an initializer that is either run at when the `start`
|
875
983
|
// method is called, or run immediately if added after `start`
|
876
984
|
// has already been called.
|
@@ -894,23 +1002,11 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
|
|
894
1002
|
// addRegions({something: "#someRegion"})
|
895
1003
|
// addRegions{{something: Region.extend({el: "#someRegion"}) });
|
896
1004
|
addRegions: function(regions){
|
897
|
-
var
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
if (typeof RegionValue === "string"){
|
904
|
-
regionObj = new Marionette.Region({
|
905
|
-
el: RegionValue
|
906
|
-
});
|
907
|
-
} else {
|
908
|
-
regionObj = new RegionValue();
|
909
|
-
}
|
910
|
-
|
911
|
-
this[region] = regionObj;
|
912
|
-
}
|
913
|
-
}
|
1005
|
+
var that = this;
|
1006
|
+
_.each(regions, function (region, name) {
|
1007
|
+
var regionManager = Marionette.Region.buildRegion(region, Marionette.Region);
|
1008
|
+
that[name] = regionManager;
|
1009
|
+
});
|
914
1010
|
},
|
915
1011
|
|
916
1012
|
// Removes a region from your app.
|
@@ -934,7 +1030,7 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
|
|
934
1030
|
});
|
935
1031
|
|
936
1032
|
// Copy the `extend` function used by Backbone's classes
|
937
|
-
Marionette.Application.extend =
|
1033
|
+
Marionette.Application.extend = Marionette.extend;
|
938
1034
|
|
939
1035
|
// AppRouter
|
940
1036
|
// ---------
|
@@ -1008,7 +1104,7 @@ Marionette.AppRouter = Backbone.Router.extend({
|
|
1008
1104
|
|
1009
1105
|
// A simple module system, used to create privacy and encapsulation in
|
1010
1106
|
// Marionette applications
|
1011
|
-
Marionette.Module = function(moduleName, app
|
1107
|
+
Marionette.Module = function(moduleName, app){
|
1012
1108
|
this.moduleName = moduleName;
|
1013
1109
|
|
1014
1110
|
// store sub-modules
|
@@ -1019,12 +1115,9 @@ Marionette.Module = function(moduleName, app, customArgs){
|
|
1019
1115
|
// store the configuration for this module
|
1020
1116
|
this.config = {};
|
1021
1117
|
this.config.app = app;
|
1022
|
-
this.config.customArgs = customArgs;
|
1023
|
-
this.config.definitions = [];
|
1024
1118
|
|
1025
1119
|
// extend this module with an event binder
|
1026
|
-
|
1027
|
-
_.extend(this, eventBinder);
|
1120
|
+
Marionette.addEventBinder(this);
|
1028
1121
|
};
|
1029
1122
|
|
1030
1123
|
// Extend the Module prototype with events / bindTo, so that the module
|
@@ -1082,13 +1175,13 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1082
1175
|
|
1083
1176
|
// Configure the module with a definition function and any custom args
|
1084
1177
|
// that are to be passed in to the definition function
|
1085
|
-
addDefinition: function(moduleDefinition){
|
1086
|
-
this._runModuleDefinition(moduleDefinition);
|
1178
|
+
addDefinition: function(moduleDefinition, customArgs){
|
1179
|
+
this._runModuleDefinition(moduleDefinition, customArgs);
|
1087
1180
|
},
|
1088
1181
|
|
1089
1182
|
// Internal method: run the module definition function with the correct
|
1090
1183
|
// arguments
|
1091
|
-
_runModuleDefinition: function(definition){
|
1184
|
+
_runModuleDefinition: function(definition, customArgs){
|
1092
1185
|
if (!definition){ return; }
|
1093
1186
|
|
1094
1187
|
// build the correct list of arguments for the module definition
|
@@ -1098,7 +1191,7 @@ _.extend(Marionette.Module.prototype, Backbone.Events, {
|
|
1098
1191
|
Backbone,
|
1099
1192
|
Marionette,
|
1100
1193
|
$, _,
|
1101
|
-
|
1194
|
+
customArgs
|
1102
1195
|
]);
|
1103
1196
|
|
1104
1197
|
definition.apply(this, args);
|
@@ -1132,7 +1225,7 @@ _.extend(Marionette.Module, {
|
|
1132
1225
|
_.each(moduleNames, function(moduleName, i){
|
1133
1226
|
var isLastModuleInChain = (i === length-1);
|
1134
1227
|
|
1135
|
-
var module = that._getModuleDefinition(parentModule, moduleName, app
|
1228
|
+
var module = that._getModuleDefinition(parentModule, moduleName, app);
|
1136
1229
|
module.config.options = that._getModuleOptions(parentModule, moduleDefinition);
|
1137
1230
|
|
1138
1231
|
// if it's the first module in the chain, configure it
|
@@ -1145,7 +1238,7 @@ _.extend(Marionette.Module, {
|
|
1145
1238
|
// the last module in a "parent.child.grandchild" hierarchy of
|
1146
1239
|
// module names
|
1147
1240
|
if (isLastModuleInChain && module.config.options.hasDefinition){
|
1148
|
-
module.addDefinition(module.config.options.definition);
|
1241
|
+
module.addDefinition(module.config.options.definition, customArgs);
|
1149
1242
|
}
|
1150
1243
|
|
1151
1244
|
// Reset the parent module so that the next child
|
@@ -1173,13 +1266,13 @@ _.extend(Marionette.Module, {
|
|
1173
1266
|
module.config.autoStartConfigured = true;
|
1174
1267
|
},
|
1175
1268
|
|
1176
|
-
_getModuleDefinition: function(parentModule, moduleName, app
|
1269
|
+
_getModuleDefinition: function(parentModule, moduleName, app){
|
1177
1270
|
// Get an existing module of this name if we have one
|
1178
1271
|
var module = parentModule[moduleName];
|
1179
1272
|
|
1180
1273
|
if (!module){
|
1181
1274
|
// Create a new module if we don't have one
|
1182
|
-
module = new Marionette.Module(moduleName, app
|
1275
|
+
module = new Marionette.Module(moduleName, app);
|
1183
1276
|
parentModule[moduleName] = module;
|
1184
1277
|
// store the module on the parent
|
1185
1278
|
parentModule.submodules[moduleName] = module;
|
@@ -1386,37 +1479,12 @@ _.extend(Marionette.Callbacks.prototype, {
|
|
1386
1479
|
|
1387
1480
|
// Event Aggregator
|
1388
1481
|
// ----------------
|
1389
|
-
|
1390
1482
|
// A pub-sub object that can be used to decouple various parts
|
1391
1483
|
// of an application through event-driven architecture.
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
constructor: function(options){
|
1396
|
-
Marionette.EventBinder.apply(this, arguments);
|
1397
|
-
_.extend(this, options);
|
1398
|
-
},
|
1399
|
-
|
1400
|
-
// Override the `bindTo` method to ensure that the event aggregator
|
1401
|
-
// is used as the event binding storage
|
1402
|
-
bindTo: function(eventName, callback, context){
|
1403
|
-
return Marionette.EventBinder.prototype.bindTo.call(this, this, eventName, callback, context);
|
1404
|
-
}
|
1405
|
-
});
|
1406
|
-
|
1407
|
-
// Copy the basic Backbone.Events on to the event aggregator
|
1408
|
-
_.extend(Marionette.EventAggregator.prototype, Backbone.Events);
|
1409
|
-
|
1410
|
-
// Copy the `extend` function used by Backbone's classes
|
1411
|
-
Marionette.EventAggregator.extend = Backbone.View.extend;
|
1412
|
-
|
1413
|
-
|
1414
|
-
// Helpers
|
1415
|
-
// -------
|
1416
|
-
|
1417
|
-
// For slicing `arguments` in functions
|
1418
|
-
var slice = Array.prototype.slice;
|
1484
|
+
//
|
1485
|
+
// https://github.com/marionettejs/backbone.wreqr
|
1486
|
+
Marionette.EventAggregator = Backbone.Wreqr.EventAggregator;
|
1419
1487
|
|
1420
1488
|
|
1421
1489
|
return Marionette;
|
1422
|
-
})(Backbone, _, window.jQuery || window.Zepto || window.ender);
|
1490
|
+
})(Backbone, _, $ || window.jQuery || window.Zepto || window.ender);
|
metadata
CHANGED
@@ -1,81 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: marionette-rails
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 10
|
8
|
-
- 2
|
9
|
-
version: 0.10.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.beta1
|
5
|
+
prerelease: 6
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Godfrey Chan
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: rails
|
22
|
-
|
23
|
-
|
24
|
-
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 3
|
29
|
-
- 1
|
30
|
-
- 0
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
31
21
|
version: 3.1.0
|
32
22
|
type: :runtime
|
33
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.1.0
|
34
30
|
description: Vendors Backbone.Marionette for use with asset pipeline.
|
35
|
-
email:
|
31
|
+
email:
|
36
32
|
- godfreykfc@gmail.com
|
37
33
|
executables: []
|
38
|
-
|
39
34
|
extensions: []
|
40
|
-
|
41
35
|
extra_rdoc_files: []
|
42
|
-
|
43
|
-
files:
|
36
|
+
files:
|
44
37
|
- lib/marionette-rails.rb
|
45
38
|
- vendor/assets/javascripts/backbone.marionette.js
|
46
39
|
- LICENSE
|
47
40
|
- README.md
|
48
|
-
has_rdoc: true
|
49
41
|
homepage: https://github.com/chancancode/marionette-rails
|
50
42
|
licenses: []
|
51
|
-
|
52
43
|
post_install_message:
|
53
44
|
rdoc_options: []
|
54
|
-
|
55
|
-
require_paths:
|
45
|
+
require_paths:
|
56
46
|
- lib
|
57
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
requirements:
|
66
|
-
- -
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
segments:
|
69
|
-
- 1
|
70
|
-
- 3
|
71
|
-
- 6
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
72
58
|
version: 1.3.6
|
73
59
|
requirements: []
|
74
|
-
|
75
60
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.
|
61
|
+
rubygems_version: 1.8.23
|
77
62
|
signing_key:
|
78
63
|
specification_version: 3
|
79
64
|
summary: Backbone.Marionette for Rails
|
80
65
|
test_files: []
|
81
|
-
|