actionpack 2.2.3 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (264) hide show
  1. data/CHANGELOG +433 -375
  2. data/MIT-LICENSE +1 -1
  3. data/README +21 -75
  4. data/Rakefile +1 -1
  5. data/lib/action_controller.rb +80 -43
  6. data/lib/action_controller/assertions/model_assertions.rb +1 -0
  7. data/lib/action_controller/assertions/response_assertions.rb +43 -16
  8. data/lib/action_controller/assertions/routing_assertions.rb +1 -1
  9. data/lib/action_controller/assertions/selector_assertions.rb +17 -12
  10. data/lib/action_controller/assertions/tag_assertions.rb +1 -4
  11. data/lib/action_controller/base.rb +153 -82
  12. data/lib/action_controller/benchmarking.rb +9 -9
  13. data/lib/action_controller/caching.rb +9 -11
  14. data/lib/action_controller/caching/actions.rb +11 -18
  15. data/lib/action_controller/caching/fragments.rb +28 -20
  16. data/lib/action_controller/caching/pages.rb +13 -15
  17. data/lib/action_controller/caching/sweeping.rb +2 -2
  18. data/lib/action_controller/cgi_ext.rb +0 -1
  19. data/lib/action_controller/cgi_ext/cookie.rb +2 -0
  20. data/lib/action_controller/cgi_process.rb +54 -162
  21. data/lib/action_controller/cookies.rb +13 -25
  22. data/lib/action_controller/dispatcher.rb +43 -122
  23. data/lib/action_controller/failsafe.rb +52 -0
  24. data/lib/action_controller/flash.rb +38 -47
  25. data/lib/action_controller/helpers.rb +13 -9
  26. data/lib/action_controller/http_authentication.rb +203 -23
  27. data/lib/action_controller/integration.rb +126 -70
  28. data/lib/action_controller/layout.rb +36 -39
  29. data/lib/action_controller/middleware_stack.rb +119 -0
  30. data/lib/action_controller/middlewares.rb +13 -0
  31. data/lib/action_controller/mime_responds.rb +19 -4
  32. data/lib/action_controller/mime_type.rb +8 -0
  33. data/lib/action_controller/params_parser.rb +71 -0
  34. data/lib/action_controller/performance_test.rb +0 -1
  35. data/lib/action_controller/polymorphic_routes.rb +36 -30
  36. data/lib/action_controller/reloader.rb +14 -0
  37. data/lib/action_controller/request.rb +107 -499
  38. data/lib/action_controller/request_forgery_protection.rb +7 -39
  39. data/lib/action_controller/rescue.rb +55 -35
  40. data/lib/action_controller/resources.rb +34 -31
  41. data/lib/action_controller/response.rb +99 -57
  42. data/lib/action_controller/rewindable_input.rb +28 -0
  43. data/lib/action_controller/routing.rb +7 -7
  44. data/lib/action_controller/routing/builder.rb +4 -1
  45. data/lib/action_controller/routing/optimisations.rb +1 -1
  46. data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
  47. data/lib/action_controller/routing/route.rb +15 -5
  48. data/lib/action_controller/routing/route_set.rb +82 -35
  49. data/lib/action_controller/routing/segments.rb +35 -0
  50. data/lib/action_controller/session/abstract_store.rb +181 -0
  51. data/lib/action_controller/session/cookie_store.rb +197 -175
  52. data/lib/action_controller/session/mem_cache_store.rb +36 -83
  53. data/lib/action_controller/session_management.rb +26 -134
  54. data/lib/action_controller/streaming.rb +24 -7
  55. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  56. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  57. data/lib/action_controller/test_case.rb +87 -30
  58. data/lib/action_controller/test_process.rb +145 -104
  59. data/lib/action_controller/uploaded_file.rb +44 -0
  60. data/lib/action_controller/url_rewriter.rb +3 -6
  61. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  62. data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
  63. data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
  64. data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
  65. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
  66. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
  67. data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
  68. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
  69. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
  70. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
  71. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
  72. data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
  73. data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
  74. data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
  75. data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
  76. data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
  77. data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
  78. data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
  79. data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
  80. data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
  81. data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
  82. data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
  83. data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
  84. data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
  85. data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
  86. data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
  87. data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
  88. data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
  89. data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
  90. data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
  91. data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
  92. data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
  93. data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
  94. data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
  95. data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
  96. data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
  97. data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
  98. data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
  99. data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
  100. data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
  101. data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
  102. data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
  103. data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
  104. data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
  105. data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
  106. data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
  107. data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
  108. data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
  109. data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
  110. data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
  111. data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
  112. data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
  113. data/lib/action_controller/verification.rb +1 -1
  114. data/lib/action_pack.rb +1 -1
  115. data/lib/action_pack/version.rb +2 -2
  116. data/lib/action_view.rb +22 -17
  117. data/lib/action_view/base.rb +53 -79
  118. data/lib/action_view/erb/util.rb +38 -0
  119. data/lib/action_view/helpers.rb +24 -5
  120. data/lib/action_view/helpers/active_record_helper.rb +2 -2
  121. data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
  122. data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
  123. data/lib/action_view/helpers/benchmark_helper.rb +26 -5
  124. data/lib/action_view/helpers/date_helper.rb +82 -7
  125. data/lib/action_view/helpers/form_helper.rb +295 -64
  126. data/lib/action_view/helpers/form_options_helper.rb +160 -18
  127. data/lib/action_view/helpers/form_tag_helper.rb +2 -2
  128. data/lib/action_view/helpers/number_helper.rb +31 -18
  129. data/lib/action_view/helpers/prototype_helper.rb +2 -12
  130. data/lib/action_view/helpers/sanitize_helper.rb +0 -10
  131. data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
  132. data/lib/action_view/helpers/tag_helper.rb +3 -4
  133. data/lib/action_view/helpers/text_helper.rb +99 -122
  134. data/lib/action_view/helpers/translation_helper.rb +19 -1
  135. data/lib/action_view/helpers/url_helper.rb +25 -2
  136. data/lib/action_view/inline_template.rb +1 -1
  137. data/lib/action_view/locale/en.yml +19 -1
  138. data/lib/action_view/partials.rb +46 -9
  139. data/lib/action_view/paths.rb +28 -84
  140. data/lib/action_view/reloadable_template.rb +117 -0
  141. data/lib/action_view/renderable.rb +28 -35
  142. data/lib/action_view/renderable_partial.rb +3 -4
  143. data/lib/action_view/template.rb +172 -31
  144. data/lib/action_view/template_error.rb +8 -9
  145. data/lib/action_view/template_handler.rb +1 -1
  146. data/lib/action_view/template_handlers.rb +9 -6
  147. data/lib/action_view/template_handlers/erb.rb +2 -39
  148. data/lib/action_view/template_handlers/rjs.rb +1 -0
  149. data/lib/action_view/test_case.rb +27 -1
  150. data/test/abstract_unit.rb +23 -17
  151. data/test/active_record_unit.rb +5 -4
  152. data/test/activerecord/active_record_store_test.rb +139 -106
  153. data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
  154. data/test/controller/action_pack_assertions_test.rb +25 -23
  155. data/test/controller/addresses_render_test.rb +3 -6
  156. data/test/controller/assert_select_test.rb +83 -70
  157. data/test/controller/base_test.rb +11 -13
  158. data/test/controller/benchmark_test.rb +3 -3
  159. data/test/controller/caching_test.rb +34 -24
  160. data/test/controller/capture_test.rb +3 -6
  161. data/test/controller/content_type_test.rb +3 -6
  162. data/test/controller/cookie_test.rb +31 -66
  163. data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
  164. data/test/controller/dispatcher_test.rb +23 -28
  165. data/test/controller/fake_models.rb +8 -0
  166. data/test/controller/filters_test.rb +6 -2
  167. data/test/controller/flash_test.rb +2 -6
  168. data/test/controller/helper_test.rb +15 -1
  169. data/test/controller/html-scanner/document_test.rb +1 -1
  170. data/test/controller/html-scanner/sanitizer_test.rb +1 -1
  171. data/test/controller/http_basic_authentication_test.rb +88 -0
  172. data/test/controller/http_digest_authentication_test.rb +178 -0
  173. data/test/controller/integration_test.rb +56 -52
  174. data/test/controller/layout_test.rb +46 -44
  175. data/test/controller/middleware_stack_test.rb +90 -0
  176. data/test/controller/mime_responds_test.rb +7 -11
  177. data/test/controller/mime_type_test.rb +9 -0
  178. data/test/controller/polymorphic_routes_test.rb +235 -151
  179. data/test/controller/rack_test.rb +52 -81
  180. data/test/controller/redirect_test.rb +6 -14
  181. data/test/controller/render_test.rb +273 -60
  182. data/test/controller/request/json_params_parsing_test.rb +45 -0
  183. data/test/controller/request/multipart_params_parsing_test.rb +223 -0
  184. data/test/controller/request/query_string_parsing_test.rb +120 -0
  185. data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
  186. data/test/controller/request/xml_params_parsing_test.rb +88 -0
  187. data/test/controller/request_forgery_protection_test.rb +17 -98
  188. data/test/controller/request_test.rb +45 -530
  189. data/test/controller/rescue_test.rb +45 -22
  190. data/test/controller/resources_test.rb +112 -37
  191. data/test/controller/routing_test.rb +1442 -1384
  192. data/test/controller/selector_test.rb +3 -3
  193. data/test/controller/send_file_test.rb +30 -3
  194. data/test/controller/session/cookie_store_test.rb +169 -240
  195. data/test/controller/session/mem_cache_store_test.rb +94 -148
  196. data/test/controller/session/test_session_test.rb +58 -0
  197. data/test/controller/test_test.rb +32 -13
  198. data/test/controller/url_rewriter_test.rb +54 -4
  199. data/test/controller/verification_test.rb +1 -1
  200. data/test/controller/view_paths_test.rb +15 -15
  201. data/test/controller/webservice_test.rb +178 -147
  202. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  203. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  204. data/test/fixtures/layouts/default_html.html.erb +1 -0
  205. data/test/fixtures/layouts/xhr.html.erb +2 -0
  206. data/test/fixtures/multipart/empty +10 -0
  207. data/test/fixtures/multipart/hello.txt +1 -0
  208. data/test/fixtures/multipart/none +9 -0
  209. data/test/fixtures/public/500.da.html +1 -0
  210. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  211. data/test/fixtures/replies.yml +1 -1
  212. data/test/fixtures/test/_one.html.erb +1 -0
  213. data/test/fixtures/test/_two.html.erb +1 -0
  214. data/test/fixtures/test/dont_pick_me +1 -0
  215. data/test/fixtures/test/hello.builder +1 -1
  216. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  217. data/test/fixtures/test/hello_world.erb~ +1 -0
  218. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  219. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  220. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  221. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  222. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  223. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  224. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  225. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  226. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  227. data/test/fixtures/test/utf8.html.erb +2 -0
  228. data/test/template/active_record_helper_i18n_test.rb +31 -33
  229. data/test/template/active_record_helper_test.rb +34 -0
  230. data/test/template/asset_tag_helper_test.rb +52 -14
  231. data/test/template/atom_feed_helper_test.rb +3 -5
  232. data/test/template/benchmark_helper_test.rb +50 -24
  233. data/test/template/compiled_templates_test.rb +177 -33
  234. data/test/template/date_helper_i18n_test.rb +88 -81
  235. data/test/template/date_helper_test.rb +427 -43
  236. data/test/template/form_helper_test.rb +243 -44
  237. data/test/template/form_options_helper_test.rb +631 -565
  238. data/test/template/form_tag_helper_test.rb +9 -2
  239. data/test/template/javascript_helper_test.rb +0 -5
  240. data/test/template/number_helper_i18n_test.rb +60 -48
  241. data/test/template/number_helper_test.rb +1 -0
  242. data/test/template/render_test.rb +117 -35
  243. data/test/template/test_test.rb +4 -6
  244. data/test/template/text_helper_test.rb +129 -50
  245. data/test/template/translation_helper_test.rb +23 -19
  246. data/test/template/url_helper_test.rb +35 -2
  247. data/test/view/test_case_test.rb +8 -0
  248. metadata +197 -23
  249. data/lib/action_controller/assertions.rb +0 -69
  250. data/lib/action_controller/caching/sql_cache.rb +0 -18
  251. data/lib/action_controller/cgi_ext/session.rb +0 -53
  252. data/lib/action_controller/components.rb +0 -169
  253. data/lib/action_controller/rack_process.rb +0 -297
  254. data/lib/action_controller/request_profiler.rb +0 -169
  255. data/lib/action_controller/session/active_record_store.rb +0 -340
  256. data/lib/action_controller/session/drb_server.rb +0 -32
  257. data/lib/action_controller/session/drb_store.rb +0 -35
  258. data/test/controller/cgi_test.rb +0 -269
  259. data/test/controller/components_test.rb +0 -156
  260. data/test/controller/http_authentication_test.rb +0 -54
  261. data/test/controller/integration_upload_test.rb +0 -43
  262. data/test/controller/session_fixation_test.rb +0 -89
  263. data/test/controller/session_management_test.rb +0 -178
  264. data/test/fixtures/test/hello_world.js +0 -1
@@ -1,5 +1,4 @@
1
- require 'cgi'
2
- require 'erb'
1
+ require 'action_view/erb/util'
3
2
  require 'set'
4
3
 
5
4
  module ActionView
@@ -98,13 +97,13 @@ module ActionView
98
97
  # Returns an escaped version of +html+ without affecting existing escaped entities.
99
98
  #
100
99
  # ==== Examples
101
- # escape_once("1 > 2 & 3")
100
+ # escape_once("1 < 2 &amp; 3")
102
101
  # # => "1 &lt; 2 &amp; 3"
103
102
  #
104
103
  # escape_once("&lt;&lt; Accept & Checkout")
105
104
  # # => "&lt;&lt; Accept &amp; Checkout"
106
105
  def escape_once(html)
107
- ActiveSupport::Multibyte.clean(html.to_s).gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
106
+ html.to_s.gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
108
107
  end
109
108
 
110
109
  private
@@ -1,15 +1,5 @@
1
1
  require 'action_view/helpers/tag_helper'
2
2
 
3
- begin
4
- require 'html/document'
5
- rescue LoadError
6
- html_scanner_path = "#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner"
7
- if File.directory?(html_scanner_path)
8
- $:.unshift html_scanner_path
9
- require 'html/document'
10
- end
11
- end
12
-
13
3
  module ActionView
14
4
  module Helpers #:nodoc:
15
5
  # The TextHelper module provides a set of methods for filtering, formatting
@@ -117,7 +107,7 @@ module ActionView
117
107
  text
118
108
  else
119
109
  match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
120
- text.gsub(/(#{match})/i, options[:highlighter])
110
+ text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
121
111
  end
122
112
  end
123
113
 
@@ -226,91 +216,79 @@ module ActionView
226
216
  end * "\n"
227
217
  end
228
218
 
229
- begin
230
- require_library_or_gem "redcloth" unless Object.const_defined?(:RedCloth)
231
-
232
- # Returns the text with all the Textile[http://www.textism.com/tools/textile] codes turned into HTML tags.
233
- #
234
- # You can learn more about Textile's syntax at its website[http://www.textism.com/tools/textile].
235
- # <i>This method is only available if RedCloth[http://whytheluckystiff.net/ruby/redcloth/]
236
- # is available</i>.
237
- #
238
- # ==== Examples
239
- # textilize("*This is Textile!* Rejoice!")
240
- # # => "<p><strong>This is Textile!</strong> Rejoice!</p>"
241
- #
242
- # textilize("I _love_ ROR(Ruby on Rails)!")
243
- # # => "<p>I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!</p>"
244
- #
245
- # textilize("h2. Textile makes markup -easy- simple!")
246
- # # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"
247
- #
248
- # textilize("Visit the Rails website "here":http://www.rubyonrails.org/.)
249
- # # => "<p>Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>.</p>"
250
- def textilize(text)
251
- if text.blank?
252
- ""
253
- else
254
- textilized = RedCloth.new(text, [ :hard_breaks ])
255
- textilized.hard_breaks = true if textilized.respond_to?(:hard_breaks=)
256
- textilized.to_html
257
- end
219
+ # Returns the text with all the Textile[http://www.textism.com/tools/textile] codes turned into HTML tags.
220
+ #
221
+ # You can learn more about Textile's syntax at its website[http://www.textism.com/tools/textile].
222
+ # <i>This method is only available if RedCloth[http://whytheluckystiff.net/ruby/redcloth/]
223
+ # is available</i>.
224
+ #
225
+ # ==== Examples
226
+ # textilize("*This is Textile!* Rejoice!")
227
+ # # => "<p><strong>This is Textile!</strong> Rejoice!</p>"
228
+ #
229
+ # textilize("I _love_ ROR(Ruby on Rails)!")
230
+ # # => "<p>I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!</p>"
231
+ #
232
+ # textilize("h2. Textile makes markup -easy- simple!")
233
+ # # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"
234
+ #
235
+ # textilize("Visit the Rails website "here":http://www.rubyonrails.org/.)
236
+ # # => "<p>Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>.</p>"
237
+ def textilize(text)
238
+ if text.blank?
239
+ ""
240
+ else
241
+ textilized = RedCloth.new(text, [ :hard_breaks ])
242
+ textilized.hard_breaks = true if textilized.respond_to?(:hard_breaks=)
243
+ textilized.to_html
258
244
  end
245
+ end
259
246
 
260
- # Returns the text with all the Textile codes turned into HTML tags,
261
- # but without the bounding <p> tag that RedCloth adds.
262
- #
263
- # You can learn more about Textile's syntax at its website[http://www.textism.com/tools/textile].
264
- # <i>This method is only available if RedCloth[http://whytheluckystiff.net/ruby/redcloth/]
265
- # is available</i>.
266
- #
267
- # ==== Examples
268
- # textilize_without_paragraph("*This is Textile!* Rejoice!")
269
- # # => "<strong>This is Textile!</strong> Rejoice!"
270
- #
271
- # textilize_without_paragraph("I _love_ ROR(Ruby on Rails)!")
272
- # # => "I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!"
273
- #
274
- # textilize_without_paragraph("h2. Textile makes markup -easy- simple!")
275
- # # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"
276
- #
277
- # textilize_without_paragraph("Visit the Rails website "here":http://www.rubyonrails.org/.)
278
- # # => "Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>."
279
- def textilize_without_paragraph(text)
280
- textiled = textilize(text)
281
- if textiled[0..2] == "<p>" then textiled = textiled[3..-1] end
282
- if textiled[-4..-1] == "</p>" then textiled = textiled[0..-5] end
283
- return textiled
284
- end
285
- rescue LoadError
286
- # We can't really help what's not there
247
+ # Returns the text with all the Textile codes turned into HTML tags,
248
+ # but without the bounding <p> tag that RedCloth adds.
249
+ #
250
+ # You can learn more about Textile's syntax at its website[http://www.textism.com/tools/textile].
251
+ # <i>This method is requires RedCloth[http://whytheluckystiff.net/ruby/redcloth/]
252
+ # to be available</i>.
253
+ #
254
+ # ==== Examples
255
+ # textilize_without_paragraph("*This is Textile!* Rejoice!")
256
+ # # => "<strong>This is Textile!</strong> Rejoice!"
257
+ #
258
+ # textilize_without_paragraph("I _love_ ROR(Ruby on Rails)!")
259
+ # # => "I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!"
260
+ #
261
+ # textilize_without_paragraph("h2. Textile makes markup -easy- simple!")
262
+ # # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"
263
+ #
264
+ # textilize_without_paragraph("Visit the Rails website "here":http://www.rubyonrails.org/.)
265
+ # # => "Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>."
266
+ def textilize_without_paragraph(text)
267
+ textiled = textilize(text)
268
+ if textiled[0..2] == "<p>" then textiled = textiled[3..-1] end
269
+ if textiled[-4..-1] == "</p>" then textiled = textiled[0..-5] end
270
+ return textiled
287
271
  end
288
272
 
289
- begin
290
- require_library_or_gem "bluecloth" unless Object.const_defined?(:BlueCloth)
291
-
292
- # Returns the text with all the Markdown codes turned into HTML tags.
293
- # <i>This method is only available if BlueCloth[http://www.deveiate.org/projects/BlueCloth]
294
- # is available</i>.
295
- #
296
- # ==== Examples
297
- # markdown("We are using __Markdown__ now!")
298
- # # => "<p>We are using <strong>Markdown</strong> now!</p>"
299
- #
300
- # markdown("We like to _write_ `code`, not just _read_ it!")
301
- # # => "<p>We like to <em>write</em> <code>code</code>, not just <em>read</em> it!</p>"
302
- #
303
- # markdown("The [Markdown website](http://daringfireball.net/projects/markdown/) has more information.")
304
- # # => "<p>The <a href="http://daringfireball.net/projects/markdown/">Markdown website</a>
305
- # # has more information.</p>"
306
- #
307
- # markdown('![The ROR logo](http://rubyonrails.com/images/rails.png "Ruby on Rails")')
308
- # # => '<p><img src="http://rubyonrails.com/images/rails.png" alt="The ROR logo" title="Ruby on Rails" /></p>'
309
- def markdown(text)
310
- text.blank? ? "" : BlueCloth.new(text).to_html
311
- end
312
- rescue LoadError
313
- # We can't really help what's not there
273
+ # Returns the text with all the Markdown codes turned into HTML tags.
274
+ # <i>This method requires BlueCloth[http://www.deveiate.org/projects/BlueCloth]
275
+ # to be available</i>.
276
+ #
277
+ # ==== Examples
278
+ # markdown("We are using __Markdown__ now!")
279
+ # # => "<p>We are using <strong>Markdown</strong> now!</p>"
280
+ #
281
+ # markdown("We like to _write_ `code`, not just _read_ it!")
282
+ # # => "<p>We like to <em>write</em> <code>code</code>, not just <em>read</em> it!</p>"
283
+ #
284
+ # markdown("The [Markdown website](http://daringfireball.net/projects/markdown/) has more information.")
285
+ # # => "<p>The <a href="http://daringfireball.net/projects/markdown/">Markdown website</a>
286
+ # # has more information.</p>"
287
+ #
288
+ # markdown('![The ROR logo](http://rubyonrails.com/images/rails.png "Ruby on Rails")')
289
+ # # => '<p><img src="http://rubyonrails.com/images/rails.png" alt="The ROR logo" title="Ruby on Rails" /></p>'
290
+ def markdown(text)
291
+ text.blank? ? "" : BlueCloth.new(text).to_html
314
292
  end
315
293
 
316
294
  # Returns +text+ transformed into HTML using simple formatting rules.
@@ -392,8 +370,8 @@ module ActionView
392
370
  options.reverse_merge!(:link => :all, :html => {})
393
371
 
394
372
  case options[:link].to_sym
395
- when :all then auto_link_email_addresses(auto_link_urls(text, options[:html], &block), &block)
396
- when :email_addresses then auto_link_email_addresses(text, &block)
373
+ when :all then auto_link_email_addresses(auto_link_urls(text, options[:html], &block), options[:html], &block)
374
+ when :email_addresses then auto_link_email_addresses(text, options[:html], &block)
397
375
  when :urls then auto_link_urls(text, options[:html], &block)
398
376
  end
399
377
  end
@@ -545,45 +523,44 @@ module ActionView
545
523
  end
546
524
 
547
525
  AUTO_LINK_RE = %r{
548
- ( # leading text
549
- <\w+.*?>| # leading HTML tag, or
550
- [^=!:'"/]| # leading punctuation, or
551
- ^ # beginning of line
552
- )
553
- (
554
- (?:https?://)| # protocol spec, or
555
- (?:www\.) # www.*
556
- )
557
- (
558
- [-\w]+ # subdomain or domain
559
- (?:\.[-\w]+)* # remaining subdomains or domain
560
- (?::\d+)? # port
561
- (?:/(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$]))*)* # path
562
- (?:\?[\w\+@%&=.;:-]+)? # query string
563
- (?:\#[\w\-]*)? # trailing anchor
564
- )
565
- ([[:punct:]]|<|$|) # trailing text
566
- }x unless const_defined?(:AUTO_LINK_RE)
526
+ ( https?:// | www\. )
527
+ [^\s<]+
528
+ }x unless const_defined?(:AUTO_LINK_RE)
529
+
530
+ BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
567
531
 
568
532
  # Turns all urls into clickable links. If a block is given, each url
569
533
  # is yielded and the result is used as the link text.
570
534
  def auto_link_urls(text, html_options = {})
571
- extra_options = tag_options(html_options.stringify_keys) || ""
535
+ link_attributes = html_options.stringify_keys
572
536
  text.gsub(AUTO_LINK_RE) do
573
- all, a, b, c, d = $&, $1, $2, $3, $4
574
- if a =~ /<a\s/i # don't replace URL's that are already linked
575
- all
537
+ href = $&
538
+ punctuation = ''
539
+ left, right = $`, $'
540
+ # detect already linked URLs and URLs in the middle of a tag
541
+ if left =~ /<[^>]+$/ && right =~ /^[^>]*>/
542
+ # do not change string; URL is alreay linked
543
+ href
576
544
  else
577
- text = b + c
578
- text = yield(text) if block_given?
579
- %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}"#{extra_options}>#{text}</a>#{d})
545
+ # don't include trailing punctuation character as part of the URL
546
+ if href.sub!(/[^\w\/-]$/, '') and punctuation = $& and opening = BRACKETS[punctuation]
547
+ if href.scan(opening).size > href.scan(punctuation).size
548
+ href << punctuation
549
+ punctuation = ''
550
+ end
551
+ end
552
+
553
+ link_text = block_given?? yield(href) : href
554
+ href = 'http://' + href unless href.index('http') == 0
555
+
556
+ content_tag(:a, h(link_text), link_attributes.merge('href' => href)) + punctuation
580
557
  end
581
558
  end
582
559
  end
583
560
 
584
561
  # Turns all email addresses into clickable links. If a block is given,
585
562
  # each email is yielded and the result is used as the link text.
586
- def auto_link_email_addresses(text)
563
+ def auto_link_email_addresses(text, html_options = {})
587
564
  body = text.dup
588
565
  text.gsub(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
589
566
  text = $1
@@ -592,7 +569,7 @@ module ActionView
592
569
  text
593
570
  else
594
571
  display_text = (block_given?) ? yield(text) : text
595
- %{<a href="mailto:#{text}">#{display_text}</a>}
572
+ mail_to text, display_text, html_options
596
573
  end
597
574
  end
598
575
  end
@@ -3,19 +3,37 @@ require 'action_view/helpers/tag_helper'
3
3
  module ActionView
4
4
  module Helpers
5
5
  module TranslationHelper
6
+ # Delegates to I18n#translate but also performs two additional functions. First, it'll catch MissingTranslationData exceptions
7
+ # and turn them into inline spans that contains the missing key, such that you can see in a view what is missing where.
8
+ #
9
+ # Second, it'll scope the key by the current partial if the key starts with a period. So if you call translate(".foo") from the
10
+ # people/index.html.erb template, you'll actually be calling I18n.translate("people.index.foo"). This makes it less repetitive
11
+ # to translate many keys within the same partials and gives you a simple framework for scoping them consistently. If you don't
12
+ # prepend the key with a period, nothing is converted.
6
13
  def translate(key, options = {})
7
14
  options[:raise] = true
8
- I18n.translate(key, options)
15
+ I18n.translate(scope_key_by_partial(key), options)
9
16
  rescue I18n::MissingTranslationData => e
10
17
  keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope])
11
18
  content_tag('span', keys.join(', '), :class => 'translation_missing')
12
19
  end
13
20
  alias :t :translate
14
21
 
22
+ # Delegates to I18n.localize with no additional functionality.
15
23
  def localize(*args)
16
24
  I18n.localize *args
17
25
  end
18
26
  alias :l :localize
27
+
28
+
29
+ private
30
+ def scope_key_by_partial(key)
31
+ if key.to_s.first == "."
32
+ template.path_without_format_and_extension.gsub(%r{/_?}, ".") + key.to_s
33
+ else
34
+ key
35
+ end
36
+ end
19
37
  end
20
38
  end
21
39
  end
@@ -507,7 +507,30 @@ module ActionView
507
507
  # current_page?(:controller => 'shop', :action => 'checkout')
508
508
  # # => true
509
509
  #
510
- # current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc)
510
+ # current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc')
511
+ # # => false
512
+ #
513
+ # current_page?(:action => 'checkout')
514
+ # # => true
515
+ #
516
+ # current_page?(:controller => 'library', :action => 'checkout')
517
+ # # => false
518
+ #
519
+ # Let's say we're in the <tt>/shop/checkout?order=desc&page=1</tt> action.
520
+ #
521
+ # current_page?(:action => 'process')
522
+ # # => false
523
+ #
524
+ # current_page?(:controller => 'shop', :action => 'checkout')
525
+ # # => true
526
+ #
527
+ # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'1')
528
+ # # => true
529
+ #
530
+ # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'2')
531
+ # # => false
532
+ #
533
+ # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc')
511
534
  # # => false
512
535
  #
513
536
  # current_page?(:action => 'checkout')
@@ -516,7 +539,7 @@ module ActionView
516
539
  # current_page?(:controller => 'library', :action => 'checkout')
517
540
  # # => false
518
541
  def current_page?(options)
519
- url_string = CGI.escapeHTML(url_for(options))
542
+ url_string = CGI.unescapeHTML(url_for(options))
520
543
  request = @controller.request
521
544
  # We ignore any extra parameters in the request_uri if the
522
545
  # submitted url doesn't have any either. This lets the function
@@ -12,7 +12,7 @@ module ActionView #:nodoc:
12
12
 
13
13
  private
14
14
  # Always recompile inline templates
15
- def recompile?(local_assigns)
15
+ def recompile?
16
16
  true
17
17
  end
18
18
  end
@@ -44,7 +44,18 @@
44
44
  # separator:
45
45
  delimiter: ""
46
46
  precision: 1
47
- storage_units: [Bytes, KB, MB, GB, TB]
47
+ storage_units:
48
+ # Storage units output formatting.
49
+ # %u is the storage unit, %n is the number (default: 2 MB)
50
+ format: "%n %u"
51
+ units:
52
+ byte:
53
+ one: "Byte"
54
+ other: "Bytes"
55
+ kb: "KB"
56
+ mb: "MB"
57
+ gb: "GB"
58
+ tb: "TB"
48
59
 
49
60
  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
50
61
  datetime:
@@ -80,6 +91,13 @@
80
91
  over_x_years:
81
92
  one: "over 1 year"
82
93
  other: "over {{count}} years"
94
+ prompts:
95
+ year: "Year"
96
+ month: "Month"
97
+ day: "Day"
98
+ hour: "Hour"
99
+ minute: "Minute"
100
+ second: "Seconds"
83
101
 
84
102
  activerecord:
85
103
  errors:
@@ -46,6 +46,38 @@ module ActionView
46
46
  #
47
47
  # This will render the partial "advertisement/_ad.erb" regardless of which controller this is being called from.
48
48
  #
49
+ # == Rendering objects with the RecordIdentifier
50
+ #
51
+ # Instead of explicitly naming the location of a partial, you can also let the RecordIdentifier do the work if
52
+ # you're following its conventions for RecordIdentifier#partial_path. Examples:
53
+ #
54
+ # # @account is an Account instance, so it uses the RecordIdentifier to replace
55
+ # # <%= render :partial => "accounts/account", :locals => { :account => @buyer } %>
56
+ # <%= render :partial => @account %>
57
+ #
58
+ # # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
59
+ # # <%= render :partial => "posts/post", :collection => @posts %>
60
+ # <%= render :partial => @posts %>
61
+ #
62
+ # == Rendering the default case
63
+ #
64
+ # If you're not going to be using any of the options like collections or layouts, you can also use the short-hand
65
+ # defaults of render to render partials. Examples:
66
+ #
67
+ # # Instead of <%= render :partial => "account" %>
68
+ # <%= render "account" %>
69
+ #
70
+ # # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %>
71
+ # <%= render "account", :account => @buyer %>
72
+ #
73
+ # # @account is an Account instance, so it uses the RecordIdentifier to replace
74
+ # # <%= render :partial => "accounts/account", :locals => { :account => @account } %>
75
+ # <%= render(@account) %>
76
+ #
77
+ # # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
78
+ # # <%= render :partial => "posts/post", :collection => @posts %>
79
+ # <%= render(@posts) %>
80
+ #
49
81
  # == Rendering partials with layouts
50
82
  #
51
83
  # Partials can have their own layouts applied to them. These layouts are different than the ones that are
@@ -155,15 +187,20 @@ module ActionView
155
187
  builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '')
156
188
  local_assigns.merge!(builder_partial_path.to_sym => partial_path)
157
189
  render_partial(:partial => builder_partial_path, :object => options[:object], :locals => local_assigns)
158
- when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
159
- render_partial_collection(options.except(:partial).merge(:collection => partial_path))
160
190
  else
161
- object = partial_path
162
- render_partial(
163
- :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path),
164
- :object => object,
165
- :locals => local_assigns
166
- )
191
+ if Array === partial_path ||
192
+ (defined?(ActiveRecord) &&
193
+ (ActiveRecord::Associations::AssociationCollection === partial_path ||
194
+ ActiveRecord::NamedScope::Scope === partial_path))
195
+ render_partial_collection(options.except(:partial).merge(:collection => partial_path))
196
+ else
197
+ object = partial_path
198
+ render_partial(
199
+ :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path),
200
+ :object => object,
201
+ :locals => local_assigns
202
+ )
203
+ end
167
204
  end
168
205
  end
169
206
 
@@ -196,7 +233,7 @@ module ActionView
196
233
  path = "_#{partial_path}"
197
234
  end
198
235
 
199
- _pick_template(path)
236
+ self.view_paths.find_template(path, self.template_format)
200
237
  end
201
238
  memoize :_pick_partial_template
202
239
  end