actionview 6.0.3.3 → 6.1.1

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

Potentially problematic release.


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

Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +177 -208
  3. data/MIT-LICENSE +1 -1
  4. data/lib/action_view.rb +4 -1
  5. data/lib/action_view/base.rb +19 -50
  6. data/lib/action_view/cache_expiry.rb +1 -2
  7. data/lib/action_view/dependency_tracker.rb +10 -4
  8. data/lib/action_view/digestor.rb +3 -2
  9. data/lib/action_view/gem_version.rb +3 -3
  10. data/lib/action_view/helpers/asset_tag_helper.rb +55 -15
  11. data/lib/action_view/helpers/asset_url_helper.rb +6 -4
  12. data/lib/action_view/helpers/atom_feed_helper.rb +2 -1
  13. data/lib/action_view/helpers/cache_helper.rb +10 -16
  14. data/lib/action_view/helpers/date_helper.rb +4 -4
  15. data/lib/action_view/helpers/form_helper.rb +66 -30
  16. data/lib/action_view/helpers/form_options_helper.rb +7 -16
  17. data/lib/action_view/helpers/form_tag_helper.rb +7 -7
  18. data/lib/action_view/helpers/javascript_helper.rb +3 -3
  19. data/lib/action_view/helpers/number_helper.rb +6 -6
  20. data/lib/action_view/helpers/rendering_helper.rb +11 -3
  21. data/lib/action_view/helpers/sanitize_helper.rb +2 -2
  22. data/lib/action_view/helpers/tag_helper.rb +92 -17
  23. data/lib/action_view/helpers/tags/base.rb +9 -5
  24. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  25. data/lib/action_view/helpers/tags/date_select.rb +2 -2
  26. data/lib/action_view/helpers/tags/datetime_local_field.rb +1 -1
  27. data/lib/action_view/helpers/tags/label.rb +4 -0
  28. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  29. data/lib/action_view/helpers/tags/select.rb +1 -1
  30. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  31. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  32. data/lib/action_view/helpers/text_helper.rb +1 -1
  33. data/lib/action_view/helpers/translation_helper.rb +87 -51
  34. data/lib/action_view/helpers/url_helper.rb +107 -13
  35. data/lib/action_view/layouts.rb +3 -2
  36. data/lib/action_view/log_subscriber.rb +26 -10
  37. data/lib/action_view/lookup_context.rb +3 -18
  38. data/lib/action_view/path_set.rb +0 -3
  39. data/lib/action_view/railtie.rb +39 -46
  40. data/lib/action_view/renderer/abstract_renderer.rb +93 -14
  41. data/lib/action_view/renderer/collection_renderer.rb +196 -0
  42. data/lib/action_view/renderer/object_renderer.rb +34 -0
  43. data/lib/action_view/renderer/partial_renderer.rb +20 -282
  44. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +25 -26
  45. data/lib/action_view/renderer/renderer.rb +44 -1
  46. data/lib/action_view/renderer/streaming_template_renderer.rb +5 -1
  47. data/lib/action_view/renderer/template_renderer.rb +15 -12
  48. data/lib/action_view/rendering.rb +3 -1
  49. data/lib/action_view/routing_url_for.rb +1 -1
  50. data/lib/action_view/template.rb +9 -49
  51. data/lib/action_view/template/handlers.rb +0 -26
  52. data/lib/action_view/template/handlers/erb.rb +10 -14
  53. data/lib/action_view/template/handlers/erb/erubi.rb +9 -7
  54. data/lib/action_view/template/html.rb +1 -11
  55. data/lib/action_view/template/raw_file.rb +0 -3
  56. data/lib/action_view/template/renderable.rb +24 -0
  57. data/lib/action_view/template/resolver.rb +82 -40
  58. data/lib/action_view/template/text.rb +0 -3
  59. data/lib/action_view/test_case.rb +18 -25
  60. data/lib/action_view/testing/resolvers.rb +10 -31
  61. data/lib/action_view/unbound_template.rb +3 -3
  62. data/lib/action_view/view_paths.rb +34 -36
  63. metadata +18 -15
@@ -24,8 +24,8 @@ module ActionView
24
24
  # This approach will assume that when a new topic is added, you'll touch
25
25
  # the project. The cache key generated from this call will be something like:
26
26
  #
27
- # views/template/action.html.erb:7a1156131a6928cb0026877f8b749ac9/projects/123
28
- # ^template path ^template tree digest ^class ^id
27
+ # views/template/action:7a1156131a6928cb0026877f8b749ac9/projects/123
28
+ # ^template path ^template tree digest ^class ^id
29
29
  #
30
30
  # This cache key is stable, but it's combined with a cache version derived from the project
31
31
  # record. When the project updated_at is touched, the #cache_version changes, even
@@ -165,7 +165,7 @@ module ActionView
165
165
  # expire the cache.
166
166
  def cache(name = {}, options = {}, &block)
167
167
  if controller.respond_to?(:perform_caching) && controller.perform_caching
168
- name_options = options.slice(:skip_digest, :virtual_path)
168
+ name_options = options.slice(:skip_digest)
169
169
  safe_concat(fragment_for(cache_fragment_name(name, **name_options), options, &block))
170
170
  else
171
171
  yield
@@ -205,14 +205,11 @@ module ActionView
205
205
  # fragments can be manually bypassed. This is useful when cache fragments
206
206
  # cannot be manually expired unless you know the exact key which is the
207
207
  # case when using memcached.
208
- #
209
- # The digest will be generated using +virtual_path:+ if it is provided.
210
- #
211
- def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil, digest_path: nil)
208
+ def cache_fragment_name(name = {}, skip_digest: nil, digest_path: nil)
212
209
  if skip_digest
213
210
  name
214
211
  else
215
- fragment_name_with_digest(name, virtual_path, digest_path)
212
+ fragment_name_with_digest(name, digest_path)
216
213
  end
217
214
  end
218
215
 
@@ -227,14 +224,11 @@ module ActionView
227
224
  end
228
225
 
229
226
  private
230
- def fragment_name_with_digest(name, virtual_path, digest_path)
231
- virtual_path ||= @virtual_path
232
-
233
- if virtual_path || digest_path
234
- name = controller.url_for(name).split("://").last if name.is_a?(Hash)
227
+ def fragment_name_with_digest(name, digest_path)
228
+ name = controller.url_for(name).split("://").last if name.is_a?(Hash)
235
229
 
230
+ if @current_template&.virtual_path || digest_path
236
231
  digest_path ||= digest_path_from_template(@current_template)
237
-
238
232
  [ digest_path, name ]
239
233
  else
240
234
  name
@@ -243,10 +237,10 @@ module ActionView
243
237
 
244
238
  def fragment_for(name = {}, options = nil, &block)
245
239
  if content = read_fragment_for(name, options)
246
- @view_renderer.cache_hits[@virtual_path] = :hit if defined?(@view_renderer)
240
+ @view_renderer.cache_hits[@current_template&.virtual_path] = :hit if defined?(@view_renderer)
247
241
  content
248
242
  else
249
- @view_renderer.cache_hits[@virtual_path] = :miss if defined?(@view_renderer)
243
+ @view_renderer.cache_hits[@current_template&.virtual_path] = :miss if defined?(@view_renderer)
250
244
  write_fragment_for(name, options, &block)
251
245
  end
252
246
  end
@@ -197,8 +197,8 @@ module ActionView
197
197
  # and +:name+ (string). A format string would be something like "%{name} (%<number>02d)" for example.
198
198
  # See <tt>Kernel.sprintf</tt> for documentation on format sequences.
199
199
  # * <tt>:date_separator</tt> - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
200
- # * <tt>:time_separator</tt> - Specifies a string to separate the time fields. Default is "" (i.e. nothing).
201
- # * <tt>:datetime_separator</tt>- Specifies a string to separate the date and time fields. Default is "" (i.e. nothing).
200
+ # * <tt>:time_separator</tt> - Specifies a string to separate the time fields. Default is " : ".
201
+ # * <tt>:datetime_separator</tt>- Specifies a string to separate the date and time fields. Default is " &mdash; ".
202
202
  # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Date.today.year - 5</tt> if
203
203
  # you are creating new record. While editing existing record, <tt>:start_year</tt> defaults to
204
204
  # the current selected year minus 5.
@@ -1053,7 +1053,7 @@ module ActionView
1053
1053
  select_options[:class] = css_class_attribute(type, select_options[:class], @options[:with_css_classes]) if @options[:with_css_classes]
1054
1054
 
1055
1055
  select_html = +"\n"
1056
- select_html << content_tag("option", "", value: "") + "\n" if @options[:include_blank]
1056
+ select_html << content_tag("option", "", value: "", label: " ") + "\n" if @options[:include_blank]
1057
1057
  select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
1058
1058
  select_html << select_options_as_html
1059
1059
 
@@ -1138,7 +1138,7 @@ module ActionView
1138
1138
  first_visible = order.find { |type| !@options[:"discard_#{type}"] }
1139
1139
  order.reverse_each do |type|
1140
1140
  separator = separator(type) unless type == first_visible # don't add before first visible field
1141
- select.insert(0, separator.to_s + send("select_#{type}").to_s)
1141
+ select.insert(0, separator.to_s + public_send("select_#{type}").to_s)
1142
1142
  end
1143
1143
  select.html_safe
1144
1144
  end
@@ -11,6 +11,7 @@ require "active_support/core_ext/module/attribute_accessors"
11
11
  require "active_support/core_ext/hash/slice"
12
12
  require "active_support/core_ext/string/output_safety"
13
13
  require "active_support/core_ext/string/inflections"
14
+ require "active_support/core_ext/symbol/starts_ends_with"
14
15
 
15
16
  module ActionView
16
17
  # = Action View Form Helpers
@@ -185,8 +186,7 @@ module ActionView
185
186
  # get the authenticity token from the <tt>meta</tt> tag, so embedding is
186
187
  # unnecessary unless you support browsers without JavaScript.
187
188
  # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive
188
- # JavaScript drivers to control the submit behavior. By default this
189
- # behavior is an ajax submit.
189
+ # JavaScript drivers to control the submit behavior.
190
190
  # * <tt>:enforce_utf8</tt> - If set to false, a hidden input with name
191
191
  # utf8 is not output.
192
192
  # * <tt>:html</tt> - Optional HTML attributes for the form tag.
@@ -322,10 +322,8 @@ module ActionView
322
322
  # remote: true
323
323
  #
324
324
  # in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
325
- # behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular
326
- # POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor.
327
- # Even though it's using JavaScript to serialize the form elements, the form submission will work just like
328
- # a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
325
+ # behavior. The form submission will work just like a regular submission as viewed by the receiving
326
+ # side (all elements available in <tt>params</tt>).
329
327
  #
330
328
  # Example:
331
329
  #
@@ -535,11 +533,6 @@ module ActionView
535
533
  # accessible as <tt>params[:title]</tt> and <tt>params[:post][:title]</tt>
536
534
  # respectively.
537
535
  #
538
- # By default +form_with+ attaches the <tt>data-remote</tt> attribute
539
- # submitting the form via an XMLHTTPRequest in the background if an
540
- # Unobtrusive JavaScript driver, like rails-ujs, is used. See the
541
- # <tt>:local</tt> option for more.
542
- #
543
536
  # For ease of comparison the examples above left out the submit button,
544
537
  # as well as the auto generated hidden fields that enable UTF-8 support
545
538
  # and adds an authenticity token needed for cross site request forgery
@@ -611,8 +604,10 @@ module ActionView
611
604
  # This is helpful when fragment-caching the form. Remote forms
612
605
  # get the authenticity token from the <tt>meta</tt> tag, so embedding is
613
606
  # unnecessary unless you support browsers without JavaScript.
614
- # * <tt>:local</tt> - By default form submits are remote and unobtrusive XHRs.
615
- # Disable remote submits with <tt>local: true</tt>.
607
+ # * <tt>:local</tt> - By default form submits via typical HTTP requests.
608
+ # Enable remote and unobtrusive XHRs submits with <tt>local: false</tt>.
609
+ # Remote forms may be enabled by default by setting
610
+ # <tt>config.action_view.form_with_generates_remote_forms = true</tt>.
616
611
  # * <tt>:skip_enforcing_utf8</tt> - If set to true, a hidden input with name
617
612
  # utf8 is not output.
618
613
  # * <tt>:builder</tt> - Override the object used to build the form.
@@ -888,7 +883,7 @@ module ActionView
888
883
  #
889
884
  # Now, when you use a form element with the <tt>_destroy</tt> parameter,
890
885
  # with a value that evaluates to +true+, you will destroy the associated
891
- # model (eg. 1, '1', true, or 'true'):
886
+ # model (e.g. 1, '1', true, or 'true'):
892
887
  #
893
888
  # <%= form_for @person do |person_form| %>
894
889
  # ...
@@ -977,7 +972,7 @@ module ActionView
977
972
  # This will allow you to specify which models to destroy in the
978
973
  # attributes hash by adding a form element for the <tt>_destroy</tt>
979
974
  # parameter with a value that evaluates to +true+
980
- # (eg. 1, '1', true, or 'true'):
975
+ # (e.g. 1, '1', true, or 'true'):
981
976
  #
982
977
  # <%= form_for @person do |person_form| %>
983
978
  # ...
@@ -1110,6 +1105,16 @@ module ActionView
1110
1105
  # label(:post, :privacy, "Public Post", value: "public")
1111
1106
  # # => <label for="post_privacy_public">Public Post</label>
1112
1107
  #
1108
+ # label(:post, :cost) do |translation|
1109
+ # content_tag(:span, translation, class: "cost_label")
1110
+ # end
1111
+ # # => <label for="post_cost"><span class="cost_label">Total cost</span></label>
1112
+ #
1113
+ # label(:post, :cost) do |builder|
1114
+ # content_tag(:span, builder.translation, class: "cost_label")
1115
+ # end
1116
+ # # => <label for="post_cost"><span class="cost_label">Total cost</span></label>
1117
+ #
1113
1118
  # label(:post, :terms) do
1114
1119
  # raw('Accept <a href="/terms">Terms</a>.')
1115
1120
  # end
@@ -1668,8 +1673,8 @@ module ActionView
1668
1673
 
1669
1674
  convert_to_legacy_options(@options)
1670
1675
 
1671
- if @object_name.to_s.match(/\[\]$/)
1672
- if (object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
1676
+ if @object_name&.end_with?("[]")
1677
+ if (object ||= @template.instance_variable_get("@#{@object_name[0..-3]}")) && object.respond_to?(:to_param)
1673
1678
  @auto_index = object.to_param
1674
1679
  else
1675
1680
  raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
@@ -1792,7 +1797,7 @@ module ActionView
1792
1797
  # Wraps ActionView::Helpers::FormHelper#time_field for form builders:
1793
1798
  #
1794
1799
  # <%= form_with model: @user do |f| %>
1795
- # <%= f.time_field :borned_at %>
1800
+ # <%= f.time_field :born_at %>
1796
1801
  # <% end %>
1797
1802
  #
1798
1803
  # Please refer to the documentation of the base helper for details.
@@ -1904,8 +1909,8 @@ module ActionView
1904
1909
  (field_helpers - [:label, :check_box, :radio_button, :fields_for, :fields, :hidden_field, :file_field]).each do |selector|
1905
1910
  class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
1906
1911
  def #{selector}(method, options = {}) # def text_field(method, options = {})
1907
- @template.send( # @template.send(
1908
- #{selector.inspect}, # "text_field",
1912
+ @template.public_send( # @template.public_send(
1913
+ #{selector.inspect}, # :text_field,
1909
1914
  @object_name, # @object_name,
1910
1915
  method, # method,
1911
1916
  objectify_options(options)) # objectify_options(options))
@@ -2038,7 +2043,7 @@ module ActionView
2038
2043
  #
2039
2044
  # Now, when you use a form element with the <tt>_destroy</tt> parameter,
2040
2045
  # with a value that evaluates to +true+, you will destroy the associated
2041
- # model (eg. 1, '1', true, or 'true'):
2046
+ # model (e.g. 1, '1', true, or 'true'):
2042
2047
  #
2043
2048
  # <%= form_for @person do |person_form| %>
2044
2049
  # ...
@@ -2127,7 +2132,7 @@ module ActionView
2127
2132
  # This will allow you to specify which models to destroy in the
2128
2133
  # attributes hash by adding a form element for the <tt>_destroy</tt>
2129
2134
  # parameter with a value that evaluates to +true+
2130
- # (eg. 1, '1', true, or 'true'):
2135
+ # (e.g. 1, '1', true, or 'true'):
2131
2136
  #
2132
2137
  # <%= form_for @person do |person_form| %>
2133
2138
  # ...
@@ -2174,15 +2179,14 @@ module ActionView
2174
2179
  index = if options.has_key?(:index)
2175
2180
  options[:index]
2176
2181
  elsif defined?(@auto_index)
2177
- object_name = object_name.to_s.sub(/\[\]$/, "")
2182
+ object_name = object_name.to_s.delete_suffix("[]")
2178
2183
  @auto_index
2179
2184
  end
2180
2185
 
2181
2186
  record_name = if index
2182
2187
  "#{object_name}[#{index}][#{record_name}]"
2183
- elsif record_name.to_s.end_with?("[]")
2184
- record_name = record_name.to_s.sub(/(.*)\[\]$/, "[\\1][#{record_object.id}]")
2185
- "#{object_name}#{record_name}"
2188
+ elsif record_name.end_with?("[]")
2189
+ "#{object_name}[#{record_name[0..-3]}][#{record_object.id}]"
2186
2190
  else
2187
2191
  "#{object_name}[#{record_name}]"
2188
2192
  end
@@ -2245,6 +2249,24 @@ module ActionView
2245
2249
  # label(:privacy, "Public Post", value: "public")
2246
2250
  # # => <label for="post_privacy_public">Public Post</label>
2247
2251
  #
2252
+ # label(:cost) do |translation|
2253
+ # content_tag(:span, translation, class: "cost_label")
2254
+ # end
2255
+ # # => <label for="post_cost"><span class="cost_label">Total cost</span></label>
2256
+ #
2257
+ # label(:cost) do |builder|
2258
+ # content_tag(:span, builder.translation, class: "cost_label")
2259
+ # end
2260
+ # # => <label for="post_cost"><span class="cost_label">Total cost</span></label>
2261
+ #
2262
+ # label(:cost) do |builder|
2263
+ # content_tag(:span, builder.translation, class: [
2264
+ # "cost_label",
2265
+ # ("error_label" if builder.object.errors.include?(:cost))
2266
+ # ])
2267
+ # end
2268
+ # # => <label for="post_cost"><span class="cost_label error_label">Total cost</span></label>
2269
+ #
2248
2270
  # label(:terms) do
2249
2271
  # raw('Accept <a href="/terms">Terms</a>.')
2250
2272
  # end
@@ -2468,10 +2490,22 @@ module ActionView
2468
2490
  # # <strong>Ask me!</strong>
2469
2491
  # # </button>
2470
2492
  #
2493
+ # button do |text|
2494
+ # content_tag(:strong, text)
2495
+ # end
2496
+ # # => <button name='button' type='submit'>
2497
+ # # <strong>Create post</strong>
2498
+ # # </button>
2499
+ #
2471
2500
  def button(value = nil, options = {}, &block)
2472
2501
  value, options = nil, value if value.is_a?(Hash)
2473
2502
  value ||= submit_default_value
2474
- @template.button_tag(value, options, &block)
2503
+
2504
+ if block_given?
2505
+ value = @template.capture { yield(value) }
2506
+ end
2507
+
2508
+ @template.button_tag(value, options)
2475
2509
  end
2476
2510
 
2477
2511
  def emitted_hidden_id? # :nodoc:
@@ -2480,7 +2514,9 @@ module ActionView
2480
2514
 
2481
2515
  private
2482
2516
  def objectify_options(options)
2483
- @default_options.merge(options.merge(object: @object))
2517
+ result = @default_options.merge(options)
2518
+ result[:object] = @object
2519
+ result
2484
2520
  end
2485
2521
 
2486
2522
  def submit_default_value
@@ -2515,9 +2551,9 @@ module ActionView
2515
2551
  association = convert_to_model(association)
2516
2552
 
2517
2553
  if association.respond_to?(:persisted?)
2518
- association = [association] if @object.send(association_name).respond_to?(:to_ary)
2554
+ association = [association] if @object.public_send(association_name).respond_to?(:to_ary)
2519
2555
  elsif !association.respond_to?(:to_ary)
2520
- association = @object.send(association_name)
2556
+ association = @object.public_send(association_name)
2521
2557
  end
2522
2558
 
2523
2559
  if association.respond_to?(:to_ary)
@@ -21,7 +21,7 @@ module ActionView
21
21
  # could become:
22
22
  #
23
23
  # <select name="post[category]" id="post_category">
24
- # <option value=""></option>
24
+ # <option value="" label=" "></option>
25
25
  # <option value="joke">joke</option>
26
26
  # <option value="poem">poem</option>
27
27
  # </select>
@@ -74,7 +74,6 @@ module ActionView
74
74
  # could become:
75
75
  #
76
76
  # <select name="post[category]" id="post_category">
77
- # <option value=""></option>
78
77
  # <option value="joke">joke</option>
79
78
  # <option value="poem">poem</option>
80
79
  # <option disabled="disabled" value="restricted">restricted</option>
@@ -112,7 +111,7 @@ module ActionView
112
111
  # would become:
113
112
  #
114
113
  # <select name="post[person_id]" id="post_person_id">
115
- # <option value=""></option>
114
+ # <option value="" label=" "></option>
116
115
  # <option value="1" selected="selected">David</option>
117
116
  # <option value="2">Eileen</option>
118
117
  # <option value="3">Rafael</option>
@@ -143,7 +142,7 @@ module ActionView
143
142
  #
144
143
  # The HTML specification says when +multiple+ parameter passed to select and all options got deselected
145
144
  # web browsers do not send any value to server. Unfortunately this introduces a gotcha:
146
- # if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
145
+ # if a +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
147
146
  # the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
148
147
  # any mass-assignment idiom like
149
148
  #
@@ -569,7 +568,7 @@ module ActionView
569
568
  # be obtained in Active Record as a value object). The +model+ parameter
570
569
  # must respond to +all+ and return an array of objects that represent time
571
570
  # zones; each object must respond to +name+. If a Regexp is given it will
572
- # attempt to match the zones using the <code>=~<code> operator.
571
+ # attempt to match the zones using <code>match?</code> method.
573
572
  #
574
573
  # NOTE: Only the option tags are returned, you have to wrap this call in
575
574
  # a regular HTML select tag.
@@ -581,7 +580,7 @@ module ActionView
581
580
 
582
581
  if priority_zones
583
582
  if priority_zones.is_a?(Regexp)
584
- priority_zones = zones.select { |z| z =~ priority_zones }
583
+ priority_zones = zones.select { |z| z.match?(priority_zones) }
585
584
  end
586
585
 
587
586
  zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
@@ -795,7 +794,7 @@ module ActionView
795
794
  def extract_values_from_collection(collection, value_method, selected)
796
795
  if selected.is_a?(Proc)
797
796
  collection.map do |element|
798
- public_or_deprecated_send(element, value_method) if selected.call(element)
797
+ element.public_send(value_method) if selected.call(element)
799
798
  end.compact
800
799
  else
801
800
  selected
@@ -803,15 +802,7 @@ module ActionView
803
802
  end
804
803
 
805
804
  def value_for_collection(item, value)
806
- value.respond_to?(:call) ? value.call(item) : public_or_deprecated_send(item, value)
807
- end
808
-
809
- def public_or_deprecated_send(item, value)
810
- item.public_send(value)
811
- rescue NoMethodError
812
- raise unless item.respond_to?(value, true) && !item.respond_to?(value)
813
- ActiveSupport::Deprecation.warn "Using private methods from view helpers is deprecated (calling private #{item.class}##{value})"
814
- item.send(value)
805
+ value.respond_to?(:call) ? value.call(item) : item.public_send(value)
815
806
  end
816
807
 
817
808
  def prompt_text(prompt)
@@ -4,6 +4,7 @@ require "cgi"
4
4
  require "action_view/helpers/tag_helper"
5
5
  require "active_support/core_ext/string/output_safety"
6
6
  require "active_support/core_ext/module/attribute_accessors"
7
+ require "active_support/core_ext/symbol/starts_ends_with"
7
8
 
8
9
  module ActionView
9
10
  # = Action View Form Tag Helpers
@@ -134,7 +135,7 @@ module ActionView
134
135
  # # <option selected="selected">MasterCard</option></select>
135
136
  def select_tag(name, option_tags = nil, options = {})
136
137
  option_tags ||= ""
137
- html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
138
+ html_name = (options[:multiple] == true && !name.end_with?("[]")) ? "#{name}[]" : name
138
139
 
139
140
  if options.include?(:include_blank)
140
141
  include_blank = options[:include_blank]
@@ -896,16 +897,15 @@ module ActionView
896
897
  end
897
898
 
898
899
  def set_default_disable_with(value, tag_options)
899
- return unless ActionView::Base.automatically_disable_submit_tag
900
- data = tag_options["data"]
900
+ data = tag_options.fetch("data", {})
901
901
 
902
- unless tag_options["data-disable-with"] == false || (data && data["disable_with"] == false)
902
+ if tag_options["data-disable-with"] == false || data["disable_with"] == false
903
+ data.delete("disable_with")
904
+ elsif ActionView::Base.automatically_disable_submit_tag
903
905
  disable_with_text = tag_options["data-disable-with"]
904
- disable_with_text ||= data["disable_with"] if data
906
+ disable_with_text ||= data["disable_with"]
905
907
  disable_with_text ||= value.to_s.clone
906
908
  tag_options.deep_merge!("data" => { "disable_with" => disable_with_text })
907
- else
908
- data.delete("disable_with") if data
909
909
  end
910
910
 
911
911
  tag_options.delete("data-disable-with")
@@ -51,10 +51,10 @@ module ActionView
51
51
  # +html_options+ may be a hash of attributes for the <tt>\<script></tt>
52
52
  # tag.
53
53
  #
54
- # javascript_tag "alert('All is good')", defer: 'defer'
54
+ # javascript_tag "alert('All is good')", type: 'application/javascript'
55
55
  #
56
56
  # Returns:
57
- # <script defer="defer">
57
+ # <script type="application/javascript">
58
58
  # //<![CDATA[
59
59
  # alert('All is good')
60
60
  # //]]>
@@ -63,7 +63,7 @@ module ActionView
63
63
  # Instead of passing the content as an argument, you can also use a block
64
64
  # in which case, you pass your +html_options+ as the first parameter.
65
65
  #
66
- # <%= javascript_tag defer: 'defer' do -%>
66
+ # <%= javascript_tag type: 'application/javascript' do -%>
67
67
  # alert('All is good')
68
68
  # <% end -%>
69
69
  #