actionpack 3.2.19 → 4.2.11.3

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 (244) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +412 -503
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +11 -294
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +52 -18
  7. data/lib/abstract_controller/callbacks.rb +87 -89
  8. data/lib/abstract_controller/collector.rb +17 -3
  9. data/lib/abstract_controller/helpers.rb +41 -14
  10. data/lib/abstract_controller/logger.rb +1 -2
  11. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  12. data/lib/abstract_controller/rendering.rb +65 -118
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +7 -7
  15. data/lib/abstract_controller.rb +2 -10
  16. data/lib/action_controller/base.rb +61 -28
  17. data/lib/action_controller/caching/fragments.rb +30 -54
  18. data/lib/action_controller/caching.rb +38 -35
  19. data/lib/action_controller/log_subscriber.rb +35 -18
  20. data/lib/action_controller/metal/conditional_get.rb +103 -34
  21. data/lib/action_controller/metal/data_streaming.rb +20 -26
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  23. data/lib/action_controller/metal/exceptions.rb +19 -6
  24. data/lib/action_controller/metal/flash.rb +41 -9
  25. data/lib/action_controller/metal/force_ssl.rb +70 -12
  26. data/lib/action_controller/metal/head.rb +30 -7
  27. data/lib/action_controller/metal/helpers.rb +11 -11
  28. data/lib/action_controller/metal/hide_actions.rb +0 -1
  29. data/lib/action_controller/metal/http_authentication.rb +140 -94
  30. data/lib/action_controller/metal/implicit_render.rb +1 -1
  31. data/lib/action_controller/metal/instrumentation.rb +11 -7
  32. data/lib/action_controller/metal/live.rb +328 -0
  33. data/lib/action_controller/metal/mime_responds.rb +161 -152
  34. data/lib/action_controller/metal/params_wrapper.rb +126 -81
  35. data/lib/action_controller/metal/rack_delegation.rb +10 -4
  36. data/lib/action_controller/metal/redirecting.rb +44 -41
  37. data/lib/action_controller/metal/renderers.rb +48 -19
  38. data/lib/action_controller/metal/rendering.rb +46 -11
  39. data/lib/action_controller/metal/request_forgery_protection.rb +250 -29
  40. data/lib/action_controller/metal/streaming.rb +30 -38
  41. data/lib/action_controller/metal/strong_parameters.rb +669 -0
  42. data/lib/action_controller/metal/testing.rb +12 -18
  43. data/lib/action_controller/metal/url_for.rb +31 -29
  44. data/lib/action_controller/metal.rb +31 -40
  45. data/lib/action_controller/model_naming.rb +12 -0
  46. data/lib/action_controller/railtie.rb +38 -18
  47. data/lib/action_controller/railties/helpers.rb +22 -0
  48. data/lib/action_controller/test_case.rb +359 -173
  49. data/lib/action_controller.rb +9 -16
  50. data/lib/action_dispatch/http/cache.rb +64 -11
  51. data/lib/action_dispatch/http/filter_parameters.rb +20 -10
  52. data/lib/action_dispatch/http/filter_redirect.rb +38 -0
  53. data/lib/action_dispatch/http/headers.rb +85 -17
  54. data/lib/action_dispatch/http/mime_negotiation.rb +55 -5
  55. data/lib/action_dispatch/http/mime_type.rb +167 -114
  56. data/lib/action_dispatch/http/mime_types.rb +2 -1
  57. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  58. data/lib/action_dispatch/http/parameters.rb +30 -46
  59. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  60. data/lib/action_dispatch/http/request.rb +108 -45
  61. data/lib/action_dispatch/http/response.rb +247 -48
  62. data/lib/action_dispatch/http/upload.rb +60 -29
  63. data/lib/action_dispatch/http/url.rb +135 -45
  64. data/lib/action_dispatch/journey/backwards.rb +5 -0
  65. data/lib/action_dispatch/journey/formatter.rb +166 -0
  66. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  67. data/lib/action_dispatch/journey/gtg/simulator.rb +47 -0
  68. data/lib/action_dispatch/journey/gtg/transition_table.rb +157 -0
  69. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  70. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  71. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  72. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  73. data/lib/action_dispatch/journey/nodes/node.rb +128 -0
  74. data/lib/action_dispatch/journey/parser.rb +198 -0
  75. data/lib/action_dispatch/journey/parser.y +49 -0
  76. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  77. data/lib/action_dispatch/journey/path/pattern.rb +193 -0
  78. data/lib/action_dispatch/journey/route.rb +125 -0
  79. data/lib/action_dispatch/journey/router/strexp.rb +27 -0
  80. data/lib/action_dispatch/journey/router/utils.rb +93 -0
  81. data/lib/action_dispatch/journey/router.rb +144 -0
  82. data/lib/action_dispatch/journey/routes.rb +80 -0
  83. data/lib/action_dispatch/journey/scanner.rb +61 -0
  84. data/lib/action_dispatch/journey/visitors.rb +221 -0
  85. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  86. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  87. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  88. data/lib/action_dispatch/journey.rb +5 -0
  89. data/lib/action_dispatch/middleware/callbacks.rb +16 -11
  90. data/lib/action_dispatch/middleware/cookies.rb +346 -125
  91. data/lib/action_dispatch/middleware/debug_exceptions.rb +52 -24
  92. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -9
  93. data/lib/action_dispatch/middleware/flash.rb +85 -72
  94. data/lib/action_dispatch/middleware/params_parser.rb +16 -31
  95. data/lib/action_dispatch/middleware/public_exceptions.rb +39 -14
  96. data/lib/action_dispatch/middleware/reloader.rb +16 -7
  97. data/lib/action_dispatch/middleware/remote_ip.rb +132 -40
  98. data/lib/action_dispatch/middleware/request_id.rb +3 -7
  99. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  100. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  101. data/lib/action_dispatch/middleware/session/cookie_store.rb +84 -29
  102. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  103. data/lib/action_dispatch/middleware/show_exceptions.rb +15 -44
  104. data/lib/action_dispatch/middleware/ssl.rb +72 -0
  105. data/lib/action_dispatch/middleware/stack.rb +6 -1
  106. data/lib/action_dispatch/middleware/static.rb +80 -23
  107. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +34 -0
  108. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  109. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +27 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  114. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +133 -5
  115. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  125. data/lib/action_dispatch/railtie.rb +19 -6
  126. data/lib/action_dispatch/request/session.rb +193 -0
  127. data/lib/action_dispatch/request/utils.rb +35 -0
  128. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  129. data/lib/action_dispatch/routing/inspector.rb +234 -0
  130. data/lib/action_dispatch/routing/mapper.rb +897 -436
  131. data/lib/action_dispatch/routing/polymorphic_routes.rb +213 -92
  132. data/lib/action_dispatch/routing/redirection.rb +97 -37
  133. data/lib/action_dispatch/routing/route_set.rb +432 -239
  134. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  135. data/lib/action_dispatch/routing/url_for.rb +63 -34
  136. data/lib/action_dispatch/routing.rb +57 -89
  137. data/lib/action_dispatch/testing/assertions/dom.rb +2 -36
  138. data/lib/action_dispatch/testing/assertions/response.rb +24 -38
  139. data/lib/action_dispatch/testing/assertions/routing.rb +55 -54
  140. data/lib/action_dispatch/testing/assertions/selector.rb +2 -434
  141. data/lib/action_dispatch/testing/assertions/tag.rb +2 -137
  142. data/lib/action_dispatch/testing/assertions.rb +11 -7
  143. data/lib/action_dispatch/testing/integration.rb +88 -72
  144. data/lib/action_dispatch/testing/test_process.rb +9 -6
  145. data/lib/action_dispatch/testing/test_request.rb +13 -9
  146. data/lib/action_dispatch/testing/test_response.rb +1 -5
  147. data/lib/action_dispatch.rb +24 -21
  148. data/lib/action_pack/gem_version.rb +15 -0
  149. data/lib/action_pack/version.rb +5 -7
  150. data/lib/action_pack.rb +1 -1
  151. metadata +181 -292
  152. data/lib/abstract_controller/layouts.rb +0 -423
  153. data/lib/abstract_controller/view_paths.rb +0 -96
  154. data/lib/action_controller/caching/actions.rb +0 -185
  155. data/lib/action_controller/caching/pages.rb +0 -187
  156. data/lib/action_controller/caching/sweeping.rb +0 -97
  157. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  158. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  159. data/lib/action_controller/deprecated.rb +0 -3
  160. data/lib/action_controller/metal/compatibility.rb +0 -65
  161. data/lib/action_controller/metal/responder.rb +0 -286
  162. data/lib/action_controller/metal/session_management.rb +0 -14
  163. data/lib/action_controller/railties/paths.rb +0 -25
  164. data/lib/action_controller/record_identifier.rb +0 -85
  165. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  166. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  167. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  168. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  169. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  170. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  171. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  172. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  173. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  174. data/lib/action_dispatch/middleware/head.rb +0 -18
  175. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  176. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  177. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  178. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  179. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  180. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  181. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  182. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  183. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  184. data/lib/action_view/asset_paths.rb +0 -142
  185. data/lib/action_view/base.rb +0 -220
  186. data/lib/action_view/buffers.rb +0 -43
  187. data/lib/action_view/context.rb +0 -36
  188. data/lib/action_view/flows.rb +0 -79
  189. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  190. data/lib/action_view/helpers/asset_paths.rb +0 -7
  191. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  192. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  193. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  194. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  195. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  196. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  197. data/lib/action_view/helpers/cache_helper.rb +0 -64
  198. data/lib/action_view/helpers/capture_helper.rb +0 -203
  199. data/lib/action_view/helpers/controller_helper.rb +0 -25
  200. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  201. data/lib/action_view/helpers/date_helper.rb +0 -1062
  202. data/lib/action_view/helpers/debug_helper.rb +0 -40
  203. data/lib/action_view/helpers/form_helper.rb +0 -1486
  204. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  205. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  206. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  207. data/lib/action_view/helpers/number_helper.rb +0 -622
  208. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  209. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  210. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  211. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  212. data/lib/action_view/helpers/tag_helper.rb +0 -160
  213. data/lib/action_view/helpers/text_helper.rb +0 -426
  214. data/lib/action_view/helpers/translation_helper.rb +0 -91
  215. data/lib/action_view/helpers/url_helper.rb +0 -693
  216. data/lib/action_view/helpers.rb +0 -60
  217. data/lib/action_view/locale/en.yml +0 -160
  218. data/lib/action_view/log_subscriber.rb +0 -28
  219. data/lib/action_view/lookup_context.rb +0 -254
  220. data/lib/action_view/path_set.rb +0 -89
  221. data/lib/action_view/railtie.rb +0 -55
  222. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  223. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  224. data/lib/action_view/renderer/renderer.rb +0 -54
  225. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  226. data/lib/action_view/renderer/template_renderer.rb +0 -94
  227. data/lib/action_view/template/error.rb +0 -128
  228. data/lib/action_view/template/handlers/builder.rb +0 -26
  229. data/lib/action_view/template/handlers/erb.rb +0 -125
  230. data/lib/action_view/template/handlers.rb +0 -50
  231. data/lib/action_view/template/resolver.rb +0 -272
  232. data/lib/action_view/template/text.rb +0 -30
  233. data/lib/action_view/template.rb +0 -337
  234. data/lib/action_view/test_case.rb +0 -245
  235. data/lib/action_view/testing/resolvers.rb +0 -50
  236. data/lib/action_view.rb +0 -84
  237. data/lib/sprockets/assets.rake +0 -99
  238. data/lib/sprockets/bootstrap.rb +0 -37
  239. data/lib/sprockets/compressors.rb +0 -83
  240. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  241. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  242. data/lib/sprockets/helpers.rb +0 -6
  243. data/lib/sprockets/railtie.rb +0 -62
  244. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,685 +0,0 @@
1
- require 'cgi'
2
- require 'action_view/helpers/tag_helper'
3
- require 'active_support/core_ext/object/blank'
4
- require 'active_support/core_ext/string/output_safety'
5
- require 'active_support/core_ext/module/attribute_accessors'
6
-
7
- module ActionView
8
- # = Action View Form Tag Helpers
9
- module Helpers
10
- # Provides a number of methods for creating form tags that doesn't rely on an Active Record object assigned to the template like
11
- # FormHelper does. Instead, you provide the names and values manually.
12
- #
13
- # NOTE: The HTML options <tt>disabled</tt>, <tt>readonly</tt>, and <tt>multiple</tt> can all be treated as booleans. So specifying
14
- # <tt>:disabled => true</tt> will give <tt>disabled="disabled"</tt>.
15
- module FormTagHelper
16
- extend ActiveSupport::Concern
17
-
18
- include UrlHelper
19
- include TextHelper
20
-
21
- mattr_accessor :embed_authenticity_token_in_remote_forms
22
- self.embed_authenticity_token_in_remote_forms = true
23
-
24
- # Starts a form tag that points the action to an url configured with <tt>url_for_options</tt> just like
25
- # ActionController::Base#url_for. The method for the form defaults to POST.
26
- #
27
- # ==== Options
28
- # * <tt>:multipart</tt> - If set to true, the enctype is set to "multipart/form-data".
29
- # * <tt>:method</tt> - The method to use when submitting the form, usually either "get" or "post".
30
- # If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
31
- # is added to simulate the verb over post.
32
- # * <tt>:authenticity_token</tt> - Authenticity token to use in the form. Use only if you need to
33
- # pass custom authenticity token string, or to not add authenticity_token field at all
34
- # (by passing <tt>false</tt>). Remote forms may omit the embedded authenticity token
35
- # by setting <tt>config.action_view.embed_authenticity_token_in_remote_forms = false</tt>.
36
- # This is helpful when you're fragment-caching the form. Remote forms get the
37
- # authenticity from the <tt>meta</tt> tag, so embedding is unnecessary unless you
38
- # support browsers without JavaScript.
39
- # * A list of parameters to feed to the URL the form will be posted to.
40
- # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
41
- # submit behavior. By default this behavior is an ajax submit.
42
- #
43
- # ==== Examples
44
- # form_tag('/posts')
45
- # # => <form action="/posts" method="post">
46
- #
47
- # form_tag('/posts/1', :method => :put)
48
- # # => <form action="/posts/1" method="post"> ... <input name="_method" type="hidden" value="put" /> ...
49
- #
50
- # form_tag('/upload', :multipart => true)
51
- # # => <form action="/upload" method="post" enctype="multipart/form-data">
52
- #
53
- # <%= form_tag('/posts') do -%>
54
- # <div><%= submit_tag 'Save' %></div>
55
- # <% end -%>
56
- # # => <form action="/posts" method="post"><div><input type="submit" name="commit" value="Save" /></div></form>
57
- #
58
- # <%= form_tag('/posts', :remote => true) %>
59
- # # => <form action="/posts" method="post" data-remote="true">
60
- #
61
- # form_tag('http://far.away.com/form', :authenticity_token => false)
62
- # # form without authenticity token
63
- #
64
- # form_tag('http://far.away.com/form', :authenticity_token => "cf50faa3fe97702ca1ae")
65
- # # form with custom authenticity token
66
- #
67
- def form_tag(url_for_options = {}, options = {}, &block)
68
- html_options = html_options_for_form(url_for_options, options)
69
- if block_given?
70
- form_tag_in_block(html_options, &block)
71
- else
72
- form_tag_html(html_options)
73
- end
74
- end
75
-
76
- # Creates a dropdown selection box, or if the <tt>:multiple</tt> option is set to true, a multiple
77
- # choice selection box.
78
- #
79
- # Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or
80
- # associated records. <tt>option_tags</tt> is a string containing the option tags for the select box.
81
- #
82
- # ==== Options
83
- # * <tt>:multiple</tt> - If set to true the selection will allow multiple choices.
84
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
85
- # * <tt>:include_blank</tt> - If set to true, an empty option will be create
86
- # * <tt>:prompt</tt> - Create a prompt option with blank value and the text asking user to select something
87
- # * Any other key creates standard HTML attributes for the tag.
88
- #
89
- # ==== Examples
90
- # select_tag "people", options_from_collection_for_select(@people, "id", "name")
91
- # # <select id="people" name="people"><option value="1">David</option></select>
92
- #
93
- # select_tag "people", "<option>David</option>".html_safe
94
- # # => <select id="people" name="people"><option>David</option></select>
95
- #
96
- # select_tag "count", "<option>1</option><option>2</option><option>3</option><option>4</option>".html_safe
97
- # # => <select id="count" name="count"><option>1</option><option>2</option>
98
- # # <option>3</option><option>4</option></select>
99
- #
100
- # select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>".html_safe, :multiple => true
101
- # # => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
102
- # # <option>Green</option><option>Blue</option></select>
103
- #
104
- # select_tag "locations", "<option>Home</option><option selected="selected">Work</option><option>Out</option>".html_safe
105
- # # => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
106
- # # <option>Out</option></select>
107
- #
108
- # select_tag "access", "<option>Read</option><option>Write</option>".html_safe, :multiple => true, :class => 'form_input'
109
- # # => <select class="form_input" id="access" multiple="multiple" name="access[]"><option>Read</option>
110
- # # <option>Write</option></select>
111
- #
112
- # select_tag "people", options_from_collection_for_select(@people, "id", "name"), :include_blank => true
113
- # # => <select id="people" name="people"><option value=""></option><option value="1">David</option></select>
114
- #
115
- # select_tag "people", options_from_collection_for_select(@people, "id", "name"), :prompt => "Select something"
116
- # # => <select id="people" name="people"><option value="">Select something</option><option value="1">David</option></select>
117
- #
118
- # select_tag "destination", "<option>NYC</option><option>Paris</option><option>Rome</option>".html_safe, :disabled => true
119
- # # => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
120
- # # <option>Paris</option><option>Rome</option></select>
121
- def select_tag(name, option_tags = nil, options = {})
122
- option_tags ||= ""
123
- html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
124
-
125
- if options.delete(:include_blank)
126
- option_tags = content_tag(:option, '', :value => '').safe_concat(option_tags)
127
- end
128
-
129
- if prompt = options.delete(:prompt)
130
- option_tags = content_tag(:option, prompt, :value => '').safe_concat(option_tags)
131
- end
132
-
133
- content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
134
- end
135
-
136
- # Creates a standard text field; use these text fields to input smaller chunks of text like a username
137
- # or a search query.
138
- #
139
- # ==== Options
140
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
141
- # * <tt>:size</tt> - The number of visible characters that will fit in the input.
142
- # * <tt>:maxlength</tt> - The maximum number of characters that the browser will allow the user to enter.
143
- # * <tt>:placeholder</tt> - The text contained in the field by default which is removed when the field receives focus.
144
- # * Any other key creates standard HTML attributes for the tag.
145
- #
146
- # ==== Examples
147
- # text_field_tag 'name'
148
- # # => <input id="name" name="name" type="text" />
149
- #
150
- # text_field_tag 'query', 'Enter your search query here'
151
- # # => <input id="query" name="query" type="text" value="Enter your search query here" />
152
- #
153
- # text_field_tag 'search', nil, :placeholder => 'Enter search term...'
154
- # # => <input id="search" name="search" placeholder="Enter search term..." type="text" />
155
- #
156
- # text_field_tag 'request', nil, :class => 'special_input'
157
- # # => <input class="special_input" id="request" name="request" type="text" />
158
- #
159
- # text_field_tag 'address', '', :size => 75
160
- # # => <input id="address" name="address" size="75" type="text" value="" />
161
- #
162
- # text_field_tag 'zip', nil, :maxlength => 5
163
- # # => <input id="zip" maxlength="5" name="zip" type="text" />
164
- #
165
- # text_field_tag 'payment_amount', '$0.00', :disabled => true
166
- # # => <input disabled="disabled" id="payment_amount" name="payment_amount" type="text" value="$0.00" />
167
- #
168
- # text_field_tag 'ip', '0.0.0.0', :maxlength => 15, :size => 20, :class => "ip-input"
169
- # # => <input class="ip-input" id="ip" maxlength="15" name="ip" size="20" type="text" value="0.0.0.0" />
170
- def text_field_tag(name, value = nil, options = {})
171
- tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
172
- end
173
-
174
- # Creates a label element. Accepts a block.
175
- #
176
- # ==== Options
177
- # * Creates standard HTML attributes for the tag.
178
- #
179
- # ==== Examples
180
- # label_tag 'name'
181
- # # => <label for="name">Name</label>
182
- #
183
- # label_tag 'name', 'Your name'
184
- # # => <label for="name">Your name</label>
185
- #
186
- # label_tag 'name', nil, :class => 'small_label'
187
- # # => <label for="name" class="small_label">Name</label>
188
- def label_tag(name = nil, content_or_options = nil, options = nil, &block)
189
- if block_given? && content_or_options.is_a?(Hash)
190
- options = content_or_options = content_or_options.stringify_keys
191
- else
192
- options ||= {}
193
- options = options.stringify_keys
194
- end
195
- options["for"] = sanitize_to_id(name) unless name.blank? || options.has_key?("for")
196
- content_tag :label, content_or_options || name.to_s.humanize, options, &block
197
- end
198
-
199
- # Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or
200
- # data that should be hidden from the user.
201
- #
202
- # ==== Options
203
- # * Creates standard HTML attributes for the tag.
204
- #
205
- # ==== Examples
206
- # hidden_field_tag 'tags_list'
207
- # # => <input id="tags_list" name="tags_list" type="hidden" />
208
- #
209
- # hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
210
- # # => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
211
- #
212
- # hidden_field_tag 'collected_input', '', :onchange => "alert('Input collected!')"
213
- # # => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
214
- # # type="hidden" value="" />
215
- def hidden_field_tag(name, value = nil, options = {})
216
- text_field_tag(name, value, options.stringify_keys.update("type" => "hidden"))
217
- end
218
-
219
- # Creates a file upload field. If you are using file uploads then you will also need
220
- # to set the multipart option for the form tag:
221
- #
222
- # <%= form_tag '/upload', :multipart => true do %>
223
- # <label for="file">File to Upload</label> <%= file_field_tag "file" %>
224
- # <%= submit_tag %>
225
- # <% end %>
226
- #
227
- # The specified URL will then be passed a File object containing the selected file, or if the field
228
- # was left blank, a StringIO object.
229
- #
230
- # ==== Options
231
- # * Creates standard HTML attributes for the tag.
232
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
233
- #
234
- # ==== Examples
235
- # file_field_tag 'attachment'
236
- # # => <input id="attachment" name="attachment" type="file" />
237
- #
238
- # file_field_tag 'avatar', :class => 'profile_input'
239
- # # => <input class="profile_input" id="avatar" name="avatar" type="file" />
240
- #
241
- # file_field_tag 'picture', :disabled => true
242
- # # => <input disabled="disabled" id="picture" name="picture" type="file" />
243
- #
244
- # file_field_tag 'resume', :value => '~/resume.doc'
245
- # # => <input id="resume" name="resume" type="file" value="~/resume.doc" />
246
- #
247
- # file_field_tag 'user_pic', :accept => 'image/png,image/gif,image/jpeg'
248
- # # => <input accept="image/png,image/gif,image/jpeg" id="user_pic" name="user_pic" type="file" />
249
- #
250
- # file_field_tag 'file', :accept => 'text/html', :class => 'upload', :value => 'index.html'
251
- # # => <input accept="text/html" class="upload" id="file" name="file" type="file" value="index.html" />
252
- def file_field_tag(name, options = {})
253
- text_field_tag(name, nil, options.update("type" => "file"))
254
- end
255
-
256
- # Creates a password field, a masked text field that will hide the users input behind a mask character.
257
- #
258
- # ==== Options
259
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
260
- # * <tt>:size</tt> - The number of visible characters that will fit in the input.
261
- # * <tt>:maxlength</tt> - The maximum number of characters that the browser will allow the user to enter.
262
- # * Any other key creates standard HTML attributes for the tag.
263
- #
264
- # ==== Examples
265
- # password_field_tag 'pass'
266
- # # => <input id="pass" name="pass" type="password" />
267
- #
268
- # password_field_tag 'secret', 'Your secret here'
269
- # # => <input id="secret" name="secret" type="password" value="Your secret here" />
270
- #
271
- # password_field_tag 'masked', nil, :class => 'masked_input_field'
272
- # # => <input class="masked_input_field" id="masked" name="masked" type="password" />
273
- #
274
- # password_field_tag 'token', '', :size => 15
275
- # # => <input id="token" name="token" size="15" type="password" value="" />
276
- #
277
- # password_field_tag 'key', nil, :maxlength => 16
278
- # # => <input id="key" maxlength="16" name="key" type="password" />
279
- #
280
- # password_field_tag 'confirm_pass', nil, :disabled => true
281
- # # => <input disabled="disabled" id="confirm_pass" name="confirm_pass" type="password" />
282
- #
283
- # password_field_tag 'pin', '1234', :maxlength => 4, :size => 6, :class => "pin_input"
284
- # # => <input class="pin_input" id="pin" maxlength="4" name="pin" size="6" type="password" value="1234" />
285
- def password_field_tag(name = "password", value = nil, options = {})
286
- text_field_tag(name, value, options.update("type" => "password"))
287
- end
288
-
289
- # Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions.
290
- #
291
- # ==== Options
292
- # * <tt>:size</tt> - A string specifying the dimensions (columns by rows) of the textarea (e.g., "25x10").
293
- # * <tt>:rows</tt> - Specify the number of rows in the textarea
294
- # * <tt>:cols</tt> - Specify the number of columns in the textarea
295
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
296
- # * <tt>:escape</tt> - By default, the contents of the text input are HTML escaped.
297
- # If you need unescaped contents, set this to false.
298
- # * Any other key creates standard HTML attributes for the tag.
299
- #
300
- # ==== Examples
301
- # text_area_tag 'post'
302
- # # => <textarea id="post" name="post"></textarea>
303
- #
304
- # text_area_tag 'bio', @user.bio
305
- # # => <textarea id="bio" name="bio">This is my biography.</textarea>
306
- #
307
- # text_area_tag 'body', nil, :rows => 10, :cols => 25
308
- # # => <textarea cols="25" id="body" name="body" rows="10"></textarea>
309
- #
310
- # text_area_tag 'body', nil, :size => "25x10"
311
- # # => <textarea name="body" id="body" cols="25" rows="10"></textarea>
312
- #
313
- # text_area_tag 'description', "Description goes here.", :disabled => true
314
- # # => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>
315
- #
316
- # text_area_tag 'comment', nil, :class => 'comment_input'
317
- # # => <textarea class="comment_input" id="comment" name="comment"></textarea>
318
- def text_area_tag(name, content = nil, options = {})
319
- options = options.stringify_keys
320
-
321
- if size = options.delete("size")
322
- options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
323
- end
324
-
325
- escape = options.key?("escape") ? options.delete("escape") : true
326
- content = ERB::Util.html_escape(content) if escape
327
-
328
- content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
329
- end
330
-
331
- # Creates a check box form input tag.
332
- #
333
- # ==== Options
334
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
335
- # * Any other key creates standard HTML options for the tag.
336
- #
337
- # ==== Examples
338
- # check_box_tag 'accept'
339
- # # => <input id="accept" name="accept" type="checkbox" value="1" />
340
- #
341
- # check_box_tag 'rock', 'rock music'
342
- # # => <input id="rock" name="rock" type="checkbox" value="rock music" />
343
- #
344
- # check_box_tag 'receive_email', 'yes', true
345
- # # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />
346
- #
347
- # check_box_tag 'tos', 'yes', false, :class => 'accept_tos'
348
- # # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />
349
- #
350
- # check_box_tag 'eula', 'accepted', false, :disabled => true
351
- # # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
352
- def check_box_tag(name, value = "1", checked = false, options = {})
353
- html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
354
- html_options["checked"] = "checked" if checked
355
- tag :input, html_options
356
- end
357
-
358
- # Creates a radio button; use groups of radio buttons named the same to allow users to
359
- # select from a group of options.
360
- #
361
- # ==== Options
362
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
363
- # * Any other key creates standard HTML options for the tag.
364
- #
365
- # ==== Examples
366
- # radio_button_tag 'gender', 'male'
367
- # # => <input id="gender_male" name="gender" type="radio" value="male" />
368
- #
369
- # radio_button_tag 'receive_updates', 'no', true
370
- # # => <input checked="checked" id="receive_updates_no" name="receive_updates" type="radio" value="no" />
371
- #
372
- # radio_button_tag 'time_slot', "3:00 p.m.", false, :disabled => true
373
- # # => <input disabled="disabled" id="time_slot_300_pm" name="time_slot" type="radio" value="3:00 p.m." />
374
- #
375
- # radio_button_tag 'color', "green", true, :class => "color_input"
376
- # # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
377
- def radio_button_tag(name, value, checked = false, options = {})
378
- html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
379
- html_options["checked"] = "checked" if checked
380
- tag :input, html_options
381
- end
382
-
383
- # Creates a submit button with the text <tt>value</tt> as the caption.
384
- #
385
- # ==== Options
386
- # * <tt>:confirm => 'question?'</tt> - If present the unobtrusive JavaScript
387
- # drivers will provide a prompt with the question specified. If the user accepts,
388
- # the form is processed normally, otherwise no action is taken.
389
- # * <tt>:disabled</tt> - If true, the user will not be able to use this input.
390
- # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
391
- # disabled version of the submit button when the form is submitted. This feature is
392
- # provided by the unobtrusive JavaScript driver.
393
- # * Any other key creates standard HTML options for the tag.
394
- #
395
- # ==== Examples
396
- # submit_tag
397
- # # => <input name="commit" type="submit" value="Save changes" />
398
- #
399
- # submit_tag "Edit this article"
400
- # # => <input name="commit" type="submit" value="Edit this article" />
401
- #
402
- # submit_tag "Save edits", :disabled => true
403
- # # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
404
- #
405
- # submit_tag "Complete sale", :disable_with => "Please wait..."
406
- # # => <input name="commit" data-disable-with="Please wait..." type="submit" value="Complete sale" />
407
- #
408
- # submit_tag nil, :class => "form_submit"
409
- # # => <input class="form_submit" name="commit" type="submit" />
410
- #
411
- # submit_tag "Edit", :disable_with => "Editing...", :class => "edit_button"
412
- # # => <input class="edit_button" data-disable_with="Editing..." name="commit" type="submit" value="Edit" />
413
- #
414
- # submit_tag "Save", :confirm => "Are you sure?"
415
- # # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />
416
- #
417
- def submit_tag(value = "Save changes", options = {})
418
- options = options.stringify_keys
419
-
420
- if disable_with = options.delete("disable_with")
421
- options["data-disable-with"] = disable_with
422
- end
423
-
424
- if confirm = options.delete("confirm")
425
- options["data-confirm"] = confirm
426
- end
427
-
428
- tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options)
429
- end
430
-
431
- # Creates a button element that defines a <tt>submit</tt> button,
432
- # <tt>reset</tt>button or a generic button which can be used in
433
- # JavaScript, for example. You can use the button tag as a regular
434
- # submit tag but it isn't supported in legacy browsers. However,
435
- # the button tag allows richer labels such as images and emphasis,
436
- # so this helper will also accept a block.
437
- #
438
- # ==== Options
439
- # * <tt>:confirm => 'question?'</tt> - If present, the
440
- # unobtrusive JavaScript drivers will provide a prompt with
441
- # the question specified. If the user accepts, the form is
442
- # processed normally, otherwise no action is taken.
443
- # * <tt>:disabled</tt> - If true, the user will not be able to
444
- # use this input.
445
- # * <tt>:disable_with</tt> - Value of this parameter will be
446
- # used as the value for a disabled version of the submit
447
- # button when the form is submitted. This feature is provided
448
- # by the unobtrusive JavaScript driver.
449
- # * Any other key creates standard HTML options for the tag.
450
- #
451
- # ==== Examples
452
- # button_tag
453
- # # => <button name="button" type="submit">Button</button>
454
- #
455
- # button_tag(:type => 'button') do
456
- # content_tag(:strong, 'Ask me!')
457
- # end
458
- # # => <button name="button" type="button">
459
- # # <strong>Ask me!</strong>
460
- # # </button>
461
- #
462
- # button_tag "Checkout", :disable_with => "Please wait..."
463
- # # => <button data-disable-with="Please wait..." name="button" type="submit">Checkout</button>
464
- #
465
- def button_tag(content_or_options = nil, options = nil, &block)
466
- options = content_or_options if block_given? && content_or_options.is_a?(Hash)
467
- options ||= {}
468
- options = options.stringify_keys
469
-
470
- if disable_with = options.delete("disable_with")
471
- options["data-disable-with"] = disable_with
472
- end
473
-
474
- if confirm = options.delete("confirm")
475
- options["data-confirm"] = confirm
476
- end
477
-
478
- options.reverse_merge! 'name' => 'button', 'type' => 'submit'
479
-
480
- content_tag :button, content_or_options || 'Button', options, &block
481
- end
482
-
483
- # Displays an image which when clicked will submit the form.
484
- #
485
- # <tt>source</tt> is passed to AssetTagHelper#path_to_image
486
- #
487
- # ==== Options
488
- # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
489
- # prompt with the question specified. If the user accepts, the form is
490
- # processed normally, otherwise no action is taken.
491
- # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
492
- # * Any other key creates standard HTML options for the tag.
493
- #
494
- # ==== Examples
495
- # image_submit_tag("login.png")
496
- # # => <input src="/images/login.png" type="image" />
497
- #
498
- # image_submit_tag("purchase.png", :disabled => true)
499
- # # => <input disabled="disabled" src="/images/purchase.png" type="image" />
500
- #
501
- # image_submit_tag("search.png", :class => 'search_button')
502
- # # => <input class="search_button" src="/images/search.png" type="image" />
503
- #
504
- # image_submit_tag("agree.png", :disabled => true, :class => "agree_disagree_button")
505
- # # => <input class="agree_disagree_button" disabled="disabled" src="/images/agree.png" type="image" />
506
- def image_submit_tag(source, options = {})
507
- options = options.stringify_keys
508
-
509
- if confirm = options.delete("confirm")
510
- options["data-confirm"] = confirm
511
- end
512
-
513
- tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options)
514
- end
515
-
516
- # Creates a field set for grouping HTML form elements.
517
- #
518
- # <tt>legend</tt> will become the fieldset's title (optional as per W3C).
519
- # <tt>options</tt> accept the same values as tag.
520
- #
521
- # ==== Examples
522
- # <%= field_set_tag do %>
523
- # <p><%= text_field_tag 'name' %></p>
524
- # <% end %>
525
- # # => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
526
- #
527
- # <%= field_set_tag 'Your details' do %>
528
- # <p><%= text_field_tag 'name' %></p>
529
- # <% end %>
530
- # # => <fieldset><legend>Your details</legend><p><input id="name" name="name" type="text" /></p></fieldset>
531
- #
532
- # <%= field_set_tag nil, :class => 'format' do %>
533
- # <p><%= text_field_tag 'name' %></p>
534
- # <% end %>
535
- # # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset>
536
- def field_set_tag(legend = nil, options = nil, &block)
537
- content = capture(&block)
538
- output = tag(:fieldset, options, true)
539
- output.safe_concat(content_tag(:legend, legend)) unless legend.blank?
540
- output.concat(content)
541
- output.safe_concat("</fieldset>")
542
- end
543
-
544
- # Creates a text field of type "search".
545
- #
546
- # ==== Options
547
- # * Accepts the same options as text_field_tag.
548
- def search_field_tag(name, value = nil, options = {})
549
- text_field_tag(name, value, options.stringify_keys.update("type" => "search"))
550
- end
551
-
552
- # Creates a text field of type "tel".
553
- #
554
- # ==== Options
555
- # * Accepts the same options as text_field_tag.
556
- def telephone_field_tag(name, value = nil, options = {})
557
- text_field_tag(name, value, options.stringify_keys.update("type" => "tel"))
558
- end
559
- alias phone_field_tag telephone_field_tag
560
-
561
- # Creates a text field of type "url".
562
- #
563
- # ==== Options
564
- # * Accepts the same options as text_field_tag.
565
- def url_field_tag(name, value = nil, options = {})
566
- text_field_tag(name, value, options.stringify_keys.update("type" => "url"))
567
- end
568
-
569
- # Creates a text field of type "email".
570
- #
571
- # ==== Options
572
- # * Accepts the same options as text_field_tag.
573
- def email_field_tag(name, value = nil, options = {})
574
- text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
575
- end
576
-
577
- # Creates a number field.
578
- #
579
- # ==== Options
580
- # * <tt>:min</tt> - The minimum acceptable value.
581
- # * <tt>:max</tt> - The maximum acceptable value.
582
- # * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
583
- # <tt>:max</tt> values.
584
- # * <tt>:step</tt> - The acceptable value granularity.
585
- # * Otherwise accepts the same options as text_field_tag.
586
- #
587
- # ==== Examples
588
- # number_field_tag 'quantity', nil, :in => 1...10
589
- # # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
590
- def number_field_tag(name, value = nil, options = {})
591
- options = options.stringify_keys
592
- options["type"] ||= "number"
593
- if range = options.delete("in") || options.delete("within")
594
- options.update("min" => range.min, "max" => range.max)
595
- end
596
- text_field_tag(name, value, options)
597
- end
598
-
599
- # Creates a range form element.
600
- #
601
- # ==== Options
602
- # * Accepts the same options as number_field_tag.
603
- def range_field_tag(name, value = nil, options = {})
604
- number_field_tag(name, value, options.stringify_keys.update("type" => "range"))
605
- end
606
-
607
- # Creates the hidden UTF8 enforcer tag. Override this method in a helper
608
- # to customize the tag.
609
- def utf8_enforcer_tag
610
- tag(:input, :type => "hidden", :name => "utf8", :value => "&#x2713;".html_safe)
611
- end
612
-
613
- private
614
- def html_options_for_form(url_for_options, options)
615
- options.stringify_keys.tap do |html_options|
616
- html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
617
- # The following URL is unescaped, this is just a hash of options, and it is the
618
- # responsibility of the caller to escape all the values.
619
- html_options["action"] = url_for(url_for_options)
620
- html_options["accept-charset"] = "UTF-8"
621
-
622
- html_options["data-remote"] = true if html_options.delete("remote")
623
-
624
- if html_options["data-remote"] &&
625
- !embed_authenticity_token_in_remote_forms &&
626
- html_options["authenticity_token"].blank?
627
- # The authenticity token is taken from the meta tag in this case
628
- html_options["authenticity_token"] = false
629
- elsif html_options["authenticity_token"] == true
630
- # Include the default authenticity_token, which is only generated when its set to nil,
631
- # but we needed the true value to override the default of no authenticity_token on data-remote.
632
- html_options["authenticity_token"] = nil
633
- end
634
- end
635
- end
636
-
637
- def extra_tags_for_form(html_options)
638
- authenticity_token = html_options.delete("authenticity_token")
639
- method = html_options.delete("method").to_s
640
-
641
- method_tag = case method
642
- when /^get$/i # must be case-insensitive, but can't use downcase as might be nil
643
- html_options["method"] = "get"
644
- ''
645
- when /^post$/i, "", nil
646
- html_options["method"] = "post"
647
- token_tag(authenticity_token)
648
- else
649
- html_options["method"] = "post"
650
- tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag(authenticity_token)
651
- end
652
-
653
- tags = utf8_enforcer_tag << method_tag
654
- content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
655
- end
656
-
657
- def form_tag_html(html_options)
658
- extra_tags = extra_tags_for_form(html_options)
659
- (tag(:form, html_options, true) + extra_tags).html_safe
660
- end
661
-
662
- def form_tag_in_block(html_options, &block)
663
- content = capture(&block)
664
- output = ActiveSupport::SafeBuffer.new
665
- output.safe_concat(form_tag_html(html_options))
666
- output << content
667
- output.safe_concat("</form>")
668
- end
669
-
670
- def token_tag(token)
671
- if token == false || !protect_against_forgery?
672
- ''
673
- else
674
- token ||= form_authenticity_token
675
- tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
676
- end
677
- end
678
-
679
- # see http://www.w3.org/TR/html4/types.html#type-name
680
- def sanitize_to_id(name)
681
- name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
682
- end
683
- end
684
- end
685
- end