cheveret 1.1.3 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/Rakefile +4 -1
- data/cheveret.gemspec +12 -4
- data/init.rb +1 -1
- data/lib/cheveret.rb +9 -257
- data/lib/cheveret/base.rb +57 -0
- data/lib/cheveret/column.rb +57 -0
- data/lib/cheveret/config.rb +44 -0
- data/lib/cheveret/dsl.rb +124 -0
- data/lib/cheveret/filtering.rb +39 -0
- data/lib/cheveret/helper.rb +37 -0
- data/lib/cheveret/rendering.rb +83 -0
- data/lib/cheveret/resizing.rb +95 -0
- data/lib/cheveret/version.rb +33 -0
- metadata +23 -12
- data/VERSION +0 -1
data/LICENSE
CHANGED
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
+
require File.expand_path('../lib/cheveret/version', __FILE__)
|
5
|
+
|
4
6
|
begin
|
5
7
|
require 'jeweler'
|
6
8
|
Jeweler::Tasks.new do |gem|
|
@@ -12,8 +14,9 @@ clearly separate logic and templating and reduce the amount of code in your view
|
|
12
14
|
gem.email = "aulankz@gmail.com"
|
13
15
|
gem.homepage = "http://github.com/ratecity/cheveret"
|
14
16
|
gem.authors = ["Ben Caldwell"]
|
17
|
+
gem.version = Cheveret::VERSION::STRING
|
18
|
+
|
15
19
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
16
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
20
|
end
|
18
21
|
Jeweler::GemcutterTasks.new
|
19
22
|
rescue LoadError
|
data/cheveret.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cheveret}
|
8
|
-
s.version = "
|
8
|
+
s.version = "2.0.0.rc1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ben Caldwell"]
|
12
|
-
s.date = %q{2010-09-
|
12
|
+
s.date = %q{2010-09-29}
|
13
13
|
s.description = %q{Generating HTML tables of data in the views of your Rails
|
14
14
|
application is not very DRY even for the simpler of cases. Cheveret allows you to more
|
15
15
|
clearly separate logic and templating and reduce the amount of code in your views.}
|
@@ -24,10 +24,18 @@ clearly separate logic and templating and reduce the amount of code in your view
|
|
24
24
|
"LICENSE",
|
25
25
|
"README.md",
|
26
26
|
"Rakefile",
|
27
|
-
"VERSION",
|
28
27
|
"cheveret.gemspec",
|
29
28
|
"init.rb",
|
30
29
|
"lib/cheveret.rb",
|
30
|
+
"lib/cheveret/base.rb",
|
31
|
+
"lib/cheveret/column.rb",
|
32
|
+
"lib/cheveret/config.rb",
|
33
|
+
"lib/cheveret/dsl.rb",
|
34
|
+
"lib/cheveret/filtering.rb",
|
35
|
+
"lib/cheveret/helper.rb",
|
36
|
+
"lib/cheveret/rendering.rb",
|
37
|
+
"lib/cheveret/resizing.rb",
|
38
|
+
"lib/cheveret/version.rb",
|
31
39
|
"rails/init.rb",
|
32
40
|
"spec/cheveret_spec.rb",
|
33
41
|
"spec/spec.opts",
|
data/init.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'cheveret'
|
2
|
-
ActionView::Base.send :include, Cheveret::
|
2
|
+
ActionView::Base.send :include, Cheveret::Helper
|
data/lib/cheveret.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2010 RateCity
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -21,262 +21,14 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
-
require 'forwardable'
|
25
|
-
|
26
24
|
module Cheveret
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def columns(*args, &block)
|
36
|
-
return @columns.values unless block_given?
|
37
|
-
instance_eval(&block)
|
38
|
-
# todo: support populating columns from an array
|
39
|
-
# todo: attempt to automatically resolve columns from activerecord etc.
|
40
|
-
end
|
41
|
-
|
42
|
-
def add_column(column_name, config={})
|
43
|
-
@columns[column_name] = Column.new(column_name, config)
|
44
|
-
end
|
45
|
-
|
46
|
-
alias_method :column, :add_column
|
47
|
-
|
48
|
-
def fixed(column_name, config={})
|
49
|
-
add_column(column_name, config.merge({ :flexible => false }))
|
50
|
-
end
|
51
|
-
|
52
|
-
def flexible(column_name, config={})
|
53
|
-
add_column(column_name, config.merge({ :flexible => true }))
|
54
|
-
end
|
55
|
-
|
56
|
-
def hidden(column_name, config={})
|
57
|
-
add_column(column_name, config.merge({ :visible => false }))
|
58
|
-
end
|
59
|
-
|
60
|
-
def remove_column(column_name)
|
61
|
-
# todo: allow columns to be removed, not sure why you'd want to do this. maybe
|
62
|
-
# just set :visible => false instead?
|
63
|
-
raise NotImplementedError
|
64
|
-
end
|
65
|
-
|
66
|
-
def resize!(new_width)
|
67
|
-
return true if new_width == @width
|
68
|
-
@width = new_width
|
69
|
-
|
70
|
-
columns_width = 0
|
71
|
-
flexibles = []
|
72
|
-
|
73
|
-
self.columns.each do |column|
|
74
|
-
if column.visible?
|
75
|
-
columns_width += column.width
|
76
|
-
flexibles << column.name if column.flexible?
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# todo: handle too-many/too-wide columns
|
81
|
-
raise "uh-oh spaghettio-s" if columns_width > new_width
|
82
|
-
|
83
|
-
# todo: fix rounding in with calculation
|
84
|
-
# todo: trim last column that fits into table width if necessary
|
85
|
-
if columns_width < new_width && !flexibles.empty?
|
86
|
-
padding = (new_width - columns_width) / flexibles.length
|
87
|
-
flexibles.each { |name| @columns[name].width += padding }
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class Column
|
93
|
-
extend ::Forwardable
|
94
|
-
|
95
|
-
[ :width, :visible, :flexible, :label, :sortable ].each do |attr|
|
96
|
-
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
97
|
-
def_delegator :@config, :#{attr}, :#{attr}
|
98
|
-
def_delegator :@config, :#{attr}=, :#{attr}=
|
99
|
-
RUBY_EVAL
|
100
|
-
end
|
101
|
-
|
102
|
-
attr_accessor :name
|
103
|
-
|
104
|
-
def initialize(column_name, config={})
|
105
|
-
@name = column_name
|
106
|
-
|
107
|
-
@config = ::ActiveSupport::OrderedOptions.new
|
108
|
-
config.each { |k, v| send("#{k}=", v) if respond_to?(k) }
|
109
|
-
end
|
110
|
-
|
111
|
-
# sets the column to be visible. columns are visible by default. use this when
|
112
|
-
# you've defined hidden columns that should only be displayed on some condition
|
113
|
-
def show
|
114
|
-
self.visible = true
|
115
|
-
end
|
116
|
-
|
117
|
-
# hides the column, prevents it from being rendered in the table. acts as a
|
118
|
-
# helper for setting <tt>:visible => false</tt>
|
119
|
-
def hide
|
120
|
-
self.visible = false
|
121
|
-
end
|
122
|
-
|
123
|
-
# returns +true+ for columns that have <tt>:visible => true</tt> or #show called
|
124
|
-
# on them. columns are visible by default
|
125
|
-
def visible?
|
126
|
-
self.visible != false
|
127
|
-
end
|
128
|
-
|
129
|
-
def flexible?
|
130
|
-
self.flexible != false
|
131
|
-
end
|
132
|
-
|
133
|
-
# returns +true+ unless a column has explicitly set <tt>:sortable => false</tt>
|
134
|
-
def sortable?
|
135
|
-
self.sortable != false
|
136
|
-
end
|
137
|
-
|
138
|
-
def label
|
139
|
-
case @config.label
|
140
|
-
when nil then @name.to_s.humanize # todo: support i18n for column labels
|
141
|
-
when false then nil
|
142
|
-
else @config.label
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def data(object)
|
147
|
-
object.send(self.name) if object.respond_to?(self.name)
|
148
|
-
end
|
149
|
-
|
150
|
-
def width
|
151
|
-
@config.width || 0
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
module Helpers
|
156
|
-
# view helper that facilities the rendering of tables for a collection of similar
|
157
|
-
# objects
|
158
|
-
#
|
159
|
-
# behaves much in the same way as Rails +form_for+ helper in that it takes a proc
|
160
|
-
# and provides access to a table builder object. the entire block is captured, so
|
161
|
-
# additional markup can be output at any point
|
162
|
-
#
|
163
|
-
# <% table_for @books, :width => 480 do |t| %>
|
164
|
-
# <% t.columns :title, :author, :publisher, :price %>
|
165
|
-
# <% t.header %>
|
166
|
-
# <% t.body %>
|
167
|
-
# <% end %>
|
168
|
-
#
|
169
|
-
# === Options
|
170
|
-
# * <tt>:width</tt> - the total width of the table in pixels
|
171
|
-
# * <tt>:html</tt> - a hash of html attributes used for the form container
|
172
|
-
# * <tt>:url</tt> - used to generate urls for sortable columns
|
173
|
-
# * <tt>:table</tt> - specify a pre-configured table to render
|
174
|
-
#
|
175
|
-
# === Examples
|
176
|
-
def table_for(collection, options={}, &block)
|
177
|
-
builder = options.delete(:builder) || ActionView::Base.default_table_builder
|
178
|
-
table = options.delete(:table) || Table.new
|
179
|
-
|
180
|
-
options.merge!({ :collection => collection })
|
181
|
-
builder.render(table, self, options, &block)
|
182
|
-
end
|
183
|
-
|
184
|
-
# the default #TableBuilder class generates an HTML table using div tags
|
185
|
-
class TableBuilder
|
186
|
-
extend ::Forwardable
|
187
|
-
def_delegators :@table, :columns
|
188
|
-
|
189
|
-
def self.render(table, template, options={}, &block)
|
190
|
-
html_attrs = options.delete(:html) || {}
|
191
|
-
html_attrs.merge!({ :class => "table",
|
192
|
-
:style => "width: #{options[:width]}px;" })
|
193
|
-
|
194
|
-
template.content_tag(:div, html_attrs) do
|
195
|
-
template.capture(self.new(table, template, options), &block)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def initialize(table, template, options={})
|
200
|
-
@table, @template, = table, template
|
201
|
-
|
202
|
-
@width = options.delete(:width)
|
203
|
-
@collection = options.delete(:collection)
|
204
|
-
@url = options.delete(:url)
|
205
|
-
end
|
206
|
-
|
207
|
-
def header(*args, &block)
|
208
|
-
@table.resize!(@width)
|
209
|
-
|
210
|
-
row = content_tag(:div, :class => "tr") do
|
211
|
-
map_columns(:th) do |column|
|
212
|
-
# todo: prevent output of empty <a> tag for header label
|
213
|
-
output = nil_capture(column, &block) if block_given?
|
214
|
-
output ||= sort_tag(column) if column.sortable?
|
215
|
-
output ||= content_tag(:span, column.label)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
content_tag(:div, row, :class => "thead")
|
220
|
-
end
|
221
|
-
|
222
|
-
def body(&block)
|
223
|
-
@table.resize!(@width)
|
224
|
-
alt = false
|
225
|
-
|
226
|
-
rows = @collection.map do |object|
|
227
|
-
object_name = object.class.to_s.split('::').last.underscore || ''
|
228
|
-
klass = [ 'tr', object_name, (alt = !alt) ? nil : 'alt' ].compact
|
229
|
-
content_tag(:div, :class => klass.join(' ')) do
|
230
|
-
map_columns(:td) do |column|
|
231
|
-
output = nil_capture(column, object, &block) if block_given?
|
232
|
-
output ||= content_tag(:span, column.data(object))
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
content_tag(:div, rows.join, :class => "tbody")
|
238
|
-
end
|
239
|
-
|
240
|
-
private
|
241
|
-
|
242
|
-
def map_columns(type, &block) #:nodoc:
|
243
|
-
@table.columns.map do |column|
|
244
|
-
attrs = { :class => [type, column.name].join(' '),
|
245
|
-
:style => "width: #{column.width}px;" }
|
246
|
-
attrs[:class] << ' sortable' if column.sortable?
|
247
|
-
|
248
|
-
content_tag(:div, attrs) do
|
249
|
-
yield(column)
|
250
|
-
end if column.visible?
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
def nil_capture(*args, &block) #:nodoc:
|
255
|
-
custom = capture(*args, &block).strip
|
256
|
-
output = custom.empty? ? nil : custom
|
257
|
-
end
|
258
|
-
|
259
|
-
def sort_tag(column) #:nodoc:
|
260
|
-
return nil unless column.sortable? && @url.present?
|
261
|
-
|
262
|
-
sort = column.name
|
263
|
-
order = "desc" if params[:sort].to_s == column.name.to_s && params[:order] == "asc"
|
264
|
-
attrs = { :href => url_for(@url.merge({ :sort => sort, :order => order || "desc" })) }
|
265
|
-
|
266
|
-
attrs[:class] = "sorted #{params[:order]}" if params[:sort].to_s == column.name.to_s
|
267
|
-
|
268
|
-
content_tag(:a, column.label, attrs)
|
269
|
-
end
|
270
|
-
|
271
|
-
def method_missing(method_name, *args, &block) #:nodoc:
|
272
|
-
return @template.send(method_name, *args, &block) if @template.respond_to?(method_name)
|
273
|
-
super
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
25
|
+
autoload :Base, 'cheveret/base'
|
26
|
+
autoload :Column, 'cheveret/column'
|
27
|
+
autoload :Config, 'cheveret/config'
|
28
|
+
autoload :DSL, 'cheveret/dsl'
|
29
|
+
autoload :Filtering, 'cheveret/filtering'
|
30
|
+
autoload :Helper, 'cheveret/helper'
|
31
|
+
autoload :Rendering, 'cheveret/rendering'
|
32
|
+
autoload :Resizing, 'cheveret/resizing'
|
277
33
|
|
278
|
-
ActionView::Base.class_eval do
|
279
|
-
cattr_accessor :default_table_builder
|
280
|
-
self.default_table_builder = ::Cheveret::Helpers::TableBuilder
|
281
|
-
end
|
282
34
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'active_support/ordered_hash'
|
25
|
+
|
26
|
+
module Cheveret
|
27
|
+
class Base
|
28
|
+
attr_accessor :columns
|
29
|
+
|
30
|
+
def initialize(template, &block)
|
31
|
+
@template = template
|
32
|
+
@columns = ::ActiveSupport::OrderedHash.new
|
33
|
+
|
34
|
+
instance_eval(&block) if block_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
include DSL
|
38
|
+
include Rendering
|
39
|
+
include Config
|
40
|
+
include Resizing
|
41
|
+
include Filtering
|
42
|
+
# include Sorting
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
# since the define_table block gets instance_eval'd in the context of this object
|
47
|
+
# we need to proxy view methods (e.g. check_box_tag) back to the template
|
48
|
+
def method_missing(method_name, *args, &block) #:nodoc:
|
49
|
+
if @template.respond_to?(method_name)
|
50
|
+
@template.send(method_name, *args, &block)
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
class Column
|
26
|
+
attr_accessor :name, :data, :label, :weight, :width
|
27
|
+
attr_accessor :flexible, :sortable
|
28
|
+
|
29
|
+
def initialize(name, config={})
|
30
|
+
config.merge(:name => name).each do |k, v|
|
31
|
+
instance_variable_set(:"@#{k}", v) if respond_to?(:"#{k}=")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def flexible?
|
36
|
+
@flexible == true
|
37
|
+
end
|
38
|
+
|
39
|
+
def label
|
40
|
+
case @label
|
41
|
+
when nil then @name.to_s.humanize # todo: support i18n for column labels
|
42
|
+
when false then nil
|
43
|
+
else @label
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# returns +true+ unless a column has explicitly set <tt>:sortable => false</tt>
|
48
|
+
def sortable?
|
49
|
+
@sortable == true
|
50
|
+
end
|
51
|
+
|
52
|
+
def width
|
53
|
+
@width || 0
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module Config
|
26
|
+
# dsl method for defining default configuration options for table rendering
|
27
|
+
#
|
28
|
+
# @param [Hash] new_config
|
29
|
+
# a hash of configuration options. gets merged with any existing config
|
30
|
+
def config(new_config)
|
31
|
+
if @config then @config.merge!(new_config) else @config = new_config.dup end
|
32
|
+
end
|
33
|
+
|
34
|
+
[ :render, :header, :body, :rows ].each do |renderer|
|
35
|
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
36
|
+
def #{renderer}(*args)
|
37
|
+
config = @config.merge(args.extract_options!)
|
38
|
+
super(*args << config)
|
39
|
+
end
|
40
|
+
RUBY_EVAL
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/lib/cheveret/dsl.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module DSL
|
26
|
+
def header_default(&block)
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def data_default(&block)
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
# registers a new column with the specified options
|
35
|
+
#
|
36
|
+
# @example minimum required to define a column
|
37
|
+
# column :author
|
38
|
+
#
|
39
|
+
# @example flexible width, sortable column
|
40
|
+
# column :description => [ :flexible, :sortable ]
|
41
|
+
#
|
42
|
+
# @example fixed with column with no header label
|
43
|
+
# column :check_box, :label => false, :width => 30
|
44
|
+
#
|
45
|
+
# @example sortable column with custom header label
|
46
|
+
# column :published => [ :sortable ], :label => "Publish Date"
|
47
|
+
#
|
48
|
+
# @param [Symbol,Array] name_or_hash
|
49
|
+
# the name of the column, optionally combined with any flags that should be
|
50
|
+
# set to +true+
|
51
|
+
#
|
52
|
+
# @param [Hash] options a hash of options for the column
|
53
|
+
#
|
54
|
+
# @option options [Proc] :data
|
55
|
+
#
|
56
|
+
# @option options [Boolean] :flexible (false)
|
57
|
+
# if +true+ the column will resize automatically depending on the size of the
|
58
|
+
# table
|
59
|
+
#
|
60
|
+
# @option options [Proc] :header
|
61
|
+
#
|
62
|
+
# @option options [String,Boolean] :label
|
63
|
+
# used to determine what gets used as a label in the column header. if set to
|
64
|
+
# +false+ no lable will be rendered
|
65
|
+
#
|
66
|
+
# @option options [Boolean] :sortable (false)
|
67
|
+
#
|
68
|
+
# @option options [Integer] :width
|
69
|
+
def column(name_or_hash, options={})
|
70
|
+
if name_or_hash.is_a?(Hash)
|
71
|
+
name = name_or_hash.except(:label, :width).keys.first
|
72
|
+
name_or_hash.delete(name).each { |k| options[k] = true }
|
73
|
+
options.merge!(name_or_hash)
|
74
|
+
else
|
75
|
+
name = name_or_hash
|
76
|
+
end
|
77
|
+
|
78
|
+
if @columns[name].present?
|
79
|
+
options.each { |k, v| @column[name].send(:"#{k}=", v) }
|
80
|
+
else
|
81
|
+
@columns[name] = Column.new(name, options)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# define how to extract and render data value for a particular column
|
86
|
+
#
|
87
|
+
# chevert will call the block you define here to render the inner part of the
|
88
|
+
# table data cell for each object in the collection
|
89
|
+
#
|
90
|
+
# if you don't specify one or more column names when calling this method,
|
91
|
+
# cheveret will assume that you're defining the data block for the last column
|
92
|
+
# you registered
|
93
|
+
#
|
94
|
+
# @example format money values in the view
|
95
|
+
# - column :price
|
96
|
+
# - data do |book|
|
97
|
+
# %span= number_to_currency book.price
|
98
|
+
#
|
99
|
+
# @example define data block for multiple columns
|
100
|
+
# - column :title
|
101
|
+
# - column :author
|
102
|
+
# - data [ :title, :author ] do |column, object|
|
103
|
+
# %p{ :class => column.name }= object.send(column.name)
|
104
|
+
def data(*args, &block)
|
105
|
+
options = args.extract_options!
|
106
|
+
|
107
|
+
[ *args.first || @columns.keys.last ].each do |column_name|
|
108
|
+
column = @columns[column_name ]
|
109
|
+
column.data = block
|
110
|
+
|
111
|
+
instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
112
|
+
def data_for_#{column.name}(object)
|
113
|
+
capture(object, &@columns[:#{column.name}].data)
|
114
|
+
end
|
115
|
+
RUBY_EVAL
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def header(*args, &block)
|
120
|
+
raise NotImplementedError
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module Filtering
|
26
|
+
def config(new_config)
|
27
|
+
except, only = new_config[:except], new_config[:only]
|
28
|
+
if (except || only)
|
29
|
+
@columns.reject! { |k, v| !only.include?(k) } if only
|
30
|
+
# todo: support use of except
|
31
|
+
end
|
32
|
+
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
# todo: wrap around header, body, rows and allow localised :only and :except
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module Helper
|
26
|
+
def define_table(options={}, &block)
|
27
|
+
builder = options.delete(:builder) || ActionView::Base.default_table_builder
|
28
|
+
builder.new(self, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
ActionView::Base.class_eval do
|
32
|
+
cattr_accessor :default_table_builder
|
33
|
+
self.default_table_builder = Cheveret::Base
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module Rendering
|
26
|
+
def render(collection, options={})
|
27
|
+
options[:class] = [ 'table', options[:class] ].flatten.join(' ').strip
|
28
|
+
|
29
|
+
content_tag(:div, options) do
|
30
|
+
header + body(collection)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def header(options={})
|
35
|
+
row = @columns.values.map do |column|
|
36
|
+
cell(:th, column) do
|
37
|
+
if column.sortable?
|
38
|
+
content_tag(:a, column.label)
|
39
|
+
else
|
40
|
+
column.label
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
content_tag(:div, row, {
|
46
|
+
:class => 'thead'
|
47
|
+
})
|
48
|
+
end
|
49
|
+
|
50
|
+
def body(collection, options={})
|
51
|
+
content_tag(:div, rows(collection), {
|
52
|
+
:class => 'tbody'
|
53
|
+
})
|
54
|
+
end
|
55
|
+
|
56
|
+
def rows(collection, options={})
|
57
|
+
collection.map { |object| row(object) }.join
|
58
|
+
end
|
59
|
+
|
60
|
+
# render a single table row for the specified data object
|
61
|
+
#
|
62
|
+
# @param [Object] object
|
63
|
+
# @param [Hash] options
|
64
|
+
#
|
65
|
+
# @option options [Array] :only
|
66
|
+
# @option options [Array] :except
|
67
|
+
# @option options [Array,String] :class
|
68
|
+
# @option options [Integer] :width
|
69
|
+
def row(object, options={})
|
70
|
+
content_tag(:div, :class => 'tr') do
|
71
|
+
@columns.values.map do |column|
|
72
|
+
cell(:td, column) { send(:"data_for_#{column.name}", object) rescue nil }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def cell(type, column, options={}, &block)
|
78
|
+
options[:class] = [ type, column.name, options[:class] ].flatten.join(' ').strip
|
79
|
+
content_tag(:div, yield, options)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module Resizing
|
26
|
+
def width
|
27
|
+
@width || 0
|
28
|
+
end
|
29
|
+
|
30
|
+
# set width constraint for the table.
|
31
|
+
#
|
32
|
+
# if the width value is different to that previously set, cheveret will call the
|
33
|
+
# #resize! method to adjust the widths of flexible columns to fit
|
34
|
+
#
|
35
|
+
# @param [Integer] new_width the maximum width of the table in pixels
|
36
|
+
def width=(new_width)
|
37
|
+
return @width if new_width == @width
|
38
|
+
|
39
|
+
@width = new_width
|
40
|
+
resize!
|
41
|
+
end
|
42
|
+
|
43
|
+
def config(new_config={})
|
44
|
+
self.width = new_config[:width] if new_config[:width]
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
# some meta magic - make sure that the table is resized correctly before any of
|
49
|
+
# the render methods start generating output
|
50
|
+
[ :render, :header, :body, :rows ].each do |renderer|
|
51
|
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
52
|
+
def #{renderer}(*args)
|
53
|
+
config = args.extract_options!
|
54
|
+
|
55
|
+
width = config.delete(:width)
|
56
|
+
super(*args << config)
|
57
|
+
end
|
58
|
+
RUBY_EVAL
|
59
|
+
end
|
60
|
+
|
61
|
+
def cell(type, column, options={}, &block)
|
62
|
+
options[:style] = "width: #{@widths[column.name] || column.width}px"
|
63
|
+
super
|
64
|
+
end
|
65
|
+
|
66
|
+
# resize flexible columns in attempt to reduce the total width, making sure it
|
67
|
+
# fits within the constraints of the table
|
68
|
+
def resize!
|
69
|
+
@widths = {}
|
70
|
+
|
71
|
+
columns_width = 0
|
72
|
+
flexibles = []
|
73
|
+
|
74
|
+
@columns.values.each do |column|
|
75
|
+
columns_width += column.width
|
76
|
+
flexibles << column if column.flexible?
|
77
|
+
end
|
78
|
+
|
79
|
+
# todo: handle too-many/too-wide columns
|
80
|
+
raise "uh-oh spaghettio-s" if columns_width > @width
|
81
|
+
|
82
|
+
# todo: fix rounding in with calculation
|
83
|
+
# todo: trim last column that fits into table width if necessary
|
84
|
+
if columns_width < @width && !flexibles.empty?
|
85
|
+
padding = (@width - columns_width) / flexibles.length
|
86
|
+
flexibles.each { |column| @widths[column.name] = column.width + padding }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def weigh!
|
91
|
+
raise NotImplementedError
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 RateCity Pty. Ltd.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Cheveret
|
25
|
+
module VERSION
|
26
|
+
MAJOR = 2
|
27
|
+
MINOR = 0
|
28
|
+
PATCH = 0
|
29
|
+
BUILD = 'rc1'
|
30
|
+
|
31
|
+
STRING = [ MAJOR, MINOR, PATCH, BUILD ].join('.')
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheveret
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 977940590
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
- rc1
|
11
|
+
version: 2.0.0.rc1
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- Ben Caldwell
|
@@ -15,7 +16,7 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-09-
|
19
|
+
date: 2010-09-29 00:00:00 +10:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
@@ -52,10 +53,18 @@ files:
|
|
52
53
|
- LICENSE
|
53
54
|
- README.md
|
54
55
|
- Rakefile
|
55
|
-
- VERSION
|
56
56
|
- cheveret.gemspec
|
57
57
|
- init.rb
|
58
58
|
- lib/cheveret.rb
|
59
|
+
- lib/cheveret/base.rb
|
60
|
+
- lib/cheveret/column.rb
|
61
|
+
- lib/cheveret/config.rb
|
62
|
+
- lib/cheveret/dsl.rb
|
63
|
+
- lib/cheveret/filtering.rb
|
64
|
+
- lib/cheveret/helper.rb
|
65
|
+
- lib/cheveret/rendering.rb
|
66
|
+
- lib/cheveret/resizing.rb
|
67
|
+
- lib/cheveret/version.rb
|
59
68
|
- rails/init.rb
|
60
69
|
- spec/cheveret_spec.rb
|
61
70
|
- spec/spec.opts
|
@@ -81,12 +90,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
91
|
none: false
|
83
92
|
requirements:
|
84
|
-
- - "
|
93
|
+
- - ">"
|
85
94
|
- !ruby/object:Gem::Version
|
86
|
-
hash:
|
95
|
+
hash: 25
|
87
96
|
segments:
|
88
|
-
-
|
89
|
-
|
97
|
+
- 1
|
98
|
+
- 3
|
99
|
+
- 1
|
100
|
+
version: 1.3.1
|
90
101
|
requirements: []
|
91
102
|
|
92
103
|
rubyforge_project:
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.1.3
|