actionpack 3.2.19 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +850 -401
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +39 -37
  7. data/lib/abstract_controller/callbacks.rb +101 -82
  8. data/lib/abstract_controller/collector.rb +7 -3
  9. data/lib/abstract_controller/helpers.rb +25 -13
  10. data/lib/abstract_controller/layouts.rb +74 -74
  11. data/lib/abstract_controller/logger.rb +1 -2
  12. data/lib/abstract_controller/rendering.rb +30 -13
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +6 -6
  15. data/lib/abstract_controller/view_paths.rb +1 -1
  16. data/lib/abstract_controller.rb +1 -8
  17. data/lib/action_controller/base.rb +46 -22
  18. data/lib/action_controller/caching/fragments.rb +23 -53
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/log_subscriber.rb +16 -8
  23. data/lib/action_controller/metal/conditional_get.rb +76 -32
  24. data/lib/action_controller/metal/data_streaming.rb +20 -26
  25. data/lib/action_controller/metal/exceptions.rb +19 -6
  26. data/lib/action_controller/metal/flash.rb +24 -9
  27. data/lib/action_controller/metal/force_ssl.rb +70 -12
  28. data/lib/action_controller/metal/head.rb +25 -4
  29. data/lib/action_controller/metal/helpers.rb +5 -9
  30. data/lib/action_controller/metal/hide_actions.rb +0 -1
  31. data/lib/action_controller/metal/http_authentication.rb +107 -83
  32. data/lib/action_controller/metal/implicit_render.rb +1 -1
  33. data/lib/action_controller/metal/instrumentation.rb +2 -1
  34. data/lib/action_controller/metal/live.rb +175 -0
  35. data/lib/action_controller/metal/mime_responds.rb +161 -47
  36. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  37. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  38. data/lib/action_controller/metal/redirecting.rb +15 -20
  39. data/lib/action_controller/metal/renderers.rb +11 -9
  40. data/lib/action_controller/metal/rendering.rb +9 -1
  41. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  42. data/lib/action_controller/metal/responder.rb +20 -19
  43. data/lib/action_controller/metal/streaming.rb +12 -18
  44. data/lib/action_controller/metal/strong_parameters.rb +520 -0
  45. data/lib/action_controller/metal/testing.rb +13 -18
  46. data/lib/action_controller/metal/url_for.rb +28 -25
  47. data/lib/action_controller/metal.rb +17 -32
  48. data/lib/action_controller/model_naming.rb +12 -0
  49. data/lib/action_controller/railtie.rb +33 -17
  50. data/lib/action_controller/railties/helpers.rb +22 -0
  51. data/lib/action_controller/record_identifier.rb +18 -72
  52. data/lib/action_controller/test_case.rb +251 -131
  53. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  54. data/lib/action_controller.rb +15 -6
  55. data/lib/action_dispatch/http/cache.rb +63 -11
  56. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  57. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  58. data/lib/action_dispatch/http/headers.rb +49 -17
  59. data/lib/action_dispatch/http/mime_negotiation.rb +24 -1
  60. data/lib/action_dispatch/http/mime_type.rb +154 -100
  61. data/lib/action_dispatch/http/mime_types.rb +1 -1
  62. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  63. data/lib/action_dispatch/http/parameters.rb +28 -28
  64. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  65. data/lib/action_dispatch/http/request.rb +64 -18
  66. data/lib/action_dispatch/http/response.rb +130 -35
  67. data/lib/action_dispatch/http/upload.rb +63 -20
  68. data/lib/action_dispatch/http/url.rb +98 -35
  69. data/lib/action_dispatch/journey/backwards.rb +5 -0
  70. data/lib/action_dispatch/journey/formatter.rb +146 -0
  71. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  72. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  73. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  74. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  75. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  76. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  77. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  78. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  79. data/lib/action_dispatch/journey/parser.rb +206 -0
  80. data/lib/action_dispatch/journey/parser.y +47 -0
  81. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  82. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  83. data/lib/action_dispatch/journey/route.rb +124 -0
  84. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  85. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  86. data/lib/action_dispatch/journey/router.rb +166 -0
  87. data/lib/action_dispatch/journey/routes.rb +75 -0
  88. data/lib/action_dispatch/journey/scanner.rb +61 -0
  89. data/lib/action_dispatch/journey/visitors.rb +197 -0
  90. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  91. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  92. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  93. data/lib/action_dispatch/journey.rb +5 -0
  94. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  95. data/lib/action_dispatch/middleware/cookies.rb +259 -114
  96. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  97. data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -3
  98. data/lib/action_dispatch/middleware/flash.rb +58 -58
  99. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  100. data/lib/action_dispatch/middleware/public_exceptions.rb +30 -14
  101. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  102. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  103. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  104. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  105. data/lib/action_dispatch/middleware/session/cookie_store.rb +82 -28
  106. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  107. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  108. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  109. data/lib/action_dispatch/middleware/stack.rb +6 -1
  110. data/lib/action_dispatch/middleware/static.rb +2 -1
  111. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  112. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +7 -9
  114. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  115. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +127 -5
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  118. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  119. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  120. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  121. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  122. data/lib/action_dispatch/railtie.rb +16 -6
  123. data/lib/action_dispatch/request/session.rb +181 -0
  124. data/lib/action_dispatch/routing/inspector.rb +240 -0
  125. data/lib/action_dispatch/routing/mapper.rb +540 -291
  126. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  127. data/lib/action_dispatch/routing/redirection.rb +46 -29
  128. data/lib/action_dispatch/routing/route_set.rb +207 -164
  129. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  130. data/lib/action_dispatch/routing/url_for.rb +48 -33
  131. data/lib/action_dispatch/routing.rb +48 -83
  132. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  133. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  134. data/lib/action_dispatch/testing/assertions/routing.rb +42 -41
  135. data/lib/action_dispatch/testing/assertions/selector.rb +17 -22
  136. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  137. data/lib/action_dispatch/testing/integration.rb +65 -51
  138. data/lib/action_dispatch/testing/test_process.rb +9 -6
  139. data/lib/action_dispatch/testing/test_request.rb +7 -3
  140. data/lib/action_dispatch.rb +21 -15
  141. data/lib/action_pack/version.rb +7 -6
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_view/base.rb +15 -34
  144. data/lib/action_view/buffers.rb +7 -1
  145. data/lib/action_view/context.rb +4 -4
  146. data/lib/action_view/dependency_tracker.rb +93 -0
  147. data/lib/action_view/digestor.rb +85 -0
  148. data/lib/action_view/flows.rb +1 -4
  149. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  150. data/lib/action_view/helpers/asset_tag_helper.rb +215 -352
  151. data/lib/action_view/helpers/asset_url_helper.rb +355 -0
  152. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  153. data/lib/action_view/helpers/cache_helper.rb +150 -18
  154. data/lib/action_view/helpers/capture_helper.rb +44 -31
  155. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  156. data/lib/action_view/helpers/date_helper.rb +269 -248
  157. data/lib/action_view/helpers/debug_helper.rb +10 -11
  158. data/lib/action_view/helpers/form_helper.rb +931 -537
  159. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  160. data/lib/action_view/helpers/form_tag_helper.rb +190 -90
  161. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  162. data/lib/action_view/helpers/number_helper.rb +148 -329
  163. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  164. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  165. data/lib/action_view/helpers/rendering_helper.rb +2 -2
  166. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  167. data/lib/action_view/helpers/tag_helper.rb +46 -33
  168. data/lib/action_view/helpers/tags/base.rb +147 -0
  169. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  170. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  171. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  172. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  173. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  174. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  175. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  176. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  177. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  178. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  179. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  180. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  181. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  182. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  183. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  184. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  185. data/lib/action_view/helpers/tags/label.rb +65 -0
  186. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  187. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  188. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  189. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  190. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  191. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  192. data/lib/action_view/helpers/tags/select.rb +40 -0
  193. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  194. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  195. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  196. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  197. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  198. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  199. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  200. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  201. data/lib/action_view/helpers/tags.rb +39 -0
  202. data/lib/action_view/helpers/text_helper.rb +130 -114
  203. data/lib/action_view/helpers/translation_helper.rb +32 -16
  204. data/lib/action_view/helpers/url_helper.rb +211 -270
  205. data/lib/action_view/helpers.rb +2 -4
  206. data/lib/action_view/locale/en.yml +1 -105
  207. data/lib/action_view/log_subscriber.rb +6 -4
  208. data/lib/action_view/lookup_context.rb +15 -28
  209. data/lib/action_view/model_naming.rb +12 -0
  210. data/lib/action_view/path_set.rb +8 -20
  211. data/lib/action_view/railtie.rb +6 -22
  212. data/lib/action_view/record_identifier.rb +84 -0
  213. data/lib/action_view/renderer/abstract_renderer.rb +25 -19
  214. data/lib/action_view/renderer/partial_renderer.rb +158 -81
  215. data/lib/action_view/renderer/renderer.rb +8 -12
  216. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  217. data/lib/action_view/renderer/template_renderer.rb +12 -10
  218. data/lib/action_view/routing_url_for.rb +107 -0
  219. data/lib/action_view/template/error.rb +22 -12
  220. data/lib/action_view/template/handlers/builder.rb +1 -1
  221. data/lib/action_view/template/handlers/erb.rb +40 -19
  222. data/lib/action_view/template/handlers/raw.rb +11 -0
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/resolver.rb +107 -53
  225. data/lib/action_view/template/text.rb +12 -8
  226. data/lib/action_view/template/types.rb +57 -0
  227. data/lib/action_view/template.rb +25 -23
  228. data/lib/action_view/test_case.rb +67 -42
  229. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  230. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  231. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +13 -2
  232. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +9 -9
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  235. data/lib/action_view/vendor/html-scanner.rb +20 -0
  236. data/lib/action_view.rb +17 -8
  237. metadata +184 -214
  238. data/lib/action_controller/caching/actions.rb +0 -185
  239. data/lib/action_controller/caching/pages.rb +0 -187
  240. data/lib/action_controller/caching/sweeping.rb +0 -97
  241. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  242. data/lib/action_controller/metal/compatibility.rb +0 -65
  243. data/lib/action_controller/metal/session_management.rb +0 -14
  244. data/lib/action_controller/railties/paths.rb +0 -25
  245. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  246. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  247. data/lib/action_dispatch/middleware/head.rb +0 -18
  248. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  249. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  250. data/lib/action_view/asset_paths.rb +0 -142
  251. data/lib/action_view/helpers/asset_paths.rb +0 -7
  252. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  253. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  254. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  255. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  256. data/lib/sprockets/assets.rake +0 -99
  257. data/lib/sprockets/bootstrap.rb +0 -37
  258. data/lib/sprockets/compressors.rb +0 -83
  259. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  260. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/railtie.rb +0 -62
  263. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,15 +1,13 @@
1
- require 'action_controller/record_identifier'
2
-
3
1
  module ActionView
4
2
  # = Action View Record Tag Helpers
5
3
  module Helpers
6
4
  module RecordTagHelper
7
- include ActionController::RecordIdentifier
5
+ include ActionView::RecordIdentifier
8
6
 
9
7
  # Produces a wrapper DIV element with id and class parameters that
10
8
  # relate to the specified Active Record object. Usage example:
11
9
  #
12
- # <%= div_for(@person, :class => "foo") do %>
10
+ # <%= div_for(@person, class: "foo") do %>
13
11
  # <%= @person.name %>
14
12
  # <% end %>
15
13
  #
@@ -21,7 +19,7 @@ module ActionView
21
19
  # get iterated over and yield each record as an argument for the block.
22
20
  # For example:
23
21
  #
24
- # <%= div_for(@people, :class => "foo") do |person| %>
22
+ # <%= div_for(@people, class: "foo") do |person| %>
25
23
  # <%= person.name %>
26
24
  # <% end %>
27
25
  #
@@ -67,27 +65,25 @@ module ActionView
67
65
  #
68
66
  # produces:
69
67
  #
70
- # <tr id="person_123" class="person">...</tr>
71
- # <tr id="person_124" class="person">...</tr>
68
+ # <tr id="person_123" class="person">...</tr>
69
+ # <tr id="person_124" class="person">...</tr>
72
70
  #
73
71
  # content_tag_for also accepts a hash of options, which will be converted to
74
72
  # additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
75
73
  # with the default class name for your object. For example:
76
74
  #
77
- # <%= content_tag_for(:li, @person, :class => "bar") %>...
75
+ # <%= content_tag_for(:li, @person, class: "bar") %>...
78
76
  #
79
77
  # produces:
80
78
  #
81
79
  # <li id="person_123" class="person bar">...
82
80
  #
83
81
  def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block)
84
- if single_or_multiple_records.respond_to?(:to_ary)
85
- single_or_multiple_records.to_ary.map do |single_record|
86
- capture { content_tag_for_single_record(tag_name, single_record, prefix, options, &block) }
87
- end.join("\n").html_safe
88
- else
89
- content_tag_for_single_record(tag_name, single_or_multiple_records, prefix, options, &block)
90
- end
82
+ options, prefix = prefix, nil if prefix.is_a?(Hash)
83
+
84
+ Array(single_or_multiple_records).map do |single_record|
85
+ content_tag_for_single_record(tag_name, single_record, prefix, options, &block)
86
+ end.join("\n").html_safe
91
87
  end
92
88
 
93
89
  private
@@ -95,15 +91,14 @@ module ActionView
95
91
  # Called by <tt>content_tag_for</tt> internally to render a content tag
96
92
  # for each record.
97
93
  def content_tag_for_single_record(tag_name, record, prefix, options, &block)
98
- options, prefix = prefix, nil if prefix.is_a?(Hash)
99
94
  options = options ? options.dup : {}
100
- options.merge!(:class => "#{dom_class(record, prefix)} #{options[:class]}".strip, :id => dom_id(record, prefix))
101
- if !block_given?
102
- content_tag(tag_name, "", options)
103
- elsif block.arity == 0
104
- content_tag(tag_name, capture(&block), options)
105
- else
95
+ options[:class] = [ dom_class(record, prefix), options[:class] ].compact
96
+ options[:id] = dom_id(record, prefix)
97
+
98
+ if block_given?
106
99
  content_tag(tag_name, capture(record, &block), options)
100
+ else
101
+ content_tag(tag_name, "", options)
107
102
  end
108
103
  end
109
104
  end
@@ -39,7 +39,7 @@ module ActionView
39
39
  # The user can override this default by passing a block to the layout:
40
40
  #
41
41
  # # The template
42
- # <%= render :layout => "my_layout" do %>
42
+ # <%= render layout: "my_layout" do %>
43
43
  # Content
44
44
  # <% end %>
45
45
  #
@@ -59,7 +59,7 @@ module ActionView
59
59
  # Finally, the block can take block arguments, which can be passed in by +yield+:
60
60
  #
61
61
  # # The template
62
- # <%= render :layout => "my_layout" do |customer| %>
62
+ # <%= render layout: "my_layout" do |customer| %>
63
63
  # Hello <%= customer.name %>
64
64
  # <% end %>
65
65
  #
@@ -1,9 +1,9 @@
1
1
  require 'active_support/core_ext/object/try'
2
- require 'action_controller/vendor/html-scanner'
2
+ require 'action_view/vendor/html-scanner'
3
3
 
4
4
  module ActionView
5
5
  # = Action View Sanitize Helpers
6
- module Helpers #:nodoc:
6
+ module Helpers
7
7
  # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
8
8
  # These helper methods extend Action View making them callable within your template files.
9
9
  module SanitizeHelper
@@ -29,7 +29,7 @@ module ActionView
29
29
  #
30
30
  # Custom Use (only the mentioned tags and attributes are allowed, nothing else)
31
31
  #
32
- # <%= sanitize @article.body, :tags => %w(table tr td), :attributes => %w(id class style) %>
32
+ # <%= sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style) %>
33
33
  #
34
34
  # Add table tags to the default allowed tags
35
35
  #
@@ -69,8 +69,6 @@ module ActionView
69
69
  # html-scanner tokenizer and so its HTML parsing ability is limited by
70
70
  # that of html-scanner.
71
71
  #
72
- # ==== Examples
73
- #
74
72
  # strip_tags("Strip <i>these</i> tags!")
75
73
  # # => Strip these tags!
76
74
  #
@@ -85,7 +83,6 @@ module ActionView
85
83
 
86
84
  # Strips all link tags from +text+ leaving just the link text.
87
85
  #
88
- # ==== Examples
89
86
  # strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
90
87
  # # => Ruby on Rails
91
88
  #
@@ -1,4 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
1
  require 'active_support/core_ext/string/output_safety'
3
2
  require 'set'
4
3
 
@@ -14,7 +13,7 @@ module ActionView
14
13
  BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
15
14
  autoplay controls loop selected hidden scoped async
16
15
  defer reversed ismap seemless muted required
17
- autofocus novalidate formnovalidate open pubdate).to_set
16
+ autofocus novalidate formnovalidate open pubdate itemscope).to_set
18
17
  BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })
19
18
 
20
19
  PRE_CONTENT_STRINGS = {
@@ -41,7 +40,7 @@ module ActionView
41
40
  # thus accessed as <tt>dataset.userId</tt>.
42
41
  #
43
42
  # Values are encoded to JSON, with the exception of strings and symbols.
44
- # This may come in handy when using jQuery's HTML5-aware <tt>.data()<tt>
43
+ # This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
45
44
  # from 1.4.3.
46
45
  #
47
46
  # ==== Examples
@@ -51,16 +50,16 @@ module ActionView
51
50
  # tag("br", nil, true)
52
51
  # # => <br>
53
52
  #
54
- # tag("input", :type => 'text', :disabled => true)
53
+ # tag("input", type: 'text', disabled: true)
55
54
  # # => <input type="text" disabled="disabled" />
56
55
  #
57
- # tag("img", :src => "open & shut.png")
56
+ # tag("img", src: "open & shut.png")
58
57
  # # => <img src="open &amp; shut.png" />
59
58
  #
60
- # tag("img", {:src => "open &amp; shut.png"}, false, false)
59
+ # tag("img", {src: "open &amp; shut.png"}, false, false)
61
60
  # # => <img src="open &amp; shut.png" />
62
61
  #
63
- # tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)})
62
+ # tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
64
63
  # # => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
65
64
  def tag(name, options = nil, open = false, escape = true)
66
65
  "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
@@ -80,12 +79,12 @@ module ActionView
80
79
  # ==== Examples
81
80
  # content_tag(:p, "Hello world!")
82
81
  # # => <p>Hello world!</p>
83
- # content_tag(:div, content_tag(:p, "Hello world!"), :class => "strong")
82
+ # content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
84
83
  # # => <div class="strong"><p>Hello world!</p></div>
85
- # content_tag("select", options, :multiple => true)
84
+ # content_tag("select", options, multiple: true)
86
85
  # # => <select multiple="multiple">...options...</select>
87
86
  #
88
- # <%= content_tag :div, :class => "strong" do -%>
87
+ # <%= content_tag :div, class: "strong" do -%>
89
88
  # Hello world!
90
89
  # <% end -%>
91
90
  # # => <div class="strong">Hello world!</div>
@@ -103,57 +102,71 @@ module ActionView
103
102
  # otherwise be recognized as markup. CDATA sections begin with the string
104
103
  # <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
105
104
  #
106
- # ==== Examples
107
105
  # cdata_section("<hello world>")
108
106
  # # => <![CDATA[<hello world>]]>
109
107
  #
110
108
  # cdata_section(File.read("hello_world.txt"))
111
109
  # # => <![CDATA[<hello from a text file]]>
110
+ #
111
+ # cdata_section("hello]]>world")
112
+ # # => <![CDATA[hello]]]]><![CDATA[>world]]>
112
113
  def cdata_section(content)
113
- "<![CDATA[#{content}]]>".html_safe
114
+ splitted = content.gsub(']]>', ']]]]><![CDATA[>')
115
+ "<![CDATA[#{splitted}]]>".html_safe
114
116
  end
115
117
 
116
118
  # Returns an escaped version of +html+ without affecting existing escaped entities.
117
119
  #
118
- # ==== Examples
119
120
  # escape_once("1 < 2 &amp; 3")
120
121
  # # => "1 &lt; 2 &amp; 3"
121
122
  #
122
123
  # escape_once("&lt;&lt; Accept & Checkout")
123
124
  # # => "&lt;&lt; Accept &amp; Checkout"
124
125
  def escape_once(html)
125
- ActiveSupport::Multibyte.clean(html.to_s).gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
126
+ ERB::Util.html_escape_once(html)
126
127
  end
127
128
 
128
129
  private
129
130
 
130
131
  def content_tag_string(name, content, options, escape = true)
131
132
  tag_options = tag_options(options, escape) if options
132
- "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{escape ? ERB::Util.h(content) : content}</#{name}>".html_safe
133
+ content = ERB::Util.h(content) if escape
134
+ "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe
133
135
  end
134
136
 
135
137
  def tag_options(options, escape = true)
136
- unless options.blank?
137
- attrs = []
138
- options.each_pair do |key, value|
139
- if key.to_s == 'data' && value.is_a?(Hash)
140
- value.each do |k, v|
141
- unless v.is_a?(String) || v.is_a?(Symbol) || v.is_a?(BigDecimal)
142
- v = v.to_json
143
- end
144
- v = ERB::Util.html_escape(v) if escape
145
- attrs << %(data-#{k.to_s.dasherize}="#{v}")
146
- end
147
- elsif BOOLEAN_ATTRIBUTES.include?(key)
148
- attrs << %(#{key}="#{key}") if value
149
- elsif !value.nil?
150
- final_value = value.is_a?(Array) ? value.join(" ") : value
151
- final_value = ERB::Util.html_escape(final_value) if escape
152
- attrs << %(#{key}="#{final_value}")
138
+ return if options.blank?
139
+ attrs = []
140
+ options.each_pair do |key, value|
141
+ if key.to_s == 'data' && value.is_a?(Hash)
142
+ value.each_pair do |k, v|
143
+ attrs << data_tag_option(k, v, escape)
153
144
  end
145
+ elsif BOOLEAN_ATTRIBUTES.include?(key)
146
+ attrs << boolean_tag_option(key) if value
147
+ elsif !value.nil?
148
+ attrs << tag_option(key, value, escape)
154
149
  end
155
- " #{attrs.sort * ' '}".html_safe unless attrs.empty?
156
150
  end
151
+ " #{attrs.sort * ' '}".html_safe unless attrs.empty?
152
+ end
153
+
154
+ def data_tag_option(key, value, escape)
155
+ key = "data-#{key.to_s.dasherize}"
156
+ unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal)
157
+ value = value.to_json
158
+ end
159
+ tag_option(key, value, escape)
160
+ end
161
+
162
+ def boolean_tag_option(key)
163
+ %(#{key}="#{key}")
164
+ end
165
+
166
+ def tag_option(key, value, escape)
167
+ value = value.join(" ") if value.is_a?(Array)
168
+ value = ERB::Util.h(value) if escape
169
+ %(#{key}="#{value}")
157
170
  end
158
171
  end
159
172
  end
@@ -0,0 +1,147 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class Base # :nodoc:
5
+ include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper
6
+ include FormOptionsHelper
7
+
8
+ attr_reader :object
9
+
10
+ def initialize(object_name, method_name, template_object, options = {})
11
+ @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
12
+ @template_object = template_object
13
+
14
+ @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
15
+ @object = retrieve_object(options.delete(:object))
16
+ @options = options
17
+ @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
18
+ end
19
+
20
+ # This is what child classes implement.
21
+ def render
22
+ raise NotImplementedError, "Subclasses must implement a render method"
23
+ end
24
+
25
+ private
26
+
27
+ def value(object)
28
+ object.send @method_name if object
29
+ end
30
+
31
+ def value_before_type_cast(object)
32
+ unless object.nil?
33
+ method_before_type_cast = @method_name + "_before_type_cast"
34
+
35
+ object.respond_to?(method_before_type_cast) ?
36
+ object.send(method_before_type_cast) :
37
+ value(object)
38
+ end
39
+ end
40
+
41
+ def retrieve_object(object)
42
+ if object
43
+ object
44
+ elsif @template_object.instance_variable_defined?("@#{@object_name}")
45
+ @template_object.instance_variable_get("@#{@object_name}")
46
+ end
47
+ rescue NameError
48
+ # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.
49
+ nil
50
+ end
51
+
52
+ def retrieve_autoindex(pre_match)
53
+ object = self.object || @template_object.instance_variable_get("@#{pre_match}")
54
+ if object && object.respond_to?(:to_param)
55
+ object.to_param
56
+ else
57
+ raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
58
+ end
59
+ end
60
+
61
+ def add_default_name_and_id_for_value(tag_value, options)
62
+ if tag_value.nil?
63
+ add_default_name_and_id(options)
64
+ else
65
+ specified_id = options["id"]
66
+ add_default_name_and_id(options)
67
+
68
+ if specified_id.blank? && options["id"].present?
69
+ options["id"] += "_#{sanitized_value(tag_value)}"
70
+ end
71
+ end
72
+ end
73
+
74
+ def add_default_name_and_id(options)
75
+ if options.has_key?("index")
76
+ options["name"] ||= options.fetch("name"){ tag_name_with_index(options["index"], options["multiple"]) }
77
+ options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) }
78
+ options.delete("index")
79
+ elsif defined?(@auto_index)
80
+ options["name"] ||= options.fetch("name"){ tag_name_with_index(@auto_index, options["multiple"]) }
81
+ options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
82
+ else
83
+ options["name"] ||= options.fetch("name"){ tag_name(options["multiple"]) }
84
+ options["id"] = options.fetch("id"){ tag_id }
85
+ end
86
+
87
+ options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
88
+ end
89
+
90
+ def tag_name(multiple = false)
91
+ "#{@object_name}[#{sanitized_method_name}]#{"[]" if multiple}"
92
+ end
93
+
94
+ def tag_name_with_index(index, multiple = false)
95
+ "#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]" if multiple}"
96
+ end
97
+
98
+ def tag_id
99
+ "#{sanitized_object_name}_#{sanitized_method_name}"
100
+ end
101
+
102
+ def tag_id_with_index(index)
103
+ "#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
104
+ end
105
+
106
+ def sanitized_object_name
107
+ @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
108
+ end
109
+
110
+ def sanitized_method_name
111
+ @sanitized_method_name ||= @method_name.sub(/\?$/,"")
112
+ end
113
+
114
+ def sanitized_value(value)
115
+ value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
116
+ end
117
+
118
+ def select_content_tag(option_tags, options, html_options)
119
+ html_options = html_options.stringify_keys
120
+ add_default_name_and_id(html_options)
121
+ options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
122
+ select = content_tag("select", add_options(option_tags, options, value(object)), html_options)
123
+
124
+ if html_options["multiple"] && options.fetch(:include_hidden, true)
125
+ tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
126
+ else
127
+ select
128
+ end
129
+ end
130
+
131
+ def select_not_required?(html_options)
132
+ !html_options["required"] || html_options["multiple"] || html_options["size"].to_i > 1
133
+ end
134
+
135
+ def add_options(option_tags, options, value = nil)
136
+ if options[:include_blank]
137
+ option_tags = content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
138
+ end
139
+ if value.blank? && options[:prompt]
140
+ option_tags = content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
141
+ end
142
+ option_tags
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,64 @@
1
+ require 'action_view/helpers/tags/checkable'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class CheckBox < Base #:nodoc:
7
+ include Checkable
8
+
9
+ def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options)
10
+ @checked_value = checked_value
11
+ @unchecked_value = unchecked_value
12
+ super(object_name, method_name, template_object, options)
13
+ end
14
+
15
+ def render
16
+ options = @options.stringify_keys
17
+ options["type"] = "checkbox"
18
+ options["value"] = @checked_value
19
+ options["checked"] = "checked" if input_checked?(object, options)
20
+
21
+ if options["multiple"]
22
+ add_default_name_and_id_for_value(@checked_value, options)
23
+ options.delete("multiple")
24
+ else
25
+ add_default_name_and_id(options)
26
+ end
27
+
28
+ include_hidden = options.delete("include_hidden") { true }
29
+ checkbox = tag("input", options)
30
+
31
+ if include_hidden
32
+ hidden = hidden_field_for_checkbox(options)
33
+ hidden + checkbox
34
+ else
35
+ checkbox
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def checked?(value)
42
+ case value
43
+ when TrueClass, FalseClass
44
+ value == !!@checked_value
45
+ when NilClass
46
+ false
47
+ when String
48
+ value == @checked_value
49
+ else
50
+ if value.respond_to?(:include?)
51
+ value.include?(@checked_value)
52
+ else
53
+ value.to_i == @checked_value.to_i
54
+ end
55
+ end
56
+ end
57
+
58
+ def hidden_field_for_checkbox(options)
59
+ @unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value)) : "".html_safe
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ module Checkable # :nodoc:
5
+ def input_checked?(object, options)
6
+ if options.has_key?("checked")
7
+ checked = options.delete "checked"
8
+ checked == true || checked == "checked"
9
+ else
10
+ checked?(value(object))
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,43 @@
1
+ require 'action_view/helpers/tags/collection_helpers'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class CollectionCheckBoxes < Base # :nodoc:
7
+ include CollectionHelpers
8
+
9
+ class CheckBoxBuilder < Builder # :nodoc:
10
+ def check_box(extra_html_options={})
11
+ html_options = extra_html_options.merge(@input_html_options)
12
+ @template_object.check_box(@object_name, @method_name, html_options, @value, nil)
13
+ end
14
+ end
15
+
16
+ def render(&block)
17
+ rendered_collection = render_collection do |item, value, text, default_html_options|
18
+ default_html_options[:multiple] = true
19
+ builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)
20
+
21
+ if block_given?
22
+ @template_object.capture(builder, &block)
23
+ else
24
+ render_component(builder)
25
+ end
26
+ end
27
+
28
+ # Append a hidden field to make sure something will be sent back to the
29
+ # server if all check boxes are unchecked.
30
+ hidden = @template_object.hidden_field_tag("#{tag_name}[]", "", :id => nil)
31
+
32
+ rendered_collection + hidden
33
+ end
34
+
35
+ private
36
+
37
+ def render_component(builder)
38
+ builder.check_box + builder.label
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,83 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ module CollectionHelpers # :nodoc:
5
+ class Builder # :nodoc:
6
+ attr_reader :object, :text, :value
7
+
8
+ def initialize(template_object, object_name, method_name, object,
9
+ sanitized_attribute_name, text, value, input_html_options)
10
+ @template_object = template_object
11
+ @object_name = object_name
12
+ @method_name = method_name
13
+ @object = object
14
+ @sanitized_attribute_name = sanitized_attribute_name
15
+ @text = text
16
+ @value = value
17
+ @input_html_options = input_html_options
18
+ end
19
+
20
+ def label(label_html_options={}, &block)
21
+ @template_object.label(@object_name, @sanitized_attribute_name, @text, label_html_options, &block)
22
+ end
23
+ end
24
+
25
+ def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
26
+ @collection = collection
27
+ @value_method = value_method
28
+ @text_method = text_method
29
+ @html_options = html_options
30
+
31
+ super(object_name, method_name, template_object, options)
32
+ end
33
+
34
+ private
35
+
36
+ def instantiate_builder(builder_class, item, value, text, html_options)
37
+ builder_class.new(@template_object, @object_name, @method_name, item,
38
+ sanitize_attribute_name(value), text, value, html_options)
39
+ end
40
+
41
+ # Generate default options for collection helpers, such as :checked and
42
+ # :disabled.
43
+ def default_html_options_for_collection(item, value) #:nodoc:
44
+ html_options = @html_options.dup
45
+
46
+ [:checked, :selected, :disabled].each do |option|
47
+ current_value = @options[option]
48
+ next if current_value.nil?
49
+
50
+ accept = if current_value.respond_to?(:call)
51
+ current_value.call(item)
52
+ else
53
+ Array(current_value).map(&:to_s).include?(value.to_s)
54
+ end
55
+
56
+ if accept
57
+ html_options[option] = true
58
+ elsif option == :checked
59
+ html_options[option] = false
60
+ end
61
+ end
62
+
63
+ html_options[:object] = @object
64
+ html_options
65
+ end
66
+
67
+ def sanitize_attribute_name(value) #:nodoc:
68
+ "#{sanitized_method_name}_#{sanitized_value(value)}"
69
+ end
70
+
71
+ def render_collection #:nodoc:
72
+ @collection.map do |item|
73
+ value = value_for_collection(item, @value_method)
74
+ text = value_for_collection(item, @text_method)
75
+ default_html_options = default_html_options_for_collection(item, value)
76
+
77
+ yield item, value, text, default_html_options
78
+ end.join.html_safe
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end