actionpack 2.3.18 → 3.0.0.beta

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 (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
@@ -221,31 +221,31 @@ module ActionView
221
221
  #
222
222
  # In addition to the <tt>:include_blank</tt> option documented above,
223
223
  # this method also supports a <tt>:model</tt> option, which defaults
224
- # to TimeZone. This may be used by users to specify a different time
225
- # zone model object. (See +time_zone_options_for_select+ for more
226
- # information.)
224
+ # to ActiveSupport::TimeZone. This may be used by users to specify a
225
+ # different time zone model object. (See +time_zone_options_for_select+
226
+ # for more information.)
227
227
  #
228
- # You can also supply an array of TimeZone objects
228
+ # You can also supply an array of ActiveSupport::TimeZone objects
229
229
  # as +priority_zones+, so that they will be listed above the rest of the
230
- # (long) list. (You can use TimeZone.us_zones as a convenience for
231
- # obtaining a list of the US time zones, or a Regexp to select the zones
230
+ # (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience
231
+ # for obtaining a list of the US time zones, or a Regexp to select the zones
232
232
  # of your choice)
233
233
  #
234
234
  # Finally, this method supports a <tt>:default</tt> option, which selects
235
- # a default TimeZone if the object's time zone is +nil+.
235
+ # a default ActiveSupport::TimeZone if the object's time zone is +nil+.
236
236
  #
237
237
  # Examples:
238
238
  # time_zone_select( "user", "time_zone", nil, :include_blank => true)
239
239
  #
240
240
  # time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" )
241
241
  #
242
- # time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
242
+ # time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
243
243
  #
244
- # time_zone_select( "user", 'time_zone', [ TimeZone['Alaska'], TimeZone['Hawaii'] ])
244
+ # time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
245
245
  #
246
246
  # time_zone_select( "user", 'time_zone', /Australia/)
247
247
  #
248
- # time_zone_select( "user", "time_zone", TZInfo::Timezone.all.sort, :model => TZInfo::Timezone)
248
+ # time_zone_select( "user", "time_zone", ActiveSupport::Timezone.all.sort, :model => ActiveSupport::Timezone)
249
249
  def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
250
250
  InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options)
251
251
  end
@@ -447,20 +447,20 @@ module ActionView
447
447
  end
448
448
 
449
449
  # Returns a string of option tags for pretty much any time zone in the
450
- # world. Supply a TimeZone name as +selected+ to have it marked as the
451
- # selected option tag. You can also supply an array of TimeZone objects
452
- # as +priority_zones+, so that they will be listed above the rest of the
453
- # (long) list. (You can use TimeZone.us_zones as a convenience for
454
- # obtaining a list of the US time zones, or a Regexp to select the zones
455
- # of your choice)
450
+ # world. Supply a ActiveSupport::TimeZone name as +selected+ to have it
451
+ # marked as the selected option tag. You can also supply an array of
452
+ # ActiveSupport::TimeZone objects as +priority_zones+, so that they will
453
+ # be listed above the rest of the (long) list. (You can use
454
+ # ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list
455
+ # of the US time zones, or a Regexp to select the zones of your choice)
456
456
  #
457
457
  # The +selected+ parameter must be either +nil+, or a string that names
458
- # a TimeZone.
458
+ # a ActiveSupport::TimeZone.
459
459
  #
460
- # By default, +model+ is the TimeZone constant (which can be obtained
461
- # in Active Record as a value object). The only requirement is that the
462
- # +model+ parameter be an object that responds to +all+, and returns
463
- # an array of objects that represent time zones.
460
+ # By default, +model+ is the ActiveSupport::TimeZone constant (which can
461
+ # be obtained in Active Record as a value object). The only requirement
462
+ # is that the +model+ parameter be an object that responds to +all+, and
463
+ # returns an array of objects that represent time zones.
464
464
  #
465
465
  # NOTE: Only the option tags are returned, you have to wrap this call in
466
466
  # a regular HTML select tag.
@@ -481,7 +481,7 @@ module ActionView
481
481
  end
482
482
 
483
483
  zone_options += options_for_select(convert_zones[zones], selected)
484
- zone_options.html_safe
484
+ zone_options
485
485
  end
486
486
 
487
487
  private
@@ -571,10 +571,11 @@ module ActionView
571
571
  option_tags = "<option value=\"\">#{options[:include_blank] if options[:include_blank].kind_of?(String)}</option>\n" + option_tags
572
572
  end
573
573
  if value.blank? && options[:prompt]
574
- prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('support.select.prompt', :default => 'Please select')
575
- option_tags = "<option value=\"\">#{prompt}</option>\n" + option_tags
574
+ prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select')
575
+ "<option value=\"\">#{prompt}</option>\n" + option_tags
576
+ else
577
+ option_tags
576
578
  end
577
- option_tags.html_safe
578
579
  end
579
580
  end
580
581
 
@@ -1,5 +1,6 @@
1
1
  require 'cgi'
2
2
  require 'action_view/helpers/tag_helper'
3
+ require 'active_support/core_ext/object/returning'
3
4
 
4
5
  module ActionView
5
6
  module Helpers
@@ -18,6 +19,8 @@ module ActionView
18
19
  # If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
19
20
  # is added to simulate the verb over post.
20
21
  # * A list of parameters to feed to the URL the form will be posted to.
22
+ # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
23
+ # submit behaviour. By default this behaviour is an ajax submit.
21
24
  #
22
25
  # ==== Examples
23
26
  # form_tag('/posts')
@@ -29,10 +32,14 @@ module ActionView
29
32
  # form_tag('/upload', :multipart => true)
30
33
  # # => <form action="/upload" method="post" enctype="multipart/form-data">
31
34
  #
32
- # <% form_tag '/posts' do -%>
35
+ # <% form_tag('/posts')do -%>
33
36
  # <div><%= submit_tag 'Save' %></div>
34
37
  # <% end -%>
35
38
  # # => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
39
+ #
40
+ # <% form_tag('/posts', :remote => true) %>
41
+ # # => <form action="/posts" method="post" data-remote="true">
42
+ #
36
43
  def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)
37
44
  html_options = html_options_for_form(url_for_options, options, *parameters_for_url)
38
45
  if block_given?
@@ -54,6 +61,9 @@ module ActionView
54
61
  # * Any other key creates standard HTML attributes for the tag.
55
62
  #
56
63
  # ==== Examples
64
+ # select_tag "people", options_from_collection_for_select(@people, "name", "id")
65
+ # # <select id="people" name="people"><option value="1">David</option></select>
66
+ #
57
67
  # select_tag "people", "<option>David</option>"
58
68
  # # => <select id="people" name="people"><option>David</option></select>
59
69
  #
@@ -78,8 +88,12 @@ module ActionView
78
88
  # # <option>Paris</option><option>Rome</option></select>
79
89
  def select_tag(name, option_tags = nil, options = {})
80
90
  html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
81
- if Array === option_tags
82
- ActiveSupport::Deprecation.warn 'Passing an array of option_tags to select_tag implicitly joins them without marking them as HTML-safe. Pass option_tags.join.html_safe instead.', caller
91
+ if blank = options.delete(:include_blank)
92
+ if blank.kind_of?(String)
93
+ option_tags = "<option value=\"\">#{blank}</option>" + option_tags
94
+ else
95
+ option_tags = "<option value=\"\"></option>" + option_tags
96
+ end
83
97
  end
84
98
  content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
85
99
  end
@@ -120,7 +134,7 @@ module ActionView
120
134
 
121
135
  # Creates a label field
122
136
  #
123
- # ==== Options
137
+ # ==== Options
124
138
  # * Creates standard HTML attributes for the tag.
125
139
  #
126
140
  # ==== Examples
@@ -265,7 +279,7 @@ module ActionView
265
279
  escape = options.key?("escape") ? options.delete("escape") : true
266
280
  content = html_escape(content) if escape
267
281
 
268
- content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
282
+ content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
269
283
  end
270
284
 
271
285
  # Creates a check box form input tag.
@@ -315,9 +329,7 @@ module ActionView
315
329
  # radio_button_tag 'color', "green", true, :class => "color_input"
316
330
  # # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
317
331
  def radio_button_tag(name, value, checked = false, options = {})
318
- pretty_tag_value = value.to_s.gsub(/\s/, "_").gsub(/(?!-)\W/, "").downcase
319
- pretty_name = name.to_s.gsub(/\[/, "_").gsub(/\]/, "")
320
- html_options = { "type" => "radio", "name" => name, "id" => "#{pretty_name}_#{pretty_tag_value}", "value" => value }.update(options.stringify_keys)
332
+ html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
321
333
  html_options["checked"] = "checked" if checked
322
334
  tag :input, html_options
323
335
  end
@@ -325,12 +337,13 @@ module ActionView
325
337
  # Creates a submit button with the text <tt>value</tt> as the caption.
326
338
  #
327
339
  # ==== Options
328
- # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
329
- # prompt with the question specified. If the user accepts, the form is
330
- # processed normally, otherwise no action is taken.
340
+ # * <tt>:confirm => 'question?'</tt> - If present the unobtrusive JavaScript
341
+ # drivers will provide a prompt with the question specified. If the user accepts,
342
+ # the form is processed normally, otherwise no action is taken.
331
343
  # * <tt>:disabled</tt> - If true, the user will not be able to use this input.
332
- # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a disabled version
333
- # of the submit button when the form is submitted.
344
+ # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
345
+ # disabled version of the submit button when the form is submitted. This feature is
346
+ # provided by the unobtrusive JavaScript driver.
334
347
  # * Any other key creates standard HTML options for the tag.
335
348
  #
336
349
  # ==== Examples
@@ -343,34 +356,31 @@ module ActionView
343
356
  # submit_tag "Save edits", :disabled => true
344
357
  # # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
345
358
  #
359
+ #
346
360
  # submit_tag "Complete sale", :disable_with => "Please wait..."
347
- # # => <input name="commit" onclick="this.disabled=true;this.value='Please wait...';this.form.submit();"
361
+ # # => <input name="commit" data-disable-with="Please wait..."
348
362
  # # type="submit" value="Complete sale" />
349
363
  #
350
364
  # submit_tag nil, :class => "form_submit"
351
365
  # # => <input class="form_submit" name="commit" type="submit" />
352
366
  #
353
367
  # submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
354
- # # => <input class="edit-button" onclick="this.disabled=true;this.value='Editing...';this.form.submit();"
368
+ # # => <input class="edit-button" data-disable_with="Editing..."
355
369
  # # name="commit" type="submit" value="Edit" />
370
+ #
371
+ # submit_tag "Save", :confirm => "Are you sure?"
372
+ # # => <input name='commit' type='submit' value='Save'
373
+ # data-confirm="Are you sure?" />
374
+ #
356
375
  def submit_tag(value = "Save changes", options = {})
357
376
  options.stringify_keys!
358
377
 
359
378
  if disable_with = options.delete("disable_with")
360
- disable_with = "this.value='#{disable_with}'"
361
- disable_with << ";#{options.delete('onclick')}" if options['onclick']
362
-
363
- options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
364
- options["onclick"] << "else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';"
365
- options["onclick"] << "hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }"
366
- options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
367
- options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
368
- options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
379
+ options["data-disable-with"] = disable_with if disable_with
369
380
  end
370
381
 
371
382
  if confirm = options.delete("confirm")
372
- options["onclick"] ||= 'return true;'
373
- options["onclick"] = "if (!#{confirm_javascript_function(confirm)}) return false; #{options['onclick']}"
383
+ add_confirm_to_attributes!(options, confirm)
374
384
  end
375
385
 
376
386
  tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
@@ -403,8 +413,7 @@ module ActionView
403
413
  options.stringify_keys!
404
414
 
405
415
  if confirm = options.delete("confirm")
406
- options["onclick"] ||= ''
407
- options["onclick"] += "return #{confirm_javascript_function(confirm)};"
416
+ add_confirm_to_attributes!(options, confirm)
408
417
  end
409
418
 
410
419
  tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
@@ -415,7 +424,7 @@ module ActionView
415
424
  # <tt>legend</tt> will become the fieldset's title (optional as per W3C).
416
425
  # <tt>options</tt> accept the same values as tag.
417
426
  #
418
- # === Examples
427
+ # ==== Examples
419
428
  # <% field_set_tag do %>
420
429
  # <p><%= text_field_tag 'name' %></p>
421
430
  # <% end %>
@@ -435,14 +444,15 @@ module ActionView
435
444
  concat(tag(:fieldset, options, true))
436
445
  concat(content_tag(:legend, legend)) unless legend.blank?
437
446
  concat(content)
438
- concat("</fieldset>".html_safe)
447
+ safe_concat("</fieldset>")
439
448
  end
440
449
 
441
450
  private
442
451
  def html_options_for_form(url_for_options, options, *parameters_for_url)
443
- options.stringify_keys.tap do |html_options|
452
+ returning options.stringify_keys do |html_options|
444
453
  html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
445
454
  html_options["action"] = url_for(url_for_options, *parameters_for_url)
455
+ html_options["data-remote"] = true if html_options.delete("remote")
446
456
  end
447
457
  end
448
458
 
@@ -469,7 +479,7 @@ module ActionView
469
479
  content = capture(&block)
470
480
  concat(form_tag_html(html_options))
471
481
  concat(content)
472
- concat("</form>".html_safe)
482
+ safe_concat("</form>")
473
483
  end
474
484
 
475
485
  def token_tag
@@ -484,7 +494,6 @@ module ActionView
484
494
  def sanitize_to_id(name)
485
495
  name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
486
496
  end
487
-
488
497
  end
489
498
  end
490
499
  end
@@ -35,99 +35,8 @@ module ActionView
35
35
  # For documentation on +javascript_include_tag+ see
36
36
  # ActionView::Helpers::AssetTagHelper.
37
37
  module JavaScriptHelper
38
- unless const_defined? :JAVASCRIPT_PATH
39
- JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
40
- end
41
-
42
38
  include PrototypeHelper
43
39
 
44
- # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
45
- # onclick handler and return false after the fact.
46
- #
47
- # The first argument +name+ is used as the link text.
48
- #
49
- # The next arguments are optional and may include the javascript function definition and a hash of html_options.
50
- #
51
- # The +function+ argument can be omitted in favor of an +update_page+
52
- # block, which evaluates to a string when the template is rendered
53
- # (instead of making an Ajax request first).
54
- #
55
- # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
56
- #
57
- # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
58
- #
59
- #
60
- # Examples:
61
- # link_to_function "Greeting", "alert('Hello world!')"
62
- # Produces:
63
- # <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
64
- #
65
- # link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
66
- # Produces:
67
- # <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
68
- # <img src="/images/delete.png?" alt="Delete"/>
69
- # </a>
70
- #
71
- # link_to_function("Show me more", nil, :id => "more_link") do |page|
72
- # page[:details].visual_effect :toggle_blind
73
- # page[:more_link].replace_html "Show me less"
74
- # end
75
- # Produces:
76
- # <a href="#" id="more_link" onclick="try {
77
- # $(&quot;details&quot;).visualEffect(&quot;toggle_blind&quot;);
78
- # $(&quot;more_link&quot;).update(&quot;Show me less&quot;);
79
- # }
80
- # catch (e) {
81
- # alert('RJS error:\n\n' + e.toString());
82
- # alert('$(\&quot;details\&quot;).visualEffect(\&quot;toggle_blind\&quot;);
83
- # \n$(\&quot;more_link\&quot;).update(\&quot;Show me less\&quot;);');
84
- # throw e
85
- # };
86
- # return false;">Show me more</a>
87
- #
88
- def link_to_function(name, *args, &block)
89
- html_options = args.extract_options!.symbolize_keys
90
-
91
- function = block_given? ? update_page(&block) : args[0] || ''
92
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
93
- href = html_options[:href] || '#'
94
-
95
- content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
96
- end
97
-
98
- # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
99
- # onclick handler.
100
- #
101
- # The first argument +name+ is used as the button's value or display text.
102
- #
103
- # The next arguments are optional and may include the javascript function definition and a hash of html_options.
104
- #
105
- # The +function+ argument can be omitted in favor of an +update_page+
106
- # block, which evaluates to a string when the template is rendered
107
- # (instead of making an Ajax request first).
108
- #
109
- # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
110
- #
111
- # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
112
- #
113
- # Examples:
114
- # button_to_function "Greeting", "alert('Hello world!')"
115
- # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
116
- # button_to_function "Details" do |page|
117
- # page[:details].visual_effect :toggle_slide
118
- # end
119
- # button_to_function "Details", :class => "details_button" do |page|
120
- # page[:details].visual_effect :toggle_slide
121
- # end
122
- def button_to_function(name, *args, &block)
123
- html_options = args.extract_options!.symbolize_keys
124
-
125
- function = block_given? ? update_page(&block) : args[0] || ''
126
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
127
-
128
- tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
129
- end
130
-
131
40
  JS_ESCAPE_MAP = {
132
41
  '\\' => '\\\\',
133
42
  '</' => '<\/',
@@ -184,24 +93,7 @@ module ActionView
184
93
  end
185
94
 
186
95
  def javascript_cdata_section(content) #:nodoc:
187
- "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
188
- end
189
-
190
- protected
191
- def options_for_javascript(options)
192
- if options.empty?
193
- '{}'
194
- else
195
- "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
196
- end
197
- end
198
-
199
- def array_or_string_for_javascript(option)
200
- if option.kind_of?(Array)
201
- "['#{option.join('\',\'')}']"
202
- elsif !option.nil?
203
- "'#{option}'"
204
- end
96
+ "\n//#{cdata_section("\n#{content}\n//")}\n"
205
97
  end
206
98
  end
207
99
  end
@@ -1,3 +1,6 @@
1
+ require 'active_support/core_ext/big_decimal/conversions'
2
+ require 'active_support/core_ext/float/rounding'
3
+
1
4
  module ActionView
2
5
  module Helpers #:nodoc:
3
6
  # Provides methods for converting numbers into formatted strings.
@@ -213,7 +216,7 @@ module ActionView
213
216
  delimiter ||= (options[:delimiter] || defaults[:delimiter])
214
217
 
215
218
  begin
216
- rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision
219
+ rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision
217
220
  number_with_delimiter("%01.#{precision}f" % rounded_number,
218
221
  :separator => separator,
219
222
  :delimiter => delimiter)
@@ -1,5 +1,6 @@
1
1
  require 'set'
2
2
  require 'active_support/json'
3
+ require 'active_support/core_ext/object/returning'
3
4
 
4
5
  module ActionView
5
6
  module Helpers
@@ -38,20 +39,6 @@ module ActionView
38
39
  # <div><%= submit_tag 'Recalculate Shipping' %></div>
39
40
  # <% end -%>
40
41
  #
41
- # ...periodically...
42
- #
43
- # periodically_call_remote(:url => 'update', :frequency => '5', :update => 'ticker')
44
- #
45
- # ...or through an observer (i.e., a form or field that is observed and calls a remote
46
- # action when changed).
47
- #
48
- # <%= observe_field(:searchbox,
49
- # :url => { :action => :live_search }),
50
- # :frequency => 0.5,
51
- # :update => :hits,
52
- # :with => 'query'
53
- # %>
54
- #
55
42
  # As you can see, there are numerous ways to use Prototype's Ajax functions (and actually more than
56
43
  # are listed here); check out the documentation for each method to find out more about its usage and options.
57
44
  #
@@ -115,323 +102,37 @@ module ActionView
115
102
  :form, :with, :update, :script, :type ]).merge(CALLBACKS)
116
103
  end
117
104
 
118
- # Returns a link to a remote action defined by <tt>options[:url]</tt>
119
- # (using the url_for format) that's called in the background using
120
- # XMLHttpRequest. The result of that request can then be inserted into a
121
- # DOM object whose id can be specified with <tt>options[:update]</tt>.
122
- # Usually, the result would be a partial prepared by the controller with
123
- # render :partial.
105
+ # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
106
+ # onclick handler.
124
107
  #
125
- # Examples:
126
- # # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true});
127
- # # return false;">Delete this post</a>
128
- # link_to_remote "Delete this post", :update => "posts",
129
- # :url => { :action => "destroy", :id => post.id }
130
- #
131
- # # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true});
132
- # # return false;"><img alt="Refresh" src="/images/refresh.png?" /></a>
133
- # link_to_remote(image_tag("refresh"), :update => "emails",
134
- # :url => { :action => "list_emails" })
108
+ # The first argument +name+ is used as the button's value or display text.
135
109
  #
136
- # You can override the generated HTML options by specifying a hash in
137
- # <tt>options[:html]</tt>.
110
+ # The next arguments are optional and may include the javascript function definition and a hash of html_options.
138
111
  #
139
- # link_to_remote "Delete this post", :update => "posts",
140
- # :url => post_url(@post), :method => :delete,
141
- # :html => { :class => "destructive" }
112
+ # The +function+ argument can be omitted in favor of an +update_page+
113
+ # block, which evaluates to a string when the template is rendered
114
+ # (instead of making an Ajax request first).
142
115
  #
143
- # You can also specify a hash for <tt>options[:update]</tt> to allow for
144
- # easy redirection of output to an other DOM element if a server-side
145
- # error occurs:
146
- #
147
- # Example:
148
- # # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5',
149
- # # {asynchronous:true, evalScripts:true}); return false;">Delete this post</a>
150
- # link_to_remote "Delete this post",
151
- # :url => { :action => "destroy", :id => post.id },
152
- # :update => { :success => "posts", :failure => "error" }
116
+ # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
153
117
  #
154
- # Optionally, you can use the <tt>options[:position]</tt> parameter to
155
- # influence how the target DOM element is updated. It must be one of
156
- # <tt>:before</tt>, <tt>:top</tt>, <tt>:bottom</tt>, or <tt>:after</tt>.
157
- #
158
- # The method used is by default POST. You can also specify GET or you
159
- # can simulate PUT or DELETE over POST. All specified with <tt>options[:method]</tt>
160
- #
161
- # Example:
162
- # # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'});
163
- # # return false;">Destroy</a>
164
- # link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete
165
- #
166
- # By default, these remote requests are processed asynchronous during
167
- # which various JavaScript callbacks can be triggered (for progress
168
- # indicators and the likes). All callbacks get access to the
169
- # <tt>request</tt> object, which holds the underlying XMLHttpRequest.
170
- #
171
- # To access the server response, use <tt>request.responseText</tt>, to
172
- # find out the HTTP status, use <tt>request.status</tt>.
173
- #
174
- # Example:
175
- # # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true,
176
- # # onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a>
177
- # word = 'hello'
178
- # link_to_remote word,
179
- # :url => { :action => "undo", :n => word_counter },
180
- # :complete => "undoRequestCompleted(request)"
118
+ # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
181
119
  #
182
- # The callbacks that may be specified are (in order):
183
- #
184
- # <tt>:loading</tt>:: Called when the remote document is being
185
- # loaded with data by the browser.
186
- # <tt>:loaded</tt>:: Called when the browser has finished loading
187
- # the remote document.
188
- # <tt>:interactive</tt>:: Called when the user can interact with the
189
- # remote document, even though it has not
190
- # finished loading.
191
- # <tt>:success</tt>:: Called when the XMLHttpRequest is completed,
192
- # and the HTTP status code is in the 2XX range.
193
- # <tt>:failure</tt>:: Called when the XMLHttpRequest is completed,
194
- # and the HTTP status code is not in the 2XX
195
- # range.
196
- # <tt>:complete</tt>:: Called when the XMLHttpRequest is complete
197
- # (fires after success/failure if they are
198
- # present).
199
- #
200
- # You can further refine <tt>:success</tt> and <tt>:failure</tt> by
201
- # adding additional callbacks for specific status codes.
202
- #
203
- # Example:
204
- # # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true,
205
- # # on404:function(request){alert('Not found...? Wrong URL...?')},
206
- # # onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a>
207
- # link_to_remote word,
208
- # :url => { :action => "action" },
209
- # 404 => "alert('Not found...? Wrong URL...?')",
210
- # :failure => "alert('HTTP Error ' + request.status + '!')"
211
- #
212
- # A status code callback overrides the success/failure handlers if
213
- # present.
214
- #
215
- # If you for some reason or another need synchronous processing (that'll
216
- # block the browser while the request is happening), you can specify
217
- # <tt>options[:type] = :synchronous</tt>.
218
- #
219
- # You can customize further browser side call logic by passing in
220
- # JavaScript code snippets via some optional parameters. In their order
221
- # of use these are:
222
- #
223
- # <tt>:confirm</tt>:: Adds confirmation dialog.
224
- # <tt>:condition</tt>:: Perform remote request conditionally
225
- # by this expression. Use this to
226
- # describe browser-side conditions when
227
- # request should not be initiated.
228
- # <tt>:before</tt>:: Called before request is initiated.
229
- # <tt>:after</tt>:: Called immediately after request was
230
- # initiated and before <tt>:loading</tt>.
231
- # <tt>:submit</tt>:: Specifies the DOM element ID that's used
232
- # as the parent of the form elements. By
233
- # default this is the current form, but
234
- # it could just as well be the ID of a
235
- # table row or any other DOM element.
236
- # <tt>:with</tt>:: A JavaScript expression specifying
237
- # the parameters for the XMLHttpRequest.
238
- # Any expressions should return a valid
239
- # URL query string.
240
- #
241
- # Example:
242
- #
243
- # :with => "'name=' + $('name').value"
244
- #
245
- # You can generate a link that uses AJAX in the general case, while
246
- # degrading gracefully to plain link behavior in the absence of
247
- # JavaScript by setting <tt>html_options[:href]</tt> to an alternate URL.
248
- # Note the extra curly braces around the <tt>options</tt> hash separate
249
- # it as the second parameter from <tt>html_options</tt>, the third.
250
- #
251
- # Example:
252
- # link_to_remote "Delete this post",
253
- # { :update => "posts", :url => { :action => "destroy", :id => post.id } },
254
- # :href => url_for(:action => "destroy", :id => post.id)
255
- def link_to_remote(name, options = {}, html_options = nil)
256
- link_to_function(name, remote_function(options), html_options || options.delete(:html))
257
- end
258
-
259
- # Creates a button with an onclick event which calls a remote action
260
- # via XMLHttpRequest
261
- # The options for specifying the target with :url
262
- # and defining callbacks is the same as link_to_remote.
263
- def button_to_remote(name, options = {}, html_options = {})
264
- button_to_function(name, remote_function(options), html_options)
265
- end
266
-
267
- # Periodically calls the specified url (<tt>options[:url]</tt>) every
268
- # <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
269
- # update a specified div (<tt>options[:update]</tt>) with the results
270
- # of the remote call. The options for specifying the target with <tt>:url</tt>
271
- # and defining callbacks is the same as link_to_remote.
272
120
  # Examples:
273
- # # Call get_averages and put its results in 'avg' every 10 seconds
274
- # # Generates:
275
- # # new PeriodicalExecuter(function() {new Ajax.Updater('avg', '/grades/get_averages',
276
- # # {asynchronous:true, evalScripts:true})}, 10)
277
- # periodically_call_remote(:url => { :action => 'get_averages' }, :update => 'avg')
278
- #
279
- # # Call invoice every 10 seconds with the id of the customer
280
- # # If it succeeds, update the invoice DIV; if it fails, update the error DIV
281
- # # Generates:
282
- # # new PeriodicalExecuter(function() {new Ajax.Updater({success:'invoice',failure:'error'},
283
- # # '/testing/invoice/16', {asynchronous:true, evalScripts:true})}, 10)
284
- # periodically_call_remote(:url => { :action => 'invoice', :id => customer.id },
285
- # :update => { :success => "invoice", :failure => "error" }
286
- #
287
- # # Call update every 20 seconds and update the new_block DIV
288
- # # Generates:
289
- # # new PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20)
290
- # periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
291
- #
292
- def periodically_call_remote(options = {})
293
- frequency = options[:frequency] || 10 # every ten seconds by default
294
- code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})"
295
- javascript_tag(code)
296
- end
297
-
298
- # Returns a form tag that will submit using XMLHttpRequest in the
299
- # background instead of the regular reloading POST arrangement. Even
300
- # though it's using JavaScript to serialize the form elements, the form
301
- # submission will work just like a regular submission as viewed by the
302
- # receiving side (all elements available in <tt>params</tt>). The options for
303
- # specifying the target with <tt>:url</tt> and defining callbacks is the same as
304
- # +link_to_remote+.
305
- #
306
- # A "fall-through" target for browsers that doesn't do JavaScript can be
307
- # specified with the <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>.
308
- #
309
- # Example:
310
- # # Generates:
311
- # # <form action="/some/place" method="post" onsubmit="new Ajax.Request('',
312
- # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
313
- # form_remote_tag :html => { :action =>
314
- # url_for(:controller => "some", :action => "place") }
315
- #
316
- # The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd)
317
- # argument in the FormTagHelper.form_tag method.
318
- #
319
- # By default the fall-through action is the same as the one specified in
320
- # the <tt>:url</tt> (and the default method is <tt>:post</tt>).
321
- #
322
- # form_remote_tag also takes a block, like form_tag:
323
- # # Generates:
324
- # # <form action="/" method="post" onsubmit="new Ajax.Request('/',
325
- # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)});
326
- # # return false;"> <div><input name="commit" type="submit" value="Save" /></div>
327
- # # </form>
328
- # <% form_remote_tag :url => '/posts' do -%>
329
- # <div><%= submit_tag 'Save' %></div>
330
- # <% end -%>
331
- def form_remote_tag(options = {}, &block)
332
- options[:form] = true
333
-
334
- options[:html] ||= {}
335
- options[:html][:onsubmit] =
336
- (options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") +
337
- "#{remote_function(options)}; return false;"
338
-
339
- form_tag(options[:html].delete(:action) || url_for(options[:url]), options[:html], &block)
340
- end
341
-
342
- # Creates a form that will submit using XMLHttpRequest in the background
343
- # instead of the regular reloading POST arrangement and a scope around a
344
- # specific resource that is used as a base for questioning about
345
- # values for the fields.
346
- #
347
- # === Resource
348
- #
349
- # Example:
350
- # <% remote_form_for(@post) do |f| %>
351
- # ...
352
- # <% end %>
353
- #
354
- # This will expand to be the same as:
355
- #
356
- # <% remote_form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
357
- # ...
358
- # <% end %>
359
- #
360
- # === Nested Resource
361
- #
362
- # Example:
363
- # <% remote_form_for([@post, @comment]) do |f| %>
364
- # ...
365
- # <% end %>
366
- #
367
- # This will expand to be the same as:
368
- #
369
- # <% remote_form_for :comment, @comment, :url => post_comment_path(@post, @comment), :html => { :method => :put, :class => "edit_comment", :id => "edit_comment_45" } do |f| %>
370
- # ...
371
- # <% end %>
372
- #
373
- # If you don't need to attach a form to a resource, then check out form_remote_tag.
374
- #
375
- # See FormHelper#form_for for additional semantics.
376
- def remote_form_for(record_or_name_or_array, *args, &proc)
377
- options = args.extract_options!
378
-
379
- case record_or_name_or_array
380
- when String, Symbol
381
- object_name = record_or_name_or_array
382
- when Array
383
- object = record_or_name_or_array.last
384
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
385
- apply_form_for_options!(record_or_name_or_array, options)
386
- args.unshift object
387
- else
388
- object = record_or_name_or_array
389
- object_name = ActionController::RecordIdentifier.singular_class_name(record_or_name_or_array)
390
- apply_form_for_options!(object, options)
391
- args.unshift object
392
- end
393
-
394
- concat(form_remote_tag(options))
395
- fields_for(object_name, *(args << options), &proc)
396
- concat('</form>'.html_safe)
397
- end
398
- alias_method :form_remote_for, :remote_form_for
399
-
400
- # Returns a button input tag with the element name of +name+ and a value (i.e., display text) of +value+
401
- # that will submit form using XMLHttpRequest in the background instead of a regular POST request that
402
- # reloads the page.
403
- #
404
- # # Create a button that submits to the create action
405
- # #
406
- # # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create',
407
- # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
408
- # # return false;" type="button" value="Create" />
409
- # <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
410
- #
411
- # # Submit to the remote action update and update the DIV succeed or fail based
412
- # # on the success or failure of the request
413
- # #
414
- # # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'},
415
- # # '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
416
- # # return false;" type="button" value="Update" />
417
- # <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
418
- # :update => { :success => "succeed", :failure => "fail" }
419
- #
420
- # <tt>options</tt> argument is the same as in form_remote_tag.
421
- def submit_to_remote(name, value, options = {})
422
- options[:with] ||= 'Form.serialize(this.form)'
423
-
424
- html_options = options.delete(:html) || {}
425
- html_options[:name] = name
121
+ # button_to_function "Greeting", "alert('Hello world!')"
122
+ # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
123
+ # button_to_function "Details" do |page|
124
+ # page[:details].visual_effect :toggle_slide
125
+ # end
126
+ # button_to_function "Details", :class => "details_button" do |page|
127
+ # page[:details].visual_effect :toggle_slide
128
+ # end
129
+ def button_to_function(name, *args, &block)
130
+ html_options = args.extract_options!.symbolize_keys
426
131
 
427
- button_to_remote(value, options, html_options)
428
- end
132
+ function = block_given? ? update_page(&block) : args[0] || ''
133
+ onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
429
134
 
430
- # Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function
431
- # that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
432
- # update return document using +update_element_function+ calls.
433
- def evaluate_remote_response
434
- "eval(request.responseText)"
135
+ tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
435
136
  end
436
137
 
437
138
  # Returns the JavaScript needed for a remote function.
@@ -475,103 +176,11 @@ module ActionView
475
176
  return function
476
177
  end
477
178
 
478
- # Observes the field with the DOM ID specified by +field_id+ and calls a
479
- # callback when its contents have changed. The default callback is an
480
- # Ajax call. By default the value of the observed field is sent as a
481
- # parameter with the Ajax call.
482
- #
483
- # Example:
484
- # # Generates: new Form.Element.Observer('suggest', 0.25, function(element, value) {new Ajax.Updater('suggest',
485
- # # '/testing/find_suggestion', {asynchronous:true, evalScripts:true, parameters:'q=' + value})})
486
- # <%= observe_field :suggest, :url => { :action => :find_suggestion },
487
- # :frequency => 0.25,
488
- # :update => :suggest,
489
- # :with => 'q'
490
- # %>
491
- #
492
- # Required +options+ are either of:
493
- # <tt>:url</tt>:: +url_for+-style options for the action to call
494
- # when the field has changed.
495
- # <tt>:function</tt>:: Instead of making a remote call to a URL, you
496
- # can specify javascript code to be called instead.
497
- # Note that the value of this option is used as the
498
- # *body* of the javascript function, a function definition
499
- # with parameters named element and value will be generated for you
500
- # for example:
501
- # observe_field("glass", :frequency => 1, :function => "alert('Element changed')")
502
- # will generate:
503
- # new Form.Element.Observer('glass', 1, function(element, value) {alert('Element changed')})
504
- # The element parameter is the DOM element being observed, and the value is its value at the
505
- # time the observer is triggered.
506
- #
507
- # Additional options are:
508
- # <tt>:frequency</tt>:: The frequency (in seconds) at which changes to
509
- # this field will be detected. Not setting this
510
- # option at all or to a value equal to or less than
511
- # zero will use event based observation instead of
512
- # time based observation.
513
- # <tt>:update</tt>:: Specifies the DOM ID of the element whose
514
- # innerHTML should be updated with the
515
- # XMLHttpRequest response text.
516
- # <tt>:with</tt>:: A JavaScript expression specifying the parameters
517
- # for the XMLHttpRequest. The default is to send the
518
- # key and value of the observed field. Any custom
519
- # expressions should return a valid URL query string.
520
- # The value of the field is stored in the JavaScript
521
- # variable +value+.
522
- #
523
- # Examples
524
- #
525
- # :with => "'my_custom_key=' + value"
526
- # :with => "'person[name]=' + prompt('New name')"
527
- # :with => "Form.Element.serialize('other-field')"
528
- #
529
- # Finally
530
- # :with => 'name'
531
- # is shorthand for
532
- # :with => "'name=' + value"
533
- # This essentially just changes the key of the parameter.
534
- #
535
- # Additionally, you may specify any of the options documented in the
536
- # <em>Common options</em> section at the top of this document.
537
- #
538
- # Example:
539
- #
540
- # # Sends params: {:title => 'Title of the book'} when the book_title input
541
- # # field is changed.
542
- # observe_field 'book_title',
543
- # :url => 'http://example.com/books/edit/1',
544
- # :with => 'title'
545
- #
546
- #
547
- def observe_field(field_id, options = {})
548
- if options[:frequency] && options[:frequency] > 0
549
- build_observer('Form.Element.Observer', field_id, options)
550
- else
551
- build_observer('Form.Element.EventObserver', field_id, options)
552
- end
553
- end
554
-
555
- # Observes the form with the DOM ID specified by +form_id+ and calls a
556
- # callback when its contents have changed. The default callback is an
557
- # Ajax call. By default all fields of the observed field are sent as
558
- # parameters with the Ajax call.
559
- #
560
- # The +options+ for +observe_form+ are the same as the options for
561
- # +observe_field+. The JavaScript variable +value+ available to the
562
- # <tt>:with</tt> option is set to the serialized form by default.
563
- def observe_form(form_id, options = {})
564
- if options[:frequency]
565
- build_observer('Form.Observer', form_id, options)
566
- else
567
- build_observer('Form.EventObserver', form_id, options)
568
- end
569
- end
570
-
571
179
  # All the methods were moved to GeneratorMethods so that
572
180
  # #include_helpers_from_context has nothing to overwrite.
573
181
  class JavaScriptGenerator #:nodoc:
574
182
  def initialize(context, &block) #:nodoc:
183
+ context._evaluate_assigns_and_ivars
575
184
  @context, @lines = context, []
576
185
  include_helpers_from_context
577
186
  @context.with_output_buffer(@lines) do
@@ -653,7 +262,7 @@ module ActionView
653
262
  # <script> tag.
654
263
  module GeneratorMethods
655
264
  def to_s #:nodoc:
656
- (@lines * $/).tap do |javascript|
265
+ returning javascript = @lines * $/ do
657
266
  if ActionView::Base.debug_rjs
658
267
  source = javascript.dup
659
268
  javascript.replace "try {\n#{source}\n} catch (e) "
@@ -943,37 +552,11 @@ module ActionView
943
552
  record "}, #{(seconds * 1000).to_i})"
944
553
  end
945
554
 
946
- # Starts a script.aculo.us visual effect. See
947
- # ActionView::Helpers::ScriptaculousHelper for more information.
948
- def visual_effect(name, id = nil, options = {})
949
- record @context.send(:visual_effect, name, id, options)
950
- end
951
-
952
- # Creates a script.aculo.us sortable element. Useful
953
- # to recreate sortable elements after items get added
954
- # or deleted.
955
- # See ActionView::Helpers::ScriptaculousHelper for more information.
956
- def sortable(id, options = {})
957
- record @context.send(:sortable_element_js, id, options)
958
- end
959
-
960
- # Creates a script.aculo.us draggable element.
961
- # See ActionView::Helpers::ScriptaculousHelper for more information.
962
- def draggable(id, options = {})
963
- record @context.send(:draggable_element_js, id, options)
964
- end
965
-
966
- # Creates a script.aculo.us drop receiving element.
967
- # See ActionView::Helpers::ScriptaculousHelper for more information.
968
- def drop_receiving(id, options = {})
969
- record @context.send(:drop_receiving_element_js, id, options)
970
- end
971
-
972
555
  private
973
556
  def loop_on_multiple_args(method, ids)
974
557
  record(ids.size>1 ?
975
558
  "#{javascript_object_for(ids)}.each(#{method})" :
976
- "#{method}(#{::ActiveSupport::JSON.encode(ids.first)})")
559
+ "#{method}(#{javascript_object_for(ids.first)})")
977
560
  end
978
561
 
979
562
  def page
@@ -981,19 +564,20 @@ module ActionView
981
564
  end
982
565
 
983
566
  def record(line)
984
- "#{line.to_s.chomp.gsub(/\;\z/, '')};".tap do |_line|
985
- self << _line
567
+ returning line = "#{line.to_s.chomp.gsub(/\;\z/, '')};" do
568
+ self << line
986
569
  end
987
570
  end
988
571
 
989
572
  def render(*options_for_render)
990
- old_format = @context && @context.template_format
991
- @context.template_format = :html if @context
573
+ old_formats = @context && @context.formats
574
+
575
+ @context.reset_formats([:html]) if @context
992
576
  Hash === options_for_render.first ?
993
577
  @context.render(*options_for_render) :
994
578
  options_for_render.first.to_s
995
579
  ensure
996
- @context.template_format = old_format if @context
580
+ @context.reset_formats(old_formats) if @context
997
581
  end
998
582
 
999
583
  def javascript_object_for(object)
@@ -1039,65 +623,57 @@ module ActionView
1039
623
  javascript_tag update_page(&block), html_options
1040
624
  end
1041
625
 
1042
- protected
1043
- def options_for_ajax(options)
1044
- js_options = build_callbacks(options)
1045
-
1046
- js_options['asynchronous'] = options[:type] != :synchronous
1047
- js_options['method'] = method_option_to_s(options[:method]) if options[:method]
1048
- js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
1049
- js_options['evalScripts'] = options[:script].nil? || options[:script]
1050
-
1051
- if options[:form]
1052
- js_options['parameters'] = 'Form.serialize(this)'
1053
- elsif options[:submit]
1054
- js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
1055
- elsif options[:with]
1056
- js_options['parameters'] = options[:with]
1057
- end
1058
-
1059
- if protect_against_forgery? && !options[:form]
1060
- if js_options['parameters']
1061
- js_options['parameters'] << " + '&"
626
+ protected
627
+ def options_for_javascript(options)
628
+ if options.empty?
629
+ '{}'
1062
630
  else
1063
- js_options['parameters'] = "'"
631
+ "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
1064
632
  end
1065
- js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
1066
633
  end
1067
634
 
1068
- options_for_javascript(js_options)
1069
- end
635
+ def options_for_ajax(options)
636
+ js_options = build_callbacks(options)
1070
637
 
1071
- def method_option_to_s(method)
1072
- (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'"
1073
- end
638
+ js_options['asynchronous'] = options[:type] != :synchronous
639
+ js_options['method'] = method_option_to_s(options[:method]) if options[:method]
640
+ js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
641
+ js_options['evalScripts'] = options[:script].nil? || options[:script]
1074
642
 
1075
- def build_observer(klass, name, options = {})
1076
- if options[:with] && (options[:with] !~ /[\{=(.]/)
1077
- options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)"
1078
- else
1079
- options[:with] ||= 'value' unless options[:function]
643
+ if options[:form]
644
+ js_options['parameters'] = 'Form.serialize(this)'
645
+ elsif options[:submit]
646
+ js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
647
+ elsif options[:with]
648
+ js_options['parameters'] = options[:with]
649
+ end
650
+
651
+ if protect_against_forgery? && !options[:form]
652
+ if js_options['parameters']
653
+ js_options['parameters'] << " + '&"
654
+ else
655
+ js_options['parameters'] = "'"
656
+ end
657
+ js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
658
+ end
659
+
660
+ options_for_javascript(js_options)
1080
661
  end
1081
662
 
1082
- callback = options[:function] || remote_function(options)
1083
- javascript = "new #{klass}('#{name}', "
1084
- javascript << "#{options[:frequency]}, " if options[:frequency]
1085
- javascript << "function(element, value) {"
1086
- javascript << "#{callback}}"
1087
- javascript << ")"
1088
- javascript_tag(javascript)
1089
- end
663
+ def method_option_to_s(method)
664
+ (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'"
665
+ end
1090
666
 
1091
- def build_callbacks(options)
1092
- callbacks = {}
1093
- options.each do |callback, code|
1094
- if CALLBACKS.include?(callback)
1095
- name = 'on' + callback.to_s.capitalize
1096
- callbacks[name] = "function(request){#{code}}"
667
+ def build_callbacks(options)
668
+ callbacks = {}
669
+ options.each do |callback, code|
670
+ if CALLBACKS.include?(callback)
671
+ name = 'on' + callback.to_s.capitalize
672
+ callbacks[name] = "function(request){#{code}}"
673
+ end
1097
674
  end
675
+ callbacks
1098
676
  end
1099
- callbacks
1100
- end
1101
677
  end
1102
678
 
1103
679
  # Converts chained method calls on DOM proxy elements into JavaScript chains
@@ -1173,18 +749,18 @@ module ActionView
1173
749
 
1174
750
  class JavaScriptVariableProxy < JavaScriptProxy #:nodoc:
1175
751
  def initialize(generator, variable)
1176
- @variable = variable
752
+ @variable = ::ActiveSupport::JSON::Variable.new(variable)
1177
753
  @empty = true # only record lines if we have to. gets rid of unnecessary linebreaks
1178
754
  super(generator)
1179
755
  end
1180
756
 
1181
757
  # The JSON Encoder calls this to check for the +to_json+ method
1182
758
  # Since it's a blank slate object, I suppose it responds to anything.
1183
- def respond_to?(method)
759
+ def respond_to?(*)
1184
760
  true
1185
761
  end
1186
762
 
1187
- def to_json(options = nil)
763
+ def as_json(options = nil)
1188
764
  @variable
1189
765
  end
1190
766