actionview 7.2.2.1 → 8.1.2

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -71
  3. data/README.rdoc +1 -1
  4. data/lib/action_view/base.rb +11 -11
  5. data/lib/action_view/buffers.rb +1 -1
  6. data/lib/action_view/dependency_tracker/erb_tracker.rb +37 -28
  7. data/lib/action_view/dependency_tracker/ruby_tracker.rb +2 -19
  8. data/lib/action_view/dependency_tracker/wildcard_resolver.rb +32 -0
  9. data/lib/action_view/dependency_tracker.rb +7 -1
  10. data/lib/action_view/digestor.rb +6 -2
  11. data/lib/action_view/gem_version.rb +3 -3
  12. data/lib/action_view/helpers/asset_tag_helper.rb +25 -6
  13. data/lib/action_view/helpers/atom_feed_helper.rb +1 -3
  14. data/lib/action_view/helpers/cache_helper.rb +10 -2
  15. data/lib/action_view/helpers/capture_helper.rb +2 -2
  16. data/lib/action_view/helpers/controller_helper.rb +6 -2
  17. data/lib/action_view/helpers/date_helper.rb +28 -4
  18. data/lib/action_view/helpers/form_helper.rb +103 -103
  19. data/lib/action_view/helpers/form_options_helper.rb +39 -35
  20. data/lib/action_view/helpers/form_tag_helper.rb +35 -25
  21. data/lib/action_view/helpers/javascript_helper.rb +5 -1
  22. data/lib/action_view/helpers/number_helper.rb +14 -0
  23. data/lib/action_view/helpers/output_safety_helper.rb +1 -2
  24. data/lib/action_view/helpers/rendering_helper.rb +160 -50
  25. data/lib/action_view/helpers/sanitize_helper.rb +6 -0
  26. data/lib/action_view/helpers/tag_helper.rb +57 -73
  27. data/lib/action_view/helpers/tags/base.rb +11 -9
  28. data/lib/action_view/helpers/tags/check_box.rb +9 -3
  29. data/lib/action_view/helpers/tags/collection_check_boxes.rb +4 -3
  30. data/lib/action_view/helpers/tags/collection_helpers.rb +2 -1
  31. data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
  32. data/lib/action_view/helpers/tags/file_field.rb +7 -2
  33. data/lib/action_view/helpers/tags/hidden_field.rb +1 -1
  34. data/lib/action_view/helpers/tags/label.rb +3 -10
  35. data/lib/action_view/helpers/tags/radio_button.rb +1 -1
  36. data/lib/action_view/helpers/tags/select.rb +6 -1
  37. data/lib/action_view/helpers/tags/select_renderer.rb +6 -4
  38. data/lib/action_view/helpers/tags/text_area.rb +1 -1
  39. data/lib/action_view/helpers/tags/text_field.rb +1 -1
  40. data/lib/action_view/helpers/text_helper.rb +10 -3
  41. data/lib/action_view/helpers/translation_helper.rb +6 -1
  42. data/lib/action_view/helpers/url_helper.rb +39 -13
  43. data/lib/action_view/layouts.rb +7 -7
  44. data/lib/action_view/locale/en.yml +3 -0
  45. data/lib/action_view/log_subscriber.rb +1 -4
  46. data/lib/action_view/railtie.rb +12 -1
  47. data/lib/action_view/record_identifier.rb +22 -1
  48. data/lib/action_view/render_parser/prism_render_parser.rb +13 -1
  49. data/lib/action_view/render_parser/ripper_render_parser.rb +10 -1
  50. data/lib/action_view/renderer/partial_renderer.rb +18 -2
  51. data/lib/action_view/renderer/streaming_template_renderer.rb +8 -2
  52. data/lib/action_view/renderer/template_renderer.rb +3 -3
  53. data/lib/action_view/rendering.rb +2 -3
  54. data/lib/action_view/structured_event_subscriber.rb +97 -0
  55. data/lib/action_view/template/error.rb +18 -3
  56. data/lib/action_view/template/handlers/erb/erubi.rb +1 -1
  57. data/lib/action_view/template/handlers/erb.rb +77 -44
  58. data/lib/action_view/template/raw_file.rb +4 -0
  59. data/lib/action_view/template/resolver.rb +0 -1
  60. data/lib/action_view/template.rb +3 -4
  61. data/lib/action_view/test_case.rb +50 -53
  62. data/lib/action_view.rb +4 -0
  63. metadata +15 -16
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cgi"
4
3
  require "erb"
5
4
  require "active_support/core_ext/string/output_safety"
6
5
  require "active_support/core_ext/array/extract_options"
@@ -13,7 +12,7 @@ module ActionView
13
12
  #
14
13
  # Provides a number of methods for turning different kinds of containers into a set of option tags.
15
14
  #
16
- # The <tt>collection_select</tt>, <tt>select</tt> and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter, a hash:
15
+ # The #collection_select, #select and #time_zone_select methods take an <tt>options</tt> parameter, a hash:
17
16
  #
18
17
  # * <tt>:include_blank</tt> - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.
19
18
  #
@@ -55,7 +54,7 @@ module ActionView
55
54
  # <option value="3">Rafael</option>
56
55
  # </select>
57
56
  #
58
- # * <tt>:index</tt> - like the other form helpers, <tt>select</tt> can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, <tt>select</tt> expects this
57
+ # * <tt>:index</tt> - like the other form helpers, #select can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, #select expects this
59
58
  # option to be in the +html_options+ parameter.
60
59
  #
61
60
  # select("album[]", :genre, %w[ rap rock country ], {}, { index: nil })
@@ -80,7 +79,7 @@ module ActionView
80
79
  # <option disabled="disabled" value="restricted">restricted</option>
81
80
  # </select>
82
81
  #
83
- # When used with the <tt>collection_select</tt> helper, <tt>:disabled</tt> can also be a Proc that identifies those options that should be disabled.
82
+ # When used with the #collection_select helper, <tt>:disabled</tt> can also be a Proc that identifies those options that should be disabled.
84
83
  #
85
84
  # collection_select(:post, :category_id, Category.all, :id, :name, { disabled: -> (category) { category.archived? } })
86
85
  #
@@ -105,7 +104,7 @@ module ActionView
105
104
  #
106
105
  # Example with <tt>@post.person_id => 2</tt>:
107
106
  #
108
- # select :post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })
107
+ # select :post, :person_id, Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true }
109
108
  #
110
109
  # would become:
111
110
  #
@@ -126,7 +125,7 @@ module ActionView
126
125
  # or <tt>selected: nil</tt> to leave all options unselected. Similarly, you can specify values to be disabled in the option
127
126
  # tags by specifying the <tt>:disabled</tt> option. This can either be a single value or an array of values to be disabled.
128
127
  #
129
- # A block can be passed to +select+ to customize how the options tags will be rendered. This
128
+ # A block can be passed to #select to customize how the options tags will be rendered. This
130
129
  # is useful when the options tag has complex attributes.
131
130
  #
132
131
  # select(report, :campaign_ids) do
@@ -265,7 +264,7 @@ module ActionView
265
264
  # In addition to the <tt>:include_blank</tt> option documented above,
266
265
  # this method also supports a <tt>:model</tt> option, which defaults
267
266
  # to ActiveSupport::TimeZone. This may be used by users to specify a
268
- # different time zone model object. (See +time_zone_options_for_select+
267
+ # different time zone model object. (See #time_zone_options_for_select
269
268
  # for more information.)
270
269
  #
271
270
  # You can also supply an array of ActiveSupport::TimeZone objects
@@ -294,7 +293,7 @@ module ActionView
294
293
  end
295
294
 
296
295
  # Returns select and option tags for the given object and method, using
297
- # <tt>weekday_options_for_select</tt> to generate the list of option tags.
296
+ # #weekday_options_for_select to generate the list of option tags.
298
297
  def weekday_select(object, method, options = {}, html_options = {}, &block)
299
298
  Tags::WeekdaySelect.new(object, method, self, options, html_options, &block).render
300
299
  end
@@ -370,7 +369,7 @@ module ActionView
370
369
  html_attributes[:disabled] ||= disabled && option_value_selected?(value, disabled)
371
370
  html_attributes[:value] = value
372
371
 
373
- tag_builder.content_tag_string(:option, text, html_attributes)
372
+ tag_builder.option(text, **html_attributes)
374
373
  end.join("\n").html_safe
375
374
  end
376
375
 
@@ -411,7 +410,7 @@ module ActionView
411
410
  options_for_select(options, select_deselect)
412
411
  end
413
412
 
414
- # Returns a string of <tt><option></tt> tags, like <tt>options_from_collection_for_select</tt>, but
413
+ # Returns a string of <tt><option></tt> tags, like #options_from_collection_for_select, but
415
414
  # groups them by <tt><optgroup></tt> tags based on the object relationships of the arguments.
416
415
  #
417
416
  # Parameters:
@@ -468,7 +467,7 @@ module ActionView
468
467
  end.join.html_safe
469
468
  end
470
469
 
471
- # Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
470
+ # Returns a string of <tt><option></tt> tags, like #options_for_select, but
472
471
  # wraps them with <tt><optgroup></tt> tags:
473
472
  #
474
473
  # grouped_options = [
@@ -496,7 +495,8 @@ module ActionView
496
495
  # <option value="France">France</option>
497
496
  # </optgroup>
498
497
  #
499
- # Parameters:
498
+ # ==== Parameters
499
+ #
500
500
  # * +grouped_options+ - Accepts a nested array or hash of strings. The first value serves as the
501
501
  # <tt><optgroup></tt> label while the second value must be an array of options. The second value can be a
502
502
  # nested array of text-value pairs. See <tt>options_for_select</tt> for more info.
@@ -507,7 +507,8 @@ module ActionView
507
507
  # which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
508
508
  # as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
509
509
  #
510
- # Options:
510
+ # ==== Options
511
+ #
511
512
  # * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this
512
513
  # prepends an option with a generic prompt - "Please select" - or the given prompt string.
513
514
  # * <tt>:divider</tt> - the divider for the options groups.
@@ -599,7 +600,8 @@ module ActionView
599
600
 
600
601
  # Returns a string of option tags for the days of the week.
601
602
  #
602
- # Options:
603
+ # ====Options
604
+ #
603
605
  # * <tt>:index_as_value</tt> - Defaults to false, set to true to use the indexes from
604
606
  # <tt>I18n.translate("date.day_names")</tt> as the values. By default, Sunday is always 0.
605
607
  # * <tt>:day_format</tt> - The I18n key of the array to use for the weekday options.
@@ -686,7 +688,7 @@ module ActionView
686
688
  # if a +User+ model has a +category_id+ field and in the form no category is selected, no +category_id+ parameter is sent. So,
687
689
  # any strong parameters idiom like:
688
690
  #
689
- # params.require(:user).permit(...)
691
+ # params.expect(user: [...])
690
692
  #
691
693
  # will raise an error since no <tt>{user: ...}</tt> will be present.
692
694
  #
@@ -723,7 +725,7 @@ module ActionView
723
725
  # end
724
726
  #
725
727
  # Sample usage (selecting the associated Author for an instance of Post, <tt>@post</tt>):
726
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
728
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial)
727
729
  #
728
730
  # If <tt>@post.author_ids</tt> is already <tt>[1]</tt>, this would return:
729
731
  # <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
@@ -736,8 +738,8 @@ module ActionView
736
738
  #
737
739
  # It is also possible to customize the way the elements will be shown by
738
740
  # giving a block to the method:
739
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
740
- # b.label { b.check_box }
741
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
742
+ # b.label { b.checkbox }
741
743
  # end
742
744
  #
743
745
  # The argument passed to the block is a special kind of builder for this
@@ -746,17 +748,17 @@ module ActionView
746
748
  # Using it, you can change the label and check box display order or even
747
749
  # use the label as wrapper, as in the example above.
748
750
  #
749
- # The builder methods <tt>label</tt> and <tt>check_box</tt> also accept
751
+ # The builder methods <tt>label</tt> and <tt>checkbox</tt> also accept
750
752
  # extra HTML options:
751
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
752
- # b.label(class: "check_box") { b.check_box(class: "check_box") }
753
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
754
+ # b.label(class: "checkbox") { b.checkbox(class: "checkbox") }
753
755
  # end
754
756
  #
755
757
  # There are also three special methods available: <tt>object</tt>, <tt>text</tt> and
756
758
  # <tt>value</tt>, which are the current item being rendered, its text and value methods,
757
759
  # respectively. You can use them like this:
758
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
759
- # b.label(:"data-value" => b.value) { b.check_box + b.text }
760
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
761
+ # b.label(:"data-value" => b.value) { b.checkbox + b.text }
760
762
  # end
761
763
  #
762
764
  # ==== Gotcha
@@ -779,9 +781,10 @@ module ActionView
779
781
  #
780
782
  # In the rare case you don't want this hidden field, you can pass the
781
783
  # <tt>include_hidden: false</tt> option to the helper method.
782
- def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
784
+ def collection_checkboxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
783
785
  Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
784
786
  end
787
+ alias_method :collection_check_boxes, :collection_checkboxes
785
788
 
786
789
  private
787
790
  def option_html_attributes(element)
@@ -839,7 +842,7 @@ module ActionView
839
842
  class FormBuilder
840
843
  # Wraps ActionView::Helpers::FormOptionsHelper#select for form builders:
841
844
  #
842
- # <%= form_for @post do |f| %>
845
+ # <%= form_with model: @post do |f| %>
843
846
  # <%= f.select :person_id, Person.all.collect { |p| [ p.name, p.id ] }, include_blank: true %>
844
847
  # <%= f.submit %>
845
848
  # <% end %>
@@ -851,7 +854,7 @@ module ActionView
851
854
 
852
855
  # Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders:
853
856
  #
854
- # <%= form_for @post do |f| %>
857
+ # <%= form_with model: @post do |f| %>
855
858
  # <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %>
856
859
  # <%= f.submit %>
857
860
  # <% end %>
@@ -863,7 +866,7 @@ module ActionView
863
866
 
864
867
  # Wraps ActionView::Helpers::FormOptionsHelper#grouped_collection_select for form builders:
865
868
  #
866
- # <%= form_for @city do |f| %>
869
+ # <%= form_with model: @city do |f| %>
867
870
  # <%= f.grouped_collection_select :country_id, @continents, :countries, :name, :id, :name %>
868
871
  # <%= f.submit %>
869
872
  # <% end %>
@@ -875,7 +878,7 @@ module ActionView
875
878
 
876
879
  # Wraps ActionView::Helpers::FormOptionsHelper#time_zone_select for form builders:
877
880
  #
878
- # <%= form_for @user do |f| %>
881
+ # <%= form_with model: @user do |f| %>
879
882
  # <%= f.time_zone_select :time_zone, nil, include_blank: true %>
880
883
  # <%= f.submit %>
881
884
  # <% end %>
@@ -887,7 +890,7 @@ module ActionView
887
890
 
888
891
  # Wraps ActionView::Helpers::FormOptionsHelper#weekday_select for form builders:
889
892
  #
890
- # <%= form_for @user do |f| %>
893
+ # <%= form_with model: @user do |f| %>
891
894
  # <%= f.weekday_select :weekday, include_blank: true %>
892
895
  # <%= f.submit %>
893
896
  # <% end %>
@@ -897,21 +900,22 @@ module ActionView
897
900
  @template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
898
901
  end
899
902
 
900
- # Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:
903
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_checkboxes for form builders:
901
904
  #
902
- # <%= form_for @post do |f| %>
903
- # <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
905
+ # <%= form_with model: @post do |f| %>
906
+ # <%= f.collection_checkboxes :author_ids, Author.all, :id, :name_with_initial %>
904
907
  # <%= f.submit %>
905
908
  # <% end %>
906
909
  #
907
910
  # Please refer to the documentation of the base helper for details.
908
- def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
909
- @template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
911
+ def collection_checkboxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
912
+ @template.collection_checkboxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
910
913
  end
914
+ alias_method :collection_check_boxes, :collection_checkboxes
911
915
 
912
916
  # Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:
913
917
  #
914
- # <%= form_for @post do |f| %>
918
+ # <%= form_with model: @post do |f| %>
915
919
  # <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %>
916
920
  # <%= f.submit %>
917
921
  # <% end %>
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cgi"
4
3
  require "action_view/helpers/content_exfiltration_prevention_helper"
5
4
  require "action_view/helpers/url_helper"
6
5
  require "action_view/helpers/text_helper"
@@ -306,7 +305,11 @@ module ActionView
306
305
  # # => <input type="hidden" name="collected_input" id="collected_input"
307
306
  # value="" onchange="alert(&#39;Input collected!&#39;)" autocomplete="off" />
308
307
  def hidden_field_tag(name, value = nil, options = {})
309
- text_field_tag(name, value, options.merge(type: :hidden, autocomplete: "off"))
308
+ html_options = options.merge(type: :hidden)
309
+ unless ActionView::Base.remove_hidden_field_autocomplete
310
+ html_options[:autocomplete] = "off" unless html_options.key?(:autocomplete)
311
+ end
312
+ text_field_tag(name, value, html_options)
310
313
  end
311
314
 
312
315
  # Creates a file upload field. If you are using file uploads then you will also need
@@ -393,24 +396,24 @@ module ActionView
393
396
  # * Any other key creates standard HTML attributes for the tag.
394
397
  #
395
398
  # ==== Examples
396
- # text_area_tag 'post'
399
+ # textarea_tag 'post'
397
400
  # # => <textarea id="post" name="post"></textarea>
398
401
  #
399
- # text_area_tag 'bio', @user.bio
402
+ # textarea_tag 'bio', @user.bio
400
403
  # # => <textarea id="bio" name="bio">This is my biography.</textarea>
401
404
  #
402
- # text_area_tag 'body', nil, rows: 10, cols: 25
405
+ # textarea_tag 'body', nil, rows: 10, cols: 25
403
406
  # # => <textarea cols="25" id="body" name="body" rows="10"></textarea>
404
407
  #
405
- # text_area_tag 'body', nil, size: "25x10"
408
+ # textarea_tag 'body', nil, size: "25x10"
406
409
  # # => <textarea name="body" id="body" cols="25" rows="10"></textarea>
407
410
  #
408
- # text_area_tag 'description', "Description goes here.", disabled: true
411
+ # textarea_tag 'description', "Description goes here.", disabled: true
409
412
  # # => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>
410
413
  #
411
- # text_area_tag 'comment', nil, class: 'comment_input'
414
+ # textarea_tag 'comment', nil, class: 'comment_input'
412
415
  # # => <textarea class="comment_input" id="comment" name="comment"></textarea>
413
- def text_area_tag(name, content = nil, options = {})
416
+ def textarea_tag(name, content = nil, options = {})
414
417
  options = options.stringify_keys
415
418
 
416
419
  if size = options.delete("size")
@@ -422,12 +425,13 @@ module ActionView
422
425
 
423
426
  content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
424
427
  end
428
+ alias_method :text_area_tag, :textarea_tag
425
429
 
426
430
  ##
427
431
  # :call-seq:
428
- # check_box_tag(name, options = {})
429
- # check_box_tag(name, value, options = {})
430
- # check_box_tag(name, value, checked, options = {})
432
+ # checkbox_tag(name, options = {})
433
+ # checkbox_tag(name, value, options = {})
434
+ # checkbox_tag(name, value, checked, options = {})
431
435
  #
432
436
  # Creates a check box form input tag.
433
437
  #
@@ -438,21 +442,21 @@ module ActionView
438
442
  # * Any other key creates standard HTML options for the tag.
439
443
  #
440
444
  # ==== Examples
441
- # check_box_tag 'accept'
445
+ # checkbox_tag 'accept'
442
446
  # # => <input id="accept" name="accept" type="checkbox" value="1" />
443
447
  #
444
- # check_box_tag 'rock', 'rock music'
448
+ # checkbox_tag 'rock', 'rock music'
445
449
  # # => <input id="rock" name="rock" type="checkbox" value="rock music" />
446
450
  #
447
- # check_box_tag 'receive_email', 'yes', true
451
+ # checkbox_tag 'receive_email', 'yes', true
448
452
  # # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />
449
453
  #
450
- # check_box_tag 'tos', 'yes', false, class: 'accept_tos'
454
+ # checkbox_tag 'tos', 'yes', false, class: 'accept_tos'
451
455
  # # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />
452
456
  #
453
- # check_box_tag 'eula', 'accepted', false, disabled: true
457
+ # checkbox_tag 'eula', 'accepted', false, disabled: true
454
458
  # # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
455
- def check_box_tag(name, *args)
459
+ def checkbox_tag(name, *args)
456
460
  if args.length >= 4
457
461
  raise ArgumentError, "wrong number of arguments (given #{args.length + 1}, expected 1..4)"
458
462
  end
@@ -462,6 +466,7 @@ module ActionView
462
466
  html_options["checked"] = "checked" if checked
463
467
  tag :input, html_options
464
468
  end
469
+ alias_method :check_box_tag, :checkbox_tag
465
470
 
466
471
  ##
467
472
  # :call-seq:
@@ -974,10 +979,15 @@ module ActionView
974
979
  # Creates the hidden UTF-8 enforcer tag. Override this method in a helper
975
980
  # to customize the tag.
976
981
  def utf8_enforcer_tag
977
- # Use raw HTML to ensure the value is written as an HTML entity; it
978
- # needs to be the right character regardless of which encoding the
979
- # browser infers.
980
- '<input name="utf8" type="hidden" value="&#x2713;" autocomplete="off" />'.html_safe
982
+ options = {
983
+ type: "hidden",
984
+ name: "utf8",
985
+ value: "&#x2713;".html_safe
986
+ }
987
+
988
+ options[:autocomplete] = "off" unless ActionView::Base.remove_hidden_field_autocomplete
989
+
990
+ tag(:input, options)
981
991
  end
982
992
 
983
993
  private
@@ -1045,9 +1055,9 @@ module ActionView
1045
1055
  end
1046
1056
 
1047
1057
  def form_tag_with_body(html_options, content)
1048
- output = form_tag_html(html_options)
1049
- output << content.to_s if content
1050
- output.safe_concat("</form>")
1058
+ extra_tags = extra_tags_for_form(html_options)
1059
+ html = content_tag(:form, safe_join([extra_tags, content]), html_options)
1060
+ prevent_content_exfiltration(html)
1051
1061
  end
1052
1062
 
1053
1063
  # see http://www.w3.org/TR/html4/types.html#type-name
@@ -4,6 +4,8 @@ module ActionView
4
4
  module Helpers # :nodoc:
5
5
  # = Action View JavaScript \Helpers
6
6
  module JavaScriptHelper
7
+ mattr_accessor :auto_include_nonce
8
+
7
9
  JS_ESCAPE_MAP = {
8
10
  "\\" => "\\\\",
9
11
  "</" => '<\/',
@@ -81,8 +83,10 @@ module ActionView
81
83
  content_or_options_with_block
82
84
  end
83
85
 
84
- if html_options[:nonce] == true
86
+ if html_options[:nonce] == true || (!html_options.key?(:nonce) && auto_include_nonce)
85
87
  html_options[:nonce] = content_security_policy_nonce
88
+ elsif html_options[:nonce] == false
89
+ html_options.delete(:nonce)
86
90
  end
87
91
 
88
92
  content_tag("script", javascript_cdata_section(content), html_options)
@@ -26,6 +26,8 @@ module ActionView
26
26
 
27
27
  # Delegates to ActiveSupport::NumberHelper#number_to_phone.
28
28
  #
29
+ # number_to_phone("1234567890") # => "123-456-7890"
30
+ #
29
31
  # Additionally, supports a +:raise+ option that will cause
30
32
  # InvalidNumberError to be raised if +number+ is not a valid number:
31
33
  #
@@ -42,6 +44,8 @@ module ActionView
42
44
 
43
45
  # Delegates to ActiveSupport::NumberHelper#number_to_currency.
44
46
  #
47
+ # number_to_currency("1234") # => "$1234.00"
48
+ #
45
49
  # Additionally, supports a +:raise+ option that will cause
46
50
  # InvalidNumberError to be raised if +number+ is not a valid number:
47
51
  #
@@ -54,6 +58,8 @@ module ActionView
54
58
 
55
59
  # Delegates to ActiveSupport::NumberHelper#number_to_percentage.
56
60
  #
61
+ # number_to_percentage("99") # => "99.000%"
62
+ #
57
63
  # Additionally, supports a +:raise+ option that will cause
58
64
  # InvalidNumberError to be raised if +number+ is not a valid number:
59
65
  #
@@ -66,6 +72,8 @@ module ActionView
66
72
 
67
73
  # Delegates to ActiveSupport::NumberHelper#number_to_delimited.
68
74
  #
75
+ # number_with_delimiter("1234") # => "1,234"
76
+ #
69
77
  # Additionally, supports a +:raise+ option that will cause
70
78
  # InvalidNumberError to be raised if +number+ is not a valid number:
71
79
  #
@@ -78,6 +86,8 @@ module ActionView
78
86
 
79
87
  # Delegates to ActiveSupport::NumberHelper#number_to_rounded.
80
88
  #
89
+ # number_with_precision("1234") # => "1234.000"
90
+ #
81
91
  # Additionally, supports a +:raise+ option that will cause
82
92
  # InvalidNumberError to be raised if +number+ is not a valid number:
83
93
  #
@@ -90,6 +100,8 @@ module ActionView
90
100
 
91
101
  # Delegates to ActiveSupport::NumberHelper#number_to_human_size.
92
102
  #
103
+ # number_to_human_size("1234") # => "1.21 KB"
104
+ #
93
105
  # Additionally, supports a +:raise+ option that will cause
94
106
  # InvalidNumberError to be raised if +number+ is not a valid number:
95
107
  #
@@ -102,6 +114,8 @@ module ActionView
102
114
 
103
115
  # Delegates to ActiveSupport::NumberHelper#number_to_human.
104
116
  #
117
+ # number_to_human("1234") # => "1.23 Thousand"
118
+ #
105
119
  # Additionally, supports a +:raise+ option that will cause
106
120
  # InvalidNumberError to be raised if +number+ is not a valid number:
107
121
  #
@@ -38,8 +38,7 @@ module ActionView # :nodoc:
38
38
 
39
39
  # Converts the array to a comma-separated sentence where the last element is
40
40
  # joined by the connector word. This is the html_safe-aware version of
41
- # ActiveSupport's {Array#to_sentence}[https://api.rubyonrails.org/classes/Array.html#method-i-to_sentence].
42
- #
41
+ # ActiveSupport's Array#to_sentence.
43
42
  def to_sentence(array, options = {})
44
43
  options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
45
44