aurita-gui 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,13 @@
1
+ === 0.3.3 / 2009-01-24
2
+
3
+ * Added form helpers for template rendering.
4
+ * Extended API by convenience shortcuts:
5
+ Content for elements can be set markaby-like now:
6
+
7
+ HTML.div 'content here' :class => :highlighted
8
+
9
+ * Minor bug fixes.
10
+
1
11
  === 0.3.1 / 2009-01-15
2
12
 
3
13
  * Added specs for Element and HTML.
data/TODO CHANGED
@@ -20,6 +20,18 @@
20
20
 
21
21
  = DONE =============================================
22
22
 
23
+ - Provide markaby-like syntax, Example:
24
+
25
+ HTML.div 'content here' :class => :highlight
26
+
27
+ and
28
+
29
+ HTML.build {
30
+ div 'content' {
31
+ h1 'header'
32
+ }
33
+ }
34
+
23
35
  - Decorate required fields.
24
36
  Required fields are always rendered.
25
37
 
data/aurita-gui.gemspec CHANGED
@@ -14,7 +14,7 @@ as stand-alone library in any context (such as rails).
14
14
  As there seems to be a lack of ruby form generators, i decided to release this
15
15
  part of Aurita in a single gem with no dependencies.
16
16
  EOF
17
- s.version = '0.3.2'
17
+ s.version = '0.3.3'
18
18
  s.author = 'Tobias Fuchs'
19
19
  s.email = 'fuchs@atomnode.net'
20
20
  s.date = Time.now
data/lib/aurita-gui.rb CHANGED
@@ -1,6 +1,7 @@
1
1
 
2
2
  require('aurita-gui/element')
3
3
  require('aurita-gui/html')
4
+ require('aurita-gui/javascript')
4
5
  require('aurita-gui/form')
5
6
  require('aurita-gui/table')
6
7
  require('aurita-gui/button')
@@ -50,7 +50,7 @@ module GUI
50
50
  #
51
51
  # b = Submit_Button.new(:class => :css_class) { 'click me' }
52
52
  #
53
- class Submit_Button < Element
53
+ class Submit_Button < Button
54
54
  def initialize(params, &block)
55
55
  params[:tag] = :input
56
56
  params[:type] = :submit unless params[:type]
@@ -70,7 +70,7 @@ module GUI
70
70
  #
71
71
  # Note that reset buttons in forms are considered
72
72
  # bad style in terms of usability.
73
- class Reset_Button < Element
73
+ class Reset_Button < Button
74
74
  def initialize(params, &block)
75
75
  params[:tag] = :input
76
76
  params[:type] = :reset unless params[:type]
@@ -59,19 +59,28 @@ module GUI
59
59
 
60
60
  @@element_count = 0
61
61
 
62
- attr_accessor :attrib, :content, :parent, :tag, :force_closing_tag
62
+ attr_accessor :attrib, :content, :parent, :force_closing_tag, :tag
63
63
 
64
- def initialize(params={}, &block)
64
+ def initialize(*args, &block)
65
+
66
+ params = {}
67
+ case args[0]
68
+ when Hash
69
+ params = args[0]
70
+ else
71
+ params = args[1]
72
+ params ||= {}
73
+ params[:content] = args[0]
74
+ end
65
75
 
66
76
  @@element_count += 1
67
77
  @id = @@element_count
68
78
  @parent = params[:parent]
69
79
  @force_closing_tag = params[:force_closing_tag]
80
+
70
81
  params[:tag] = :div if params[:tag].nil?
71
- @tag = params[:tag]
72
- if [ :div, :label, :button, :textarea ].include? @tag then
73
- @force_closing_tag = true
74
- end
82
+ @tag = params[:tag]
83
+
75
84
  params.delete(:parent)
76
85
  params.delete(:force_closing_tag)
77
86
 
@@ -104,6 +113,16 @@ module GUI
104
113
  def dom_id=(value)
105
114
  @attrib[:id] = value if @attrib
106
115
  end
116
+ # Alias definition for #dom_id=(value)
117
+ # Define explicitly so built-in method #id
118
+ # is not invoked instead
119
+ def id=(value)
120
+ @attrib[:id] = value
121
+ end
122
+ # Alias definition for #dom_id()
123
+ def id
124
+ @attrib[:id]
125
+ end
107
126
 
108
127
  # Render this element to a string and append another
109
128
  # element.
@@ -118,7 +137,6 @@ module GUI
118
137
  end
119
138
  alias to_a to_ary
120
139
 
121
-
122
140
  # Redirect methods to setting or retreiving tag
123
141
  # attributes.
124
142
  def method_missing(meth, value=nil)
@@ -135,16 +153,6 @@ module GUI
135
153
  def type=(type)
136
154
  @attrib[:type] = type
137
155
  end
138
- # Alias definition for #dom_id=(value)
139
- # Define explicitly so built-in method #id
140
- # is not invoked instead
141
- def id=(value)
142
- @attrib[:id] = value
143
- end
144
- # Alias definition for #dom_id()
145
- def id
146
- @attrib[:id]
147
- end
148
156
 
149
157
  # Do not redirect random access operators.
150
158
  def [](index)
@@ -186,6 +194,10 @@ module GUI
186
194
  }
187
195
 
188
196
  out = ''
197
+ if (!(@force_closing_tag.instance_of?(FalseClass)) &&
198
+ [ :div, :label, :button, :textarea ].include?(@tag)) then
199
+ @force_closing_tag = true
200
+ end
189
201
  if @force_closing_tag || content.to_s != '' then
190
202
  out << "<#{@tag}"
191
203
  out << attrib_string if attrib_string.length > 0
@@ -72,12 +72,13 @@ module GUI
72
72
  else
73
73
  @content = field
74
74
  end
75
+ field.dom_id = field.name.to_s.gsub('.','_') unless field.dom_id
75
76
  css_classes = field.class.to_s.split('::')[-1].downcase + '_wrap form_field'
76
77
  css_classes << ' required' if field.required?
77
78
  css_classes << ' invalid' if field.invalid?
78
79
  params = { :tag => :li,
79
80
  :content => @content,
80
- :id => field.dom_id + '_wrap',
81
+ :id => field.dom_id.to_s + '_wrap',
81
82
  :class => css_classes }
82
83
  super(params)
83
84
  end
@@ -142,14 +143,32 @@ module GUI
142
143
  # }
143
144
  # textarea = GUI::Textarea.new(:name => :comment, :label => 'Comment')
144
145
  # form.add(textarea)
145
- #
146
- # In case you want to override the form action (default: /aurita/dispatch),
147
- # use :action_url:
148
146
  #
149
- # Form.new(:action_url => '/where/to/send/form')
150
- # or
151
- # Form.action_url = '/where/to/send/form'
147
+ # === Rails
152
148
  #
149
+ # In Rails, you could use form instances like:
150
+ #
151
+ # class ItemController < ActionController::Base
152
+ # def add
153
+ # @form = Form.new(:action => 'where/to/send')
154
+ # @form[:title].required!
155
+ # end
156
+ # end
157
+ #
158
+ # And in view 'item/add':
159
+ #
160
+ # <%
161
+ # @form[:title].value = 'Enter a title here'
162
+ # @form[:description].disabled! unless @may_edit_description
163
+ # %>
164
+ #
165
+ # <%= @form.string %>
166
+ #
167
+ # You can also use form template helpers from
168
+ # Aurita::GUI::Form_Field_Helpers.
169
+ # You'd have to define you own form builder class, but that's
170
+ # quite simple (see comments on module Form_Field_Helpers).
171
+ # I'll soon provide a Rails-specific form builder, though.
153
172
  #
154
173
  # == Render modes
155
174
  #
@@ -173,6 +192,7 @@ module GUI
173
192
  # :id => :the_form_id,
174
193
  # :action => :where_to_send)
175
194
  #
195
+ #
176
196
  # You can either set all attributes in the
177
197
  # constructor call ...
178
198
  #
@@ -286,14 +306,11 @@ module GUI
286
306
  #
287
307
  class Form < Element
288
308
 
289
- attr_accessor :method, :target, :action, :fields, :elements, :element_map, :values, :field_decorator, :content_decorator
309
+ attr_accessor :fields, :elements, :element_map, :values, :field_decorator, :content_decorator
290
310
 
291
311
  def initialize(params={}, &block)
292
- @action = params[:action]
293
- @method = params[:method]
294
312
  @fields = params[:fields]
295
313
  @values = params[:values]
296
- @method ||= :post
297
314
  @fields ||= []
298
315
  @elements = []
299
316
  @element_map = {}
@@ -307,8 +324,12 @@ module GUI
307
324
  end
308
325
  params.delete(:fields)
309
326
  params.delete(:values)
327
+ params.delete(:title)
328
+ params[:method] = 'POST' unless params[:method]
329
+ params[:enctype] = 'multipart/form-data' unless params[:enctype]
310
330
  params[:tag] = 'form'
311
331
  params[:content] = content()
332
+ params[:action] = @action
312
333
  super(params)
313
334
  end
314
335
 
@@ -331,7 +352,7 @@ module GUI
331
352
  def []=(index, form_field)
332
353
  @content = false # Invalidate
333
354
  if !index.kind_of? Numeric
334
- @element_map[index,to_s] = form_field
355
+ @element_map[index.to_s] = form_field
335
356
  @elements.collect { |e|
336
357
  e = form_field if e.name.to_s == index.to_s
337
358
  }
@@ -477,6 +498,19 @@ module GUI
477
498
  HTML.form(@attrib) { content() }
478
499
  end
479
500
 
501
+ # Returns opening tag of this form instance.
502
+ # Useful for template helper methods.
503
+ # Example:
504
+ #
505
+ # form = Form.new(:action => 'where/to/send')
506
+ # puts form.header_string
507
+ # -->
508
+ # '<form action="where/to/send" enctype="multipart/form-data" method="POST">'
509
+ #
510
+ def header_string
511
+ HTML.form(@attrib).string.gsub('</form>','')
512
+ end
513
+
480
514
  # Render this form to a string
481
515
  def string
482
516
  element().to_s
@@ -12,7 +12,11 @@ module GUI
12
12
  @date_format = params[:date_format]
13
13
  @date_format ||= 'mdy'
14
14
  @year_range = params[:year_range]
15
+ @year_range ||= (2009..2020)
15
16
 
17
+ if params[:value] then set_date(params[:value]) end
18
+
19
+ params.delete(:value)
16
20
  params.delete(:date_format)
17
21
  params.delete(:date)
18
22
  params.delete(:day)
@@ -24,7 +28,7 @@ module GUI
24
28
 
25
29
  def year_element
26
30
  if !@year_element then
27
- @year_element = Select_Field.new(:name => @attrib[:name] + '_year',
31
+ @year_element = Select_Field.new(:name => @attrib[:name].to_s + '_year',
28
32
  :class => :year_select,
29
33
  :value => @year, :options => @year_range)
30
34
  end
@@ -32,7 +36,7 @@ module GUI
32
36
  end
33
37
  def month_element
34
38
  if !@month_element then
35
- @month_element = Select_Field.new(:name => @attrib[:name] + '_month',
39
+ @month_element = Select_Field.new(:name => @attrib[:name].to_s + '_month',
36
40
  :class => :month_select,
37
41
  :value => @month, :options => (1..12))
38
42
  end
@@ -40,7 +44,7 @@ module GUI
40
44
  end
41
45
  def day_element
42
46
  if !@day_element then
43
- @day_element = Select_Field.new(:name => @attrib[:name] + '_day',
47
+ @day_element = Select_Field.new(:name => @attrib[:name].to_s + '_day',
44
48
  :class => :day_select,
45
49
  :value => @day, :options => (1..31))
46
50
  end
@@ -68,7 +72,7 @@ module GUI
68
72
  case date
69
73
  when Hash then
70
74
  @value = date
71
- when Datetime then
75
+ when ::DateTime then
72
76
  @value = { :year => date.year,
73
77
  :month => date.month,
74
78
  :day => date.day }
@@ -77,13 +81,15 @@ module GUI
77
81
  :month => date.month,
78
82
  :day => date.day }
79
83
  when String then
80
- date = Datetime.strptime(date)
84
+ date = (::DateTime).strptime(date, "%Y%m%d")
81
85
  @value = { :year => date.year,
82
86
  :month => date.month,
83
87
  :day => date.day }
84
88
  else
85
89
  end
90
+ @year, @month, @day = @value[:year], @value[:month], @value[:day]
86
91
  end
92
+ alias set_date value=
87
93
 
88
94
  def value
89
95
  { :day => @day, :month => @month, :year => @year }
@@ -21,7 +21,7 @@ module GUI
21
21
 
22
22
  def hour_element
23
23
  if !@hour_element then
24
- @hour_element = Select_Field.new(:name => @attrib[:name] + '_hour',
24
+ @hour_element = Select_Field.new(:name => @attrib[:name].to_s + '_hour',
25
25
  :class => :hour_select,
26
26
  :value => @hour, :options => (0..23))
27
27
  end
@@ -29,7 +29,7 @@ module GUI
29
29
  end
30
30
  def minute_element
31
31
  if !@minute_element then
32
- @minute_element = Select_Field.new(:name => @attrib[:name] + '_minute',
32
+ @minute_element = Select_Field.new(:name => @attrib[:name].to_s + '_minute',
33
33
  :class => :minute_select,
34
34
  :value => @minute, :options => (0..59))
35
35
  end
@@ -37,7 +37,7 @@ module GUI
37
37
  end
38
38
  def second_element
39
39
  if !@second_element then
40
- @second_element = Select_Field.new(:name => @attrib[:name] + '_second',
40
+ @second_element = Select_Field.new(:name => @attrib[:name].to_s + '_second',
41
41
  :class => :second_select,
42
42
  :value => @second, :options => (0..59))
43
43
  end
@@ -0,0 +1,109 @@
1
+
2
+ require('aurita-gui/form')
3
+
4
+ module Aurita
5
+ module GUI
6
+
7
+ # Provides wrapper methods for every
8
+ # form field type.
9
+ # Include this module in your template
10
+ # helper class.
11
+ #
12
+ # Form_Helper methods each return a string
13
+ # for a respective Form_Field element.
14
+ # Rendering respects the form instances'
15
+ # @field_decorator, but not @content_decorator,
16
+ # so you have to wrap form contents manually
17
+ # in your helper method.
18
+ #
19
+ # Example: (what your template helper could look like)
20
+ #
21
+ # module Form_Helper_Class_Methods
22
+ # def form_for(params, &block)
23
+ # form = Form.new(params, &block)
24
+ # render form.header_string # <form ...> tag is prepared by form instance
25
+ # render '<ul class="form_fields">' # begin content wrap
26
+ # yield(form)
27
+ # render '</ul>' # end content wrap
28
+ # render '</form>' # Closing tag for a form should always be </form>
29
+ # end
30
+ # end
31
+ #
32
+ # Usage, e.g. in ERB templates:
33
+ #
34
+ # <% form_for(:action => '/where/to/send') do |f| %>
35
+ # <%= f.text(:name => :title) { 'Value for this field' } %>
36
+ # <%= f.select(:name => :color, :options => [ :blue, :red, :green ], :value => :red)
37
+ # <% end %>
38
+ #
39
+ # Form_Helper automatically extends Aurita::GUI::Form
40
+ # when included.
41
+ #
42
+ module Form_Field_Helper
43
+
44
+ def text(params, &block)
45
+ params[:type] = :text
46
+ @field_decorator.new(Input_Field.new(params, &block)).string
47
+ end
48
+
49
+ def boolean(params, &block)
50
+ @field_decorator.new(Boolean_Field.new(params, &block)).string
51
+ end
52
+
53
+ def password(params, &block)
54
+ params[:type] = :password
55
+ @field_decorator.new(Password_Field.new(params, &block)).string
56
+ end
57
+
58
+ def select(params, &block)
59
+ @field_decorator.new(Select_Field.new(params, &block)).string
60
+ end
61
+
62
+ def radio(params, &block)
63
+ @field_decorator.new(Radio_Field.new(params, &block)).string
64
+ end
65
+
66
+ def checkbox(params, &block)
67
+ @field_decorator.new(Checkbox_Field.new(params, &block)).string
68
+ end
69
+
70
+ def textarea(params, &block)
71
+ @field_decorator.new(Textarea_Field.new(params, &block)).string
72
+ end
73
+
74
+ def hidden(params, &block)
75
+ @field_decorator.new(Hidden_Field.new(params, &block)).string
76
+ end
77
+
78
+ def file(params, &block)
79
+ @field_decorator.new(File_Field.new(params, &block)).string
80
+ end
81
+
82
+ def fieldset(params, &block)
83
+ @field_decorator.new(Fieldset.new(params, &block)).string
84
+ end
85
+
86
+ def date(params, &block)
87
+ @field_decorator.new(Date_Field.new(params, &block)).string
88
+ end
89
+
90
+ def datetime(params, &block)
91
+ @field_decorator.new(Datetime_Field.new(params, &block)).string
92
+ end
93
+
94
+ def custom(params, &block)
95
+ klass = params[:element]
96
+ params.delete(:element)
97
+ @field_decorator.new(klass.new(params, &block)).string
98
+ end
99
+
100
+ end
101
+
102
+ # Extend class Aurita::GUI::Form by helper
103
+ # methods.
104
+ class Form
105
+ include Form_Field_Helper
106
+ end
107
+
108
+ end
109
+ end
@@ -66,6 +66,20 @@ module GUI
66
66
  #
67
67
  # HTML.a(:href => 'http://domain.com', :content => 'click me')
68
68
  #
69
+ # Or as first argument:
70
+ #
71
+ # HTML.a('click me', :href => 'http://domain.com')
72
+ #
73
+ # So the following statements are equivalent:
74
+ #
75
+ # e = HTML.div 'hello', :class => 'highlight'
76
+ # e = HTML.div(:class => :highlight) { 'hello' }
77
+ # e = HTML.div(:class => :highlight, :content => 'hello')
78
+ #
79
+ # In all cases, e.to_s renders:
80
+ #
81
+ # <div class="highlight">hello</div>
82
+ #
69
83
  # == Further Examples
70
84
  #
71
85
  # There are some few usage principles that are
@@ -217,12 +231,12 @@ module GUI
217
231
  Element.new(:tag => :br)
218
232
  end
219
233
 
220
- def self.render(meth_name, attrib_hash={}, &block)
221
- raise ::Exception.new('Missing attributes for HTML.' << meth_name.inspect) unless attrib_hash
222
- attrib_hash[:tag] = meth_name
223
- # cont = yield if block_given?
224
- # attrib_hash[:content] = cont
225
- Element.new(attrib_hash, &block)
234
+ def self.render(meth_name, *args, &block)
235
+ raise ::Exception.new('Missing attributes for HTML.' << meth_name.inspect) unless args
236
+
237
+ e = Element.new(*args, &block)
238
+ e.tag = meth_name
239
+ e
226
240
  end
227
241
 
228
242
  def self.build(&block)
@@ -231,19 +245,19 @@ module GUI
231
245
  end
232
246
 
233
247
 
234
- def self.a(attrib_hash={}, &block)
235
- render(:a, attrib_hash, &block)
248
+ def self.a(*attribs, &block)
249
+ render(:a, *attribs, &block)
236
250
  end
237
251
 
238
252
  # p is defined in Kernel, so we have to
239
253
  # redirect it manually (method_missing won't be
240
254
  # triggered for it)
241
- def self.p(attrib_hash={}, &block)
242
- render(:p, attrib_hash, &block)
255
+ def self.p(*attribs, &block)
256
+ render(:p, *attribs, &block)
243
257
  end
244
258
 
245
- def self.method_missing(meth_name, attrib_hash={}, &block)
246
- render(meth_name, attrib_hash, &block)
259
+ def self.method_missing(meth_name, *attribs, &block)
260
+ render(meth_name, *attribs, &block)
247
261
  end
248
262
 
249
263
  =begin
@@ -259,68 +273,7 @@ EOC
259
273
  =end
260
274
 
261
275
  end # class
262
-
263
- # A minimalistic generator for javascript calls.
264
- # Usage:
265
- #
266
- # my_element.onclick = Javascript.new("alert('an alert message');")
267
- #
268
- # or just:
269
- #
270
- # my_element.onclick = Javascript.my_function('foo', 2, 'bar')
271
- # --> my_function('foo', 2, 'bar');
272
- #
273
- # For namespaces:
274
- #
275
- # my_element.onclick = Javascript[:Foo].my_function(1,2)
276
- # --> Foo.my_function('foo', 2, 'bar');
277
- #
278
- # Method #string renders the code passed in constructir,
279
- # enclosed in <script> tags:
280
- #
281
- # Javascript.new("alert('message');").string
282
- # -->
283
- # <script language="Javascript" type="text/javascript">
284
- # alert('message');
285
- # </script>
286
- #
287
- class Javascript
288
-
289
- def initialize(script)
290
- @script = script
291
- end
292
-
293
- # Renders script to a <script> block.
294
- def code_block
295
- '<script language="Javascript" type="text/javascript">' << "\n" <<
296
- @script + "\n" <<
297
- '</script>'
298
- end
299
-
300
- def string
301
- @script
302
- end
303
- alias to_s string
304
-
305
- def self.[](namespace)
306
- return self.new(namespace.to_s + '.')
307
- end
308
-
309
- def self.method_missing(meth, *args)
310
- args = args.collect { |arg|
311
- if arg.instance_of? String then
312
- '\'' << arg << '\''
313
- else
314
- arg
315
- end
316
- }
317
- args_string = args.join(',')
318
- meth.to_s << '(' << args_string + ');'
319
- end
320
-
321
- end # class
322
-
323
-
276
+
324
277
  end # module
325
278
  end # module
326
279
 
@@ -0,0 +1,158 @@
1
+
2
+ module Aurita
3
+ module GUI
4
+
5
+ # A minimalistic generator for javascript calls.
6
+ #
7
+ # Javascript is a simple string factory so you can
8
+ # write pieces of javascript code in ruby instead of
9
+ # using plain old strings.
10
+ # This does not introduce functionality, it just
11
+ # eases the rendering of ruby objects to javascript:
12
+ # Aurita::GUI::Javascript renders method parameters
13
+ # to their respective meaning in javascript, and also
14
+ # understands namespaces, variables, and object
15
+ # notation.
16
+ #
17
+ # Sometimes i needed somethind like this in ERB
18
+ # templates:
19
+ #
20
+ # <%= button(:class => :cancel, :onclick => "Aurita.cancel_form('#{form.dom_id}"')) %>
21
+ #
22
+ # Now i can do the same in pure ruby:
23
+ #
24
+ # <%= button(:class => :cancel, :onclick => js.Aurita.cancel_form(form.dom_id)) %>
25
+ #
26
+ # Just by defining a helper method in 5 lines of
27
+ # code (see below, section Template helper example).
28
+ #
29
+ # == Usage with block:
30
+ #
31
+ # Javascript.build { |j|
32
+ # j.Some.Namespace.do_stuff()
33
+ # j.bla(123, { :gna => 23, :blu => '42' })
34
+ # j.alert("escape 'this' string")
35
+ # }
36
+ #
37
+ # -->
38
+ # Some.Namespace.do_stuff(); bla(123,{gna: 23, blu: '42' }); alert('escape \'this\' string');
39
+ #
40
+ # == Calling class methods
41
+ #
42
+ # For a single call of a javascipt method, you can also use:
43
+ #
44
+ # my_element.onclick = Javascript.alert('an alert message')
45
+ # --> alert('an alert message');
46
+ #
47
+ # This also provides method chaining. Uppercase
48
+ # methods are interpreted as namespaces.
49
+ #
50
+ # my_element.onclick = Javascript.Some.Namespace.my_function('foo', 2, 'bar')
51
+ # --> <div onclick="Some_Namespace.my_function('foo', 2, 'bar'); "> ... </div>
52
+ #
53
+ # == Template helper example
54
+ #
55
+ # In Aurita, there's a simple helper, defined as
56
+ #
57
+ # def js(&block)
58
+ # if block_given? then
59
+ # Javascript.build(&block)
60
+ # else
61
+ # Javascript
62
+ # end
63
+ # end
64
+ #
65
+ # It works like that:
66
+ #
67
+ # input = Input_Field.new(:onchange => js.Aurita.notify_change_of(:this))
68
+ # --> <input onchange="Aurita.notify_change_of(this); " />
69
+ # or
70
+ # input.onfocus = js.Aurita.notify_focus_on(:this)
71
+ # --> <input onchange="Aurita.notify_change_of(this); "
72
+ # onfocus="Aurita.notify_focus_of(this); " />
73
+ #
74
+ # == Render to <script> tag
75
+ #
76
+ # Method #to_tag renders the code enclosed in <script> tags:
77
+ #
78
+ # Javascript.new("alert('message');").to_tag
79
+ # -->
80
+ # <script language="Javascript" type="text/javascript">
81
+ # alert('message');
82
+ # </script>
83
+ #
84
+ class Javascript
85
+
86
+ def initialize(script='')
87
+ @script = script
88
+ @scripy ||= ''
89
+ end
90
+
91
+ def self.build(&block)
92
+ if block.arity > 0 then
93
+ yield(Javascript.new)
94
+ else
95
+ self.class_eval(&block)
96
+ end
97
+ end
98
+
99
+ # Renders script to a <script> block.
100
+ def to_tag
101
+ '<script language="Javascript" type="text/javascript">' << "\n" <<
102
+ @script + "\n" <<
103
+ '</script>'
104
+ end
105
+
106
+ def string
107
+ @script
108
+ end
109
+ alias to_s string
110
+
111
+ def self.[](namespace)
112
+ return self.new(namespace.to_s + '.')
113
+ end
114
+
115
+ def method_missing(meth, *args)
116
+ args = args.collect { |arg|
117
+ arg = to_js(arg)
118
+ }
119
+ args_string = args.join(',') if args.size > 0
120
+ meth = meth.to_s
121
+ # Uppercase method => method call
122
+ meth << '(' << args_string.to_s << '); ' if meth[0] > 96
123
+ # Uppercase method => Namespace
124
+ meth << '.' if meth[0] < 97
125
+ @script << meth
126
+ return self
127
+ end
128
+ alias render method_missing
129
+ def self.method_missing(meth, *args)
130
+ return self.new().__send__(meth, *args)
131
+ end
132
+
133
+ protected
134
+
135
+ def to_js(arg)
136
+ case arg
137
+ when String:
138
+ arg.gsub!("'","\\\\'")
139
+ "'#{arg}'"
140
+ when Hash:
141
+ obj = []
142
+ arg.each_pair { |k,v|
143
+ v = to_js(v)
144
+ obj << "#{k}: #{v}"
145
+ }
146
+ "{#{obj.join(', ')}}"
147
+ when Symbol
148
+ arg.to_s
149
+ else
150
+ arg
151
+ end
152
+ end
153
+
154
+ end # class
155
+
156
+ end
157
+ end
158
+
data/spec/element.rb CHANGED
@@ -16,6 +16,15 @@ describe Aurita::GUI::Element, "basic rendering" do
16
16
  e.tag.should == :tagname
17
17
  end
18
18
 
19
+ it "should provide a shortcut for content as first constructor argument" do
20
+ e = Element.new('I am the content')
21
+ e.string.should == '<div>I am the content</div>'
22
+ e = Element.new('I am the content', :tag => :p)
23
+ e.string.should == '<p>I am the content</p>'
24
+ e.class = 'highlight'
25
+ e.string.should == '<p class="highlight">I am the content</p>'
26
+ end
27
+
19
28
  it "should have :div as default attribute" do
20
29
  e = Element.new()
21
30
  e.tag.should == :div
data/spec/form.rb CHANGED
@@ -22,7 +22,7 @@ describe Aurita::GUI::Form, "basic rendering" do
22
22
 
23
23
  it "should wrap form fields as list elements (<li>...</li>)" do
24
24
  @form.add(@text_field)
25
- @form.to_s.should == '<form><ul class="form_fields"><li class="input_field_wrap form_field" id="textfield_wrap"><input type="text" name="textfield" id="textfield" /></li></ul></form>'
25
+ @form.to_s.should == '<form method="POST" enctype="multipart/form-data"><ul class="form_fields"><li class="input_field_wrap form_field" id="textfield_wrap"><input type="text" name="textfield" id="textfield" /></li></ul></form>'
26
26
  end
27
27
 
28
28
  end
data/spec/html.rb CHANGED
@@ -8,7 +8,7 @@ describe Aurita::GUI::HTML, "basic rendering" do
8
8
  before do
9
9
  @e = HTML.build {
10
10
  div(:class => :outer) {
11
- h2(:id => :header) { 'Header' } +
11
+ h2('Header', :id => :header) +
12
12
  p(:id => :content) { 'Content' }
13
13
  }
14
14
  }
@@ -23,6 +23,13 @@ describe Aurita::GUI::HTML, "basic rendering" do
23
23
  HTML.p { 'string' }.to_s.should == '<p>string</p>'
24
24
  end
25
25
 
26
+ it "should also accept the first constructor argument as content" do
27
+ e = HTML.p 'I am the content'
28
+ e.to_s.should == Element.new(:tag => :p) { 'I am the content' }.to_s
29
+ e = HTML.div 'foo', :class => 'highlight'
30
+ e.to_s.should == '<div class="highlight">foo</div>'
31
+ end
32
+
26
33
  it "should provide a build mechanism that delegates class methods" do
27
34
  @e.to_s = '<div class="outer"><h2 id="header">Header</h2><p id="content">Content</p></div>'
28
35
  end
@@ -0,0 +1,25 @@
1
+
2
+ require('rubygems')
3
+ require('aurita-gui/javascript')
4
+
5
+ include Aurita::GUI
6
+
7
+ describe Aurita::GUI::Javascript, "basic rendering" do
8
+ before do
9
+ end
10
+
11
+ it "should provide a nice DSL" do
12
+ js = Javascript.build { |j|
13
+ j.Some.Namespace.do_stuff()
14
+ j.bla(123, { :gna => 23, :blu => '42' })
15
+ j.alert("escape 'this' string")
16
+ }
17
+ js.to_s.should == "Some.Namespace.do_stuff(); bla(123,{gna: 23, blu: '42'}); alert('escape \\'this\\' string'); "
18
+ end
19
+
20
+ it "should render on class method calls" do
21
+ Javascript.Some.Namespace.do_stuff(23, 'wombat').to_s.should == "Some.Namespace.do_stuff(23,'wombat'); "
22
+ end
23
+
24
+ end
25
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aurita-gui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Fuchs
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-20 00:00:00 +01:00
12
+ date: 2009-01-25 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -35,6 +35,7 @@ files:
35
35
  - LICENSE
36
36
  - lib/aurita-gui
37
37
  - lib/aurita-gui.rb
38
+ - lib/aurita-gui/javascript.rb
38
39
  - lib/aurita-gui/button.rb
39
40
  - lib/aurita-gui/form.rb
40
41
  - lib/aurita-gui/html.rb
@@ -55,9 +56,10 @@ files:
55
56
  - lib/aurita-gui/form/radio_field.rb
56
57
  - lib/aurita-gui/form/hidden_field.rb
57
58
  - lib/aurita-gui/form/text_field.rb
59
+ - lib/aurita-gui/form/template_helper.rb
58
60
  - lib/aurita-gui/form/input_field.rb
59
61
  - lib/aurita-gui/form/date_field.rb
60
- - spec/;
62
+ - spec/javascript.rb
61
63
  - spec/form.rb
62
64
  - spec/html.rb
63
65
  - spec/element.rb
data/spec/; DELETED
@@ -1,14 +0,0 @@
1
-
2
- class Context_Loader
3
-
4
- def self.render(element)
5
- puts 'loader: ' << element.to_s + ' end loader'
6
-
7
- def run(&block)
8
- class_eval(&block)
9
- end
10
-
11
- end
12
-
13
- l = Context_Loader.new()
14
- l.run { 'foo' }