actionpack 2.3.18 → 3.0.0.beta

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 (513) hide show
  1. data/CHANGELOG +15 -64
  2. data/README +39 -48
  3. data/lib/abstract_controller.rb +22 -0
  4. data/lib/abstract_controller/base.rb +191 -0
  5. data/lib/abstract_controller/callbacks.rb +113 -0
  6. data/lib/abstract_controller/collector.rb +30 -0
  7. data/lib/abstract_controller/compatibility.rb +18 -0
  8. data/lib/abstract_controller/helpers.rb +163 -0
  9. data/lib/abstract_controller/layouts.rb +413 -0
  10. data/lib/abstract_controller/localized_cache.rb +49 -0
  11. data/lib/abstract_controller/logger.rb +13 -0
  12. data/lib/abstract_controller/rendering.rb +238 -0
  13. data/lib/{action_controller → abstract_controller}/translation.rb +1 -1
  14. data/lib/action_controller.rb +68 -102
  15. data/lib/action_controller/base.rb +77 -1409
  16. data/lib/action_controller/caching.rb +58 -45
  17. data/lib/action_controller/caching/actions.rb +100 -114
  18. data/lib/action_controller/caching/fragments.rb +17 -19
  19. data/lib/action_controller/caching/pages.rb +12 -6
  20. data/lib/action_controller/caching/sweeping.rb +42 -0
  21. data/lib/action_controller/deprecated.rb +5 -0
  22. data/lib/action_controller/deprecated/dispatcher.rb +28 -0
  23. data/lib/action_controller/deprecated/integration_test.rb +2 -0
  24. data/lib/action_controller/deprecated/performance_test.rb +1 -0
  25. data/lib/action_controller/metal.rb +125 -0
  26. data/lib/action_controller/metal/compatibility.rb +141 -0
  27. data/lib/action_controller/metal/conditional_get.rb +86 -0
  28. data/lib/action_controller/metal/configuration.rb +28 -0
  29. data/lib/action_controller/metal/cookies.rb +17 -0
  30. data/lib/action_controller/metal/exceptions.rb +46 -0
  31. data/lib/action_controller/metal/flash.rb +28 -0
  32. data/lib/action_controller/metal/head.rb +33 -0
  33. data/lib/action_controller/metal/helpers.rb +116 -0
  34. data/lib/action_controller/metal/hide_actions.rb +50 -0
  35. data/lib/action_controller/{http_authentication.rb → metal/http_authentication.rb} +18 -15
  36. data/lib/action_controller/metal/instrumentation.rb +99 -0
  37. data/lib/action_controller/metal/mime_responds.rb +300 -0
  38. data/lib/action_controller/metal/rack_delegation.rb +35 -0
  39. data/lib/action_controller/metal/redirecting.rb +90 -0
  40. data/lib/action_controller/metal/renderers.rb +95 -0
  41. data/lib/action_controller/metal/rendering.rb +69 -0
  42. data/lib/action_controller/metal/request_forgery_protection.rb +115 -0
  43. data/lib/action_controller/metal/rescue.rb +13 -0
  44. data/lib/action_controller/metal/responder.rb +220 -0
  45. data/lib/action_controller/{session_management.rb → metal/session_management.rb} +5 -14
  46. data/lib/action_controller/{streaming.rb → metal/streaming.rb} +13 -12
  47. data/lib/action_controller/metal/testing.rb +42 -0
  48. data/lib/action_controller/metal/url_for.rb +157 -0
  49. data/lib/action_controller/{verification.rb → metal/verification.rb} +41 -41
  50. data/lib/action_controller/middleware.rb +38 -0
  51. data/lib/action_controller/polymorphic_routes.rb +20 -26
  52. data/lib/action_controller/railtie.rb +30 -0
  53. data/lib/action_controller/railties/subscriber.rb +63 -0
  54. data/lib/action_controller/record_identifier.rb +3 -16
  55. data/lib/action_controller/test_case.rb +156 -18
  56. data/lib/action_controller/url_rewriter.rb +47 -200
  57. data/lib/action_controller/vendor/html-scanner.rb +16 -12
  58. data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
  59. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +12 -9
  60. data/lib/action_dispatch.rb +88 -0
  61. data/lib/action_dispatch/http/cache.rb +123 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +98 -0
  63. data/lib/{action_controller → action_dispatch/http}/headers.rb +8 -8
  64. data/lib/action_dispatch/http/mime_negotiation.rb +101 -0
  65. data/lib/{action_controller → action_dispatch/http}/mime_type.rb +30 -11
  66. data/lib/{action_controller → action_dispatch/http}/mime_types.rb +5 -3
  67. data/lib/action_dispatch/http/parameters.rb +49 -0
  68. data/lib/action_dispatch/http/request.rb +223 -0
  69. data/lib/action_dispatch/http/response.rb +209 -0
  70. data/lib/action_dispatch/http/upload.rb +48 -0
  71. data/lib/action_dispatch/http/url.rb +129 -0
  72. data/lib/action_dispatch/middleware/callbacks.rb +50 -0
  73. data/lib/action_dispatch/middleware/cascade.rb +29 -0
  74. data/lib/action_dispatch/middleware/cookies.rb +216 -0
  75. data/lib/{action_controller → action_dispatch/middleware}/flash.rb +51 -90
  76. data/lib/action_dispatch/middleware/head.rb +18 -0
  77. data/lib/action_dispatch/middleware/params_parser.rb +78 -0
  78. data/lib/action_dispatch/middleware/rescue.rb +26 -0
  79. data/lib/action_dispatch/middleware/session/abstract_store.rb +209 -0
  80. data/lib/{action_controller → action_dispatch/middleware}/session/cookie_store.rb +56 -60
  81. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
  82. data/lib/action_dispatch/middleware/show_exceptions.rb +173 -0
  83. data/lib/{action_controller/middleware_stack.rb → action_dispatch/middleware/stack.rb} +23 -13
  84. data/lib/action_dispatch/middleware/static.rb +44 -0
  85. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_request_and_response.erb +10 -3
  86. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_trace.erb +4 -4
  87. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
  88. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/layout.erb +2 -2
  89. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/missing_template.erb +0 -0
  90. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/routing_error.erb +0 -0
  91. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/template_error.erb +3 -3
  92. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/unknown_action.erb +0 -0
  93. data/lib/action_dispatch/railtie.rb +15 -0
  94. data/lib/action_dispatch/routing.rb +217 -0
  95. data/lib/action_dispatch/routing/deprecated_mapper.rb +877 -0
  96. data/lib/action_dispatch/routing/mapper.rb +649 -0
  97. data/lib/action_dispatch/routing/route.rb +55 -0
  98. data/lib/action_dispatch/routing/route_set.rb +445 -0
  99. data/lib/action_dispatch/testing/assertions.rb +21 -0
  100. data/lib/action_dispatch/testing/assertions/dom.rb +37 -0
  101. data/lib/{action_controller/assertions/model_assertions.rb → action_dispatch/testing/assertions/model.rb} +2 -4
  102. data/lib/action_dispatch/testing/assertions/response.rb +154 -0
  103. data/lib/{action_controller/assertions/routing_assertions.rb → action_dispatch/testing/assertions/routing.rb} +72 -34
  104. data/lib/{action_controller/assertions/selector_assertions.rb → action_dispatch/testing/assertions/selector.rb} +14 -11
  105. data/lib/{action_controller/assertions/tag_assertions.rb → action_dispatch/testing/assertions/tag.rb} +25 -14
  106. data/lib/{action_controller → action_dispatch/testing}/integration.rb +173 -406
  107. data/lib/action_dispatch/testing/performance_test.rb +17 -0
  108. data/lib/action_dispatch/testing/test_process.rb +42 -0
  109. data/lib/action_dispatch/testing/test_request.rb +83 -0
  110. data/lib/action_dispatch/testing/test_response.rb +136 -0
  111. data/lib/action_pack/version.rb +3 -3
  112. data/lib/action_view.rb +29 -26
  113. data/lib/action_view/base.rb +101 -148
  114. data/lib/action_view/context.rb +44 -0
  115. data/lib/action_view/helpers.rb +6 -4
  116. data/lib/action_view/helpers/{active_record_helper.rb → active_model_helper.rb} +63 -63
  117. data/lib/action_view/helpers/asset_tag_helper.rb +166 -31
  118. data/lib/action_view/helpers/cache_helper.rb +1 -1
  119. data/lib/action_view/helpers/capture_helper.rb +40 -8
  120. data/lib/action_view/helpers/csrf_helper.rb +2 -4
  121. data/lib/action_view/helpers/date_helper.rb +14 -15
  122. data/lib/action_view/helpers/form_helper.rb +121 -24
  123. data/lib/action_view/helpers/form_options_helper.rb +26 -25
  124. data/lib/action_view/helpers/form_tag_helper.rb +42 -33
  125. data/lib/action_view/helpers/javascript_helper.rb +1 -109
  126. data/lib/action_view/helpers/number_helper.rb +4 -1
  127. data/lib/action_view/helpers/prototype_helper.rb +75 -499
  128. data/lib/action_view/helpers/raw_output_helper.rb +1 -1
  129. data/lib/action_view/helpers/record_tag_helper.rb +3 -3
  130. data/lib/action_view/helpers/sanitize_helper.rb +3 -2
  131. data/lib/action_view/helpers/scriptaculous_helper.rb +89 -53
  132. data/lib/action_view/helpers/tag_helper.rb +12 -13
  133. data/lib/action_view/helpers/text_helper.rb +33 -38
  134. data/lib/action_view/helpers/translation_helper.rb +11 -35
  135. data/lib/action_view/helpers/url_helper.rb +140 -134
  136. data/lib/action_view/locale/en.yml +34 -28
  137. data/lib/action_view/paths.rb +27 -24
  138. data/lib/action_view/railtie.rb +17 -0
  139. data/lib/action_view/railties/subscriber.rb +24 -0
  140. data/lib/action_view/{partials.rb → render/partials.rb} +161 -51
  141. data/lib/action_view/render/rendering.rb +117 -0
  142. data/lib/action_view/template.rb +88 -217
  143. data/lib/action_view/template/error.rb +105 -0
  144. data/lib/action_view/template/handler.rb +41 -0
  145. data/lib/action_view/template/handlers.rb +54 -0
  146. data/lib/action_view/{template_handlers → template/handlers}/builder.rb +6 -6
  147. data/lib/action_view/template/handlers/erb.rb +58 -0
  148. data/lib/action_view/{template_handlers → template/handlers}/rjs.rb +8 -3
  149. data/lib/action_view/template/resolver.rb +164 -0
  150. data/lib/action_view/template/text.rb +40 -0
  151. data/lib/action_view/test_case.rb +18 -18
  152. metadata +165 -420
  153. data/RUNNING_UNIT_TESTS +0 -24
  154. data/Rakefile +0 -158
  155. data/install.rb +0 -30
  156. data/lib/action_controller/assertions/dom_assertions.rb +0 -55
  157. data/lib/action_controller/assertions/response_assertions.rb +0 -169
  158. data/lib/action_controller/benchmarking.rb +0 -107
  159. data/lib/action_controller/caching/sweeper.rb +0 -45
  160. data/lib/action_controller/cgi_ext.rb +0 -15
  161. data/lib/action_controller/cgi_ext/cookie.rb +0 -112
  162. data/lib/action_controller/cgi_ext/query_extension.rb +0 -22
  163. data/lib/action_controller/cgi_ext/stdinput.rb +0 -24
  164. data/lib/action_controller/cgi_process.rb +0 -77
  165. data/lib/action_controller/cookies.rb +0 -197
  166. data/lib/action_controller/dispatcher.rb +0 -133
  167. data/lib/action_controller/failsafe.rb +0 -87
  168. data/lib/action_controller/filters.rb +0 -680
  169. data/lib/action_controller/helpers.rb +0 -225
  170. data/lib/action_controller/layout.rb +0 -286
  171. data/lib/action_controller/middlewares.rb +0 -14
  172. data/lib/action_controller/mime_responds.rb +0 -193
  173. data/lib/action_controller/params_parser.rb +0 -77
  174. data/lib/action_controller/performance_test.rb +0 -15
  175. data/lib/action_controller/rack_lint_patch.rb +0 -36
  176. data/lib/action_controller/reloader.rb +0 -54
  177. data/lib/action_controller/request.rb +0 -518
  178. data/lib/action_controller/request_forgery_protection.rb +0 -116
  179. data/lib/action_controller/rescue.rb +0 -183
  180. data/lib/action_controller/resources.rb +0 -682
  181. data/lib/action_controller/response.rb +0 -237
  182. data/lib/action_controller/routing.rb +0 -388
  183. data/lib/action_controller/routing/builder.rb +0 -197
  184. data/lib/action_controller/routing/optimisations.rb +0 -130
  185. data/lib/action_controller/routing/recognition_optimisation.rb +0 -167
  186. data/lib/action_controller/routing/route.rb +0 -265
  187. data/lib/action_controller/routing/route_set.rb +0 -503
  188. data/lib/action_controller/routing/routing_ext.rb +0 -49
  189. data/lib/action_controller/routing/segments.rb +0 -343
  190. data/lib/action_controller/session/abstract_store.rb +0 -276
  191. data/lib/action_controller/session/mem_cache_store.rb +0 -60
  192. data/lib/action_controller/status_codes.rb +0 -88
  193. data/lib/action_controller/string_coercion.rb +0 -29
  194. data/lib/action_controller/templates/rescues/diagnostics.erb +0 -11
  195. data/lib/action_controller/test_process.rb +0 -580
  196. data/lib/action_controller/uploaded_file.rb +0 -44
  197. data/lib/action_view/helpers/benchmark_helper.rb +0 -54
  198. data/lib/action_view/inline_template.rb +0 -19
  199. data/lib/action_view/reloadable_template.rb +0 -117
  200. data/lib/action_view/renderable.rb +0 -109
  201. data/lib/action_view/renderable_partial.rb +0 -53
  202. data/lib/action_view/template_error.rb +0 -99
  203. data/lib/action_view/template_handler.rb +0 -34
  204. data/lib/action_view/template_handlers.rb +0 -48
  205. data/lib/action_view/template_handlers/erb.rb +0 -25
  206. data/lib/actionpack.rb +0 -2
  207. data/test/abstract_unit.rb +0 -78
  208. data/test/active_record_unit.rb +0 -104
  209. data/test/activerecord/active_record_store_test.rb +0 -221
  210. data/test/activerecord/render_partial_with_record_identification_test.rb +0 -188
  211. data/test/adv_attr_test.rb +0 -20
  212. data/test/controller/action_pack_assertions_test.rb +0 -545
  213. data/test/controller/addresses_render_test.rb +0 -37
  214. data/test/controller/assert_select_test.rb +0 -735
  215. data/test/controller/base_test.rb +0 -217
  216. data/test/controller/benchmark_test.rb +0 -32
  217. data/test/controller/caching_test.rb +0 -743
  218. data/test/controller/capture_test.rb +0 -66
  219. data/test/controller/content_type_test.rb +0 -178
  220. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  221. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  222. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  223. data/test/controller/cookie_test.rb +0 -208
  224. data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -32
  225. data/test/controller/dispatcher_test.rb +0 -144
  226. data/test/controller/dom_assertions_test.rb +0 -53
  227. data/test/controller/failsafe_test.rb +0 -60
  228. data/test/controller/fake_controllers.rb +0 -33
  229. data/test/controller/fake_models.rb +0 -19
  230. data/test/controller/filter_params_test.rb +0 -52
  231. data/test/controller/filters_test.rb +0 -885
  232. data/test/controller/flash_test.rb +0 -174
  233. data/test/controller/header_test.rb +0 -14
  234. data/test/controller/helper_test.rb +0 -224
  235. data/test/controller/html-scanner/cdata_node_test.rb +0 -15
  236. data/test/controller/html-scanner/document_test.rb +0 -148
  237. data/test/controller/html-scanner/node_test.rb +0 -89
  238. data/test/controller/html-scanner/sanitizer_test.rb +0 -300
  239. data/test/controller/html-scanner/tag_node_test.rb +0 -238
  240. data/test/controller/html-scanner/text_node_test.rb +0 -50
  241. data/test/controller/html-scanner/tokenizer_test.rb +0 -131
  242. data/test/controller/http_basic_authentication_test.rb +0 -113
  243. data/test/controller/http_digest_authentication_test.rb +0 -254
  244. data/test/controller/integration_test.rb +0 -526
  245. data/test/controller/layout_test.rb +0 -215
  246. data/test/controller/localized_templates_test.rb +0 -24
  247. data/test/controller/logging_test.rb +0 -46
  248. data/test/controller/middleware_stack_test.rb +0 -90
  249. data/test/controller/mime_responds_test.rb +0 -536
  250. data/test/controller/mime_type_test.rb +0 -93
  251. data/test/controller/output_escaping_test.rb +0 -19
  252. data/test/controller/polymorphic_routes_test.rb +0 -297
  253. data/test/controller/rack_test.rb +0 -308
  254. data/test/controller/record_identifier_test.rb +0 -139
  255. data/test/controller/redirect_test.rb +0 -285
  256. data/test/controller/reloader_test.rb +0 -125
  257. data/test/controller/render_test.rb +0 -1783
  258. data/test/controller/request/json_params_parsing_test.rb +0 -65
  259. data/test/controller/request/multipart_params_parsing_test.rb +0 -177
  260. data/test/controller/request/query_string_parsing_test.rb +0 -129
  261. data/test/controller/request/test_request_test.rb +0 -35
  262. data/test/controller/request/url_encoded_params_parsing_test.rb +0 -146
  263. data/test/controller/request/xml_params_parsing_test.rb +0 -103
  264. data/test/controller/request_forgery_protection_test.rb +0 -233
  265. data/test/controller/request_test.rb +0 -398
  266. data/test/controller/rescue_test.rb +0 -541
  267. data/test/controller/resources_test.rb +0 -1393
  268. data/test/controller/routing_test.rb +0 -2592
  269. data/test/controller/selector_test.rb +0 -628
  270. data/test/controller/send_file_test.rb +0 -171
  271. data/test/controller/session/abstract_store_test.rb +0 -64
  272. data/test/controller/session/cookie_store_test.rb +0 -354
  273. data/test/controller/session/mem_cache_store_test.rb +0 -187
  274. data/test/controller/session/test_session_test.rb +0 -58
  275. data/test/controller/test_test.rb +0 -700
  276. data/test/controller/translation_test.rb +0 -26
  277. data/test/controller/url_rewriter_test.rb +0 -395
  278. data/test/controller/verification_test.rb +0 -270
  279. data/test/controller/view_paths_test.rb +0 -141
  280. data/test/controller/webservice_test.rb +0 -273
  281. data/test/fixtures/_top_level_partial.html.erb +0 -1
  282. data/test/fixtures/_top_level_partial_only.erb +0 -1
  283. data/test/fixtures/addresses/list.erb +0 -1
  284. data/test/fixtures/alternate_helpers/foo_helper.rb +0 -3
  285. data/test/fixtures/bad_customers/_bad_customer.html.erb +0 -1
  286. data/test/fixtures/companies.yml +0 -24
  287. data/test/fixtures/company.rb +0 -10
  288. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +0 -1
  289. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +0 -1
  290. data/test/fixtures/content_type/render_default_for_rjs.rjs +0 -1
  291. data/test/fixtures/content_type/render_default_for_rxml.rxml +0 -1
  292. data/test/fixtures/customers/_customer.html.erb +0 -1
  293. data/test/fixtures/db_definitions/sqlite.sql +0 -49
  294. data/test/fixtures/developer.rb +0 -9
  295. data/test/fixtures/developers.yml +0 -21
  296. data/test/fixtures/developers/_developer.erb +0 -1
  297. data/test/fixtures/developers_projects.yml +0 -13
  298. data/test/fixtures/failsafe/500.html +0 -1
  299. data/test/fixtures/fun/games/_game.erb +0 -1
  300. data/test/fixtures/fun/games/hello_world.erb +0 -1
  301. data/test/fixtures/fun/serious/games/_game.erb +0 -1
  302. data/test/fixtures/functional_caching/_partial.erb +0 -3
  303. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +0 -3
  304. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +0 -6
  305. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +0 -5
  306. data/test/fixtures/functional_caching/fragment_cached.html.erb +0 -2
  307. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +0 -1
  308. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +0 -2
  309. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +0 -1
  310. data/test/fixtures/good_customers/_good_customer.html.erb +0 -1
  311. data/test/fixtures/helpers/abc_helper.rb +0 -5
  312. data/test/fixtures/helpers/fun/games_helper.rb +0 -3
  313. data/test/fixtures/helpers/fun/pdf_helper.rb +0 -3
  314. data/test/fixtures/layout_tests/abs_path_layout.rhtml +0 -1
  315. data/test/fixtures/layout_tests/alt/hello.rhtml +0 -1
  316. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  317. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +0 -1
  318. data/test/fixtures/layout_tests/layouts/item.rhtml +0 -1
  319. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +0 -1
  320. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +0 -1
  321. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +0 -1
  322. data/test/fixtures/layout_tests/views/hello.rhtml +0 -1
  323. data/test/fixtures/layouts/_column.html.erb +0 -2
  324. data/test/fixtures/layouts/block_with_layout.erb +0 -3
  325. data/test/fixtures/layouts/builder.builder +0 -3
  326. data/test/fixtures/layouts/default_html.html.erb +0 -1
  327. data/test/fixtures/layouts/partial_with_layout.erb +0 -3
  328. data/test/fixtures/layouts/standard.erb +0 -1
  329. data/test/fixtures/layouts/talk_from_action.erb +0 -2
  330. data/test/fixtures/layouts/xhr.html.erb +0 -2
  331. data/test/fixtures/layouts/yield.erb +0 -2
  332. data/test/fixtures/localized/hello_world.de.html +0 -1
  333. data/test/fixtures/localized/hello_world.en.html +0 -1
  334. data/test/fixtures/mascot.rb +0 -3
  335. data/test/fixtures/mascots.yml +0 -4
  336. data/test/fixtures/mascots/_mascot.html.erb +0 -1
  337. data/test/fixtures/multipart/binary_file +0 -0
  338. data/test/fixtures/multipart/boundary_problem_file +0 -10
  339. data/test/fixtures/multipart/bracketed_param +0 -5
  340. data/test/fixtures/multipart/empty +0 -10
  341. data/test/fixtures/multipart/hello.txt +0 -1
  342. data/test/fixtures/multipart/large_text_file +0 -10
  343. data/test/fixtures/multipart/mixed_files +0 -0
  344. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  345. data/test/fixtures/multipart/none +0 -9
  346. data/test/fixtures/multipart/single_parameter +0 -5
  347. data/test/fixtures/multipart/text_file +0 -10
  348. data/test/fixtures/override/test/hello_world.erb +0 -1
  349. data/test/fixtures/override2/layouts/test/sub.erb +0 -1
  350. data/test/fixtures/post_test/layouts/post.html.erb +0 -1
  351. data/test/fixtures/post_test/layouts/super_post.iphone.erb +0 -1
  352. data/test/fixtures/post_test/post/index.html.erb +0 -1
  353. data/test/fixtures/post_test/post/index.iphone.erb +0 -1
  354. data/test/fixtures/post_test/super_post/index.html.erb +0 -1
  355. data/test/fixtures/post_test/super_post/index.iphone.erb +0 -1
  356. data/test/fixtures/project.rb +0 -3
  357. data/test/fixtures/projects.yml +0 -7
  358. data/test/fixtures/projects/_project.erb +0 -1
  359. data/test/fixtures/public/404.html +0 -1
  360. data/test/fixtures/public/500.da.html +0 -1
  361. data/test/fixtures/public/500.html +0 -1
  362. data/test/fixtures/public/absolute/test.css +0 -23
  363. data/test/fixtures/public/absolute/test.js +0 -63
  364. data/test/fixtures/public/images/rails.png +0 -0
  365. data/test/fixtures/public/javascripts/application.js +0 -1
  366. data/test/fixtures/public/javascripts/bank.js +0 -1
  367. data/test/fixtures/public/javascripts/controls.js +0 -1
  368. data/test/fixtures/public/javascripts/dragdrop.js +0 -1
  369. data/test/fixtures/public/javascripts/effects.js +0 -1
  370. data/test/fixtures/public/javascripts/prototype.js +0 -1
  371. data/test/fixtures/public/javascripts/robber.js +0 -1
  372. data/test/fixtures/public/javascripts/subdir/subdir.js +0 -1
  373. data/test/fixtures/public/javascripts/version.1.0.js +0 -1
  374. data/test/fixtures/public/stylesheets/bank.css +0 -1
  375. data/test/fixtures/public/stylesheets/robber.css +0 -1
  376. data/test/fixtures/public/stylesheets/subdir/subdir.css +0 -1
  377. data/test/fixtures/public/stylesheets/version.1.0.css +0 -1
  378. data/test/fixtures/quiz/questions/_question.html.erb +0 -1
  379. data/test/fixtures/replies.yml +0 -15
  380. data/test/fixtures/replies/_reply.erb +0 -1
  381. data/test/fixtures/reply.rb +0 -7
  382. data/test/fixtures/respond_to/all_types_with_layout.html.erb +0 -1
  383. data/test/fixtures/respond_to/all_types_with_layout.js.rjs +0 -1
  384. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +0 -1
  385. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +0 -1
  386. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +0 -1
  387. data/test/fixtures/respond_to/layouts/missing.html.erb +0 -1
  388. data/test/fixtures/respond_to/layouts/standard.html.erb +0 -1
  389. data/test/fixtures/respond_to/layouts/standard.iphone.erb +0 -1
  390. data/test/fixtures/respond_to/using_defaults.html.erb +0 -1
  391. data/test/fixtures/respond_to/using_defaults.js.rjs +0 -1
  392. data/test/fixtures/respond_to/using_defaults.xml.builder +0 -1
  393. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +0 -1
  394. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +0 -1
  395. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +0 -1
  396. data/test/fixtures/scope/test/modgreet.erb +0 -1
  397. data/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +0 -10
  398. data/test/fixtures/shared.html.erb +0 -1
  399. data/test/fixtures/symlink_parent/symlinked_layout.erb +0 -5
  400. data/test/fixtures/test/_counter.html.erb +0 -1
  401. data/test/fixtures/test/_customer.erb +0 -1
  402. data/test/fixtures/test/_customer_counter.erb +0 -1
  403. data/test/fixtures/test/_customer_counter_with_as.erb +0 -1
  404. data/test/fixtures/test/_customer_greeting.erb +0 -1
  405. data/test/fixtures/test/_customer_with_var.erb +0 -1
  406. data/test/fixtures/test/_form.erb +0 -1
  407. data/test/fixtures/test/_from_helper.erb +0 -1
  408. data/test/fixtures/test/_hash_greeting.erb +0 -1
  409. data/test/fixtures/test/_hash_object.erb +0 -2
  410. data/test/fixtures/test/_hello.builder +0 -1
  411. data/test/fixtures/test/_labelling_form.erb +0 -1
  412. data/test/fixtures/test/_layout_for_block_with_args.html.erb +0 -3
  413. data/test/fixtures/test/_layout_for_partial.html.erb +0 -3
  414. data/test/fixtures/test/_local_inspector.html.erb +0 -1
  415. data/test/fixtures/test/_one.html.erb +0 -1
  416. data/test/fixtures/test/_partial.erb +0 -1
  417. data/test/fixtures/test/_partial.html.erb +0 -1
  418. data/test/fixtures/test/_partial.js.erb +0 -1
  419. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +0 -1
  420. data/test/fixtures/test/_partial_only.erb +0 -1
  421. data/test/fixtures/test/_partial_with_only_html_version.html.erb +0 -1
  422. data/test/fixtures/test/_person.erb +0 -2
  423. data/test/fixtures/test/_raise.html.erb +0 -1
  424. data/test/fixtures/test/_two.html.erb +0 -1
  425. data/test/fixtures/test/_utf8_partial.html.erb +0 -1
  426. data/test/fixtures/test/_utf8_partial_magic.html.erb +0 -2
  427. data/test/fixtures/test/action_talk_to_layout.erb +0 -2
  428. data/test/fixtures/test/array_translation.erb +0 -1
  429. data/test/fixtures/test/calling_partial_with_layout.html.erb +0 -1
  430. data/test/fixtures/test/capturing.erb +0 -4
  431. data/test/fixtures/test/content_for.erb +0 -2
  432. data/test/fixtures/test/content_for_concatenated.erb +0 -3
  433. data/test/fixtures/test/content_for_with_parameter.erb +0 -2
  434. data/test/fixtures/test/delete_with_js.rjs +0 -2
  435. data/test/fixtures/test/dont_pick_me +0 -1
  436. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +0 -1
  437. data/test/fixtures/test/enum_rjs_test.rjs +0 -6
  438. data/test/fixtures/test/formatted_html_erb.html.erb +0 -1
  439. data/test/fixtures/test/formatted_xml_erb.builder +0 -1
  440. data/test/fixtures/test/formatted_xml_erb.html.erb +0 -1
  441. data/test/fixtures/test/formatted_xml_erb.xml.erb +0 -1
  442. data/test/fixtures/test/greeting.erb +0 -1
  443. data/test/fixtures/test/greeting.js.rjs +0 -1
  444. data/test/fixtures/test/hello.builder +0 -4
  445. data/test/fixtures/test/hello_world.da.html.erb +0 -1
  446. data/test/fixtures/test/hello_world.erb +0 -1
  447. data/test/fixtures/test/hello_world.erb~ +0 -1
  448. data/test/fixtures/test/hello_world.pt-BR.html.erb +0 -1
  449. data/test/fixtures/test/hello_world_container.builder +0 -3
  450. data/test/fixtures/test/hello_world_from_rxml.builder +0 -4
  451. data/test/fixtures/test/hello_world_with_layout_false.erb +0 -1
  452. data/test/fixtures/test/hello_xml_world.builder +0 -11
  453. data/test/fixtures/test/hyphen-ated.erb +0 -1
  454. data/test/fixtures/test/implicit_content_type.atom.builder +0 -2
  455. data/test/fixtures/test/list.erb +0 -1
  456. data/test/fixtures/test/malformed/malformed.en.html.erb~ +0 -1
  457. data/test/fixtures/test/malformed/malformed.erb~ +0 -1
  458. data/test/fixtures/test/malformed/malformed.html.erb~ +0 -1
  459. data/test/fixtures/test/nested_layout.erb +0 -3
  460. data/test/fixtures/test/non_erb_block_content_for.builder +0 -4
  461. data/test/fixtures/test/potential_conflicts.erb +0 -4
  462. data/test/fixtures/test/render_explicit_html_template.js.rjs +0 -1
  463. data/test/fixtures/test/render_file_from_template.html.erb +0 -1
  464. data/test/fixtures/test/render_file_with_ivar.erb +0 -1
  465. data/test/fixtures/test/render_file_with_locals.erb +0 -1
  466. data/test/fixtures/test/render_implicit_html_template.js.rjs +0 -1
  467. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +0 -1
  468. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +0 -1
  469. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +0 -1
  470. data/test/fixtures/test/render_to_string_test.erb +0 -1
  471. data/test/fixtures/test/scoped_array_translation.erb +0 -1
  472. data/test/fixtures/test/sub_template_raise.html.erb +0 -1
  473. data/test/fixtures/test/template.erb +0 -1
  474. data/test/fixtures/test/translation.erb +0 -1
  475. data/test/fixtures/test/update_element_with_capture.erb +0 -9
  476. data/test/fixtures/test/using_layout_around_block.html.erb +0 -1
  477. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +0 -1
  478. data/test/fixtures/test/utf8.html.erb +0 -4
  479. data/test/fixtures/test/utf8_magic.html.erb +0 -5
  480. data/test/fixtures/test/utf8_magic_with_bare_partial.html.erb +0 -5
  481. data/test/fixtures/topic.rb +0 -3
  482. data/test/fixtures/topics.yml +0 -22
  483. data/test/fixtures/topics/_topic.html.erb +0 -1
  484. data/test/template/active_record_helper_i18n_test.rb +0 -51
  485. data/test/template/active_record_helper_test.rb +0 -302
  486. data/test/template/asset_tag_helper_test.rb +0 -770
  487. data/test/template/atom_feed_helper_test.rb +0 -315
  488. data/test/template/benchmark_helper_test.rb +0 -86
  489. data/test/template/compiled_templates_test.rb +0 -204
  490. data/test/template/date_helper_i18n_test.rb +0 -121
  491. data/test/template/date_helper_test.rb +0 -2603
  492. data/test/template/erb_util_test.rb +0 -36
  493. data/test/template/form_helper_test.rb +0 -1447
  494. data/test/template/form_options_helper_i18n_test.rb +0 -27
  495. data/test/template/form_options_helper_test.rb +0 -811
  496. data/test/template/form_tag_helper_test.rb +0 -356
  497. data/test/template/javascript_helper_test.rb +0 -106
  498. data/test/template/number_helper_i18n_test.rb +0 -69
  499. data/test/template/number_helper_test.rb +0 -132
  500. data/test/template/prototype_helper_test.rb +0 -639
  501. data/test/template/raw_output_helper_test.rb +0 -21
  502. data/test/template/record_tag_helper_test.rb +0 -58
  503. data/test/template/render_test.rb +0 -329
  504. data/test/template/sanitize_helper_test.rb +0 -57
  505. data/test/template/scriptaculous_helper_test.rb +0 -90
  506. data/test/template/tag_helper_test.rb +0 -98
  507. data/test/template/template_test.rb +0 -32
  508. data/test/template/test_test.rb +0 -54
  509. data/test/template/text_helper_test.rb +0 -601
  510. data/test/template/translation_helper_test.rb +0 -95
  511. data/test/template/url_helper_test.rb +0 -641
  512. data/test/testing_sandbox.rb +0 -15
  513. data/test/view/test_case_test.rb +0 -176
@@ -3,30 +3,16 @@ 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
6
+ # Delegates to I18n#translate but also performs two additional functions. First, it'll catch MissingTranslationData exceptions
7
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
8
  #
9
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
10
  # people/index.html.erb template, you'll actually be calling I18n.translate("people.index.foo"). This makes it less repetitive
11
11
  # to translate many keys within the same partials and gives you a simple framework for scoping them consistently. If you don't
12
12
  # prepend the key with a period, nothing is converted.
13
- def translate(keys, options = {})
14
- if multiple_keys = keys.is_a?(Array)
15
- ActiveSupport::Deprecation.warn "Giving an array to translate is deprecated, please give a symbol or a string instead", caller
16
- end
17
-
13
+ def translate(key, options = {})
18
14
  options[:raise] = true
19
- keys = scope_keys_by_partial(keys)
20
-
21
- translations = I18n.translate(keys, options)
22
- translations = [translations] if !multiple_keys && translations.size > 1
23
- translations = html_safe_translation_keys(keys, translations)
24
-
25
- if multiple_keys || translations.size > 1
26
- translations
27
- else
28
- translations.first
29
- end
15
+ I18n.translate(scope_key_by_partial(key), options).html_safe
30
16
  rescue I18n::MissingTranslationData => e
31
17
  keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope])
32
18
  content_tag('span', keys.join(', '), :class => 'translation_missing')
@@ -39,29 +25,19 @@ module ActionView
39
25
  end
40
26
  alias :l :localize
41
27
 
42
-
43
28
  private
44
- def scope_keys_by_partial(keys)
45
- Array.wrap(keys).map do |key|
46
- key = key.to_s
47
-
48
- if key.first == "."
49
- template.path_without_format_and_extension.gsub(%r{/_?}, ".") + key
50
- else
51
- key
52
- end
53
- end
54
- end
55
29
 
56
- def html_safe_translation_keys(keys, translations)
57
- keys.zip(translations).map do |key, translation|
58
- if key =~ /(\b|_|\.)html$/ && translation.respond_to?(:html_safe)
59
- translation.html_safe
30
+ def scope_key_by_partial(key)
31
+ if key.to_s.first == "."
32
+ if @_virtual_path
33
+ @_virtual_path.gsub(%r{/_?}, ".") + key.to_s
60
34
  else
61
- translation
35
+ raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
62
36
  end
37
+ else
38
+ key
63
39
  end
64
40
  end
65
41
  end
66
42
  end
67
- end
43
+ end
@@ -1,4 +1,6 @@
1
- #require 'action_view/helpers/javascript_helper'
1
+ require 'action_view/helpers/javascript_helper'
2
+ require 'active_support/core_ext/array/access'
3
+ require 'active_support/core_ext/hash/keys'
2
4
 
3
5
  module ActionView
4
6
  module Helpers #:nodoc:
@@ -9,13 +11,18 @@ module ActionView
9
11
  module UrlHelper
10
12
  include JavaScriptHelper
11
13
 
14
+ # Need to map default url options to controller one.
15
+ def default_url_options(*args) #:nodoc:
16
+ controller.send(:default_url_options, *args)
17
+ end
18
+
12
19
  # Returns the URL for the set of +options+ provided. This takes the
13
20
  # same options as +url_for+ in Action Controller (see the
14
- # documentation for ActionController::Base#url_for). Note that by default
15
- # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative /controller/action
16
- # instead of the fully qualified URL like http://example.com/controller/action.
21
+ # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
22
+ # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action"
23
+ # instead of the fully qualified URL like "http://example.com/controller/action".
17
24
  #
18
- # When called from a view, url_for returns an HTML escaped url. If you
25
+ # When called from a view, +url_for+ returns an HTML escaped url. If you
19
26
  # need an unescaped url, pass <tt>:escape => false</tt> in the +options+.
20
27
  #
21
28
  # ==== Options
@@ -33,8 +40,8 @@ module ActionView
33
40
  #
34
41
  # If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter,
35
42
  # you'll trigger the named route for that record. The lookup will happen on the name of the class. So passing
36
- # a Workshop object will attempt to use the workshop_path route. If you have a nested route, such as
37
- # admin_workshop_path you'll have to call that explicitly (it's impossible for url_for to guess that route).
43
+ # a Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as
44
+ # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route).
38
45
  #
39
46
  # ==== Examples
40
47
  # <%= url_for(:action => 'index') %>
@@ -81,11 +88,11 @@ module ActionView
81
88
  options
82
89
  when Hash
83
90
  options = { :only_path => options[:host].nil? }.update(options.symbolize_keys)
84
- escape = options.key?(:escape) ? options.delete(:escape) : true
85
- @controller.send(:url_for, options)
91
+ escape = options.key?(:escape) ? options.delete(:escape) : false
92
+ controller.send(:url_for, options)
86
93
  when :back
87
94
  escape = false
88
- @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
95
+ controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
89
96
  else
90
97
  escape = false
91
98
  polymorphic_path(options)
@@ -96,10 +103,10 @@ module ActionView
96
103
 
97
104
  # Creates a link tag of the given +name+ using a URL created by the set
98
105
  # of +options+. See the valid options in the documentation for
99
- # url_for. It's also possible to pass a string instead
106
+ # +url_for+. It's also possible to pass a string instead
100
107
  # of an options hash to get a link tag that uses the value of the string as the
101
108
  # href for the link, or use <tt>:back</tt> to link to the referrer - a JavaScript back
102
- # link will be used in place of a referrer if none exists. If nil is passed as
109
+ # link will be used in place of a referrer if none exists. If +nil+ is passed as
103
110
  # a name, the link itself will become the name.
104
111
  #
105
112
  # ==== Signatures
@@ -110,34 +117,21 @@ module ActionView
110
117
  # end
111
118
  #
112
119
  # ==== Options
113
- # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
114
- # prompt with the question specified. If the user accepts, the link is
120
+ # * <tt>:confirm => 'question?'</tt> - This will allow the unobtrusive JavaScript
121
+ # driver to prompt with the question specified. If the user accepts, the link is
115
122
  # processed normally, otherwise no action is taken.
116
- # * <tt>:popup => true || array of window options</tt> - This will force the
117
- # link to open in a popup window. By passing true, a default browser window
118
- # will be opened with the URL. You can also specify an array of options
119
- # that are passed-thru to JavaScripts window.open method.
120
123
  # * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically
121
124
  # create an HTML form and immediately submit the form for processing using
122
125
  # the HTTP verb specified. Useful for having links perform a POST operation
123
126
  # in dangerous actions like deleting a record (which search bots can follow
124
127
  # while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt> and <tt>:put</tt>.
125
128
  # Note that if the user has JavaScript disabled, the request will fall back
126
- # to using GET. If you are relying on the POST behavior, you should check
127
- # for it in your controller's action by using the request object's methods
128
- # for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
129
+ # to using GET. If <tt>:href => '#'</tt> is used and the user has JavaScript
130
+ # disabled clicking the link will have no effect. If you are relying on the
131
+ # POST behavior, you should check for it in your controller's action by using
132
+ # the request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
129
133
  # * The +html_options+ will accept a hash of html attributes for the link tag.
130
134
  #
131
- # Note that if the user has JavaScript disabled, the request will fall back
132
- # to using GET. If <tt>:href => '#'</tt> is used and the user has JavaScript disabled
133
- # clicking the link will have no effect. If you are relying on the POST
134
- # behavior, your should check for it in your controller's action by using the
135
- # request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
136
- #
137
- # You can mix and match the +html_options+ with the exception of
138
- # <tt>:popup</tt> and <tt>:method</tt> which will raise an ActionView::ActionViewError
139
- # exception.
140
- #
141
135
  # ==== Examples
142
136
  # Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
143
137
  # and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
@@ -169,9 +163,11 @@ module ActionView
169
163
  # You can use a block as well if your link target is hard to fit into the name parameter. ERb example:
170
164
  #
171
165
  # <% link_to(@profile) do %>
172
- # <strong><%= @profile.name %></strong> -- <span>Check it out!!</span>
166
+ # <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
173
167
  # <% end %>
174
- # # => <a href="/profiles/1"><strong>David</strong> -- <span>Check it out!!</span></a>
168
+ # # => <a href="/profiles/1">
169
+ # <strong>David</strong> -- <span>Check it out!</span>
170
+ # </a>
175
171
  #
176
172
  # Classes and ids for CSS are easy to produce:
177
173
  #
@@ -199,45 +195,38 @@ module ActionView
199
195
  # link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
200
196
  # # => <a href="/searches?foo=bar&amp;baz=quux">Nonsense search</a>
201
197
  #
202
- # The three options specific to +link_to+ (<tt>:confirm</tt>, <tt>:popup</tt>, and <tt>:method</tt>) are used as follows:
198
+ # The two options specific to +link_to+ (<tt>:confirm</tt> and <tt>:method</tt>) are used as follows:
203
199
  #
204
200
  # link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
205
- # # => <a href="http://www.rubyonrails.org/" onclick="return confirm('Are you sure?');">Visit Other Site</a>
206
- #
207
- # link_to "Help", { :action => "help" }, :popup => true
208
- # # => <a href="/testing/help/" onclick="window.open(this.href);return false;">Help</a>
201
+ # # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?"">Visit Other Site</a>
209
202
  #
210
- # link_to "View Image", @image, :popup => ['new_window_name', 'height=300,width=600']
211
- # # => <a href="/images/9" onclick="window.open(this.href,'new_window_name','height=300,width=600');return false;">View Image</a>
203
+ # link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?")
204
+ # # => <a href='http://www.example.com' rel="nofollow" data-method="delete" data-confirm="Are you sure?">Destroy</a>
205
+
212
206
  #
213
- # link_to "Delete Image", @image, :confirm => "Are you sure?", :method => :delete
214
- # # => <a href="/images/9" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form');
215
- # f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
216
- # var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
217
- # m.setAttribute('value', 'delete'); f.appendChild(m);f.submit(); };return false;">Delete Image</a>
218
207
  def link_to(*args, &block)
219
208
  if block_given?
220
209
  options = args.first || {}
221
210
  html_options = args.second
222
- concat(link_to(capture(&block), options, html_options))
211
+ safe_concat(link_to(capture(&block), options, html_options))
223
212
  else
224
- name = args.first
225
- options = args.second || {}
226
- html_options = args.third
213
+ name = args[0]
214
+ options = args[1] || {}
215
+ html_options = args[2]
227
216
 
228
217
  url = url_for(options)
218
+ html_options = convert_options_to_data_attributes(options, html_options)
229
219
 
230
220
  if html_options
231
221
  html_options = html_options.stringify_keys
232
222
  href = html_options['href']
233
- convert_options_to_javascript!(html_options, url)
234
223
  tag_options = tag_options(html_options)
235
224
  else
236
225
  tag_options = nil
237
226
  end
238
227
 
239
228
  href_attr = "href=\"#{url}\"" unless href
240
- "<a #{href_attr}#{tag_options}>#{name || url}</a>".html_safe
229
+ "<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe
241
230
  end
242
231
  end
243
232
 
@@ -245,28 +234,30 @@ module ActionView
245
234
  # by the set of +options+. This is the safest method to ensure links that
246
235
  # cause changes to your data are not triggered by search bots or accelerators.
247
236
  # If the HTML button does not work with your layout, you can also consider
248
- # using the link_to method with the <tt>:method</tt> modifier as described in
249
- # the link_to documentation.
237
+ # using the +link_to+ method with the <tt>:method</tt> modifier as described in
238
+ # the +link_to+ documentation.
250
239
  #
251
- # The generated FORM element has a class name of <tt>button-to</tt>
240
+ # The generated form element has a class name of <tt>button-to</tt>
252
241
  # to allow styling of the form itself and its children. You can control
253
242
  # the form submission and input element behavior using +html_options+.
254
243
  # This method accepts the <tt>:method</tt> and <tt>:confirm</tt> modifiers
255
- # described in the link_to documentation. If no <tt>:method</tt> modifier
244
+ # described in the +link_to+ documentation. If no <tt>:method</tt> modifier
256
245
  # is given, it will default to performing a POST operation. You can also
257
246
  # disable the button by passing <tt>:disabled => true</tt> in +html_options+.
258
247
  # If you are using RESTful routes, you can pass the <tt>:method</tt>
259
248
  # to change the HTTP verb used to submit the form.
260
249
  #
261
250
  # ==== Options
262
- # The +options+ hash accepts the same options at url_for.
251
+ # The +options+ hash accepts the same options as url_for.
263
252
  #
264
253
  # There are a few special +html_options+:
265
254
  # * <tt>:method</tt> - Specifies the anchor name to be appended to the path.
266
255
  # * <tt>:disabled</tt> - Specifies the anchor name to be appended to the path.
267
- # * <tt>:confirm</tt> - This will add a JavaScript confirm
256
+ # * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
268
257
  # prompt with the question specified. If the user accepts, the link is
269
258
  # processed normally, otherwise no action is taken.
259
+ # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
260
+ # submit behaviour. By default this behaviour is an ajax submit.
270
261
  #
271
262
  # ==== Examples
272
263
  # <%= button_to "New", :action => "new" %>
@@ -274,15 +265,27 @@ module ActionView
274
265
  # # <div><input value="New" type="submit" /></div>
275
266
  # # </form>"
276
267
  #
277
- # button_to "Delete Image", { :action => "delete", :id => @image.id },
278
- # :confirm => "Are you sure?", :method => :delete
268
+ #
269
+ # <%= button_to "Delete Image", { :action => "delete", :id => @image.id },
270
+ # :confirm => "Are you sure?", :method => :delete %>
279
271
  # # => "<form method="post" action="/images/delete/1" class="button-to">
280
272
  # # <div>
281
273
  # # <input type="hidden" name="_method" value="delete" />
282
- # # <input onclick="return confirm('Are you sure?');"
283
- # # value="Delete" type="submit" />
274
+ # # <input data-confirm='Are you sure?' value="Delete" type="submit" />
284
275
  # # </div>
285
276
  # # </form>"
277
+ #
278
+ #
279
+ # <%= button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
280
+ # :method => "delete", :remote => true, :disable_with => 'loading...') %>
281
+ # # => "<form class='button-to' method='post' action='http://www.example.com' data-remote='true'>
282
+ # # <div>
283
+ # # <input name='_method' value='delete' type='hidden' />
284
+ # # <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
285
+ # # </div>
286
+ # # </form>"
287
+ # #
288
+
286
289
  def button_to(name, options = {}, html_options = {})
287
290
  html_options = html_options.stringify_keys
288
291
  convert_boolean_attributes!(html_options, %w( disabled ))
@@ -294,21 +297,21 @@ module ActionView
294
297
 
295
298
  form_method = method.to_s == 'get' ? 'get' : 'post'
296
299
 
300
+ remote = html_options.delete('remote')
301
+
297
302
  request_token_tag = ''
298
303
  if form_method == 'post' && protect_against_forgery?
299
304
  request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
300
305
  end
301
306
 
302
- if confirm = html_options.delete("confirm")
303
- html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
304
- end
305
-
306
307
  url = options.is_a?(String) ? options : self.url_for(options)
307
308
  name ||= url
308
309
 
310
+ html_options = convert_options_to_data_attributes(options, html_options)
311
+
309
312
  html_options.merge!("type" => "submit", "value" => name)
310
313
 
311
- ("<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
314
+ ("<form method=\"#{form_method}\" action=\"#{escape_once url}\" #{"data-remote=\"true\"" if remote} class=\"button-to\"><div>" +
312
315
  method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe
313
316
  end
314
317
 
@@ -316,7 +319,7 @@ module ActionView
316
319
  # Creates a link tag of the given +name+ using a URL created by the set of
317
320
  # +options+ unless the current request URI is the same as the links, in
318
321
  # which case only the name is returned (or the given block is yielded, if
319
- # one exists). You can give link_to_unless_current a block which will
322
+ # one exists). You can give +link_to_unless_current+ a block which will
320
323
  # specialize the default behavior (e.g., show a "Start Here" link rather
321
324
  # than the link's text).
322
325
  #
@@ -342,7 +345,7 @@ module ActionView
342
345
  # <li><a href="/controller/about">About Us</a></li>
343
346
  # </ul>
344
347
  #
345
- # The implicit block given to link_to_unless_current is evaluated if the current
348
+ # The implicit block given to +link_to_unless_current+ is evaluated if the current
346
349
  # action is the action given. So, if we had a comments page and wanted to render a
347
350
  # "Go Back" link instead of a link to the comments page, we could do something like this...
348
351
  #
@@ -359,7 +362,7 @@ module ActionView
359
362
  # +options+ unless +condition+ is true, in which case only the name is
360
363
  # returned. To specialize the default behavior (i.e., show a login link rather
361
364
  # than just the plaintext link text), you can pass a block that
362
- # accepts the name or the full argument list for link_to_unless.
365
+ # accepts the name or the full argument list for +link_to_unless+.
363
366
  #
364
367
  # ==== Examples
365
368
  # <%= link_to_unless(@current_user.nil?, "Reply", { :action => "reply" }) %>
@@ -390,8 +393,8 @@ module ActionView
390
393
  # Creates a link tag of the given +name+ using a URL created by the set of
391
394
  # +options+ if +condition+ is true, in which case only the name is
392
395
  # returned. To specialize the default behavior, you can pass a block that
393
- # accepts the name or the full argument list for link_to_unless (see the examples
394
- # in link_to_unless).
396
+ # accepts the name or the full argument list for +link_to_unless+ (see the examples
397
+ # in +link_to_unless+).
395
398
  #
396
399
  # ==== Examples
397
400
  # <%= link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) %>
@@ -415,27 +418,27 @@ module ActionView
415
418
  # also used as the name of the link unless +name+ is specified. Additional
416
419
  # HTML attributes for the link can be passed in +html_options+.
417
420
  #
418
- # mail_to has several methods for hindering email harvesters and customizing
421
+ # +mail_to+ has several methods for hindering email harvesters and customizing
419
422
  # the email itself by passing special keys to +html_options+.
420
423
  #
421
424
  # ==== Options
422
- # * <tt>:encode</tt> - This key will accept the strings "javascript" or "hex".
423
- # Passing "javascript" will dynamically create and encode the mailto: link then
425
+ # * <tt>:encode</tt> - This key will accept the strings "javascript" or "hex".
426
+ # Passing "javascript" will dynamically create and encode the mailto link then
424
427
  # eval it into the DOM of the page. This method will not show the link on
425
428
  # the page if the user has JavaScript disabled. Passing "hex" will hex
426
- # encode the +email_address+ before outputting the mailto: link.
427
- # * <tt>:replace_at</tt> - When the link +name+ isn't provided, the
429
+ # encode the +email_address+ before outputting the mailto link.
430
+ # * <tt>:replace_at</tt> - When the link +name+ isn't provided, the
428
431
  # +email_address+ is used for the link label. You can use this option to
429
432
  # obfuscate the +email_address+ by substituting the @ sign with the string
430
433
  # given as the value.
431
- # * <tt>:replace_dot</tt> - When the link +name+ isn't provided, the
434
+ # * <tt>:replace_dot</tt> - When the link +name+ isn't provided, the
432
435
  # +email_address+ is used for the link label. You can use this option to
433
436
  # obfuscate the +email_address+ by substituting the . in the email with the
434
437
  # string given as the value.
435
- # * <tt>:subject</tt> - Preset the subject line of the email.
438
+ # * <tt>:subject</tt> - Preset the subject line of the email.
436
439
  # * <tt>:body</tt> - Preset the body of the email.
437
- # * <tt>:cc</tt> - Carbon Copy addition recipients on the email.
438
- # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
440
+ # * <tt>:cc</tt> - Carbon Copy addition recipients on the email.
441
+ # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
439
442
  #
440
443
  # ==== Examples
441
444
  # mail_to "me@domain.com"
@@ -460,19 +463,20 @@ module ActionView
460
463
 
461
464
  string = ''
462
465
  extras = ''
463
- extras << "cc=#{CGI.escape(cc).gsub("+", "%20")}&" unless cc.nil?
464
- extras << "bcc=#{CGI.escape(bcc).gsub("+", "%20")}&" unless bcc.nil?
465
- extras << "body=#{CGI.escape(body).gsub("+", "%20")}&" unless body.nil?
466
- extras << "subject=#{CGI.escape(subject).gsub("+", "%20")}&" unless subject.nil?
466
+ extras << "cc=#{Rack::Utils.escape(cc).gsub("+", "%20")}&" unless cc.nil?
467
+ extras << "bcc=#{Rack::Utils.escape(bcc).gsub("+", "%20")}&" unless bcc.nil?
468
+ extras << "body=#{Rack::Utils.escape(body).gsub("+", "%20")}&" unless body.nil?
469
+ extras << "subject=#{Rack::Utils.escape(subject).gsub("+", "%20")}&" unless subject.nil?
467
470
  extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty?
468
471
 
469
- email_address_obfuscated = html_escape(email_address)
472
+ email_address = email_address.to_s
473
+
474
+ email_address_obfuscated = email_address.dup
470
475
  email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at")
471
476
  email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
472
477
 
473
478
  if encode == "javascript"
474
- html = content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:"+html_escape(email_address)+extras }))
475
- "document.write('#{escape_javascript(html)}');".each_byte do |c|
479
+ "document.write('#{content_tag("a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
476
480
  string << sprintf("%%%x", c)
477
481
  end
478
482
  "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>"
@@ -489,9 +493,9 @@ module ActionView
489
493
  char = c.chr
490
494
  string << (char =~ /\w/ ? sprintf("%%%x", c) : char)
491
495
  end
492
- content_tag "a", name || email_address_encoded.html_safe, html_options.merge({ "href" => "#{string}#{extras}" })
496
+ content_tag "a", name || email_address_encoded, html_options.merge({ "href" => "#{string}#{extras}" })
493
497
  else
494
- content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
498
+ content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
495
499
  end
496
500
  end
497
501
 
@@ -539,10 +543,10 @@ module ActionView
539
543
  # # => false
540
544
  def current_page?(options)
541
545
  url_string = CGI.unescapeHTML(url_for(options))
542
- request = @controller.request
543
- # We ignore any extra parameters in the request_uri if the
546
+ request = controller.request
547
+ # We ignore any extra parameters in the request_uri if the
544
548
  # submitted url doesn't have any either. This lets the function
545
- # work with things like ?order=asc
549
+ # work with things like ?order=asc
546
550
  if url_string.index("?")
547
551
  request_uri = request.request_uri
548
552
  else
@@ -556,72 +560,74 @@ module ActionView
556
560
  end
557
561
 
558
562
  private
559
- def convert_options_to_javascript!(html_options, url = '')
560
- confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
563
+ def convert_options_to_data_attributes(options, html_options)
564
+ html_options = {} if html_options.nil?
565
+ html_options = html_options.stringify_keys
566
+
567
+ if (options.is_a?(Hash) && options.key?('remote')) || (html_options.is_a?(Hash) && html_options.key?('remote'))
568
+ html_options['data-remote'] = 'true'
569
+ options.delete('remote') if options.is_a?(Hash)
570
+ html_options.delete('remote') if html_options.is_a?(Hash)
571
+ end
561
572
 
562
- method, href = html_options.delete("method"), html_options['href']
573
+ confirm = html_options.delete("confirm")
563
574
 
564
- html_options["onclick"] = case
565
- when popup && method
566
- raise ActionView::ActionViewError, "You can't use :popup and :method in the same link"
567
- when confirm && popup
568
- "if (#{confirm_javascript_function(confirm)}) { #{popup_javascript_function(popup)} };return false;"
569
- when confirm && method
570
- "if (#{confirm_javascript_function(confirm)}) { #{method_javascript_function(method, url, href)} };return false;"
571
- when confirm
572
- "return #{confirm_javascript_function(confirm)};"
573
- when method
574
- "#{method_javascript_function(method, url, href)}return false;"
575
- when popup
576
- "#{popup_javascript_function(popup)}return false;"
577
- else
578
- html_options["onclick"]
575
+ if html_options.key?("popup")
576
+ ActiveSupport::Deprecation.warn(":popup has been deprecated", caller)
579
577
  end
580
- end
581
578
 
582
- def confirm_javascript_function(confirm)
583
- "confirm('#{escape_javascript(confirm)}')"
579
+ method, href = html_options.delete("method"), html_options['href']
580
+
581
+ add_confirm_to_attributes!(html_options, confirm) if confirm
582
+ add_method_to_attributes!(html_options, method) if method
583
+
584
+ html_options["data-url"] = options[:url] if options.is_a?(Hash) && options[:url]
585
+
586
+ html_options
584
587
  end
585
588
 
586
- def popup_javascript_function(popup)
587
- popup.is_a?(Array) ? "window.open(this.href,'#{popup.first}','#{popup.last}');" : "window.open(this.href);"
589
+ def add_confirm_to_attributes!(html_options, confirm)
590
+ html_options["data-confirm"] = confirm if confirm
588
591
  end
589
592
 
590
- def method_javascript_function(method, url = '', href = nil)
591
- action = (href && url.size > 0) ? "'#{url}'" : 'this.href'
592
- submit_function =
593
- "var f = document.createElement('form'); f.style.display = 'none'; " +
594
- "this.parentNode.appendChild(f); f.method = 'POST'; f.action = #{action};"
593
+ def add_method_to_attributes!(html_options, method)
594
+ html_options["rel"] = "nofollow" if method && method.to_s.downcase != "get"
595
+ html_options["data-method"] = method if method
596
+ end
595
597
 
596
- unless method == :post
597
- submit_function << "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); "
598
- submit_function << "m.setAttribute('name', '_method'); m.setAttribute('value', '#{method}'); f.appendChild(m);"
598
+ def options_for_javascript(options)
599
+ if options.empty?
600
+ '{}'
601
+ else
602
+ "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
599
603
  end
604
+ end
600
605
 
601
- if protect_against_forgery?
602
- submit_function << "var s = document.createElement('input'); s.setAttribute('type', 'hidden'); "
603
- submit_function << "s.setAttribute('name', '#{request_forgery_protection_token}'); s.setAttribute('value', '#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
606
+ def array_or_string_for_javascript(option)
607
+ if option.kind_of?(Array)
608
+ "['#{option.join('\',\'')}']"
609
+ elsif !option.nil?
610
+ "'#{option}'"
604
611
  end
605
- submit_function << "f.submit();"
606
612
  end
607
613
 
608
- # Processes the _html_options_ hash, converting the boolean
614
+ # Processes the +html_options+ hash, converting the boolean
609
615
  # attributes from true/false form into the form required by
610
616
  # HTML/XHTML. (An attribute is considered to be boolean if
611
- # its name is listed in the given _bool_attrs_ array.)
617
+ # its name is listed in the given +bool_attrs+ array.)
612
618
  #
613
- # More specifically, for each boolean attribute in _html_options_
619
+ # More specifically, for each boolean attribute in +html_options+
614
620
  # given as:
615
621
  #
616
- # "attr" => bool_value
622
+ # "attr" => bool_value
617
623
  #
618
- # if the associated _bool_value_ evaluates to true, it is
624
+ # if the associated +bool_value+ evaluates to true, it is
619
625
  # replaced with the attribute's name; otherwise the attribute is
620
- # removed from the _html_options_ hash. (See the XHTML 1.0 spec,
626
+ # removed from the +html_options+ hash. (See the XHTML 1.0 spec,
621
627
  # section 4.5 "Attribute Minimization" for more:
622
628
  # http://www.w3.org/TR/xhtml1/#h-4.5)
623
629
  #
624
- # Returns the updated _html_options_ hash, which is also modified
630
+ # Returns the updated +html_options+ hash, which is also modified
625
631
  # in place.
626
632
  #
627
633
  # Example: