aurita-gui 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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' }