bivouac 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/README +9 -0
  2. data/bin/bivouac +15 -19
  3. data/doc/rdoc/classes/BivouacHelpers.html +117 -0
  4. data/doc/rdoc/classes/BivouacHelpers/BaseView.html +140 -0
  5. data/doc/rdoc/classes/BivouacHelpers/FormView.html +398 -0
  6. data/doc/rdoc/classes/BivouacHelpers/HtmlView.html +274 -0
  7. data/doc/rdoc/classes/BivouacHelpers/JavaScriptView.html +573 -0
  8. data/doc/rdoc/classes/BivouacHelpers/ScriptAculoUsView.html +258 -0
  9. data/doc/rdoc/classes/BivouacHelpers/TooltipView.html +158 -0
  10. data/doc/rdoc/classes/JavaScriptGenerator.html +564 -0
  11. data/doc/rdoc/created.rid +1 -1
  12. data/doc/rdoc/files/AUTHORS.html +14 -0
  13. data/doc/rdoc/files/COPYING.html +14 -0
  14. data/doc/rdoc/files/README.html +40 -1
  15. data/doc/rdoc/files/lib/bivouac/helpers/view/goh/base_rb.html +109 -0
  16. data/doc/rdoc/files/lib/bivouac/helpers/view/goh/form_rb.html +109 -0
  17. data/doc/rdoc/files/lib/bivouac/helpers/view/goh/html_rb.html +109 -0
  18. data/doc/rdoc/files/lib/bivouac/helpers/view/goh/javascript_rb.html +113 -0
  19. data/doc/rdoc/files/lib/bivouac/helpers/view/goh/scriptaculous_rb.html +113 -0
  20. data/doc/rdoc/files/lib/bivouac/helpers/view/goh/tooltip_rb.html +109 -0
  21. data/examples/bivouac_sample/app/bivouac_sample.rb +61 -0
  22. data/examples/bivouac_sample/app/controllers/autocomplete.rb +24 -0
  23. data/examples/bivouac_sample/app/controllers/drag_and_drop.rb +11 -0
  24. data/examples/bivouac_sample/app/controllers/index.rb +7 -0
  25. data/examples/bivouac_sample/app/controllers/observe.rb +14 -0
  26. data/examples/bivouac_sample/app/controllers/periodically_call.rb +12 -0
  27. data/examples/bivouac_sample/app/controllers/remote_form.rb +10 -0
  28. data/examples/bivouac_sample/app/controllers/remote_link.rb +11 -0
  29. data/examples/bivouac_sample/app/controllers/submit_remote.rb +17 -0
  30. data/examples/bivouac_sample/app/controllers/toggle.rb +10 -0
  31. data/examples/bivouac_sample/app/controllers/toggle_sortable.rb +11 -0
  32. data/examples/bivouac_sample/app/helpers/_helpers.rb +25 -0
  33. data/examples/bivouac_sample/app/helpers/source.rb +25 -0
  34. data/examples/bivouac_sample/app/views/_autocomplete_result.rb +9 -0
  35. data/examples/bivouac_sample/app/views/_drag_and_drop_result.rb +5 -0
  36. data/examples/bivouac_sample/app/views/_observe_result.rb +17 -0
  37. data/examples/bivouac_sample/app/views/_periodically_call_result.rb +5 -0
  38. data/examples/bivouac_sample/app/views/_remote_link_result.rb +5 -0
  39. data/examples/bivouac_sample/app/views/_sortable_result.rb +5 -0
  40. data/examples/bivouac_sample/app/views/_submit_remote_result.rb +5 -0
  41. data/examples/bivouac_sample/app/views/autocomplete.rb +28 -0
  42. data/examples/bivouac_sample/app/views/drag_and_drop.rb +35 -0
  43. data/examples/bivouac_sample/app/views/index.rb +19 -0
  44. data/examples/bivouac_sample/app/views/observe.rb +19 -0
  45. data/examples/bivouac_sample/app/views/periodically_call.rb +17 -0
  46. data/examples/bivouac_sample/app/views/remote_form.rb +19 -0
  47. data/examples/bivouac_sample/app/views/remote_link.rb +20 -0
  48. data/examples/bivouac_sample/app/views/submit_remote.rb +21 -0
  49. data/examples/bivouac_sample/app/views/toggle.rb +44 -0
  50. data/examples/bivouac_sample/app/views/toggle_sortable.rb +52 -0
  51. data/examples/bivouac_sample/config/environment.rb +37 -0
  52. data/examples/bivouac_sample/config/postamble.rb +62 -0
  53. data/examples/bivouac_sample/log/BivouacSample.log +77 -0
  54. data/examples/bivouac_sample/public/images/camping.png +0 -0
  55. data/examples/bivouac_sample/public/index.html +242 -0
  56. data/examples/bivouac_sample/public/javascripts/builder.js +131 -0
  57. data/examples/bivouac_sample/public/javascripts/controls.js +835 -0
  58. data/examples/bivouac_sample/public/javascripts/dragdrop.js +944 -0
  59. data/examples/bivouac_sample/public/javascripts/effects.js +1090 -0
  60. data/examples/bivouac_sample/public/javascripts/prototype.js +2515 -0
  61. data/examples/bivouac_sample/public/javascripts/scriptaculous.js +51 -0
  62. data/examples/bivouac_sample/public/javascripts/slider.js +278 -0
  63. data/examples/bivouac_sample/public/javascripts/tooltip.js +208 -0
  64. data/examples/bivouac_sample/public/javascripts/unittest.js +564 -0
  65. data/examples/bivouac_sample/public/stylesheets/autocomplete.css +22 -0
  66. data/examples/bivouac_sample/public/stylesheets/coderay.css +104 -0
  67. data/examples/bivouac_sample/script/generate +3 -0
  68. data/examples/bivouac_sample/script/server +5 -0
  69. data/lib/bivouac/helpers/view/goh/base.rb +16 -0
  70. data/lib/bivouac/helpers/view/goh/form.rb +170 -0
  71. data/lib/bivouac/helpers/view/goh/html.rb +138 -0
  72. data/lib/bivouac/helpers/view/goh/javascript.rb +532 -0
  73. data/lib/bivouac/helpers/view/goh/scriptaculous.rb +133 -0
  74. data/lib/bivouac/helpers/view/goh/tooltip.rb +33 -0
  75. data/lib/bivouac/template.rb +3 -3
  76. data/lib/bivouac/template/application/helpers_erb.rb +11 -0
  77. data/lib/bivouac/template/application/helpers_goh.rb +25 -0
  78. data/lib/bivouac/template/application/postamble.rb +62 -0
  79. data/lib/bivouac/template/application_erb.rb +4 -0
  80. data/lib/bivouac/template/application_goh.rb +4 -0
  81. data/lib/bivouac/template/environment.rb +19 -5
  82. data/lib/bivouac/template/server.rb +1 -1
  83. data/lib/bivouac/template/static/autocomplete.css +22 -0
  84. data/lib/bivouac/template/static/builder.js +131 -0
  85. data/lib/bivouac/template/static/controls.js +835 -0
  86. data/lib/bivouac/template/static/dragdrop.js +944 -0
  87. data/lib/bivouac/template/static/effects.js +1090 -0
  88. data/lib/bivouac/template/static/prototype.js +2515 -0
  89. data/lib/bivouac/template/static/scriptaculous.js +51 -0
  90. data/lib/bivouac/template/static/slider.js +278 -0
  91. data/lib/bivouac/template/static/tooltip.js +208 -0
  92. data/lib/bivouac/template/static/unittest.js +564 -0
  93. metadata +124 -7
  94. data/lib/bivouac/template/application/postamble_cgi.rb +0 -8
  95. data/lib/bivouac/template/application/postamble_fastcgi.rb +0 -8
  96. data/lib/bivouac/template/application/postamble_mongrel.rb +0 -19
  97. data/lib/bivouac/template/application/postamble_none.rb +0 -1
  98. data/lib/bivouac/template/application/postamble_webrick.rb +0 -19
@@ -0,0 +1,22 @@
1
+ div.autocomplete {
2
+ position:absolute;
3
+ width:250px;
4
+ background-color:white;
5
+ border:1px solid #888;
6
+ margin:0px;
7
+ padding:0px;
8
+ }
9
+ div.autocomplete ul {
10
+ list-style-type:none;
11
+ margin:0px;
12
+ padding:0px;
13
+ }
14
+ div.autocomplete ul li.selected { background-color: #ffb;}
15
+ div.autocomplete ul li {
16
+ list-style-type:none;
17
+ display:block;
18
+ margin:0;
19
+ padding:2px;
20
+ height:32px;
21
+ cursor:pointer;
22
+ }
@@ -0,0 +1,104 @@
1
+ .CodeRay {
2
+ background-color: #f8f8f8;
3
+ border: 1px solid silver;
4
+ font-family: 'Courier New', 'Terminal', monospace;
5
+ color: #100;
6
+ }
7
+ .CodeRay pre { margin: 0px }
8
+
9
+ div.CodeRay { }
10
+
11
+ span.CodeRay { white-space: pre; border: 0px; padding: 2px }
12
+
13
+ table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px }
14
+ table.CodeRay td { padding: 2px 4px; vertical-align: top }
15
+
16
+ .CodeRay .line_numbers, .CodeRay .no {
17
+ background-color: #def;
18
+ color: gray;
19
+ text-align: right;
20
+ }
21
+ .CodeRay .line_numbers tt { font-weight: bold }
22
+ .CodeRay .no { padding: 0px 4px }
23
+ .CodeRay .code { width: 100% }
24
+
25
+ ol.CodeRay { font-size: 10pt }
26
+ ol.CodeRay li { white-space: pre }
27
+
28
+ .CodeRay .code pre { overflow: auto }
29
+
30
+ .CodeRay .af { color:#00C }
31
+ .CodeRay .an { color:#007 }
32
+ .CodeRay .av { color:#700 }
33
+ .CodeRay .aw { color:#C00 }
34
+ .CodeRay .bi { color:#509; font-weight:bold }
35
+ .CodeRay .c { color:#888 }
36
+
37
+ .CodeRay .ch { color:#04D }
38
+ .CodeRay .ch .k { color:#04D }
39
+ .CodeRay .ch .dl { color:#039 }
40
+
41
+ .CodeRay .cl { color:#B06; font-weight:bold }
42
+ .CodeRay .co { color:#036; font-weight:bold }
43
+ .CodeRay .cr { color:#0A0 }
44
+ .CodeRay .cv { color:#369 }
45
+ .CodeRay .df { color:#099; font-weight:bold }
46
+ .CodeRay .di { color:#088; font-weight:bold }
47
+ .CodeRay .dl { color:black }
48
+ .CodeRay .do { color:#970 }
49
+ .CodeRay .ds { color:#D42; font-weight:bold }
50
+ .CodeRay .e { color:#666; font-weight:bold }
51
+ .CodeRay .en { color:#800; font-weight:bold }
52
+ .CodeRay .er { color:#F00; background-color:#FAA }
53
+ .CodeRay .ex { color:#F00; font-weight:bold }
54
+ .CodeRay .fl { color:#60E; font-weight:bold }
55
+ .CodeRay .fu { color:#06B; font-weight:bold }
56
+ .CodeRay .gv { color:#d70; font-weight:bold }
57
+ .CodeRay .hx { color:#058; font-weight:bold }
58
+ .CodeRay .i { color:#00D; font-weight:bold }
59
+ .CodeRay .ic { color:#B44; font-weight:bold }
60
+
61
+ .CodeRay .il { background: #eee }
62
+ .CodeRay .il .il { background: #ddd }
63
+ .CodeRay .il .il .il { background: #ccc }
64
+ .CodeRay .il .idl { font-weight: bold; color: #888 }
65
+
66
+ .CodeRay .in { color:#B2B; font-weight:bold }
67
+ .CodeRay .iv { color:#33B }
68
+ .CodeRay .la { color:#970; font-weight:bold }
69
+ .CodeRay .lv { color:#963 }
70
+ .CodeRay .oc { color:#40E; font-weight:bold }
71
+ .CodeRay .on { color:#000; font-weight:bold }
72
+ .CodeRay .op { }
73
+ .CodeRay .pc { color:#038; font-weight:bold }
74
+ .CodeRay .pd { color:#369; font-weight:bold }
75
+ .CodeRay .pp { color:#579 }
76
+ .CodeRay .pt { color:#339; font-weight:bold }
77
+ .CodeRay .r { color:#080; font-weight:bold }
78
+
79
+ .CodeRay .rx { background-color:#fff0ff }
80
+ .CodeRay .rx .k { color:#808 }
81
+ .CodeRay .rx .dl { color:#404 }
82
+ .CodeRay .rx .mod { color:#C2C }
83
+ .CodeRay .rx .fu { color:#404; font-weight: bold }
84
+
85
+ .CodeRay .s { background-color:#fff0f0 }
86
+ .CodeRay .s .s { background-color:#ffe0e0 }
87
+ .CodeRay .s .s .s { background-color:#ffd0d0 }
88
+ .CodeRay .s .k { color:#D20 }
89
+ .CodeRay .s .dl { color:#710 }
90
+
91
+ .CodeRay .sh { background-color:#f0fff0 }
92
+ .CodeRay .sh .k { color:#2B2 }
93
+ .CodeRay .sh .dl { color:#161 }
94
+
95
+ .CodeRay .sy { color:#A60 }
96
+ .CodeRay .sy .k { color:#A60 }
97
+ .CodeRay .sy .dl { color:#630 }
98
+
99
+ .CodeRay .ta { color:#070 }
100
+ .CodeRay .tf { color:#070; font-weight:bold }
101
+ .CodeRay .ts { color:#D70; font-weight:bold }
102
+ .CodeRay .ty { color:#339; font-weight:bold }
103
+ .CodeRay .v { color:#036 }
104
+ .CodeRay .xt { color:#444 }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'bivouac/commands/generate'
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ app = File.dirname(__FILE__) + "/../app/bivouac_sample.rb"
4
+
5
+ system "ruby #{app} #{ARGV.join(' ')}"
@@ -0,0 +1,16 @@
1
+ # bivouac/helpers/view/base
2
+
3
+ module BivouacHelpers
4
+ module BaseView
5
+ # render( :hello, :object => @my_object )
6
+ # is equivalent to
7
+ # @object = @my_object
8
+ # hello( )
9
+ def render( partial, options = {} )
10
+ options.each do |k, v|
11
+ self.instance_variable_set( "@#{k.to_s}".to_sym, v )
12
+ end
13
+ self.send( partial.to_sym )
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,170 @@
1
+ # bivouac/helpers/view/form
2
+
3
+ module BivouacHelpers
4
+ module FormView
5
+ # Adds AJAX autocomplete functionality to the text input field with the DOM ID specified by +field_id+.
6
+ def auto_complete_field( field_id, options = nil )
7
+ if options.has_key?( :indicator )
8
+ data = options[:indicator]
9
+ options[:indicator] = "indicator_#{field_id}"
10
+ span( data, :id => options[:indicator], :style => "display: none" )
11
+ end
12
+
13
+ choises_id = "choises_#{field_id}"
14
+ div( :id => choises_id, :class => "autocomplete" ) do; end
15
+ url = options.delete( :url )
16
+ javascript_tag "new Ajax.Autocompleter( '#{field_id}', '#{choises_id}', '#{url}', #{options_for_javascript(options)} );"
17
+ end
18
+
19
+ # Autocomplete options :
20
+ #
21
+ # +:url+: URL to call for autocompletion results
22
+ # +:tokens+:
23
+ # +:frequency+:
24
+ # +:minChars+:
25
+ # +:indicator+: When sending the Ajax request Autocompleter shows this
26
+ # +:updateElement+: Hook for a custom function called after the element has been updated (i.e. when the user has selected an entry).
27
+ # +:afterUpdateElement+: Hook for a custom function called after the element has been updated (i.e. when the user has selected an entry).
28
+ # +:callback+: This function is called just before the Request is actually made, allowing you to modify the querystring that is sent to the server.
29
+ # +:parameters+: If you need to send any additional parameters through your search form, add them here, in the usual {field: 'value',another: 'value'} or 'field=value&another=value' manner.
30
+ def text_field(field_name, value = "", options = {})
31
+ autocomplete_options = nil
32
+
33
+ if options.has_key?( :autocomplete )
34
+ unless ["on", "off"].include?( options[:autocomplete] )
35
+ autocomplete_options = Hash.new( )
36
+ autocomplete_options[:url] = options.delete( :autocomplete )
37
+ # options[:autocomplete] = "off"
38
+ end
39
+ end
40
+
41
+
42
+ [:tokens, :frequency, :minChars, :indicator, :updateElement, :afterUpdateElement, :callback, :parameters].each do |op|
43
+ if options.has_key?( op )
44
+ if autocomplete_options.nil?
45
+ options.delete( op )
46
+ else
47
+ autocomplete_options[op] = options.delete( op )
48
+ end
49
+ end
50
+ end
51
+
52
+ options = { :id => "default_#{Time.now.to_i}", :type => "text", :name => field_name, :value => value }.merge( options )
53
+ input( options )
54
+ auto_complete_field( options[:id], autocomplete_options ) unless autocomplete_options.nil?
55
+ end
56
+
57
+ # Returns a button that'll trigger a JavaScript function using the onclick
58
+ # handler.
59
+ #
60
+ # The function argument can be omitted in favor of an update_page block,
61
+ # which evaluates to a string when the template is rendered (instead of
62
+ # making an Ajax request first).
63
+ def button_to_function(name, *args, &block)
64
+ html_options = args.last.is_a?(Hash) ? args.pop : {}
65
+ function = args[0] || ''
66
+
67
+ function = update_page(&block) if block_given?
68
+
69
+ input( html_options.merge({
70
+ :type => "button", :value => name,
71
+ :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
72
+ }))
73
+ end
74
+
75
+ # Returns a button input tag that will submit form using XMLHttpRequest
76
+ # in the background instead of regular reloading POST arrangement.
77
+ # <tt>options</tt> argument is the same as in <tt>form_remote_tag</tt>.
78
+ def submit_to_remote(name, value, options = {})
79
+ options[:with] ||= 'Form.serialize(this.form)'
80
+
81
+ options[:html] ||= {}
82
+ options[:html][:type] = 'button'
83
+ options[:html][:onclick] = "#{remote_function(options)}; return false;"
84
+ options[:html][:name] = name
85
+ options[:html][:value] = value
86
+
87
+ input options[:html]
88
+ end
89
+
90
+ # Starts a form tag that points the action to an url. The method for the form defaults to POST.
91
+ #
92
+ # Examples:
93
+ # * <tt>form_tag('/posts') => <form action="/posts" method="post"></tt>
94
+ # * <tt>form_tag('/upload', :multipart => true) => <form action="/upload" method="post" enctype="multipart/form-data"></tt>
95
+ #
96
+ # Example:
97
+ # form_tag R(Post) do
98
+ # div do; input( :type => 'submit', :name => 'submit' :value => 'Save' ); end
99
+ # end
100
+ #
101
+ # Will output:
102
+ # <form action="/posts" method="post"><input type="submit" name="submit" value="Save" /></div></form>
103
+ #
104
+ # Options:
105
+ # * <tt>:multipart</tt> - If set to true, the enctype is set to "multipart/form-data".
106
+ # * <tt>:method</tt> - The method to use when submitting the form, usually either "get" or "post".
107
+ # If "put", "delete", or another verb is used, a hidden input with name _method
108
+ # is added to simulate the verb over post.
109
+ def form_tag(url, options = {}, &block)
110
+ options[:enctype] = "multipart/form-data" if options.delete(:multipart)
111
+ options[:action] = url
112
+
113
+ method_tag = false
114
+
115
+ case method = options.delete(:method).to_s
116
+ when /^get$/i # must be case-insentive, but can't use downcase as might be nil
117
+ options[:method] = "get"
118
+ when /^post$/i, "", nil
119
+ options[:method] = "post"
120
+ else
121
+ options[:method] = "post"
122
+ method_tag = true
123
+ end
124
+
125
+ if block_given?
126
+ form( options ) do
127
+ yield( )
128
+ input( :type => "hidden", :name => "_method", :value => method ) if method_tag
129
+ end
130
+ else
131
+ form( options ) do; end
132
+ end
133
+ end
134
+
135
+ # Returns a form tag that will submit using XMLHttpRequest in the
136
+ # background instead of the regular reloading POST arrangement. Even
137
+ # though it's using JavaScript to serialize the form elements, the form
138
+ # submission will work just like a regular submission as viewed by the
139
+ # receiving side. The options for specifying the target with :url and
140
+ # defining callbacks is the same as
141
+ # link_to_remote.
142
+ #
143
+ # A "fall-through" target for browsers that doesn't do JavaScript can be
144
+ # specified with the :action/:method options on :html.
145
+ #
146
+ # Example:
147
+ # form_remote_tag :html => { :url => R(SomePlace) }
148
+ #
149
+ # The Hash passed to the :html key is equivalent to the options (2nd)
150
+ # argument in the form_tag method.
151
+ #
152
+ # By default the fall-through action is the same as the one specified in
153
+ # the :url (and the default method is :post).
154
+ #
155
+ # form_remote_tag takes a block, like form_tag:
156
+ # form_remote_tag :url => '/posts' do
157
+ # div do; input( :type => 'submit', :name => 'submit' :value => 'Save' ); end
158
+ # end
159
+ def form_remote_tag(options = {}, &block)
160
+ options[:form] = true
161
+
162
+ options[:html] ||= {}
163
+ options[:html][:onsubmit] =
164
+ (options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") +
165
+ "#{remote_function(options)}; return false;"
166
+
167
+ form_tag( options[:html].delete(:url), options[:html], &block )
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,138 @@
1
+ # bivouac/helpers/view/html
2
+
3
+ module BivouacHelpers
4
+ module HtmlView
5
+ @@javascript_default_sources = %w{prototype.js scriptaculous.js tooltip.js}
6
+
7
+ # Returns a stylesheet link tag for the sources specified as arguments. If
8
+ # you don't specify an extension, .css will be appended automatically.
9
+ # You can modify the link attributes by passing a hash as the last argument.
10
+ #
11
+ # stylesheet_link_tag "style" # =>
12
+ # <link href="/public/stylesheets/style.css" media="screen" rel="Stylesheet" type="text/css" />
13
+ #
14
+ # stylesheet_link_tag "style", :media => "all" # =>
15
+ # <link href="/public/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" />
16
+ #
17
+ # stylesheet_link_tag "random.styles", "/css/stylish" # =>
18
+ # <link href="/public/stylesheets/random.styles" media="screen" rel="Stylesheet" type="text/css" />
19
+ # <link href="/public/stylesheets/css/stylish.css" media="screen" rel="Stylesheet" type="text/css" />
20
+ def stylesheet_link_tag( *data )
21
+ options = data.last.is_a?(Hash) ? data.pop : { }
22
+ options[:rel] = "Stylesheet"
23
+ options[:type] = "text/css"
24
+ data.collect do |file|
25
+ file << ".css" if File.extname(file).blank?
26
+ options[:href] = "/public/stylesheets/#{file}"
27
+ link( options )
28
+ end
29
+ end
30
+
31
+ # Returns an html script tag for each of the +sources+ provided. You
32
+ # can pass in the filename (.js extension is optional) of javascript files
33
+ # that exist in your public/javascripts directory for inclusion into the
34
+ # current page. To include the Prototype and Scriptaculous javascript
35
+ # libraries in your application, pass :defaults as the source.
36
+ #
37
+ # javascript_include_tag "xmlhr" # =>
38
+ # <script type="text/javascript" src="/public/javascripts/xmlhr.js"></script>
39
+ #
40
+ # javascript_include_tag "common.javascript", "elsewhere/cools" # =>
41
+ # <script type="text/javascript" src="/public/javascripts/common.javascript"></script>
42
+ # <script type="text/javascript" src="/public/javascripts/elsewhere/cools.js"></script>
43
+ def javascript_include_tag( *sources )
44
+ options = sources.last.is_a?(Hash) ? sources.pop : { }
45
+ options[:type] = "text/javascript"
46
+
47
+ if sources.include?(:defaults)
48
+ sources = sources[0..(sources.index(:defaults))] +
49
+ @@javascript_default_sources.dup +
50
+ sources[(sources.index(:defaults) + 1)..sources.length]
51
+
52
+ sources.delete(:defaults)
53
+ end
54
+ sources.collect do |file|
55
+ file = file.to_s
56
+ file << ".js" if File.extname(file).blank?
57
+ options[:src] = "/public/javascripts/#{file}"
58
+ script( options ) {}
59
+ end
60
+ end
61
+
62
+ # Returns an html image tag for the +source+. The +source+ must be a file
63
+ # that exists in your public images directory (public/images).
64
+ # You can add html attributes using the +options+. If no alt text is given,
65
+ # the file name part of the +source+ is used (capitalized and without the
66
+ # extension)
67
+ #
68
+ # image_tag("icon.png") # =>
69
+ # <img src="/public/images/icon.png" alt="Icon" />
70
+ #
71
+ # image_tag("icon.png", :alt => "Edit Entry") # =>
72
+ # <img src="/public/images/icon.png" alt="Edit Entry" />
73
+ def image_tag( source, options = {} )
74
+ options[:src] = "/public/images/#{source}"
75
+ options[:alt] ||= File.basename(options[:src], '.*').split('.').first.capitalize
76
+
77
+ img( options )
78
+ end
79
+
80
+ # Creates a link tag of the given +name+ using +address+ has the href for
81
+ # the link
82
+ #
83
+ # The +options+ will accept a hash of html attributes for the link tag.
84
+ # It also accepts 2 modifiers that specialize the link behavior.
85
+ #
86
+ # * <tt>:confirm => 'question?'</tt>: This will add a JavaScript confirm
87
+ # prompt with the question specified. If the user accepts, the link is
88
+ # processed normally, otherwise no action is taken.
89
+ # * <tt>:popup => true || array of window options</tt>: This will force the
90
+ # link to open in a popup window. By passing true, a default browser window
91
+ # will be opened with the URL. You can also specify an array of options
92
+ # that are passed-thru to JavaScripts window.open method.
93
+ #
94
+ # You can mix and match the +options+.
95
+ #
96
+ # link_to "Documentation", "http://camping.rubyforge.org/", :confirm => "Are you sure?"
97
+ # link_to "Help", R( Help ), :popup => true
98
+ # link_to image_tag( "thumb.png" ), "/public/images/fullsize.png", :popup => ['My house', 'height=300,width=600']
99
+ def link_to(name, address, options = {})
100
+ options = javascript_options( options )
101
+ options[:href] = address
102
+
103
+ a( options ) do; name; end
104
+ end
105
+
106
+ private
107
+
108
+ def javascript_options( options )
109
+ unless options.is_a?(Hash)
110
+ raise ArgumentError, "options must be a Hash!"
111
+ end
112
+
113
+ confirm, popup = options.delete(:confirm), options.delete(:popup)
114
+ options["onclick"] = case
115
+ when confirm && popup
116
+ "if (#{confirm_javascript_function(confirm)}) { #{popup_javascript_function(popup)} };return false;"
117
+ when confirm
118
+ "return #{confirm_javascript_function(confirm)};"
119
+ when popup
120
+ popup_javascript_function(popup) + 'return false;'
121
+ else
122
+ options["onclick"]
123
+ end
124
+
125
+ return options
126
+ end
127
+
128
+ # From Rails !!!!
129
+ def confirm_javascript_function(confirm)
130
+ "confirm('#{confirm}')"
131
+ end
132
+
133
+ # From Rails !!!!
134
+ def popup_javascript_function(popup)
135
+ popup.is_a?(Array) ? "window.open(this.href,'#{popup.first}','#{popup.last}');" : "window.open(this.href);"
136
+ end
137
+ end
138
+ end