actionpack 2.0.5 → 2.1.0

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.
Files changed (210) hide show
  1. data/CHANGELOG +149 -7
  2. data/MIT-LICENSE +1 -1
  3. data/README +1 -1
  4. data/Rakefile +5 -6
  5. data/lib/action_controller.rb +2 -2
  6. data/lib/action_controller/assertions/model_assertions.rb +2 -1
  7. data/lib/action_controller/assertions/response_assertions.rb +4 -2
  8. data/lib/action_controller/assertions/routing_assertions.rb +3 -3
  9. data/lib/action_controller/assertions/selector_assertions.rb +30 -27
  10. data/lib/action_controller/assertions/tag_assertions.rb +3 -3
  11. data/lib/action_controller/base.rb +103 -129
  12. data/lib/action_controller/benchmarking.rb +3 -3
  13. data/lib/action_controller/caching.rb +41 -652
  14. data/lib/action_controller/caching/actions.rb +144 -0
  15. data/lib/action_controller/caching/fragments.rb +138 -0
  16. data/lib/action_controller/caching/pages.rb +154 -0
  17. data/lib/action_controller/caching/sql_cache.rb +18 -0
  18. data/lib/action_controller/caching/sweeping.rb +97 -0
  19. data/lib/action_controller/cgi_ext/cookie.rb +27 -23
  20. data/lib/action_controller/cgi_ext/stdinput.rb +1 -0
  21. data/lib/action_controller/cgi_process.rb +6 -4
  22. data/lib/action_controller/components.rb +7 -6
  23. data/lib/action_controller/cookies.rb +31 -19
  24. data/lib/action_controller/dispatcher.rb +51 -84
  25. data/lib/action_controller/filters.rb +295 -421
  26. data/lib/action_controller/flash.rb +1 -6
  27. data/lib/action_controller/headers.rb +31 -0
  28. data/lib/action_controller/helpers.rb +26 -9
  29. data/lib/action_controller/http_authentication.rb +1 -1
  30. data/lib/action_controller/integration.rb +65 -13
  31. data/lib/action_controller/layout.rb +24 -39
  32. data/lib/action_controller/mime_responds.rb +7 -3
  33. data/lib/action_controller/mime_type.rb +25 -9
  34. data/lib/action_controller/mime_types.rb +1 -1
  35. data/lib/action_controller/polymorphic_routes.rb +32 -17
  36. data/lib/action_controller/record_identifier.rb +10 -4
  37. data/lib/action_controller/request.rb +46 -30
  38. data/lib/action_controller/request_forgery_protection.rb +10 -9
  39. data/lib/action_controller/request_profiler.rb +29 -8
  40. data/lib/action_controller/rescue.rb +24 -24
  41. data/lib/action_controller/resources.rb +66 -23
  42. data/lib/action_controller/response.rb +2 -2
  43. data/lib/action_controller/routing.rb +113 -1229
  44. data/lib/action_controller/routing/builder.rb +204 -0
  45. data/lib/action_controller/{routing_optimisation.rb → routing/optimisations.rb} +13 -12
  46. data/lib/action_controller/routing/recognition_optimisation.rb +158 -0
  47. data/lib/action_controller/routing/route.rb +240 -0
  48. data/lib/action_controller/routing/route_set.rb +435 -0
  49. data/lib/action_controller/routing/routing_ext.rb +46 -0
  50. data/lib/action_controller/routing/segments.rb +283 -0
  51. data/lib/action_controller/session/active_record_store.rb +13 -8
  52. data/lib/action_controller/session/cookie_store.rb +20 -17
  53. data/lib/action_controller/session_management.rb +10 -3
  54. data/lib/action_controller/streaming.rb +45 -31
  55. data/lib/action_controller/test_case.rb +33 -23
  56. data/lib/action_controller/test_process.rb +39 -35
  57. data/lib/action_controller/url_rewriter.rb +18 -12
  58. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -1
  59. data/lib/action_pack.rb +1 -1
  60. data/lib/action_pack/version.rb +2 -2
  61. data/lib/action_view.rb +11 -3
  62. data/lib/action_view/base.rb +73 -390
  63. data/lib/action_view/helpers/active_record_helper.rb +83 -62
  64. data/lib/action_view/helpers/asset_tag_helper.rb +101 -44
  65. data/lib/action_view/helpers/atom_feed_helper.rb +35 -7
  66. data/lib/action_view/helpers/benchmark_helper.rb +5 -3
  67. data/lib/action_view/helpers/cache_helper.rb +3 -2
  68. data/lib/action_view/helpers/capture_helper.rb +1 -2
  69. data/lib/action_view/helpers/date_helper.rb +104 -82
  70. data/lib/action_view/helpers/form_helper.rb +148 -75
  71. data/lib/action_view/helpers/form_options_helper.rb +44 -23
  72. data/lib/action_view/helpers/form_tag_helper.rb +22 -13
  73. data/lib/action_view/helpers/javascripts/controls.js +1 -1
  74. data/lib/action_view/helpers/javascripts/dragdrop.js +1 -1
  75. data/lib/action_view/helpers/javascripts/effects.js +1 -1
  76. data/lib/action_view/helpers/number_helper.rb +10 -3
  77. data/lib/action_view/helpers/prototype_helper.rb +61 -29
  78. data/lib/action_view/helpers/record_tag_helper.rb +3 -3
  79. data/lib/action_view/helpers/sanitize_helper.rb +23 -17
  80. data/lib/action_view/helpers/scriptaculous_helper.rb +86 -60
  81. data/lib/action_view/helpers/text_helper.rb +153 -125
  82. data/lib/action_view/helpers/url_helper.rb +83 -28
  83. data/lib/action_view/inline_template.rb +20 -0
  84. data/lib/action_view/partial_template.rb +70 -0
  85. data/lib/action_view/partials.rb +31 -73
  86. data/lib/action_view/template.rb +127 -0
  87. data/lib/action_view/template_error.rb +8 -7
  88. data/lib/action_view/template_finder.rb +177 -0
  89. data/lib/action_view/template_handler.rb +18 -1
  90. data/lib/action_view/template_handlers/builder.rb +10 -2
  91. data/lib/action_view/template_handlers/compilable.rb +128 -0
  92. data/lib/action_view/template_handlers/erb.rb +37 -2
  93. data/lib/action_view/template_handlers/rjs.rb +14 -1
  94. data/lib/action_view/test_case.rb +58 -0
  95. data/test/abstract_unit.rb +1 -1
  96. data/test/active_record_unit.rb +3 -6
  97. data/test/activerecord/active_record_store_test.rb +1 -2
  98. data/test/activerecord/render_partial_with_record_identification_test.rb +158 -41
  99. data/test/adv_attr_test.rb +20 -0
  100. data/test/controller/action_pack_assertions_test.rb +16 -19
  101. data/test/controller/addresses_render_test.rb +1 -1
  102. data/test/controller/assert_select_test.rb +13 -6
  103. data/test/controller/base_test.rb +48 -2
  104. data/test/controller/benchmark_test.rb +1 -2
  105. data/test/controller/caching_test.rb +282 -21
  106. data/test/controller/capture_test.rb +1 -1
  107. data/test/controller/cgi_test.rb +1 -1
  108. data/test/controller/components_test.rb +1 -1
  109. data/test/controller/content_type_test.rb +2 -2
  110. data/test/controller/cookie_test.rb +13 -2
  111. data/test/controller/custom_handler_test.rb +14 -10
  112. data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -1
  113. data/test/controller/dispatcher_test.rb +31 -49
  114. data/test/controller/fake_controllers.rb +17 -0
  115. data/test/controller/fake_models.rb +6 -0
  116. data/test/controller/filter_params_test.rb +14 -8
  117. data/test/controller/filters_test.rb +44 -16
  118. data/test/controller/flash_test.rb +2 -2
  119. data/test/controller/header_test.rb +14 -0
  120. data/test/controller/helper_test.rb +19 -15
  121. data/test/controller/html-scanner/document_test.rb +1 -2
  122. data/test/controller/html-scanner/node_test.rb +1 -2
  123. data/test/controller/html-scanner/sanitizer_test.rb +8 -5
  124. data/test/controller/html-scanner/tag_node_test.rb +1 -2
  125. data/test/controller/html-scanner/text_node_test.rb +2 -3
  126. data/test/controller/html-scanner/tokenizer_test.rb +8 -2
  127. data/test/controller/http_authentication_test.rb +1 -1
  128. data/test/controller/integration_test.rb +14 -16
  129. data/test/controller/integration_upload_test.rb +43 -0
  130. data/test/controller/layout_test.rb +26 -6
  131. data/test/controller/mime_responds_test.rb +39 -7
  132. data/test/controller/mime_type_test.rb +29 -5
  133. data/test/controller/new_render_test.rb +105 -34
  134. data/test/controller/polymorphic_routes_test.rb +32 -20
  135. data/test/controller/record_identifier_test.rb +38 -2
  136. data/test/controller/redirect_test.rb +21 -1
  137. data/test/controller/render_test.rb +59 -15
  138. data/test/controller/request_forgery_protection_test.rb +92 -5
  139. data/test/controller/request_test.rb +64 -6
  140. data/test/controller/rescue_test.rb +22 -6
  141. data/test/controller/resources_test.rb +102 -14
  142. data/test/controller/routing_test.rb +231 -19
  143. data/test/controller/selector_test.rb +2 -2
  144. data/test/controller/send_file_test.rb +14 -3
  145. data/test/controller/session/cookie_store_test.rb +16 -4
  146. data/test/controller/session/mem_cache_store_test.rb +3 -4
  147. data/test/controller/session_fixation_test.rb +1 -1
  148. data/test/controller/session_management_test.rb +23 -1
  149. data/test/controller/test_test.rb +39 -18
  150. data/test/controller/url_rewriter_test.rb +35 -1
  151. data/test/controller/verification_test.rb +1 -1
  152. data/test/controller/view_paths_test.rb +15 -12
  153. data/test/controller/webservice_test.rb +48 -3
  154. data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
  155. data/test/fixtures/company.rb +1 -0
  156. data/test/fixtures/customers/_customer.html.erb +1 -0
  157. data/test/fixtures/db_definitions/sqlite.sql +6 -0
  158. data/test/fixtures/functional_caching/_partial.erb +3 -0
  159. data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
  160. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
  161. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
  162. data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
  163. data/test/fixtures/mascot.rb +3 -0
  164. data/test/fixtures/mascots.yml +4 -0
  165. data/test/fixtures/mascots/_mascot.html.erb +1 -0
  166. data/test/fixtures/multipart/boundary_problem_file +10 -0
  167. data/test/fixtures/public/javascripts/application.js +1 -0
  168. data/test/fixtures/public/javascripts/controls.js +1 -0
  169. data/test/fixtures/public/javascripts/dragdrop.js +1 -0
  170. data/test/fixtures/public/javascripts/effects.js +1 -0
  171. data/test/fixtures/public/javascripts/prototype.js +1 -0
  172. data/test/fixtures/public/javascripts/version.1.0.js +1 -0
  173. data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
  174. data/test/fixtures/reply.rb +1 -0
  175. data/test/fixtures/shared.html.erb +1 -0
  176. data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
  177. data/test/fixtures/test/_customer_counter.erb +1 -0
  178. data/test/fixtures/test/_form.erb +1 -0
  179. data/test/fixtures/test/_labelling_form.erb +1 -0
  180. data/test/fixtures/test/_raise.html.erb +1 -0
  181. data/test/fixtures/test/greeting.js.rjs +1 -0
  182. data/test/fixtures/topics/_topic.html.erb +1 -0
  183. data/test/template/active_record_helper_test.rb +25 -8
  184. data/test/template/asset_tag_helper_test.rb +100 -17
  185. data/test/template/atom_feed_helper_test.rb +29 -1
  186. data/test/template/benchmark_helper_test.rb +10 -22
  187. data/test/template/date_helper_test.rb +455 -153
  188. data/test/template/erb_util_test.rb +10 -42
  189. data/test/template/form_helper_test.rb +192 -66
  190. data/test/template/form_options_helper_test.rb +19 -8
  191. data/test/template/form_tag_helper_test.rb +11 -8
  192. data/test/template/javascript_helper_test.rb +3 -9
  193. data/test/template/number_helper_test.rb +6 -3
  194. data/test/template/prototype_helper_test.rb +27 -40
  195. data/test/template/record_tag_helper_test.rb +54 -0
  196. data/test/template/sanitize_helper_test.rb +5 -6
  197. data/test/template/scriptaculous_helper_test.rb +7 -13
  198. data/test/template/tag_helper_test.rb +3 -6
  199. data/test/template/template_finder_test.rb +73 -0
  200. data/test/template/template_object_test.rb +95 -0
  201. data/test/template/test_test.rb +56 -0
  202. data/test/template/text_helper_test.rb +46 -33
  203. data/test/template/url_helper_test.rb +8 -10
  204. metadata +65 -12
  205. data/lib/action_view/compiled_templates.rb +0 -69
  206. data/test/action_view_test.rb +0 -44
  207. data/test/activerecord/fixtures_test.rb +0 -24
  208. data/test/controller/fragment_store_setting_test.rb +0 -47
  209. data/test/template/compiled_templates_test.rb +0 -197
  210. data/test/template/deprecate_ivars_test.rb +0 -51
@@ -3,7 +3,7 @@ require 'action_view/helpers/tag_helper'
3
3
 
4
4
  module ActionView
5
5
  module Helpers
6
- # Provides a number of methods for creating form tags that doesn't rely on an ActiveRecord object assigned to the template like
6
+ # Provides a number of methods for creating form tags that doesn't rely on an Active Record object assigned to the template like
7
7
  # FormHelper does. Instead, you provide the names and values manually.
8
8
  #
9
9
  # NOTE: The HTML options <tt>disabled</tt>, <tt>readonly</tt>, and <tt>multiple</tt> can all be treated as booleans. So specifying
@@ -14,9 +14,9 @@ module ActionView
14
14
  #
15
15
  # ==== Options
16
16
  # * <tt>:multipart</tt> - If set to true, the enctype is set to "multipart/form-data".
17
- # * <tt>:method</tt> - The method to use when submitting the form, usually either "get" or "post".
18
- # If "put", "delete", or another verb is used, a hidden input with name _method
19
- # is added to simulate the verb over post.
17
+ # * <tt>:method</tt> - The method to use when submitting the form, usually either "get" or "post".
18
+ # If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
19
+ # is added to simulate the verb over post.
20
20
  # * A list of parameters to feed to the URL the form will be posted to.
21
21
  #
22
22
  # ==== Examples
@@ -316,9 +316,12 @@ module ActionView
316
316
  # Creates a submit button with the text <tt>value</tt> as the caption.
317
317
  #
318
318
  # ==== Options
319
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
319
+ # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
320
+ # prompt with the question specified. If the user accepts, the form is
321
+ # processed normally, otherwise no action is taken.
322
+ # * <tt>:disabled</tt> - If true, the user will not be able to use this input.
320
323
  # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a disabled version
321
- # of the submit button when the form is submitted.
324
+ # of the submit button when the form is submitted.
322
325
  # * Any other key creates standard HTML options for the tag.
323
326
  #
324
327
  # ==== Examples
@@ -338,8 +341,9 @@ module ActionView
338
341
  # submit_tag nil, :class => "form_submit"
339
342
  # # => <input class="form_submit" name="commit" type="submit" />
340
343
  #
341
- # submit_tag "Edit", :disable_with => "Editing...", :class => 'edit-button'
342
- # # => <input class="edit-button" disable_with="Editing..." name="commit" type="submit" value="Edit" />
344
+ # submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
345
+ # # => <input class="edit-button" onclick="this.disabled=true;this.value='Editing...';this.form.submit();"
346
+ # # name="commit" type="submit" value="Edit" />
343
347
  def submit_tag(value = "Save changes", options = {})
344
348
  options.stringify_keys!
345
349
 
@@ -351,10 +355,15 @@ module ActionView
351
355
  "#{options["onclick"]}",
352
356
  "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
353
357
  "if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
354
- "return result",
358
+ "return result;",
355
359
  ].join(";")
356
360
  end
357
-
361
+
362
+ if confirm = options.delete("confirm")
363
+ options["onclick"] ||= ''
364
+ options["onclick"] += "return #{confirm_javascript_function(confirm)};"
365
+ end
366
+
358
367
  tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
359
368
  end
360
369
 
@@ -370,13 +379,13 @@ module ActionView
370
379
  # image_submit_tag("login.png")
371
380
  # # => <input src="/images/login.png" type="image" />
372
381
  #
373
- # image_submit_tag("purchase.png"), :disabled => true
382
+ # image_submit_tag("purchase.png", :disabled => true)
374
383
  # # => <input disabled="disabled" src="/images/purchase.png" type="image" />
375
384
  #
376
- # image_submit_tag("search.png"), :class => 'search-button'
385
+ # image_submit_tag("search.png", :class => 'search-button')
377
386
  # # => <input class="search-button" src="/images/search.png" type="image" />
378
387
  #
379
- # image_submit_tag("agree.png"), :disabled => true, :class => "agree-disagree-button"
388
+ # image_submit_tag("agree.png", :disabled => true, :class => "agree-disagree-button")
380
389
  # # => <input class="agree-disagree-button" disabled="disabled" src="/images/agree.png" type="image" />
381
390
  def image_submit_tag(source, options = {})
382
391
  tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
1
+ // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
2
  // (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
3
3
  // (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
4
4
  // Contributors:
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
1
+ // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
2
  // (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
3
3
  //
4
4
  // script.aculo.us is freely distributable under the terms of an MIT-style license.
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
1
+ // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
2
  // Contributors:
3
3
  // Justin Palmer (http://encytemedia.com/)
4
4
  // Mark Pilgrim (http://diveintomark.org/)
@@ -54,6 +54,10 @@ module ActionView
54
54
  # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
55
55
  # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
56
56
  # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
57
+ # * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
58
+ #
59
+ # %u The currency unit
60
+ # %n The number
57
61
  #
58
62
  # ==== Examples
59
63
  # number_to_currency(1234567890.50) # => $1,234,567,890.50
@@ -62,16 +66,19 @@ module ActionView
62
66
  #
63
67
  # number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
64
68
  # # => &pound;1234567890,50
69
+ # number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
70
+ # # => 1234567890,50 &pound;
65
71
  def number_to_currency(number, options = {})
66
72
  options = options.stringify_keys
67
73
  precision = options["precision"] || 2
68
74
  unit = options["unit"] || "$"
69
75
  separator = precision > 0 ? options["separator"] || "." : ""
70
76
  delimiter = options["delimiter"] || ","
77
+ format = options["format"] || "%u%n"
71
78
 
72
79
  begin
73
80
  parts = number_with_precision(number, precision).split('.')
74
- unit + number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s
81
+ format.gsub(/%n/, number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s).gsub(/%u/, unit)
75
82
  rescue
76
83
  number
77
84
  end
@@ -137,11 +144,11 @@ module ActionView
137
144
  #
138
145
  # ==== Examples
139
146
  # number_with_precision(111.2345) # => 111.235
140
- # number_with_precision(111.2345, 2) # => 111.24
147
+ # number_with_precision(111.2345, 2) # => 111.23
141
148
  # number_with_precision(13, 5) # => 13.00000
142
149
  # number_with_precision(389.32314, 0) # => 389
143
150
  def number_with_precision(number, precision=3)
144
- "%01.#{precision}f" % number
151
+ "%01.#{precision}f" % ((Float(number) * (10 ** precision)).round.to_f / 10 ** precision)
145
152
  rescue
146
153
  number
147
154
  end
@@ -255,10 +255,10 @@ module ActionView
255
255
  link_to_function(name, remote_function(options), html_options || options.delete(:html))
256
256
  end
257
257
 
258
- # Periodically calls the specified url (<tt>options[:url]</tt>) every
258
+ # Periodically calls the specified url (<tt>options[:url]</tt>) every
259
259
  # <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
260
- # update a specified div (<tt>options[:update]</tt>) with the results
261
- # of the remote call. The options for specifying the target with :url
260
+ # update a specified div (<tt>options[:update]</tt>) with the results
261
+ # of the remote call. The options for specifying the target with <tt>:url</tt>
262
262
  # and defining callbacks is the same as link_to_remote.
263
263
  # Examples:
264
264
  # # Call get_averages and put its results in 'avg' every 10 seconds
@@ -291,11 +291,11 @@ module ActionView
291
291
  # though it's using JavaScript to serialize the form elements, the form
292
292
  # submission will work just like a regular submission as viewed by the
293
293
  # receiving side (all elements available in <tt>params</tt>). The options for
294
- # specifying the target with :url and defining callbacks is the same as
295
- # link_to_remote.
294
+ # specifying the target with <tt>:url</tt> and defining callbacks is the same as
295
+ # +link_to_remote+.
296
296
  #
297
297
  # A "fall-through" target for browsers that doesn't do JavaScript can be
298
- # specified with the :action/:method options on :html.
298
+ # specified with the <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>.
299
299
  #
300
300
  # Example:
301
301
  # # Generates:
@@ -304,11 +304,11 @@ module ActionView
304
304
  # form_remote_tag :html => { :action =>
305
305
  # url_for(:controller => "some", :action => "place") }
306
306
  #
307
- # The Hash passed to the :html key is equivalent to the options (2nd)
307
+ # The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd)
308
308
  # argument in the FormTagHelper.form_tag method.
309
309
  #
310
310
  # By default the fall-through action is the same as the one specified in
311
- # the :url (and the default method is :post).
311
+ # the <tt>:url</tt> (and the default method is <tt>:post</tt>).
312
312
  #
313
313
  # form_remote_tag also takes a block, like form_tag:
314
314
  # # Generates:
@@ -422,8 +422,8 @@ module ActionView
422
422
  end
423
423
 
424
424
  # Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function
425
- # that form_remote_tag can call in :complete to evaluate a multiple
426
- # update return document using update_element_function calls.
425
+ # that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
426
+ # update return document using +update_element_function+ calls.
427
427
  def evaluate_remote_response
428
428
  "eval(request.responseText)"
429
429
  end
@@ -458,7 +458,7 @@ module ActionView
458
458
 
459
459
  url_options = options[:url]
460
460
  url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
461
- function << "'#{url_for(url_options)}'"
461
+ function << "'#{escape_javascript(url_for(url_options))}'"
462
462
  function << ", #{javascript_options})"
463
463
 
464
464
  function = "#{options[:before]}; #{function}" if options[:before]
@@ -595,8 +595,8 @@ module ActionView
595
595
  # JavaScript sent with a Content-type of "text/javascript".
596
596
  #
597
597
  # Create new instances with PrototypeHelper#update_page or with
598
- # ActionController::Base#render, then call #insert_html, #replace_html,
599
- # #remove, #show, #hide, #visual_effect, or any other of the built-in
598
+ # ActionController::Base#render, then call +insert_html+, +replace_html+,
599
+ # +remove+, +show+, +hide+, +visual_effect+, or any other of the built-in
600
600
  # methods on the yielded generator in any order you like to modify the
601
601
  # content and appearance of the current page.
602
602
  #
@@ -631,6 +631,27 @@ module ActionView
631
631
  # render(:update) { |page| page.update_time }
632
632
  # end
633
633
  #
634
+ # Calls to JavaScriptGenerator not matching a helper method below
635
+ # generate a proxy to the JavaScript Class named by the method called.
636
+ #
637
+ # Examples:
638
+ #
639
+ # # Generates:
640
+ # # Foo.init();
641
+ # update_page do |page|
642
+ # page.foo.init
643
+ # end
644
+ #
645
+ # # Generates:
646
+ # # Event.observe('one', 'click', function () {
647
+ # # $('two').show();
648
+ # # });
649
+ # update_page do |page|
650
+ # page.event.observe('one', 'click') do |p|
651
+ # p[:two].show
652
+ # end
653
+ # end
654
+ #
634
655
  # You can also use PrototypeHelper#update_page_tag instead of
635
656
  # PrototypeHelper#update_page to wrap the generated JavaScript in a
636
657
  # <script> tag.
@@ -666,7 +687,7 @@ module ActionView
666
687
  end
667
688
  end
668
689
 
669
- # Returns an object whose <tt>#to_json</tt> evaluates to +code+. Use this to pass a literal JavaScript
690
+ # Returns an object whose <tt>to_json</tt> evaluates to +code+. Use this to pass a literal JavaScript
670
691
  # expression as an argument to another JavaScriptGenerator method.
671
692
  def literal(code)
672
693
  ActiveSupport::JSON::Variable.new(code.to_s)
@@ -716,11 +737,11 @@ module ActionView
716
737
  # # Insert the rendered 'navigation' partial just before the DOM
717
738
  # # element with ID 'content'.
718
739
  # # Generates: new Insertion.Before("content", "-- Contents of 'navigation' partial --");
719
- # insert_html :before, 'content', :partial => 'navigation'
740
+ # page.insert_html :before, 'content', :partial => 'navigation'
720
741
  #
721
742
  # # Add a list item to the bottom of the <ul> with ID 'list'.
722
743
  # # Generates: new Insertion.Bottom("list", "<li>Last item</li>");
723
- # insert_html :bottom, 'list', '<li>Last item</li>'
744
+ # page.insert_html :bottom, 'list', '<li>Last item</li>'
724
745
  #
725
746
  def insert_html(position, id, *options_for_render)
726
747
  insertion = position.to_s.camelize
@@ -735,7 +756,7 @@ module ActionView
735
756
  # # Replace the HTML of the DOM element having ID 'person-45' with the
736
757
  # # 'person' partial for the appropriate object.
737
758
  # # Generates: Element.update("person-45", "-- Contents of 'person' partial --");
738
- # replace_html 'person-45', :partial => 'person', :object => @person
759
+ # page.replace_html 'person-45', :partial => 'person', :object => @person
739
760
  #
740
761
  def replace_html(id, *options_for_render)
741
762
  call 'Element.update', id, render(*options_for_render)
@@ -749,7 +770,7 @@ module ActionView
749
770
  #
750
771
  # # Replace the DOM element having ID 'person-45' with the
751
772
  # # 'person' partial for the appropriate object.
752
- # replace 'person-45', :partial => 'person', :object => @person
773
+ # page.replace 'person-45', :partial => 'person', :object => @person
753
774
  #
754
775
  # This allows the same partial that is used for the +insert_html+ to
755
776
  # be also used for the input to +replace+ without resorting to
@@ -843,7 +864,8 @@ module ActionView
843
864
  # # Generates: window.location.href = "/account/signup";
844
865
  # page.redirect_to(:controller => 'account', :action => 'signup')
845
866
  def redirect_to(location)
846
- assign 'window.location.href', @context.url_for(location)
867
+ url = location.is_a?(String) ? location : @context.url_for(location)
868
+ record "window.location.href = #{url.inspect}"
847
869
  end
848
870
 
849
871
  # Calls the JavaScript +function+, optionally with the given +arguments+.
@@ -854,12 +876,21 @@ module ActionView
854
876
  #
855
877
  # Examples:
856
878
  #
857
- # # Generates: Element.replace(my_element, "My content to replace with.")
858
- # page.call 'Element.replace', 'my_element', "My content to replace with."
859
- #
860
- # # Generates: alert('My message!')
861
- # page.call 'alert', 'My message!'
862
- #
879
+ # # Generates: Element.replace(my_element, "My content to replace with.")
880
+ # page.call 'Element.replace', 'my_element', "My content to replace with."
881
+ #
882
+ # # Generates: alert('My message!')
883
+ # page.call 'alert', 'My message!'
884
+ #
885
+ # # Generates:
886
+ # # my_method(function() {
887
+ # # $("one").show();
888
+ # # $("two").hide();
889
+ # # });
890
+ # page.call(:my_method) do |p|
891
+ # p[:one].show
892
+ # p[:two].hide
893
+ # end
863
894
  def call(function, *arguments, &block)
864
895
  record "#{function}(#{arguments_for_call(arguments, block)})"
865
896
  end
@@ -1037,7 +1068,7 @@ module ActionView
1037
1068
 
1038
1069
  def build_observer(klass, name, options = {})
1039
1070
  if options[:with] && (options[:with] !~ /[\{=(.]/)
1040
- options[:with] = "'#{options[:with]}=' + value"
1071
+ options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)"
1041
1072
  else
1042
1073
  options[:with] ||= 'value' unless options[:function]
1043
1074
  end
@@ -1065,7 +1096,8 @@ module ActionView
1065
1096
  end
1066
1097
 
1067
1098
  # Converts chained method calls on DOM proxy elements into JavaScript chains
1068
- class JavaScriptProxy < BasicObject #:nodoc:
1099
+ class JavaScriptProxy < ActiveSupport::BasicObject #:nodoc:
1100
+
1069
1101
  def initialize(generator, root = nil)
1070
1102
  @generator = generator
1071
1103
  @generator << root if root
@@ -1141,7 +1173,7 @@ module ActionView
1141
1173
  super(generator)
1142
1174
  end
1143
1175
 
1144
- # The JSON Encoder calls this to check for the #to_json method
1176
+ # The JSON Encoder calls this to check for the +to_json+ method
1145
1177
  # Since it's a blank slate object, I suppose it responds to anything.
1146
1178
  def respond_to?(method)
1147
1179
  true
@@ -1203,7 +1235,7 @@ module ActionView
1203
1235
  append_enumerable_function!("zip(#{arguments_for_call arguments}")
1204
1236
  if block
1205
1237
  function_chain[-1] += ", function(array) {"
1206
- yield ActiveSupport::JSON::Variable.new('array')
1238
+ yield ::ActiveSupport::JSON::Variable.new('array')
1207
1239
  add_return_statement!
1208
1240
  @generator << '});'
1209
1241
  else
@@ -2,7 +2,7 @@ module ActionView
2
2
  module Helpers
3
3
  module RecordTagHelper
4
4
  # Produces a wrapper DIV element with id and class parameters that
5
- # relate to the specified ActiveRecord object. Usage example:
5
+ # relate to the specified Active Record object. Usage example:
6
6
  #
7
7
  # <% div_for(@person, :class => "foo") do %>
8
8
  # <%=h @person.name %>
@@ -17,14 +17,14 @@ module ActionView
17
17
  end
18
18
 
19
19
  # content_tag_for creates an HTML element with id and class parameters
20
- # that relate to the specified ActiveRecord object. For example:
20
+ # that relate to the specified Active Record object. For example:
21
21
  #
22
22
  # <% content_tag_for(:tr, @person) do %>
23
23
  # <td><%=h @person.first_name %></td>
24
24
  # <td><%=h @person.last_name %></td>
25
25
  # <% end %>
26
26
  #
27
- # would produce hthe following HTML (assuming @person is an instance of
27
+ # would produce the following HTML (assuming @person is an instance of
28
28
  # a Person object, with an id value of 123):
29
29
  #
30
30
  # <tr id="person_123" class="person">....</tr>
@@ -10,7 +10,7 @@ module ActionView
10
10
  base.extend(ClassMethods)
11
11
  end
12
12
 
13
- # This #sanitize helper will html encode all tags and strip all attributes that aren't specifically allowed.
13
+ # This +sanitize+ helper will html encode all tags and strip all attributes that aren't specifically allowed.
14
14
  # It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any
15
15
  # tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out
16
16
  # the extensive test suite.
@@ -18,7 +18,7 @@ module ActionView
18
18
  # <%= sanitize @article.body %>
19
19
  #
20
20
  # You can add or remove tags/attributes if you want to customize it a bit. See ActionView::Base for full docs on the
21
- # available options. You can add tags/attributes for single uses of #sanitize by passing either the :attributes or :tags options:
21
+ # available options. You can add tags/attributes for single uses of +sanitize+ by passing either the <tt>:attributes</tt> or <tt>:tags</tt> options:
22
22
  #
23
23
  # Normal Use
24
24
  #
@@ -48,11 +48,16 @@ module ActionView
48
48
  # config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
49
49
  # end
50
50
  #
51
+ # Please note that sanitizing user-provided text does not guarantee that the
52
+ # resulting markup is valid (conforming to a document type) or even well-formed.
53
+ # The output may still contain e.g. unescaped '<', '>', '&' characters and
54
+ # confuse browsers.
55
+ #
51
56
  def sanitize(html, options = {})
52
57
  self.class.white_list_sanitizer.sanitize(html, options)
53
58
  end
54
59
 
55
- # Sanitizes a block of css code. Used by #sanitize when it comes across a style attribute
60
+ # Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
56
61
  def sanitize_css(style)
57
62
  self.class.white_list_sanitizer.sanitize_css(style)
58
63
  end
@@ -106,8 +111,8 @@ module ActionView
106
111
  end
107
112
  end
108
113
 
109
- # Gets the HTML::FullSanitizer instance used by strip_tags. Replace with
110
- # any object that responds to #sanitize
114
+ # Gets the HTML::FullSanitizer instance used by +strip_tags+. Replace with
115
+ # any object that responds to +sanitize+.
111
116
  #
112
117
  # Rails::Initializer.run do |config|
113
118
  # config.action_view.full_sanitizer = MySpecialSanitizer.new
@@ -117,8 +122,8 @@ module ActionView
117
122
  @full_sanitizer ||= HTML::FullSanitizer.new
118
123
  end
119
124
 
120
- # Gets the HTML::LinkSanitizer instance used by strip_links. Replace with
121
- # any object that responds to #sanitize
125
+ # Gets the HTML::LinkSanitizer instance used by +strip_links+. Replace with
126
+ # any object that responds to +sanitize+.
122
127
  #
123
128
  # Rails::Initializer.run do |config|
124
129
  # config.action_view.link_sanitizer = MySpecialSanitizer.new
@@ -128,8 +133,8 @@ module ActionView
128
133
  @link_sanitizer ||= HTML::LinkSanitizer.new
129
134
  end
130
135
 
131
- # Gets the HTML::WhiteListSanitizer instance used by sanitize and sanitize_css.
132
- # Replace with any object that responds to #sanitize
136
+ # Gets the HTML::WhiteListSanitizer instance used by sanitize and +sanitize_css+.
137
+ # Replace with any object that responds to +sanitize+.
133
138
  #
134
139
  # Rails::Initializer.run do |config|
135
140
  # config.action_view.white_list_sanitizer = MySpecialSanitizer.new
@@ -139,7 +144,7 @@ module ActionView
139
144
  @white_list_sanitizer ||= HTML::WhiteListSanitizer.new
140
145
  end
141
146
 
142
- # Adds valid HTML attributes that the #sanitize helper checks for URIs.
147
+ # Adds valid HTML attributes that the +sanitize+ helper checks for URIs.
143
148
  #
144
149
  # Rails::Initializer.run do |config|
145
150
  # config.action_view.sanitized_uri_attributes = 'lowsrc', 'target'
@@ -149,7 +154,7 @@ module ActionView
149
154
  HTML::WhiteListSanitizer.uri_attributes.merge(attributes)
150
155
  end
151
156
 
152
- # Adds to the Set of 'bad' tags for the #sanitize helper.
157
+ # Adds to the Set of 'bad' tags for the +sanitize+ helper.
153
158
  #
154
159
  # Rails::Initializer.run do |config|
155
160
  # config.action_view.sanitized_bad_tags = 'embed', 'object'
@@ -158,7 +163,8 @@ module ActionView
158
163
  def sanitized_bad_tags=(attributes)
159
164
  HTML::WhiteListSanitizer.bad_tags.merge(attributes)
160
165
  end
161
- # Adds to the Set of allowed tags for the #sanitize helper.
166
+
167
+ # Adds to the Set of allowed tags for the +sanitize+ helper.
162
168
  #
163
169
  # Rails::Initializer.run do |config|
164
170
  # config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
@@ -168,7 +174,7 @@ module ActionView
168
174
  HTML::WhiteListSanitizer.allowed_tags.merge(attributes)
169
175
  end
170
176
 
171
- # Adds to the Set of allowed html attributes for the #sanitize helper.
177
+ # Adds to the Set of allowed HTML attributes for the +sanitize+ helper.
172
178
  #
173
179
  # Rails::Initializer.run do |config|
174
180
  # config.action_view.sanitized_allowed_attributes = 'onclick', 'longdesc'
@@ -178,7 +184,7 @@ module ActionView
178
184
  HTML::WhiteListSanitizer.allowed_attributes.merge(attributes)
179
185
  end
180
186
 
181
- # Adds to the Set of allowed css properties for the #sanitize and #sanitize_css heleprs.
187
+ # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ heleprs.
182
188
  #
183
189
  # Rails::Initializer.run do |config|
184
190
  # config.action_view.sanitized_allowed_css_properties = 'expression'
@@ -188,7 +194,7 @@ module ActionView
188
194
  HTML::WhiteListSanitizer.allowed_css_properties.merge(attributes)
189
195
  end
190
196
 
191
- # Adds to the Set of allowed css keywords for the #sanitize and #sanitize_css helpers.
197
+ # Adds to the Set of allowed CSS keywords for the +sanitize+ and +sanitize_css+ helpers.
192
198
  #
193
199
  # Rails::Initializer.run do |config|
194
200
  # config.action_view.sanitized_allowed_css_keywords = 'expression'
@@ -198,7 +204,7 @@ module ActionView
198
204
  HTML::WhiteListSanitizer.allowed_css_keywords.merge(attributes)
199
205
  end
200
206
 
201
- # Adds to the Set of allowed shorthand css properties for the #sanitize and #sanitize_css helpers.
207
+ # Adds to the Set of allowed shorthand CSS properties for the +sanitize+ and +sanitize_css+ helpers.
202
208
  #
203
209
  # Rails::Initializer.run do |config|
204
210
  # config.action_view.sanitized_shorthand_css_properties = 'expression'
@@ -208,7 +214,7 @@ module ActionView
208
214
  HTML::WhiteListSanitizer.shorthand_css_properties.merge(attributes)
209
215
  end
210
216
 
211
- # Adds to the Set of allowed protocols for the #sanitize helper.
217
+ # Adds to the Set of allowed protocols for the +sanitize+ helper.
212
218
  #
213
219
  # Rails::Initializer.run do |config|
214
220
  # config.action_view.sanitized_allowed_protocols = 'ssh', 'feed'