tableling-rails 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,11 +2,12 @@
2
2
  module Tableling
3
3
 
4
4
  class Field
5
- attr_reader :name
5
+ attr_accessor :name, :alias
6
6
 
7
7
  def initialize name, view, options = {}, &block
8
8
 
9
9
  @name, @view = name.to_s, view
10
+ @alias = options[:as].try :to_s
10
11
  @value_column = options[:value].try :to_s
11
12
  @includes = options[:includes]
12
13
 
@@ -19,6 +20,14 @@ module Tableling
19
20
  instance_eval &block if block
20
21
  end
21
22
 
23
+ def working_name
24
+ @alias || @name
25
+ end
26
+
27
+ def as name
28
+ @alias = name.to_s
29
+ end
30
+
22
31
  def order &block
23
32
  @order_block = block
24
33
  end
@@ -1,3 +1,3 @@
1
1
  module Tableling
2
- VERSION = "0.0.18"
2
+ VERSION = "0.0.19"
3
3
  end
@@ -42,22 +42,34 @@ module Tableling
42
42
  if options[:sort].present?
43
43
  options[:sort].select{ |item| item.match /\A([^ ]+)* (asc|desc)\Z/i }.each do |item|
44
44
  parts = item.split ' '
45
- f = field parts[0]
45
+ # TODO: handle unknown fields
46
+ f = @fields.find{ |f| f.working_name.to_s == parts[0] }
46
47
  q = f.with_order q, parts[1].downcase.to_sym if f
47
48
  end
48
49
  end
49
50
 
50
51
  @fields.each{ |f| q = f.with_includes q }
51
52
 
52
- limit = options[:pageSize].to_i
53
- limit = 10 if limit <= 0
54
- q = q.limit limit
53
+ response_options = {
54
+ total: total
55
+ }
56
+
57
+ page_size = options[:pageSize].to_i
58
+ page_size = 10 if page_size <= 0
59
+ q = q.limit page_size
60
+
61
+ max_page = (total.to_f / page_size).ceil
62
+ page = options[:page].to_i
55
63
 
56
- offset = options[:page].to_i - 1
57
- offset = 0 if offset < 0
58
- q = q.offset offset * limit
64
+ # TODO: allow this to be disabled
65
+ if page < 1 or page > max_page
66
+ page = 1
67
+ response_options[:page] = 1
68
+ end
69
+
70
+ q = q.offset (page - 1) * page_size
59
71
 
60
- serialize_response total, q
72
+ serialize_response q, response_options
61
73
  end
62
74
 
63
75
  class DSL
@@ -86,12 +98,9 @@ module Tableling
86
98
 
87
99
  private
88
100
 
89
- def serialize_response total, query
101
+ def serialize_response query, response_options = {}
90
102
 
91
- res = {
92
- total: total,
93
- data: query.all
94
- }
103
+ res = response_options.merge data: query.all
95
104
 
96
105
  if @serialize_response_block
97
106
  @serialize_response_block.call res
@@ -1572,7 +1572,7 @@
1572
1572
 
1573
1573
  // Backbone.BabySitter
1574
1574
  // -------------------
1575
- // v0.0.5
1575
+ // v0.0.6
1576
1576
  //
1577
1577
  // Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
1578
1578
  // Distributed under MIT license
@@ -1590,14 +1590,13 @@ Backbone.ChildViewContainer = (function(Backbone, _){
1590
1590
  // Container Constructor
1591
1591
  // ---------------------
1592
1592
 
1593
- var Container = function(initialViews){
1593
+ var Container = function(views){
1594
1594
  this._views = {};
1595
1595
  this._indexByModel = {};
1596
- this._indexByCollection = {};
1597
1596
  this._indexByCustom = {};
1598
1597
  this._updateLength();
1599
1598
 
1600
- this._addInitialViews(initialViews);
1599
+ _.each(views, this.add, this);
1601
1600
  };
1602
1601
 
1603
1602
  // Container Methods
@@ -1607,7 +1606,7 @@ Backbone.ChildViewContainer = (function(Backbone, _){
1607
1606
 
1608
1607
  // Add a view to this container. Stores the view
1609
1608
  // by `cid` and makes it searchable by the model
1610
- // and/or collection of the view. Optionally specify
1609
+ // cid (and model itself). Optionally specify
1611
1610
  // a custom key to store an retrieve the view.
1612
1611
  add: function(view, customIndex){
1613
1612
  var viewCid = view.cid;
@@ -1620,11 +1619,6 @@ Backbone.ChildViewContainer = (function(Backbone, _){
1620
1619
  this._indexByModel[view.model.cid] = viewCid;
1621
1620
  }
1622
1621
 
1623
- // index it by collection
1624
- if (view.collection){
1625
- this._indexByCollection[view.collection.cid] = viewCid;
1626
- }
1627
-
1628
1622
  // index by custom
1629
1623
  if (customIndex){
1630
1624
  this._indexByCustom[customIndex] = viewCid;
@@ -1634,18 +1628,16 @@ Backbone.ChildViewContainer = (function(Backbone, _){
1634
1628
  },
1635
1629
 
1636
1630
  // Find a view by the model that was attached to
1637
- // it. Uses the model's `cid` to find it, and
1638
- // retrieves the view by it's `cid` from the result
1631
+ // it. Uses the model's `cid` to find it.
1639
1632
  findByModel: function(model){
1640
- var viewCid = this._indexByModel[model.cid];
1641
- return this.findByCid(viewCid);
1633
+ return this.findByModelCid(model.cid);
1642
1634
  },
1643
1635
 
1644
- // Find a view by the collection that was attached to
1645
- // it. Uses the collection's `cid` to find it, and
1646
- // retrieves the view by it's `cid` from the result
1647
- findByCollection: function(col){
1648
- var viewCid = this._indexByCollection[col.cid];
1636
+ // Find a view by the `cid` of the model that was attached to
1637
+ // it. Uses the model's `cid` to find the view `cid` and
1638
+ // retrieve the view using it.
1639
+ findByModelCid: function(modelCid){
1640
+ var viewCid = this._indexByModel[modelCid];
1649
1641
  return this.findByCid(viewCid);
1650
1642
  },
1651
1643
 
@@ -1675,26 +1667,13 @@ Backbone.ChildViewContainer = (function(Backbone, _){
1675
1667
  delete this._indexByModel[view.model.cid];
1676
1668
  }
1677
1669
 
1678
- // delete collection index
1679
- if (view.collection){
1680
- delete this._indexByCollection[view.collection.cid];
1681
- }
1682
-
1683
1670
  // delete custom index
1684
- var cust;
1685
-
1686
- for (var key in this._indexByCustom){
1687
- if (this._indexByCustom.hasOwnProperty(key)){
1688
- if (this._indexByCustom[key] === viewCid){
1689
- cust = key;
1690
- break;
1691
- }
1671
+ _.any(this._indexByCustom, function(cid, key) {
1672
+ if (cid === viewCid) {
1673
+ delete this._indexByCustom[key];
1674
+ return true;
1692
1675
  }
1693
- }
1694
-
1695
- if (cust){
1696
- delete this._indexByCustom[cust];
1697
- }
1676
+ }, this);
1698
1677
 
1699
1678
  // remove the view from the container
1700
1679
  delete this._views[viewCid];
@@ -1706,44 +1685,24 @@ Backbone.ChildViewContainer = (function(Backbone, _){
1706
1685
  // Call a method on every view in the container,
1707
1686
  // passing parameters to the call method one at a
1708
1687
  // time, like `function.call`.
1709
- call: function(method, args){
1710
- args = Array.prototype.slice.call(arguments, 1);
1711
- this.apply(method, args);
1688
+ call: function(method){
1689
+ this.apply(method, _.tail(arguments));
1712
1690
  },
1713
1691
 
1714
1692
  // Apply a method on every view in the container,
1715
1693
  // passing parameters to the call method one at a
1716
1694
  // time, like `function.apply`.
1717
1695
  apply: function(method, args){
1718
- var view;
1719
-
1720
- // fix for IE < 9
1721
- args = args || [];
1722
-
1723
- _.each(this._views, function(view, key){
1696
+ _.each(this._views, function(view){
1724
1697
  if (_.isFunction(view[method])){
1725
- view[method].apply(view, args);
1698
+ view[method].apply(view, args || []);
1726
1699
  }
1727
1700
  });
1728
-
1729
1701
  },
1730
1702
 
1731
1703
  // Update the `.length` attribute on this container
1732
1704
  _updateLength: function(){
1733
1705
  this.length = _.size(this._views);
1734
- },
1735
-
1736
- // set up an initial list of views
1737
- _addInitialViews: function(views){
1738
- if (!views){ return; }
1739
-
1740
- var view, i,
1741
- length = views.length;
1742
-
1743
- for (i=0; i<length; i++){
1744
- view = views[i];
1745
- this.add(view);
1746
- }
1747
1706
  }
1748
1707
  });
1749
1708
 
@@ -2071,7 +2030,7 @@ Marionette.extend = Backbone.Model.extend;
2071
2030
  // --------------------
2072
2031
 
2073
2032
  // Retrieve an object, function or other value from a target
2074
- // object or it's `options`, with `options` taking precedence.
2033
+ // object or its `options`, with `options` taking precedence.
2075
2034
  Marionette.getOption = function(target, optionName){
2076
2035
  if (!target || !optionName){ return; }
2077
2036
  var value;
@@ -2211,7 +2170,7 @@ Marionette.MonitorDOMRefresh = (function(){
2211
2170
  var methodNames = methods.split(/\s+/);
2212
2171
 
2213
2172
  _.each(methodNames,function(methodName) {
2214
- var method = target[method];
2173
+ var method = target[methodName];
2215
2174
  target.stopListening(entity, evt, method, target);
2216
2175
  });
2217
2176
  }
@@ -2452,18 +2411,24 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
2452
2411
 
2453
2412
  this.ensureEl();
2454
2413
 
2455
- if (view !== this.currentView) {
2414
+ var isViewClosed = view.isClosed || _.isUndefined(view.$el);
2415
+
2416
+ var isDifferentView = view !== this.currentView;
2417
+
2418
+ if (isDifferentView) {
2456
2419
  this.close();
2457
- view.render();
2458
- this.open(view);
2459
- } else {
2460
- view.render();
2461
2420
  }
2462
2421
 
2463
- Marionette.triggerMethod.call(view, "show");
2464
- Marionette.triggerMethod.call(this, "show", view);
2422
+ view.render();
2465
2423
 
2424
+ if (isDifferentView || isViewClosed) {
2425
+ this.open(view);
2426
+ }
2427
+
2466
2428
  this.currentView = view;
2429
+
2430
+ Marionette.triggerMethod.call(this, "show", view);
2431
+ Marionette.triggerMethod.call(view, "show");
2467
2432
  },
2468
2433
 
2469
2434
  ensureEl: function(){
@@ -2614,14 +2579,20 @@ Marionette.RegionManager = (function(Marionette){
2614
2579
  // internal method to store regions
2615
2580
  _store: function(name, region){
2616
2581
  this._regions[name] = region;
2617
- this.length = _.size(this._regions);
2582
+ this._setLength();
2618
2583
  },
2619
2584
 
2620
2585
  // internal method to remove a region
2621
2586
  _remove: function(name, region){
2622
2587
  region.close();
2623
2588
  delete this._regions[name];
2589
+ this._setLength();
2624
2590
  this.triggerMethod("region:remove", name, region);
2591
+ },
2592
+
2593
+ // set the number of regions current held
2594
+ _setLength: function(){
2595
+ this.length = _.size(this._regions);
2625
2596
  }
2626
2597
 
2627
2598
  });
@@ -2700,7 +2671,7 @@ _.extend(Marionette.TemplateCache, {
2700
2671
  });
2701
2672
 
2702
2673
  // TemplateCache instance methods, allowing each
2703
- // template cache object to manage it's own state
2674
+ // template cache object to manage its own state
2704
2675
  // and know whether or not it has been loaded
2705
2676
  _.extend(Marionette.TemplateCache.prototype, {
2706
2677
 
@@ -2755,7 +2726,20 @@ Marionette.Renderer = {
2755
2726
  // template function. Override this method to provide your own
2756
2727
  // custom rendering and template handling for all of Marionette.
2757
2728
  render: function(template, data){
2758
- var templateFunc = typeof template === 'function' ? template : Marionette.TemplateCache.get(template);
2729
+
2730
+ if (!template) {
2731
+ var error = new Error("Cannot render the template since it's false, null or undefined.");
2732
+ error.name = "TemplateNotFoundError";
2733
+ throw error;
2734
+ }
2735
+
2736
+ var templateFunc;
2737
+ if (typeof template === "function"){
2738
+ templateFunc = template;
2739
+ } else {
2740
+ templateFunc = Marionette.TemplateCache.get(template);
2741
+ }
2742
+
2759
2743
  return templateFunc(data);
2760
2744
  }
2761
2745
  };
@@ -2821,7 +2805,7 @@ Marionette.View = Backbone.View.extend({
2821
2805
  // build the event handler function for the DOM event
2822
2806
  triggerEvents[key] = function(e){
2823
2807
 
2824
- // stop the event in it's tracks
2808
+ // stop the event in its tracks
2825
2809
  if (e && e.preventDefault){ e.preventDefault(); }
2826
2810
  if (e && e.stopPropagation){ e.stopPropagation(); }
2827
2811
 
@@ -2946,7 +2930,10 @@ Marionette.View = Backbone.View.extend({
2946
2930
  // A single item view implementation that contains code for rendering
2947
2931
  // with underscore.js templates, serializing the view's model or collection,
2948
2932
  // and calling several methods on extended views, such as `onRender`.
2949
- Marionette.ItemView = Marionette.View.extend({
2933
+ Marionette.ItemView = Marionette.View.extend({
2934
+
2935
+ // Setting up the inheritance chain which allows changes to
2936
+ // Marionette.View.prototype.constructor which allows overriding
2950
2937
  constructor: function(){
2951
2938
  Marionette.View.prototype.constructor.apply(this, slice(arguments));
2952
2939
  },
@@ -2986,6 +2973,7 @@ Marionette.ItemView = Marionette.View.extend({
2986
2973
 
2987
2974
  var template = this.getTemplate();
2988
2975
  var html = Marionette.Renderer.render(template, data);
2976
+
2989
2977
  this.$el.html(html);
2990
2978
  this.bindUIElements();
2991
2979
 
@@ -3279,10 +3267,11 @@ Marionette.CollectionView = Marionette.View.extend({
3279
3267
  // Extends directly from CollectionView and also renders an
3280
3268
  // an item view as `modelView`, for the top leaf
3281
3269
  Marionette.CompositeView = Marionette.CollectionView.extend({
3282
- constructor: function(options){
3283
- Marionette.CollectionView.apply(this, slice(arguments));
3284
-
3285
- this.itemView = this.getItemView();
3270
+
3271
+ // Setting up the inheritance chain which allows changes to
3272
+ // Marionette.CollectionView.prototype.constructor which allows overriding
3273
+ constructor: function(){
3274
+ Marionette.CollectionView.prototype.constructor.apply(this, slice(arguments));
3286
3275
  },
3287
3276
 
3288
3277
  // Configured the initial events that the composite view
@@ -3370,7 +3359,7 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
3370
3359
  // `itemViewContainer` (a jQuery selector). Override this method to
3371
3360
  // provide custom logic of how the child item view instances have their
3372
3361
  // HTML appended to the composite view instance.
3373
- appendHtml: function(cv, iv){
3362
+ appendHtml: function(cv, iv, index){
3374
3363
  var $container = this.getItemViewContainer(cv);
3375
3364
  $container.append(iv.el);
3376
3365
  },
@@ -3428,7 +3417,7 @@ Marionette.Layout = Marionette.ItemView.extend({
3428
3417
  this._firstRender = true;
3429
3418
  this._initializeRegions(options);
3430
3419
 
3431
- Marionette.ItemView.call(this, options);
3420
+ Marionette.ItemView.prototype.constructor.call(this, options);
3432
3421
  },
3433
3422
 
3434
3423
  // Layout's render will use the existing region objects the
@@ -3893,7 +3882,7 @@ _.extend(Marionette.Module, {
3893
3882
  })(this, Backbone, _);
3894
3883
 
3895
3884
  /*!
3896
- * Tableling v0.0.20
3885
+ * Tableling v0.0.21
3897
3886
  * Copyright (c) 2012-2013 Simon Oulevay (Alpha Hydrae) <hydrae.alpha@gmail.com>
3898
3887
  * Distributed under MIT license
3899
3888
  * https://github.com/AlphaHydrae/tableling
@@ -3901,7 +3890,7 @@ _.extend(Marionette.Module, {
3901
3890
  Backbone.Tableling = Tableling = (function(Backbone, _, $){
3902
3891
 
3903
3892
  var Tableling = {
3904
- version : "0.0.20"
3893
+ version : "0.0.21"
3905
3894
  };
3906
3895
 
3907
3896
  // Tableling
@@ -3921,6 +3910,8 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
3921
3910
  initialize : function(options) {
3922
3911
  options = options || {};
3923
3912
 
3913
+ this.collection = options.collection;
3914
+
3924
3915
  // Table options can also be overriden for each instance at construction.
3925
3916
  this.config = _.extend(_.clone(this.config || {}), _.result(options, 'config') || {});
3926
3917
 
@@ -3933,7 +3924,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
3933
3924
 
3934
3925
  // Components should trigger the `table:update` event to update
3935
3926
  // the table (e.g. change page size, sort) and fetch the new data.
3936
- this.vent.on('table:update', this.update, this);
3927
+ this.vent.on('table:update', this.onUpdate, this);
3937
3928
 
3938
3929
  this.on('item:rendered', this.setup, this);
3939
3930
  },
@@ -3948,11 +3939,15 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
3948
3939
 
3949
3940
  // Subclasses must return the Backbone.Collection used to fetch data.
3950
3941
  getCollection : function() {
3951
- throw new Error('#getCollection not implemented. It should return the Backbone.Collection instance used to fetch data.');
3942
+ return this.collection;
3952
3943
  },
3953
3944
 
3954
3945
  // ### Refreshing the table
3955
3946
  update : function(config, options) {
3947
+ this.ventTrigger('table:update', config, options);
3948
+ },
3949
+
3950
+ onUpdate : function(config, options) {
3956
3951
 
3957
3952
  _.each(config || {}, _.bind(this.updateValue, this));
3958
3953
 
@@ -4014,6 +4009,12 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
4014
4009
  // which is the total number of items (not just in the current page).
4015
4010
  this.config.total = response.total;
4016
4011
 
4012
+ // The server may override the `page` property, for example if the
4013
+ // requested page was outside the range of available pages.
4014
+ if (response.page) {
4015
+ this.config.page = response.page;
4016
+ }
4017
+
4017
4018
  // `tableling:refreshed` is triggered after every refresh. The first argument
4018
4019
  // is the current table configuration with the following additional meta data:
4019
4020
  //
@@ -4107,18 +4108,20 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
4107
4108
  return view;
4108
4109
  },
4109
4110
 
4110
- // By default, a modular table expects a `table` module which
4111
+ // By default the collection is the one given at construction.
4112
+ // Otherwise, a modular table expects a `table` module which
4111
4113
  // should have a collection (e.g. a Marionette CompositeView or
4112
- // CollectionView). If your subclass does not have that, it
4114
+ // CollectionView). If your subclass does not have either, it
4113
4115
  // should override this method to return the Backbone.Collection
4114
4116
  // used to fetch table data.
4115
4117
  getCollection : function() {
4116
- return this.moduleViews.table.collection;
4118
+ return this.collection || (this.moduleViews && this.moduleViews.table ? this.moduleViews.table.collection : undefined);
4117
4119
  },
4118
4120
 
4119
4121
  getModuleOptions : function(name) {
4120
4122
  var options = this[name + 'ViewOptions'] || {};
4121
- return typeof(options) == 'function' ? options.call(this) : options;
4123
+ options = typeof(options) == 'function' ? options.call(this) : options;
4124
+ return name == 'table' ? _.defaults(options, { collection : this.collection }) : options;
4122
4125
  }
4123
4126
  });
4124
4127
 
@@ -4269,6 +4272,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
4269
4272
  this.vent = options.vent;
4270
4273
  this.sort = [];
4271
4274
  this.vent.on('table:setup', this.setSort, this);
4275
+ this.vent.on('table:refreshed', this.setSort, this);
4272
4276
  },
4273
4277
 
4274
4278
  updateSort : function(ev) {
@@ -4521,23 +4525,28 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
4521
4525
  return Math.ceil(this.data.total / this.data.pageSize);
4522
4526
  },
4523
4527
 
4524
- goToFirstPage : function() {
4528
+ goToFirstPage : function(e) {
4529
+ e.preventDefault();
4525
4530
  this.goToPageNumber(1);
4526
4531
  },
4527
4532
 
4528
- goToPreviousPage : function() {
4533
+ goToPreviousPage : function(e) {
4534
+ e.preventDefault();
4529
4535
  this.goToPageNumber(this.getPage(this.data) - 1);
4530
4536
  },
4531
4537
 
4532
4538
  goToPage : function(e) {
4539
+ e.preventDefault();
4533
4540
  this.goToPageNumber(parseInt($(e.target).text(), 10));
4534
4541
  },
4535
4542
 
4536
- goToNextPage : function() {
4543
+ goToNextPage : function(e) {
4544
+ e.preventDefault();
4537
4545
  this.goToPageNumber(this.getPage(this.data) + 1);
4538
4546
  },
4539
4547
 
4540
- goToLastPage : function() {
4548
+ goToLastPage : function(e) {
4549
+ e.preventDefault();
4541
4550
  this.goToPageNumber(this.numberOfPages());
4542
4551
  },
4543
4552
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Tableling v0.0.20
2
+ * Tableling v0.0.21
3
3
  * Copyright (c) 2012-2013 Simon Oulevay (Alpha Hydrae) <hydrae.alpha@gmail.com>
4
4
  * Distributed under MIT license
5
5
  * https://github.com/AlphaHydrae/tableling
@@ -7,7 +7,7 @@
7
7
  Backbone.Tableling = Tableling = (function(Backbone, _, $){
8
8
 
9
9
  var Tableling = {
10
- version : "0.0.20"
10
+ version : "0.0.21"
11
11
  };
12
12
 
13
13
  // Tableling
@@ -27,6 +27,8 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
27
27
  initialize : function(options) {
28
28
  options = options || {};
29
29
 
30
+ this.collection = options.collection;
31
+
30
32
  // Table options can also be overriden for each instance at construction.
31
33
  this.config = _.extend(_.clone(this.config || {}), _.result(options, 'config') || {});
32
34
 
@@ -39,7 +41,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
39
41
 
40
42
  // Components should trigger the `table:update` event to update
41
43
  // the table (e.g. change page size, sort) and fetch the new data.
42
- this.vent.on('table:update', this.update, this);
44
+ this.vent.on('table:update', this.onUpdate, this);
43
45
 
44
46
  this.on('item:rendered', this.setup, this);
45
47
  },
@@ -54,11 +56,15 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
54
56
 
55
57
  // Subclasses must return the Backbone.Collection used to fetch data.
56
58
  getCollection : function() {
57
- throw new Error('#getCollection not implemented. It should return the Backbone.Collection instance used to fetch data.');
59
+ return this.collection;
58
60
  },
59
61
 
60
62
  // ### Refreshing the table
61
63
  update : function(config, options) {
64
+ this.ventTrigger('table:update', config, options);
65
+ },
66
+
67
+ onUpdate : function(config, options) {
62
68
 
63
69
  _.each(config || {}, _.bind(this.updateValue, this));
64
70
 
@@ -120,6 +126,12 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
120
126
  // which is the total number of items (not just in the current page).
121
127
  this.config.total = response.total;
122
128
 
129
+ // The server may override the `page` property, for example if the
130
+ // requested page was outside the range of available pages.
131
+ if (response.page) {
132
+ this.config.page = response.page;
133
+ }
134
+
123
135
  // `tableling:refreshed` is triggered after every refresh. The first argument
124
136
  // is the current table configuration with the following additional meta data:
125
137
  //
@@ -213,18 +225,20 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
213
225
  return view;
214
226
  },
215
227
 
216
- // By default, a modular table expects a `table` module which
228
+ // By default the collection is the one given at construction.
229
+ // Otherwise, a modular table expects a `table` module which
217
230
  // should have a collection (e.g. a Marionette CompositeView or
218
- // CollectionView). If your subclass does not have that, it
231
+ // CollectionView). If your subclass does not have either, it
219
232
  // should override this method to return the Backbone.Collection
220
233
  // used to fetch table data.
221
234
  getCollection : function() {
222
- return this.moduleViews.table.collection;
235
+ return this.collection || (this.moduleViews && this.moduleViews.table ? this.moduleViews.table.collection : undefined);
223
236
  },
224
237
 
225
238
  getModuleOptions : function(name) {
226
239
  var options = this[name + 'ViewOptions'] || {};
227
- return typeof(options) == 'function' ? options.call(this) : options;
240
+ options = typeof(options) == 'function' ? options.call(this) : options;
241
+ return name == 'table' ? _.defaults(options, { collection : this.collection }) : options;
228
242
  }
229
243
  });
230
244
 
@@ -375,6 +389,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
375
389
  this.vent = options.vent;
376
390
  this.sort = [];
377
391
  this.vent.on('table:setup', this.setSort, this);
392
+ this.vent.on('table:refreshed', this.setSort, this);
378
393
  },
379
394
 
380
395
  updateSort : function(ev) {
@@ -627,23 +642,28 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
627
642
  return Math.ceil(this.data.total / this.data.pageSize);
628
643
  },
629
644
 
630
- goToFirstPage : function() {
645
+ goToFirstPage : function(e) {
646
+ e.preventDefault();
631
647
  this.goToPageNumber(1);
632
648
  },
633
649
 
634
- goToPreviousPage : function() {
650
+ goToPreviousPage : function(e) {
651
+ e.preventDefault();
635
652
  this.goToPageNumber(this.getPage(this.data) - 1);
636
653
  },
637
654
 
638
655
  goToPage : function(e) {
656
+ e.preventDefault();
639
657
  this.goToPageNumber(parseInt($(e.target).text(), 10));
640
658
  },
641
659
 
642
- goToNextPage : function() {
660
+ goToNextPage : function(e) {
661
+ e.preventDefault();
643
662
  this.goToPageNumber(this.getPage(this.data) + 1);
644
663
  },
645
664
 
646
- goToLastPage : function() {
665
+ goToLastPage : function(e) {
666
+ e.preventDefault();
647
667
  this.goToPageNumber(this.numberOfPages());
648
668
  },
649
669
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  json2.js
3
- 2012-10-08
3
+ 2013-05-26
4
4
 
5
5
  Public Domain.
6
6
 
@@ -173,7 +173,7 @@ if (typeof JSON !== 'object') {
173
173
 
174
174
  if (typeof Date.prototype.toJSON !== 'function') {
175
175
 
176
- Date.prototype.toJSON = function (key) {
176
+ Date.prototype.toJSON = function () {
177
177
 
178
178
  return isFinite(this.valueOf())
179
179
  ? this.getUTCFullYear() + '-' +
@@ -187,7 +187,7 @@ if (typeof JSON !== 'object') {
187
187
 
188
188
  String.prototype.toJSON =
189
189
  Number.prototype.toJSON =
190
- Boolean.prototype.toJSON = function (key) {
190
+ Boolean.prototype.toJSON = function () {
191
191
  return this.valueOf();
192
192
  };
193
193
  }
@@ -12885,7 +12885,7 @@ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
12885
12885
 
12886
12886
  // Backbone.BabySitter
12887
12887
  // -------------------
12888
- // v0.0.5
12888
+ // v0.0.6
12889
12889
  //
12890
12890
  // Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
12891
12891
  // Distributed under MIT license
@@ -12903,14 +12903,13 @@ Backbone.ChildViewContainer = (function(Backbone, _){
12903
12903
  // Container Constructor
12904
12904
  // ---------------------
12905
12905
 
12906
- var Container = function(initialViews){
12906
+ var Container = function(views){
12907
12907
  this._views = {};
12908
12908
  this._indexByModel = {};
12909
- this._indexByCollection = {};
12910
12909
  this._indexByCustom = {};
12911
12910
  this._updateLength();
12912
12911
 
12913
- this._addInitialViews(initialViews);
12912
+ _.each(views, this.add, this);
12914
12913
  };
12915
12914
 
12916
12915
  // Container Methods
@@ -12920,7 +12919,7 @@ Backbone.ChildViewContainer = (function(Backbone, _){
12920
12919
 
12921
12920
  // Add a view to this container. Stores the view
12922
12921
  // by `cid` and makes it searchable by the model
12923
- // and/or collection of the view. Optionally specify
12922
+ // cid (and model itself). Optionally specify
12924
12923
  // a custom key to store an retrieve the view.
12925
12924
  add: function(view, customIndex){
12926
12925
  var viewCid = view.cid;
@@ -12933,11 +12932,6 @@ Backbone.ChildViewContainer = (function(Backbone, _){
12933
12932
  this._indexByModel[view.model.cid] = viewCid;
12934
12933
  }
12935
12934
 
12936
- // index it by collection
12937
- if (view.collection){
12938
- this._indexByCollection[view.collection.cid] = viewCid;
12939
- }
12940
-
12941
12935
  // index by custom
12942
12936
  if (customIndex){
12943
12937
  this._indexByCustom[customIndex] = viewCid;
@@ -12947,18 +12941,16 @@ Backbone.ChildViewContainer = (function(Backbone, _){
12947
12941
  },
12948
12942
 
12949
12943
  // Find a view by the model that was attached to
12950
- // it. Uses the model's `cid` to find it, and
12951
- // retrieves the view by it's `cid` from the result
12944
+ // it. Uses the model's `cid` to find it.
12952
12945
  findByModel: function(model){
12953
- var viewCid = this._indexByModel[model.cid];
12954
- return this.findByCid(viewCid);
12946
+ return this.findByModelCid(model.cid);
12955
12947
  },
12956
12948
 
12957
- // Find a view by the collection that was attached to
12958
- // it. Uses the collection's `cid` to find it, and
12959
- // retrieves the view by it's `cid` from the result
12960
- findByCollection: function(col){
12961
- var viewCid = this._indexByCollection[col.cid];
12949
+ // Find a view by the `cid` of the model that was attached to
12950
+ // it. Uses the model's `cid` to find the view `cid` and
12951
+ // retrieve the view using it.
12952
+ findByModelCid: function(modelCid){
12953
+ var viewCid = this._indexByModel[modelCid];
12962
12954
  return this.findByCid(viewCid);
12963
12955
  },
12964
12956
 
@@ -12988,26 +12980,13 @@ Backbone.ChildViewContainer = (function(Backbone, _){
12988
12980
  delete this._indexByModel[view.model.cid];
12989
12981
  }
12990
12982
 
12991
- // delete collection index
12992
- if (view.collection){
12993
- delete this._indexByCollection[view.collection.cid];
12994
- }
12995
-
12996
12983
  // delete custom index
12997
- var cust;
12998
-
12999
- for (var key in this._indexByCustom){
13000
- if (this._indexByCustom.hasOwnProperty(key)){
13001
- if (this._indexByCustom[key] === viewCid){
13002
- cust = key;
13003
- break;
13004
- }
12984
+ _.any(this._indexByCustom, function(cid, key) {
12985
+ if (cid === viewCid) {
12986
+ delete this._indexByCustom[key];
12987
+ return true;
13005
12988
  }
13006
- }
13007
-
13008
- if (cust){
13009
- delete this._indexByCustom[cust];
13010
- }
12989
+ }, this);
13011
12990
 
13012
12991
  // remove the view from the container
13013
12992
  delete this._views[viewCid];
@@ -13019,44 +12998,24 @@ Backbone.ChildViewContainer = (function(Backbone, _){
13019
12998
  // Call a method on every view in the container,
13020
12999
  // passing parameters to the call method one at a
13021
13000
  // time, like `function.call`.
13022
- call: function(method, args){
13023
- args = Array.prototype.slice.call(arguments, 1);
13024
- this.apply(method, args);
13001
+ call: function(method){
13002
+ this.apply(method, _.tail(arguments));
13025
13003
  },
13026
13004
 
13027
13005
  // Apply a method on every view in the container,
13028
13006
  // passing parameters to the call method one at a
13029
13007
  // time, like `function.apply`.
13030
13008
  apply: function(method, args){
13031
- var view;
13032
-
13033
- // fix for IE < 9
13034
- args = args || [];
13035
-
13036
- _.each(this._views, function(view, key){
13009
+ _.each(this._views, function(view){
13037
13010
  if (_.isFunction(view[method])){
13038
- view[method].apply(view, args);
13011
+ view[method].apply(view, args || []);
13039
13012
  }
13040
13013
  });
13041
-
13042
13014
  },
13043
13015
 
13044
13016
  // Update the `.length` attribute on this container
13045
13017
  _updateLength: function(){
13046
13018
  this.length = _.size(this._views);
13047
- },
13048
-
13049
- // set up an initial list of views
13050
- _addInitialViews: function(views){
13051
- if (!views){ return; }
13052
-
13053
- var view, i,
13054
- length = views.length;
13055
-
13056
- for (i=0; i<length; i++){
13057
- view = views[i];
13058
- this.add(view);
13059
- }
13060
13019
  }
13061
13020
  });
13062
13021
 
@@ -13384,7 +13343,7 @@ Marionette.extend = Backbone.Model.extend;
13384
13343
  // --------------------
13385
13344
 
13386
13345
  // Retrieve an object, function or other value from a target
13387
- // object or it's `options`, with `options` taking precedence.
13346
+ // object or its `options`, with `options` taking precedence.
13388
13347
  Marionette.getOption = function(target, optionName){
13389
13348
  if (!target || !optionName){ return; }
13390
13349
  var value;
@@ -13524,7 +13483,7 @@ Marionette.MonitorDOMRefresh = (function(){
13524
13483
  var methodNames = methods.split(/\s+/);
13525
13484
 
13526
13485
  _.each(methodNames,function(methodName) {
13527
- var method = target[method];
13486
+ var method = target[methodName];
13528
13487
  target.stopListening(entity, evt, method, target);
13529
13488
  });
13530
13489
  }
@@ -13765,18 +13724,24 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
13765
13724
 
13766
13725
  this.ensureEl();
13767
13726
 
13768
- if (view !== this.currentView) {
13727
+ var isViewClosed = view.isClosed || _.isUndefined(view.$el);
13728
+
13729
+ var isDifferentView = view !== this.currentView;
13730
+
13731
+ if (isDifferentView) {
13769
13732
  this.close();
13770
- view.render();
13771
- this.open(view);
13772
- } else {
13773
- view.render();
13774
13733
  }
13775
13734
 
13776
- Marionette.triggerMethod.call(view, "show");
13777
- Marionette.triggerMethod.call(this, "show", view);
13735
+ view.render();
13778
13736
 
13737
+ if (isDifferentView || isViewClosed) {
13738
+ this.open(view);
13739
+ }
13740
+
13779
13741
  this.currentView = view;
13742
+
13743
+ Marionette.triggerMethod.call(this, "show", view);
13744
+ Marionette.triggerMethod.call(view, "show");
13780
13745
  },
13781
13746
 
13782
13747
  ensureEl: function(){
@@ -13927,14 +13892,20 @@ Marionette.RegionManager = (function(Marionette){
13927
13892
  // internal method to store regions
13928
13893
  _store: function(name, region){
13929
13894
  this._regions[name] = region;
13930
- this.length = _.size(this._regions);
13895
+ this._setLength();
13931
13896
  },
13932
13897
 
13933
13898
  // internal method to remove a region
13934
13899
  _remove: function(name, region){
13935
13900
  region.close();
13936
13901
  delete this._regions[name];
13902
+ this._setLength();
13937
13903
  this.triggerMethod("region:remove", name, region);
13904
+ },
13905
+
13906
+ // set the number of regions current held
13907
+ _setLength: function(){
13908
+ this.length = _.size(this._regions);
13938
13909
  }
13939
13910
 
13940
13911
  });
@@ -14013,7 +13984,7 @@ _.extend(Marionette.TemplateCache, {
14013
13984
  });
14014
13985
 
14015
13986
  // TemplateCache instance methods, allowing each
14016
- // template cache object to manage it's own state
13987
+ // template cache object to manage its own state
14017
13988
  // and know whether or not it has been loaded
14018
13989
  _.extend(Marionette.TemplateCache.prototype, {
14019
13990
 
@@ -14068,7 +14039,20 @@ Marionette.Renderer = {
14068
14039
  // template function. Override this method to provide your own
14069
14040
  // custom rendering and template handling for all of Marionette.
14070
14041
  render: function(template, data){
14071
- var templateFunc = typeof template === 'function' ? template : Marionette.TemplateCache.get(template);
14042
+
14043
+ if (!template) {
14044
+ var error = new Error("Cannot render the template since it's false, null or undefined.");
14045
+ error.name = "TemplateNotFoundError";
14046
+ throw error;
14047
+ }
14048
+
14049
+ var templateFunc;
14050
+ if (typeof template === "function"){
14051
+ templateFunc = template;
14052
+ } else {
14053
+ templateFunc = Marionette.TemplateCache.get(template);
14054
+ }
14055
+
14072
14056
  return templateFunc(data);
14073
14057
  }
14074
14058
  };
@@ -14134,7 +14118,7 @@ Marionette.View = Backbone.View.extend({
14134
14118
  // build the event handler function for the DOM event
14135
14119
  triggerEvents[key] = function(e){
14136
14120
 
14137
- // stop the event in it's tracks
14121
+ // stop the event in its tracks
14138
14122
  if (e && e.preventDefault){ e.preventDefault(); }
14139
14123
  if (e && e.stopPropagation){ e.stopPropagation(); }
14140
14124
 
@@ -14259,7 +14243,10 @@ Marionette.View = Backbone.View.extend({
14259
14243
  // A single item view implementation that contains code for rendering
14260
14244
  // with underscore.js templates, serializing the view's model or collection,
14261
14245
  // and calling several methods on extended views, such as `onRender`.
14262
- Marionette.ItemView = Marionette.View.extend({
14246
+ Marionette.ItemView = Marionette.View.extend({
14247
+
14248
+ // Setting up the inheritance chain which allows changes to
14249
+ // Marionette.View.prototype.constructor which allows overriding
14263
14250
  constructor: function(){
14264
14251
  Marionette.View.prototype.constructor.apply(this, slice(arguments));
14265
14252
  },
@@ -14299,6 +14286,7 @@ Marionette.ItemView = Marionette.View.extend({
14299
14286
 
14300
14287
  var template = this.getTemplate();
14301
14288
  var html = Marionette.Renderer.render(template, data);
14289
+
14302
14290
  this.$el.html(html);
14303
14291
  this.bindUIElements();
14304
14292
 
@@ -14592,10 +14580,11 @@ Marionette.CollectionView = Marionette.View.extend({
14592
14580
  // Extends directly from CollectionView and also renders an
14593
14581
  // an item view as `modelView`, for the top leaf
14594
14582
  Marionette.CompositeView = Marionette.CollectionView.extend({
14595
- constructor: function(options){
14596
- Marionette.CollectionView.apply(this, slice(arguments));
14597
-
14598
- this.itemView = this.getItemView();
14583
+
14584
+ // Setting up the inheritance chain which allows changes to
14585
+ // Marionette.CollectionView.prototype.constructor which allows overriding
14586
+ constructor: function(){
14587
+ Marionette.CollectionView.prototype.constructor.apply(this, slice(arguments));
14599
14588
  },
14600
14589
 
14601
14590
  // Configured the initial events that the composite view
@@ -14683,7 +14672,7 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
14683
14672
  // `itemViewContainer` (a jQuery selector). Override this method to
14684
14673
  // provide custom logic of how the child item view instances have their
14685
14674
  // HTML appended to the composite view instance.
14686
- appendHtml: function(cv, iv){
14675
+ appendHtml: function(cv, iv, index){
14687
14676
  var $container = this.getItemViewContainer(cv);
14688
14677
  $container.append(iv.el);
14689
14678
  },
@@ -14741,7 +14730,7 @@ Marionette.Layout = Marionette.ItemView.extend({
14741
14730
  this._firstRender = true;
14742
14731
  this._initializeRegions(options);
14743
14732
 
14744
- Marionette.ItemView.call(this, options);
14733
+ Marionette.ItemView.prototype.constructor.call(this, options);
14745
14734
  },
14746
14735
 
14747
14736
  // Layout's render will use the existing region objects the
@@ -15206,7 +15195,7 @@ _.extend(Marionette.Module, {
15206
15195
  })(this, Backbone, _);
15207
15196
 
15208
15197
  /*!
15209
- * Tableling v0.0.20
15198
+ * Tableling v0.0.21
15210
15199
  * Copyright (c) 2012-2013 Simon Oulevay (Alpha Hydrae) <hydrae.alpha@gmail.com>
15211
15200
  * Distributed under MIT license
15212
15201
  * https://github.com/AlphaHydrae/tableling
@@ -15214,7 +15203,7 @@ _.extend(Marionette.Module, {
15214
15203
  Backbone.Tableling = Tableling = (function(Backbone, _, $){
15215
15204
 
15216
15205
  var Tableling = {
15217
- version : "0.0.20"
15206
+ version : "0.0.21"
15218
15207
  };
15219
15208
 
15220
15209
  // Tableling
@@ -15234,6 +15223,8 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15234
15223
  initialize : function(options) {
15235
15224
  options = options || {};
15236
15225
 
15226
+ this.collection = options.collection;
15227
+
15237
15228
  // Table options can also be overriden for each instance at construction.
15238
15229
  this.config = _.extend(_.clone(this.config || {}), _.result(options, 'config') || {});
15239
15230
 
@@ -15246,7 +15237,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15246
15237
 
15247
15238
  // Components should trigger the `table:update` event to update
15248
15239
  // the table (e.g. change page size, sort) and fetch the new data.
15249
- this.vent.on('table:update', this.update, this);
15240
+ this.vent.on('table:update', this.onUpdate, this);
15250
15241
 
15251
15242
  this.on('item:rendered', this.setup, this);
15252
15243
  },
@@ -15261,11 +15252,15 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15261
15252
 
15262
15253
  // Subclasses must return the Backbone.Collection used to fetch data.
15263
15254
  getCollection : function() {
15264
- throw new Error('#getCollection not implemented. It should return the Backbone.Collection instance used to fetch data.');
15255
+ return this.collection;
15265
15256
  },
15266
15257
 
15267
15258
  // ### Refreshing the table
15268
15259
  update : function(config, options) {
15260
+ this.ventTrigger('table:update', config, options);
15261
+ },
15262
+
15263
+ onUpdate : function(config, options) {
15269
15264
 
15270
15265
  _.each(config || {}, _.bind(this.updateValue, this));
15271
15266
 
@@ -15327,6 +15322,12 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15327
15322
  // which is the total number of items (not just in the current page).
15328
15323
  this.config.total = response.total;
15329
15324
 
15325
+ // The server may override the `page` property, for example if the
15326
+ // requested page was outside the range of available pages.
15327
+ if (response.page) {
15328
+ this.config.page = response.page;
15329
+ }
15330
+
15330
15331
  // `tableling:refreshed` is triggered after every refresh. The first argument
15331
15332
  // is the current table configuration with the following additional meta data:
15332
15333
  //
@@ -15420,18 +15421,20 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15420
15421
  return view;
15421
15422
  },
15422
15423
 
15423
- // By default, a modular table expects a `table` module which
15424
+ // By default the collection is the one given at construction.
15425
+ // Otherwise, a modular table expects a `table` module which
15424
15426
  // should have a collection (e.g. a Marionette CompositeView or
15425
- // CollectionView). If your subclass does not have that, it
15427
+ // CollectionView). If your subclass does not have either, it
15426
15428
  // should override this method to return the Backbone.Collection
15427
15429
  // used to fetch table data.
15428
15430
  getCollection : function() {
15429
- return this.moduleViews.table.collection;
15431
+ return this.collection || (this.moduleViews && this.moduleViews.table ? this.moduleViews.table.collection : undefined);
15430
15432
  },
15431
15433
 
15432
15434
  getModuleOptions : function(name) {
15433
15435
  var options = this[name + 'ViewOptions'] || {};
15434
- return typeof(options) == 'function' ? options.call(this) : options;
15436
+ options = typeof(options) == 'function' ? options.call(this) : options;
15437
+ return name == 'table' ? _.defaults(options, { collection : this.collection }) : options;
15435
15438
  }
15436
15439
  });
15437
15440
 
@@ -15582,6 +15585,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15582
15585
  this.vent = options.vent;
15583
15586
  this.sort = [];
15584
15587
  this.vent.on('table:setup', this.setSort, this);
15588
+ this.vent.on('table:refreshed', this.setSort, this);
15585
15589
  },
15586
15590
 
15587
15591
  updateSort : function(ev) {
@@ -15834,23 +15838,28 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
15834
15838
  return Math.ceil(this.data.total / this.data.pageSize);
15835
15839
  },
15836
15840
 
15837
- goToFirstPage : function() {
15841
+ goToFirstPage : function(e) {
15842
+ e.preventDefault();
15838
15843
  this.goToPageNumber(1);
15839
15844
  },
15840
15845
 
15841
- goToPreviousPage : function() {
15846
+ goToPreviousPage : function(e) {
15847
+ e.preventDefault();
15842
15848
  this.goToPageNumber(this.getPage(this.data) - 1);
15843
15849
  },
15844
15850
 
15845
15851
  goToPage : function(e) {
15852
+ e.preventDefault();
15846
15853
  this.goToPageNumber(parseInt($(e.target).text(), 10));
15847
15854
  },
15848
15855
 
15849
- goToNextPage : function() {
15856
+ goToNextPage : function(e) {
15857
+ e.preventDefault();
15850
15858
  this.goToPageNumber(this.getPage(this.data) + 1);
15851
15859
  },
15852
15860
 
15853
- goToLastPage : function() {
15861
+ goToLastPage : function(e) {
15862
+ e.preventDefault();
15854
15863
  this.goToPageNumber(this.numberOfPages());
15855
15864
  },
15856
15865
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tableling-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.18
4
+ version: 0.0.19
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-16 00:00:00.000000000 Z
12
+ date: 2013-07-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -125,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
125
  version: '0'
126
126
  segments:
127
127
  - 0
128
- hash: -4338373402448950759
128
+ hash: -4441844229467767142
129
129
  required_rubygems_version: !ruby/object:Gem::Requirement
130
130
  none: false
131
131
  requirements:
@@ -134,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
134
  version: '0'
135
135
  segments:
136
136
  - 0
137
- hash: -4338373402448950759
137
+ hash: -4441844229467767142
138
138
  requirements: []
139
139
  rubyforge_project:
140
140
  rubygems_version: 1.8.25