marionette-rails 1.0.0.beta1 → 1.0.0.beta2
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 -40
- metadata +1 -1
@@ -1,7 +1,240 @@
|
|
1
|
-
|
1
|
+
/*!
|
2
|
+
* Backbone.Marionette, v1.0.0-beta2
|
3
|
+
* Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
4
|
+
* Distributed under MIT license
|
5
|
+
* http://github.com/marionettejs/backbone.marionette
|
6
|
+
*/
|
7
|
+
/*!
|
8
|
+
* Includes Wreqr
|
9
|
+
* https://github.com/marionettejs/backbone.wreqr/
|
10
|
+
* Includes EventBinder
|
11
|
+
* https://github.com/marionettejs/backbone.eventbinder/
|
12
|
+
*/
|
13
|
+
// Backbone.EventBinder, v0.1.0
|
2
14
|
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
3
15
|
// Distributed under MIT license
|
4
|
-
// http://github.com/marionettejs/backbone.
|
16
|
+
// http://github.com/marionettejs/backbone.eventbinder
|
17
|
+
// EventBinder
|
18
|
+
// -----------
|
19
|
+
//
|
20
|
+
// The event binder facilitates the binding and unbinding of events
|
21
|
+
// from objects that extend `Backbone.Events`. It makes
|
22
|
+
// unbinding events, even with anonymous callback functions,
|
23
|
+
// easy.
|
24
|
+
//
|
25
|
+
// Inspired by [Johnny Oshika](http://stackoverflow.com/questions/7567404/backbone-js-repopulate-or-recreate-the-view/7607853#7607853)
|
26
|
+
|
27
|
+
Backbone.EventBinder = (function(Backbone, _){
|
28
|
+
"use strict";
|
29
|
+
|
30
|
+
// A map of objects that support binding/unbinding events.
|
31
|
+
// This allows EventBinder to support events on arbitrary
|
32
|
+
// objects with EB's consistent api.
|
33
|
+
var handlerMap = {
|
34
|
+
// 'default' type accounts for Backbone style objects extending
|
35
|
+
// Backbone.Events
|
36
|
+
"default" : {
|
37
|
+
bindTo : function (obj, eventName, callback, context) {
|
38
|
+
context = context || this;
|
39
|
+
obj.on(eventName, callback, context);
|
40
|
+
|
41
|
+
var binding = {
|
42
|
+
type : 'default',
|
43
|
+
obj: obj,
|
44
|
+
eventName: eventName,
|
45
|
+
callback: callback,
|
46
|
+
context: context
|
47
|
+
};
|
48
|
+
|
49
|
+
return binding;
|
50
|
+
},
|
51
|
+
unbindFrom : function(binding){
|
52
|
+
binding.obj.off(binding.eventName, binding.callback, binding.context);
|
53
|
+
}
|
54
|
+
},
|
55
|
+
|
56
|
+
// 'jquery' style handlers allow us to bind to jQuery
|
57
|
+
// (or compatible) objects
|
58
|
+
jquery : {
|
59
|
+
bindTo : function (obj, eventName, callback, context) {
|
60
|
+
context = context || this;
|
61
|
+
callback = _(callback).bind(context);
|
62
|
+
obj.on(eventName, callback);
|
63
|
+
|
64
|
+
var binding = {
|
65
|
+
type : 'jquery',
|
66
|
+
obj: obj,
|
67
|
+
eventName: eventName,
|
68
|
+
callback: callback,
|
69
|
+
context: context
|
70
|
+
};
|
71
|
+
|
72
|
+
return binding;
|
73
|
+
},
|
74
|
+
unbindFrom : function(binding){
|
75
|
+
binding.obj.off(binding.eventName, binding.callback);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
};
|
79
|
+
|
80
|
+
// Use whatever best logic necessary to determine the type
|
81
|
+
// of the supplied object
|
82
|
+
function getHandlerForObject(obj) {
|
83
|
+
if (obj.jquery) { return handlerMap.jquery; }
|
84
|
+
|
85
|
+
return handlerMap["default"];
|
86
|
+
}
|
87
|
+
|
88
|
+
// Constructor function
|
89
|
+
var EventBinder = function(){
|
90
|
+
this._eventBindings = [];
|
91
|
+
};
|
92
|
+
|
93
|
+
// Copy the `extend` function used by Backbone's classes
|
94
|
+
EventBinder.extend = Backbone.View.extend;
|
95
|
+
|
96
|
+
// Extend the EventBinder with additional methods
|
97
|
+
_.extend(EventBinder.prototype, {
|
98
|
+
|
99
|
+
// Delegate to the bindTo for the appropriate type and
|
100
|
+
// store the event binding in array so it can be unbound
|
101
|
+
// easily, at a later point in time.
|
102
|
+
bindTo: function(/* args... */) {
|
103
|
+
var obj = arguments[0];
|
104
|
+
var handlers = getHandlerForObject(obj);
|
105
|
+
|
106
|
+
var binding = handlers.bindTo.apply(this,arguments);
|
107
|
+
|
108
|
+
this._eventBindings.push(binding);
|
109
|
+
|
110
|
+
return binding;
|
111
|
+
},
|
112
|
+
|
113
|
+
// Unbind from a single binding object. Binding objects are
|
114
|
+
// returned from the `bindTo` method call.
|
115
|
+
unbindFrom: function(binding) {
|
116
|
+
handlerMap[binding.type].unbindFrom.apply(this,arguments);
|
117
|
+
this._eventBindings = _.reject(this._eventBindings, function(bind){return bind === binding;});
|
118
|
+
},
|
119
|
+
|
120
|
+
// Unbind all of the events that we have stored.
|
121
|
+
unbindAll: function() {
|
122
|
+
// The `unbindFrom` call removes elements from the array
|
123
|
+
// while it is being iterated, so clone it first.
|
124
|
+
var bindings = _.map(this._eventBindings, _.identity);
|
125
|
+
_.each(bindings, this.unbindFrom, this);
|
126
|
+
}
|
127
|
+
});
|
128
|
+
|
129
|
+
return EventBinder;
|
130
|
+
})(Backbone, _);
|
131
|
+
|
132
|
+
// Backbone.Wreqr, v0.0.0
|
133
|
+
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
134
|
+
// Distributed under MIT license
|
135
|
+
// http://github.com/marionettejs/backbone.wreqr
|
136
|
+
Backbone.Wreqr = (function(Backbone, Marionette, _){
|
137
|
+
"option strict";
|
138
|
+
var Wreqr = {};
|
139
|
+
|
140
|
+
Wreqr.Handlers = (function(Backbone, _){
|
141
|
+
"option strict";
|
142
|
+
|
143
|
+
var Handlers = function(){
|
144
|
+
"use strict";
|
145
|
+
this._handlers = {};
|
146
|
+
};
|
147
|
+
|
148
|
+
Handlers.extend = Backbone.Model.extend;
|
149
|
+
|
150
|
+
_.extend(Handlers.prototype, {
|
151
|
+
addHandler: function(name, handler, context){
|
152
|
+
var config = {
|
153
|
+
callback: handler,
|
154
|
+
context: context
|
155
|
+
};
|
156
|
+
|
157
|
+
this._handlers[name] = config;
|
158
|
+
},
|
159
|
+
|
160
|
+
getHandler: function(name){
|
161
|
+
var config = this._handlers[name];
|
162
|
+
|
163
|
+
if (!config){
|
164
|
+
throw new Error("Handler not found for '" + name + "'");
|
165
|
+
}
|
166
|
+
|
167
|
+
return function(){
|
168
|
+
return config.callback.apply(config.context, arguments);
|
169
|
+
};
|
170
|
+
},
|
171
|
+
|
172
|
+
removeHandler: function(name){
|
173
|
+
delete this._handlers[name];
|
174
|
+
},
|
175
|
+
|
176
|
+
removeAllHandlers: function(){
|
177
|
+
this._handlers = {};
|
178
|
+
}
|
179
|
+
});
|
180
|
+
|
181
|
+
return Handlers;
|
182
|
+
})(Backbone, _);
|
183
|
+
|
184
|
+
// Wreqr.Commands
|
185
|
+
// --------------
|
186
|
+
//
|
187
|
+
// A simple command pattern implementation. Register a command
|
188
|
+
// handler and execute it.
|
189
|
+
Wreqr.Commands = (function(Wreqr){
|
190
|
+
"option strict";
|
191
|
+
|
192
|
+
return Wreqr.Handlers.extend({
|
193
|
+
execute: function(name, args){
|
194
|
+
this.getHandler(name)(args);
|
195
|
+
}
|
196
|
+
});
|
197
|
+
|
198
|
+
})(Wreqr);
|
199
|
+
|
200
|
+
// Wreqr.RequestResponse
|
201
|
+
// ---------------------
|
202
|
+
//
|
203
|
+
// A simple request/response implementation. Register a
|
204
|
+
// request handler, and return a response from it
|
205
|
+
Wreqr.RequestResponse = (function(Wreqr){
|
206
|
+
"option strict";
|
207
|
+
|
208
|
+
return Wreqr.Handlers.extend({
|
209
|
+
request: function(name, args){
|
210
|
+
return this.getHandler(name)(args);
|
211
|
+
}
|
212
|
+
});
|
213
|
+
|
214
|
+
})(Wreqr);
|
215
|
+
|
216
|
+
// Event Aggregator
|
217
|
+
// ----------------
|
218
|
+
// A pub-sub object that can be used to decouple various parts
|
219
|
+
// of an application through event-driven architecture.
|
220
|
+
|
221
|
+
Wreqr.EventAggregator = (function(Backbone, _){
|
222
|
+
"option strict";
|
223
|
+
var EA = function(){};
|
224
|
+
|
225
|
+
// Copy the `extend` function used by Backbone's classes
|
226
|
+
EA.extend = Backbone.Model.extend;
|
227
|
+
|
228
|
+
// Copy the basic Backbone.Events on to the event aggregator
|
229
|
+
_.extend(EA.prototype, Backbone.Events);
|
230
|
+
|
231
|
+
return EA;
|
232
|
+
})(Backbone, _);
|
233
|
+
|
234
|
+
|
235
|
+
return Wreqr;
|
236
|
+
})(Backbone, Backbone.Marionette, _);
|
237
|
+
|
5
238
|
Backbone.Marionette = Marionette = (function(Backbone, _, $){
|
6
239
|
var Marionette = {};
|
7
240
|
|
@@ -61,6 +294,22 @@ Marionette.addEventBinder = function(target){
|
|
61
294
|
target.unbindAll = _.bind(eventBinder.unbindAll, eventBinder);
|
62
295
|
};
|
63
296
|
|
297
|
+
// Event Aggregator
|
298
|
+
// ----------------
|
299
|
+
// A pub-sub object that can be used to decouple various parts
|
300
|
+
// of an application through event-driven architecture.
|
301
|
+
//
|
302
|
+
// Extends [Backbone.Wreqr.EventAggregator](https://github.com/marionettejs/backbone.wreqr)
|
303
|
+
// and mixes in an EventBinder from [Backbone.EventBinder](https://github.com/marionettejs/backbone.eventbinder).
|
304
|
+
Marionette.EventAggregator = Backbone.Wreqr.EventAggregator.extend({
|
305
|
+
|
306
|
+
constructor: function(){
|
307
|
+
Marionette.addEventBinder(this);
|
308
|
+
Backbone.Wreqr.EventAggregator.prototype.constructor.apply(this, arguments);
|
309
|
+
}
|
310
|
+
|
311
|
+
});
|
312
|
+
|
64
313
|
// Marionette.View
|
65
314
|
// ---------------
|
66
315
|
|
@@ -120,12 +369,11 @@ Marionette.View = Backbone.View.extend({
|
|
120
369
|
configureTriggers: function(){
|
121
370
|
if (!this.triggers) { return; }
|
122
371
|
|
123
|
-
var triggers = this.triggers;
|
124
372
|
var that = this;
|
125
373
|
var triggerEvents = {};
|
126
374
|
|
127
375
|
// Allow `triggers` to be configured as a function
|
128
|
-
|
376
|
+
var triggers = _.result(this, "triggers");
|
129
377
|
|
130
378
|
// Configure the triggers, prevent default
|
131
379
|
// action and stop propagation of DOM events
|
@@ -234,7 +482,7 @@ Marionette.ItemView = Marionette.View.extend({
|
|
234
482
|
// You can override the `serializeData` method in your own view
|
235
483
|
// definition, to provide custom serialization for your view's data.
|
236
484
|
serializeData: function(){
|
237
|
-
var data;
|
485
|
+
var data = {};
|
238
486
|
|
239
487
|
if (this.model) {
|
240
488
|
data = this.model.toJSON();
|
@@ -243,8 +491,6 @@ Marionette.ItemView = Marionette.View.extend({
|
|
243
491
|
data = { items: this.collection.toJSON() };
|
244
492
|
}
|
245
493
|
|
246
|
-
data = this.mixinTemplateHelpers(data);
|
247
|
-
|
248
494
|
return data;
|
249
495
|
},
|
250
496
|
|
@@ -260,6 +506,8 @@ Marionette.ItemView = Marionette.View.extend({
|
|
260
506
|
this.triggerMethod("item:before:render", this);
|
261
507
|
|
262
508
|
var data = this.serializeData();
|
509
|
+
data = this.mixinTemplateHelpers(data);
|
510
|
+
|
263
511
|
var template = this.getTemplate();
|
264
512
|
var html = Marionette.Renderer.render(template, data);
|
265
513
|
this.$el.html(html);
|
@@ -288,11 +536,15 @@ Marionette.ItemView = Marionette.View.extend({
|
|
288
536
|
// A view that iterates over a Backbone.Collection
|
289
537
|
// and renders an individual ItemView for each model.
|
290
538
|
Marionette.CollectionView = Marionette.View.extend({
|
291
|
-
constructor: function(){
|
539
|
+
constructor: function(options){
|
292
540
|
this.initChildViewStorage();
|
293
541
|
Marionette.View.prototype.constructor.apply(this, arguments);
|
294
542
|
this.initialEvents();
|
295
543
|
this.onShowCallbacks = new Marionette.Callbacks();
|
544
|
+
|
545
|
+
if (options && options.itemViewOptions) {
|
546
|
+
this.itemViewOptions = options.itemViewOptions;
|
547
|
+
}
|
296
548
|
},
|
297
549
|
|
298
550
|
// Configured the initial events that the collection view
|
@@ -421,14 +673,6 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
421
673
|
this.storeChild(view);
|
422
674
|
this.triggerMethod("item:added", view);
|
423
675
|
|
424
|
-
// Render it and show it
|
425
|
-
var renderResult = this.renderItemView(view, index);
|
426
|
-
|
427
|
-
// call onShow for child item views
|
428
|
-
if (view.onShow){
|
429
|
-
this.onShowCallbacks.add(view.onShow, view);
|
430
|
-
}
|
431
|
-
|
432
676
|
// Forward all child item view events through the parent,
|
433
677
|
// prepending "itemview:" to the event name
|
434
678
|
var childBinding = this.bindTo(view, "all", function(){
|
@@ -444,6 +688,14 @@ Marionette.CollectionView = Marionette.View.extend({
|
|
444
688
|
this.childBindings = this.childBindings || {};
|
445
689
|
this.childBindings[view.cid] = childBinding;
|
446
690
|
|
691
|
+
// Render it and show it
|
692
|
+
var renderResult = this.renderItemView(view, index);
|
693
|
+
|
694
|
+
// call onShow for child item views
|
695
|
+
if (view.onShow){
|
696
|
+
this.onShowCallbacks.add(view.onShow, view);
|
697
|
+
}
|
698
|
+
|
447
699
|
return renderResult;
|
448
700
|
},
|
449
701
|
|
@@ -602,7 +854,6 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
|
|
602
854
|
this.bindUIElements();
|
603
855
|
|
604
856
|
this.triggerMethod("composite:model:rendered");
|
605
|
-
this.triggerMethod("render");
|
606
857
|
|
607
858
|
this.renderCollection();
|
608
859
|
this.triggerMethod("composite:rendered");
|
@@ -784,11 +1035,8 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
784
1035
|
view.render();
|
785
1036
|
this.open(view);
|
786
1037
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
if (this.onShow) { this.onShow(view); }
|
791
|
-
this.trigger("view:show", view);
|
1038
|
+
Marionette.triggerMethod.call(view, "show");
|
1039
|
+
Marionette.triggerMethod.call(this, "show");
|
792
1040
|
|
793
1041
|
this.currentView = view;
|
794
1042
|
},
|
@@ -818,7 +1066,7 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
|
|
818
1066
|
if (!view || view.isClosed){ return; }
|
819
1067
|
|
820
1068
|
if (view.close) { view.close(); }
|
821
|
-
|
1069
|
+
Marionette.triggerMethod.call(this, "close");
|
822
1070
|
|
823
1071
|
delete this.currentView;
|
824
1072
|
},
|
@@ -859,6 +1107,7 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
859
1107
|
// Ensure the regions are avialable when the `initialize` method
|
860
1108
|
// is called.
|
861
1109
|
constructor: function () {
|
1110
|
+
this._firstRender = true;
|
862
1111
|
this.initializeRegions();
|
863
1112
|
Backbone.Marionette.ItemView.apply(this, arguments);
|
864
1113
|
},
|
@@ -868,13 +1117,16 @@ Marionette.Layout = Marionette.ItemView.extend({
|
|
868
1117
|
// views that the regions are showing and then reset the `el`
|
869
1118
|
// for the regions to the newly rendered DOM elements.
|
870
1119
|
render: function(){
|
871
|
-
|
872
|
-
|
873
|
-
|
1120
|
+
|
1121
|
+
if (this._firstRender){
|
1122
|
+
// if this is the first render, don't do anything to
|
1123
|
+
// reset the regions
|
1124
|
+
this._firstRender = false;
|
1125
|
+
} else {
|
1126
|
+
// If this is not the first render call, then we need to
|
1127
|
+
// re-initializing the `el` for each region
|
874
1128
|
this.closeRegions();
|
875
1129
|
this.reInitializeRegions();
|
876
|
-
} else {
|
877
|
-
this._firstRender = false;
|
878
1130
|
}
|
879
1131
|
|
880
1132
|
var result = Marionette.ItemView.prototype.render.apply(this, arguments);
|
@@ -966,6 +1218,7 @@ Marionette.Application = function(options){
|
|
966
1218
|
_.extend(this, options);
|
967
1219
|
|
968
1220
|
Marionette.addEventBinder(this);
|
1221
|
+
this.triggerMethod = Marionette.triggerMethod;
|
969
1222
|
};
|
970
1223
|
|
971
1224
|
_.extend(Marionette.Application.prototype, Backbone.Events, {
|
@@ -990,11 +1243,11 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
|
|
990
1243
|
// initializes all of the regions that have been added
|
991
1244
|
// to the app, and runs all of the initializer functions
|
992
1245
|
start: function(options){
|
993
|
-
this.
|
1246
|
+
this.triggerMethod("initialize:before", options);
|
994
1247
|
this.initCallbacks.run(options, this);
|
995
|
-
this.
|
1248
|
+
this.triggerMethod("initialize:after", options);
|
996
1249
|
|
997
|
-
this.
|
1250
|
+
this.triggerMethod("start", options);
|
998
1251
|
},
|
999
1252
|
|
1000
1253
|
// Add regions to your app.
|
@@ -1477,14 +1730,6 @@ _.extend(Marionette.Callbacks.prototype, {
|
|
1477
1730
|
});
|
1478
1731
|
|
1479
1732
|
|
1480
|
-
// Event Aggregator
|
1481
|
-
// ----------------
|
1482
|
-
// A pub-sub object that can be used to decouple various parts
|
1483
|
-
// of an application through event-driven architecture.
|
1484
|
-
//
|
1485
|
-
// https://github.com/marionettejs/backbone.wreqr
|
1486
|
-
Marionette.EventAggregator = Backbone.Wreqr.EventAggregator;
|
1487
|
-
|
1488
1733
|
|
1489
1734
|
return Marionette;
|
1490
|
-
})(Backbone, _, $ || window.jQuery || window.Zepto || window.ender);
|
1735
|
+
})(Backbone, _, $ || window.jQuery || window.Zepto || window.ender);
|