marionette-rails 0.10.2 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,65 +1,65 @@
1
- // Backbone.Marionette, v0.10.2
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/derickbailey/backbone.marionette
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
- // EventBinder
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
- _.extend(Marionette.EventBinder.prototype, {
23
- // Store the event binding in array so it can be unbound
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
- this._eventBindings.push(binding);
14
+ // Borrow the Backbone `extend` method so we can use it as needed
15
+ Marionette.extend = Backbone.Model.extend;
37
16
 
38
- return binding;
39
- },
40
-
41
- // Unbind from a single binding object. Binding objects are
42
- // returned from the `bindTo` method call.
43
- unbindFrom: function(binding){
44
- binding.obj.off(binding.eventName, binding.callback, binding.context);
45
- this._eventBindings = _.reject(this._eventBindings, function(bind){return bind === binding;});
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
- // Unbind all of the events that we have stored.
49
- unbindAll: function () {
50
- var that = this;
36
+ this.trigger.apply(this, arguments);
51
37
 
52
- // The `unbindFrom` call removes elements from the array
53
- // while it is being iterated, so clone it first.
54
- var bindings = _.map(this._eventBindings, _.identity);
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
- // Copy the `extend` function used by Backbone's classes
62
- Marionette.EventBinder.extend = Backbone.View.extend;
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
- var eventBinder = new Marionette.EventBinder();
72
- _.extend(this, eventBinder);
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.beforeClose) { this.beforeClose(); }
166
+ if (this.isClosed) { return; }
184
167
 
185
- this.remove();
168
+ this.triggerMethod("before:close");
186
169
 
187
- if (this.onClose) { this.onClose(); }
188
- this.trigger('close');
170
+ this.remove();
189
171
  this.unbindAll();
190
- this.unbind();
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
- if (this.beforeRender){ this.beforeRender(); }
253
- this.trigger("before:render", this);
254
- this.trigger("item:before:render", 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
- if (this.onRender){ this.onRender(); }
263
- this.trigger("render", this);
264
- this.trigger("item:rendered", this);
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.trigger('item:before:close');
277
+ if (this.isClosed){ return; }
278
+
279
+ this.triggerMethod('item:before:close');
272
280
  Marionette.View.prototype.close.apply(this, arguments);
273
- this.trigger('item:closed');
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
- return this.addItemView(item, ItemView, options.index);
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
- if (this.beforeRender) { this.beforeRender(); }
318
- this.trigger("before:render", 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
- if (this.onRender) { this.onRender(); }
326
- this.trigger("render", 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
- if (this.onItemAdded){ this.onItemAdded(view); }
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.trigger.apply(that, args);
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.trigger("item:removed", view);
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.trigger("collection:before:close");
513
+ if (this.isClosed){ return; }
514
+
515
+ this.triggerMethod("collection:before:close");
499
516
  this.closeChildren();
500
- this.trigger("collection:closed");
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
- var that = this;
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
- // the ui bindings is done here and not at the end of render since they should be
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
- this.trigger("composite:model:rendered");
570
- this.trigger("render");
603
+
604
+ this.triggerMethod("composite:model:rendered");
605
+ this.triggerMethod("render");
571
606
 
572
607
  this.renderCollection();
573
- this.trigger("composite:rendered");
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.trigger("composite:collection:rendered");
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
- container = containerView.$itemViewContainer;
609
- } else {
610
- if (containerView.itemViewContainer){
611
- container = containerView.$(_.result(containerView, "itemViewContainer"));
612
-
613
- if (container.length <= 0) {
614
- var err = new Error("Missing `itemViewContainer`");
615
- err.name = "ItemViewContainerMissingError";
616
- throw err;
617
- }
618
- } else {
619
- container = containerView.$el;
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
- containerView.$itemViewContainer = container;
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 eventBinder = new Marionette.EventBinder();
644
- _.extend(this, eventBinder, options);
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 = Backbone.View.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
- _.each(this.regions, function (region, name) {
789
- var regionIsString = (typeof region === "string");
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 selector, RegionType;
798
-
799
- if (regionIsString) {
800
- selector = region;
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
- var eventBinder = new Marionette.EventBinder();
870
- _.extend(this, eventBinder, options);
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 RegionValue, regionObj, region;
898
-
899
- for(region in regions){
900
- if (regions.hasOwnProperty(region)){
901
- RegionValue = regions[region];
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 = Backbone.View.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, customArgs){
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
- var eventBinder = new Marionette.EventBinder();
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
- this.config.customArgs
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, customArgs);
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, customArgs){
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, customArgs);
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
- Marionette.EventAggregator = Marionette.EventBinder.extend({
1393
-
1394
- // Extend any provided options directly on to the event binder
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
- prerelease: false
5
- segments:
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
- date: 2012-09-26 00:00:00 -07:00
18
- default_executable:
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
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
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
- version_requirements: *id001
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
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- segments:
62
- - 0
63
- version: "0"
64
- required_rubygems_version: !ruby/object:Gem::Requirement
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.3.6
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
-