marionette-rails 1.0.0.beta1 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,240 @@
1
- // Backbone.Marionette, v1.0.0-beta1
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.marionette
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
- if (_.isFunction(triggers)){ triggers = triggers.call(this); }
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
- if (view.onShow) { view.onShow(); }
788
- view.trigger("show");
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
- this.trigger("view:closed", view);
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
- // If this is not the first render call, then we need to
872
- // re-initializing the `el` for each region
873
- if (!this._firstRender){
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.trigger("initialize:before", options);
1246
+ this.triggerMethod("initialize:before", options);
994
1247
  this.initCallbacks.run(options, this);
995
- this.trigger("initialize:after", options);
1248
+ this.triggerMethod("initialize:after", options);
996
1249
 
997
- this.trigger("start", options);
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);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marionette-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta1
4
+ version: 1.0.0.beta2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors: