actionview 7.0.7.2 → 7.1.1

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +262 -329
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/app/assets/javascripts/rails-ujs.esm.js +693 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +33 -12
  8. data/lib/action_view/buffers.rb +106 -8
  9. data/lib/action_view/cache_expiry.rb +40 -43
  10. data/lib/action_view/context.rb +1 -1
  11. data/lib/action_view/deprecator.rb +7 -0
  12. data/lib/action_view/digestor.rb +1 -1
  13. data/lib/action_view/gem_version.rb +4 -4
  14. data/lib/action_view/helpers/active_model_helper.rb +1 -1
  15. data/lib/action_view/helpers/asset_tag_helper.rb +130 -46
  16. data/lib/action_view/helpers/asset_url_helper.rb +6 -5
  17. data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
  18. data/lib/action_view/helpers/cache_helper.rb +3 -9
  19. data/lib/action_view/helpers/capture_helper.rb +24 -10
  20. data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
  21. data/lib/action_view/helpers/controller_helper.rb +6 -0
  22. data/lib/action_view/helpers/csp_helper.rb +2 -2
  23. data/lib/action_view/helpers/csrf_helper.rb +2 -2
  24. data/lib/action_view/helpers/date_helper.rb +17 -19
  25. data/lib/action_view/helpers/debug_helper.rb +3 -3
  26. data/lib/action_view/helpers/form_helper.rb +43 -17
  27. data/lib/action_view/helpers/form_options_helper.rb +2 -1
  28. data/lib/action_view/helpers/form_tag_helper.rb +43 -9
  29. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  30. data/lib/action_view/helpers/number_helper.rb +2 -1
  31. data/lib/action_view/helpers/output_safety_helper.rb +2 -2
  32. data/lib/action_view/helpers/rendering_helper.rb +1 -1
  33. data/lib/action_view/helpers/sanitize_helper.rb +33 -14
  34. data/lib/action_view/helpers/tag_helper.rb +5 -27
  35. data/lib/action_view/helpers/tags/base.rb +11 -52
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
  37. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
  38. data/lib/action_view/helpers/tags/collection_select.rb +3 -0
  39. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  40. data/lib/action_view/helpers/tags/date_select.rb +2 -0
  41. data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
  42. data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
  43. data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
  44. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  45. data/lib/action_view/helpers/tags/select.rb +3 -0
  46. data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
  47. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  48. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
  49. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  50. data/lib/action_view/helpers/tags/weekday_select.rb +3 -0
  51. data/lib/action_view/helpers/tags.rb +2 -0
  52. data/lib/action_view/helpers/text_helper.rb +32 -16
  53. data/lib/action_view/helpers/translation_helper.rb +3 -3
  54. data/lib/action_view/helpers/url_helper.rb +41 -14
  55. data/lib/action_view/helpers.rb +2 -0
  56. data/lib/action_view/layouts.rb +6 -4
  57. data/lib/action_view/log_subscriber.rb +49 -32
  58. data/lib/action_view/lookup_context.rb +29 -13
  59. data/lib/action_view/path_registry.rb +57 -0
  60. data/lib/action_view/path_set.rb +13 -14
  61. data/lib/action_view/railtie.rb +26 -3
  62. data/lib/action_view/record_identifier.rb +15 -8
  63. data/lib/action_view/renderer/abstract_renderer.rb +1 -1
  64. data/lib/action_view/renderer/collection_renderer.rb +9 -1
  65. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +10 -2
  66. data/lib/action_view/renderer/partial_renderer.rb +2 -1
  67. data/lib/action_view/renderer/renderer.rb +2 -0
  68. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -2
  69. data/lib/action_view/renderer/template_renderer.rb +3 -2
  70. data/lib/action_view/rendering.rb +22 -4
  71. data/lib/action_view/ripper_ast_parser.rb +6 -6
  72. data/lib/action_view/template/error.rb +14 -1
  73. data/lib/action_view/template/handlers/builder.rb +4 -4
  74. data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
  75. data/lib/action_view/template/handlers/erb.rb +73 -1
  76. data/lib/action_view/template/handlers.rb +1 -1
  77. data/lib/action_view/template/html.rb +1 -1
  78. data/lib/action_view/template/raw_file.rb +1 -1
  79. data/lib/action_view/template/renderable.rb +1 -1
  80. data/lib/action_view/template/resolver.rb +10 -2
  81. data/lib/action_view/template/text.rb +1 -1
  82. data/lib/action_view/template/types.rb +25 -34
  83. data/lib/action_view/template.rb +227 -53
  84. data/lib/action_view/template_path.rb +2 -0
  85. data/lib/action_view/test_case.rb +174 -21
  86. data/lib/action_view/unbound_template.rb +15 -5
  87. data/lib/action_view/version.rb +1 -1
  88. data/lib/action_view/view_paths.rb +15 -24
  89. data/lib/action_view.rb +4 -1
  90. metadata +24 -24
@@ -10,7 +10,7 @@ require "active_support/core_ext/object/with_options"
10
10
 
11
11
  module ActionView
12
12
  module Helpers # :nodoc:
13
- # = Action View Date Helpers
13
+ # = Action View \Date \Helpers
14
14
  #
15
15
  # The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time
16
16
  # elements. All of the select-type methods share a number of common options that are as follows:
@@ -72,7 +72,7 @@ module ActionView
72
72
  # distance_of_time_in_words(to_time, from_time, include_seconds: true) # => about 6 years
73
73
  # distance_of_time_in_words(Time.now, Time.now) # => less than a minute
74
74
  #
75
- # With the <tt>scope</tt> option, you can define a custom scope for Rails
75
+ # With the <tt>scope</tt> option, you can define a custom scope for \Rails
76
76
  # to look up the translation.
77
77
  #
78
78
  # For example you can define the following in your locale (e.g. en.yml).
@@ -217,7 +217,7 @@ module ActionView
217
217
  # * <tt>:order</tt> - Set to an array containing <tt>:day</tt>, <tt>:month</tt> and <tt>:year</tt> to
218
218
  # customize the order in which the select fields are shown. If you leave out any of the symbols, the respective
219
219
  # select will not be shown (like when you set <tt>discard_xxx: true</tt>. Defaults to the order defined in
220
- # the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).
220
+ # the respective locale (e.g. [:year, :month, :day] in the en locale that ships with \Rails).
221
221
  # * <tt>:include_blank</tt> - Include a blank option in every select field so it's possible to set empty
222
222
  # dates.
223
223
  # * <tt>:default</tt> - Set a default date if the affected date isn't set or is +nil+.
@@ -320,6 +320,10 @@ module ActionView
320
320
  # # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
321
321
  # time_select 'game', 'game_time', { ampm: true }
322
322
  #
323
+ # # You can set :ignore_date option to true which will remove the hidden inputs for day,
324
+ # # month, and year that are set by default on this helper when you only want the time inputs
325
+ # time_select 'game', 'game_time', { ignore_date: true }
326
+ #
323
327
  # The selects are prepared for multi-parameter assignment to an Active Record object.
324
328
  #
325
329
  # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that
@@ -844,14 +848,14 @@ module ActionView
844
848
  if @options[:use_hidden] || @options[:discard_year]
845
849
  build_hidden(:year, val)
846
850
  else
847
- options = {}
848
- options[:start] = @options[:start_year] || middle_year - 5
849
- options[:end] = @options[:end_year] || middle_year + 5
850
- options[:step] = options[:start] < options[:end] ? 1 : -1
851
- options[:leading_zeros] = false
852
- options[:max_years_allowed] = @options[:max_years_allowed] || 1000
853
-
854
- if (options[:end] - options[:start]).abs > options[:max_years_allowed]
851
+ options = {}
852
+ options[:start] = @options[:start_year] || middle_year - 5
853
+ options[:end] = @options[:end_year] || middle_year + 5
854
+ options[:step] = options[:start] < options[:end] ? 1 : -1
855
+
856
+ max_years_allowed = @options[:max_years_allowed] || 1000
857
+
858
+ if (options[:end] - options[:start]).abs > max_years_allowed
855
859
  raise ArgumentError, "There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter."
856
860
  end
857
861
 
@@ -936,7 +940,7 @@ module ActionView
936
940
  #
937
941
  # month_name(1) # => 1
938
942
  #
939
- # If the <tt>:use_two_month_numbers</tt> option is passed:
943
+ # If the <tt>:use_two_digit_numbers</tt> option is passed:
940
944
  #
941
945
  # month_name(1) # => '01'
942
946
  #
@@ -1076,17 +1080,11 @@ module ActionView
1076
1080
  end
1077
1081
 
1078
1082
  # Build select option HTML for year.
1079
- # If <tt>year_format</tt> option is not passed
1083
+ #
1080
1084
  # build_year_options(1998, start: 1998, end: 2000)
1081
1085
  # => "<option value="1998" selected="selected">1998</option>
1082
1086
  # <option value="1999">1999</option>
1083
1087
  # <option value="2000">2000</option>"
1084
- #
1085
- # If <tt>year_format</tt> option is passed
1086
- # build_year_options(1998, start: 1998, end: 2000, year_format: ->year { "Heisei #{ year - 1988 }" })
1087
- # => "<option value="1998" selected="selected">Heisei 10</option>
1088
- # <option value="1999">Heisei 11</option>
1089
- # <option value="2000">Heisei 12</option>"
1090
1088
  def build_year_options(selected, options = {})
1091
1089
  start = options.delete(:start)
1092
1090
  stop = options.delete(:end)
@@ -3,10 +3,10 @@
3
3
  require "action_view/helpers/tag_helper"
4
4
 
5
5
  module ActionView
6
- # = Action View Debug Helper
7
- #
8
- # Provides a set of methods for making it easier to debug Rails objects.
9
6
  module Helpers # :nodoc:
7
+ # = Action View Debug \Helpers
8
+ #
9
+ # Provides a set of methods for making it easier to debug \Rails objects.
10
10
  module DebugHelper
11
11
  include TagHelper
12
12
 
@@ -13,8 +13,9 @@ require "active_support/core_ext/string/output_safety"
13
13
  require "active_support/core_ext/string/inflections"
14
14
 
15
15
  module ActionView
16
- # = Action View Form Helpers
17
16
  module Helpers # :nodoc:
17
+ # = Action View Form \Helpers
18
+ #
18
19
  # Form helpers are designed to make working with resources much easier
19
20
  # compared to using vanilla HTML.
20
21
  #
@@ -28,7 +29,7 @@ module ActionView
28
29
  # when the form is initially displayed, input fields corresponding to attributes
29
30
  # of the resource should show the current values of those attributes.
30
31
  #
31
- # In Rails, this is usually achieved by creating the form using +form_for+ and
32
+ # In \Rails, this is usually achieved by creating the form using +form_for+ and
32
33
  # a number of related helper methods. +form_for+ generates an appropriate <tt>form</tt>
33
34
  # tag and yields a form builder object that knows the model the form is about.
34
35
  # Input fields are created by calling methods defined on the form builder, which
@@ -122,7 +123,7 @@ module ActionView
122
123
  # of a specific model object.
123
124
  #
124
125
  # The method can be used in several slightly different ways, depending on
125
- # how much you wish to rely on Rails to infer automatically from the model
126
+ # how much you wish to rely on \Rails to infer automatically from the model
126
127
  # how the form should be constructed. For a generic model object, a form
127
128
  # can be created by passing +form_for+ a string or symbol representing
128
129
  # the object we are concerned with:
@@ -251,7 +252,7 @@ module ActionView
251
252
  # form is going to be sent. However, further simplification is possible
252
253
  # if the record passed to +form_for+ is a _resource_, i.e. it corresponds
253
254
  # to a set of RESTful routes, e.g. defined using the +resources+ method
254
- # in <tt>config/routes.rb</tt>. In this case Rails will simply infer the
255
+ # in <tt>config/routes.rb</tt>. In this case \Rails will simply infer the
255
256
  # appropriate URL from the record itself. For example,
256
257
  #
257
258
  # <%= form_for @post do |f| %>
@@ -438,7 +439,7 @@ module ActionView
438
439
  model = nil
439
440
  object_name = record
440
441
  else
441
- model = convert_to_model(record)
442
+ model = record
442
443
  object = _object_for_form_builder(record)
443
444
  raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
444
445
  object_name = options[:as] || model_name_from_record_or_class(object).param_key
@@ -496,7 +497,7 @@ module ActionView
496
497
  # <%= form.text_field :title %>
497
498
  # <% end %>
498
499
  # # =>
499
- # <form method="post" data-remote="true">
500
+ # <form method="post">
500
501
  # <input type="text" name="title">
501
502
  # </form>
502
503
  #
@@ -555,7 +556,7 @@ module ActionView
555
556
  # is a _resource_. It corresponds to a set of RESTful routes, most likely
556
557
  # defined via +resources+ in <tt>config/routes.rb</tt>.
557
558
  #
558
- # So when passing such a model record, Rails infers the URL and method.
559
+ # So when passing such a model record, \Rails infers the URL and method.
559
560
  #
560
561
  # <%= form_with model: @post do |form| %>
561
562
  # ...
@@ -618,12 +619,12 @@ module ActionView
618
619
  # * <tt>:local</tt> - Whether to use standard HTTP form submission.
619
620
  # When set to <tt>true</tt>, the form is submitted via standard HTTP.
620
621
  # When set to <tt>false</tt>, the form is submitted as a "remote form", which
621
- # is handled by Rails UJS as an XHR. When unspecified, the behavior is derived
622
+ # is handled by \Rails UJS as an XHR. When unspecified, the behavior is derived
622
623
  # from <tt>config.action_view.form_with_generates_remote_forms</tt> where the
623
624
  # config's value is actually the inverse of what <tt>local</tt>'s value would be.
624
- # As of Rails 6.1, that configuration option defaults to <tt>false</tt>
625
+ # As of \Rails 6.1, that configuration option defaults to <tt>false</tt>
625
626
  # (which has the equivalent effect of passing <tt>local: true</tt>).
626
- # In previous versions of Rails, that configuration option defaults to
627
+ # In previous versions of \Rails, that configuration option defaults to
627
628
  # <tt>true</tt> (the equivalent of passing <tt>local: false</tt>).
628
629
  # * <tt>:skip_enforcing_utf8</tt> - If set to true, a hidden input with name
629
630
  # utf8 is not output.
@@ -756,10 +757,14 @@ module ActionView
756
757
 
757
758
  if model
758
759
  if url != false
759
- url ||= polymorphic_path(model, format: format)
760
+ url ||= if format.nil?
761
+ polymorphic_path(model, {})
762
+ else
763
+ polymorphic_path(model, format: format)
764
+ end
760
765
  end
761
766
 
762
- model = _object_for_form_builder(model)
767
+ model = convert_to_model(_object_for_form_builder(model))
763
768
  scope ||= model_name_from_record_or_class(model).param_key
764
769
  end
765
770
 
@@ -1311,7 +1316,7 @@ module ActionView
1311
1316
  # ...
1312
1317
  # <% end %>
1313
1318
  #
1314
- # because parameter name repetition is precisely what Rails seeks to distinguish
1319
+ # because parameter name repetition is precisely what \Rails seeks to distinguish
1315
1320
  # the elements of the array. For each item with a checked check box you
1316
1321
  # get an extra ghost item with only that attribute, assigned to "0".
1317
1322
  #
@@ -1494,6 +1499,12 @@ module ActionView
1494
1499
  # datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
1495
1500
  # # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
1496
1501
  #
1502
+ # By default, provided datetimes will be formatted including seconds. You can render just the date, hour,
1503
+ # and minute by passing <tt>include_seconds: false</tt>.
1504
+ #
1505
+ # @user.born_on = Time.current
1506
+ # datetime_field("user", "born_on", include_seconds: false)
1507
+ # # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
1497
1508
  def datetime_field(object_name, method, options = {})
1498
1509
  Tags::DatetimeLocalField.new(object_name, method, self, options).render
1499
1510
  end
@@ -1610,6 +1621,8 @@ module ActionView
1610
1621
  end
1611
1622
  end
1612
1623
 
1624
+ # = Action View Form Builder
1625
+ #
1613
1626
  # A +FormBuilder+ object is associated with a particular model object and
1614
1627
  # allows you to generate fields associated with the model object. The
1615
1628
  # +FormBuilder+ object is yielded when using +form_for+ or +fields_for+.
@@ -2074,6 +2087,18 @@ module ActionView
2074
2087
  # DateHelper that are designed to work with an object as base, like
2075
2088
  # FormOptionsHelper#collection_select and DateHelper#datetime_select.
2076
2089
  #
2090
+ # +fields_for+ tries to be smart about parameters, but it can be confused if both
2091
+ # name and value parameters are provided and the provided value has the shape of an
2092
+ # option Hash. To remove the ambiguity, explicitly pass an option Hash, even if empty.
2093
+ #
2094
+ # <%= form_for @person do |person_form| %>
2095
+ # ...
2096
+ # <%= fields_for :permission, @person.permission, {} do |permission_fields| %>
2097
+ # Admin?: <%= check_box_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
2098
+ # <% end %>
2099
+ # ...
2100
+ # <% end %>
2101
+ #
2077
2102
  # === Nested Attributes Examples
2078
2103
  #
2079
2104
  # When the object belonging to the current scope has a nested attribute
@@ -2254,8 +2279,9 @@ module ActionView
2254
2279
  # to store the ID of the record. There are circumstances where this
2255
2280
  # hidden field is not needed and you can pass <tt>include_id: false</tt>
2256
2281
  # to prevent fields_for from rendering it automatically.
2257
- def fields_for(record_name, record_object = nil, fields_options = {}, &block)
2258
- fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
2282
+ def fields_for(record_name, record_object = nil, fields_options = nil, &block)
2283
+ fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
2284
+ fields_options ||= {}
2259
2285
  fields_options[:builder] ||= options[:builder]
2260
2286
  fields_options[:namespace] = options[:namespace]
2261
2287
  fields_options[:parent_builder] = self
@@ -2412,7 +2438,7 @@ module ActionView
2412
2438
  # ...
2413
2439
  # <% end %>
2414
2440
  #
2415
- # because parameter name repetition is precisely what Rails seeks to distinguish
2441
+ # because parameter name repetition is precisely what \Rails seeks to distinguish
2416
2442
  # the elements of the array. For each item with a checked check box you
2417
2443
  # get an extra ghost item with only that attribute, assigned to "0".
2418
2444
  #
@@ -2495,7 +2521,7 @@ module ActionView
2495
2521
  # * Creates standard HTML attributes for the tag.
2496
2522
  # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
2497
2523
  # * <tt>:multiple</tt> - If set to true, *in most updated browsers* the user will be allowed to select multiple files.
2498
- # * <tt>:include_hidden</tt> - When <tt>multiple: true</tt> and <tt>include_hidden: true</tt>, the field will be prefixed with an <tt><input type="hidden"></tt> field with an empty value to support submitting an empty collection of files.
2524
+ # * <tt>:include_hidden</tt> - When <tt>multiple: true</tt> and <tt>include_hidden: true</tt>, the field will be prefixed with an <tt><input type="hidden"></tt> field with an empty value to support submitting an empty collection of files. Since <tt>include_hidden</tt> will default to <tt>config.active_storage.multiple_file_field_include_hidden</tt> if you don't specify <tt>include_hidden</tt>, you will need to pass <tt>include_hidden: false</tt> to prevent submitting an empty collection of files when passing <tt>multiple: true</tt>.
2499
2525
  # * <tt>:accept</tt> - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.
2500
2526
  #
2501
2527
  # ==== Examples
@@ -8,8 +8,9 @@ require "active_support/core_ext/array/wrap"
8
8
  require "action_view/helpers/text_helper"
9
9
 
10
10
  module ActionView
11
- # = Action View Form Option Helpers
12
11
  module Helpers # :nodoc:
12
+ # = Action View Form Option \Helpers
13
+ #
13
14
  # Provides a number of methods for turning different kinds of containers into a set of option tags.
14
15
  #
15
16
  # The <tt>collection_select</tt>, <tt>select</tt> and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter, a hash:
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cgi"
4
+ require "action_view/helpers/content_exfiltration_prevention_helper"
4
5
  require "action_view/helpers/url_helper"
5
6
  require "action_view/helpers/text_helper"
6
7
  require "active_support/core_ext/string/output_safety"
7
8
  require "active_support/core_ext/module/attribute_accessors"
8
9
 
9
10
  module ActionView
10
- # = Action View Form Tag Helpers
11
11
  module Helpers # :nodoc:
12
+ # = Action View Form Tag \Helpers
13
+ #
12
14
  # Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like
13
15
  # FormHelper does. Instead, you provide the names and values manually.
14
16
  #
@@ -19,6 +21,7 @@ module ActionView
19
21
 
20
22
  include UrlHelper
21
23
  include TextHelper
24
+ include ContentExfiltrationPreventionHelper
22
25
 
23
26
  mattr_accessor :embed_authenticity_token_in_remote_forms
24
27
  self.embed_authenticity_token_in_remote_forms = nil
@@ -420,9 +423,17 @@ module ActionView
420
423
  content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
421
424
  end
422
425
 
426
+ ##
427
+ # :call-seq:
428
+ # check_box_tag(name, options = {})
429
+ # check_box_tag(name, value, options = {})
430
+ # check_box_tag(name, value, checked, options = {})
431
+ #
423
432
  # Creates a check box form input tag.
424
433
  #
425
434
  # ==== Options
435
+ # * <tt>:value</tt> - The value of the input. Defaults to <tt>"1"</tt>.
436
+ # * <tt>:checked</tt> - If set to true, the checkbox will be checked by default.
426
437
  # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
427
438
  # * Any other key creates standard HTML options for the tag.
428
439
  #
@@ -441,16 +452,27 @@ module ActionView
441
452
  #
442
453
  # check_box_tag 'eula', 'accepted', false, disabled: true
443
454
  # # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
444
- def check_box_tag(name, value = "1", checked = false, options = {})
455
+ def check_box_tag(name, *args)
456
+ if args.length >= 4
457
+ raise ArgumentError, "wrong number of arguments (given #{args.length + 1}, expected 1..4)"
458
+ end
459
+ options = args.extract_options!
460
+ value, checked = args.empty? ? ["1", false] : [*args, false]
445
461
  html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
446
462
  html_options["checked"] = "checked" if checked
447
463
  tag :input, html_options
448
464
  end
449
465
 
466
+ ##
467
+ # :call-seq:
468
+ # radio_button_tag(name, value, options = {})
469
+ # radio_button_tag(name, value, checked, options = {})
470
+ #
450
471
  # Creates a radio button; use groups of radio buttons named the same to allow users to
451
472
  # select from a group of options.
452
473
  #
453
474
  # ==== Options
475
+ # * <tt>:checked</tt> - If set to true, the radio button will be selected by default.
454
476
  # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
455
477
  # * Any other key creates standard HTML options for the tag.
456
478
  #
@@ -466,7 +488,12 @@ module ActionView
466
488
  #
467
489
  # radio_button_tag 'color', "green", true, class: "color_input"
468
490
  # # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
469
- def radio_button_tag(name, value, checked = false, options = {})
491
+ def radio_button_tag(name, value, *args)
492
+ if args.length >= 3
493
+ raise ArgumentError, "wrong number of arguments (given #{args.length + 2}, expected 2..4)"
494
+ end
495
+ options = args.extract_options!
496
+ checked = args.empty? ? false : args.first
470
497
  html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
471
498
  html_options["checked"] = "checked" if checked
472
499
  tag :input, html_options
@@ -495,9 +522,9 @@ module ActionView
495
522
  # submit_tag "Edit", class: "edit_button"
496
523
  # # => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" />
497
524
  #
498
- # ==== Deprecated: Rails UJS attributes
525
+ # ==== Deprecated: \Rails UJS attributes
499
526
  #
500
- # Prior to Rails 7, Rails shipped with the JavaScript library called @rails/ujs on by default. Following Rails 7,
527
+ # Prior to \Rails 7, \Rails shipped with the JavaScript library called @rails/ujs on by default. Following \Rails 7,
501
528
  # this library is no longer on by default. This library integrated with the following options:
502
529
  #
503
530
  # * <tt>confirm: 'question?'</tt> - If present the unobtrusive JavaScript
@@ -555,9 +582,9 @@ module ActionView
555
582
  # # <strong>Ask me!</strong>
556
583
  # # </button>
557
584
  #
558
- # ==== Deprecated: Rails UJS attributes
585
+ # ==== Deprecated: \Rails UJS attributes
559
586
  #
560
- # Prior to Rails 7, Rails shipped with a JavaScript library called @rails/ujs on by default. Following Rails 7,
587
+ # Prior to \Rails 7, \Rails shipped with a JavaScript library called @rails/ujs on by default. Following \Rails 7,
561
588
  # this library is no longer on by default. This library integrated with the following options:
562
589
  #
563
590
  # * <tt>confirm: 'question?'</tt> - If present, the
@@ -770,6 +797,7 @@ module ActionView
770
797
  # * <tt>:min</tt> - The minimum acceptable value.
771
798
  # * <tt>:max</tt> - The maximum acceptable value.
772
799
  # * <tt>:step</tt> - The acceptable value granularity.
800
+ # * <tt>:include_seconds</tt> - Include seconds in the output timestamp format (true by default).
773
801
  def datetime_field_tag(name, value = nil, options = {})
774
802
  text_field_tag(name, value, options.merge(type: "datetime-local"))
775
803
  end
@@ -979,7 +1007,8 @@ module ActionView
979
1007
 
980
1008
  def form_tag_html(html_options)
981
1009
  extra_tags = extra_tags_for_form(html_options)
982
- tag(:form, html_options, true) + extra_tags
1010
+ html = tag(:form, html_options, true) + extra_tags
1011
+ prevent_content_exfiltration(html)
983
1012
  end
984
1013
 
985
1014
  def form_tag_with_body(html_options, content)
@@ -1009,9 +1038,14 @@ module ActionView
1009
1038
  end
1010
1039
 
1011
1040
  def convert_direct_upload_option_to_url(options)
1012
- if options.delete(:direct_upload) && respond_to?(:rails_direct_uploads_url)
1041
+ return options unless options.delete(:direct_upload)
1042
+
1043
+ if respond_to?(:rails_direct_uploads_url)
1013
1044
  options["data-direct-upload-url"] = rails_direct_uploads_url
1045
+ elsif respond_to?(:main_app) && main_app.respond_to?(:rails_direct_uploads_url)
1046
+ options["data-direct-upload-url"] = main_app.rails_direct_uploads_url
1014
1047
  end
1048
+
1015
1049
  options
1016
1050
  end
1017
1051
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module ActionView
4
4
  module Helpers # :nodoc:
5
+ # = Action View JavaScript \Helpers
5
6
  module JavaScriptHelper
6
7
  JS_ESCAPE_MAP = {
7
8
  "\\" => "\\\\",
@@ -5,8 +5,9 @@ require "active_support/core_ext/string/output_safety"
5
5
  require "active_support/number_helper"
6
6
 
7
7
  module ActionView
8
- # = Action View Number Helpers
9
8
  module Helpers # :nodoc:
9
+ # = Action View Number \Helpers
10
+ #
10
11
  # Provides methods for converting numbers into formatted strings.
11
12
  # Methods are provided for phone numbers, currency, percentage,
12
13
  # precision, positional notation, file size, and pretty printing.
@@ -3,11 +3,11 @@
3
3
  require "active_support/core_ext/string/output_safety"
4
4
 
5
5
  module ActionView # :nodoc:
6
- # = Action View Raw Output Helper
7
6
  module Helpers # :nodoc:
7
+ # = Action View Raw Output \Helpers
8
8
  module OutputSafetyHelper
9
9
  # This method outputs without escaping a string. Since escaping tags is
10
- # now default, this can be used when you don't want Rails to automatically
10
+ # now default, this can be used when you don't want \Rails to automatically
11
11
  # escape tags. This is not recommended if the data is coming from the user's
12
12
  # input.
13
13
  #
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActionView
4
4
  module Helpers # :nodoc:
5
- # = Action View Rendering
5
+ # = Action View \Rendering \Helpers
6
6
  #
7
7
  # Implements methods that allow rendering from a view context.
8
8
  # In order to use this module, all you need is to implement
@@ -3,20 +3,23 @@
3
3
  require "rails-html-sanitizer"
4
4
 
5
5
  module ActionView
6
- # = Action View Sanitize Helpers
7
6
  module Helpers # :nodoc:
7
+ # = Action View Sanitize \Helpers
8
+ #
8
9
  # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
9
10
  # These helper methods extend Action View making them callable within your template files.
10
11
  module SanitizeHelper
12
+ mattr_accessor :sanitizer_vendor, default: Rails::HTML4::Sanitizer
13
+
11
14
  extend ActiveSupport::Concern
15
+
12
16
  # Sanitizes HTML input, stripping all but known-safe tags and attributes.
13
17
  #
14
- # It also strips href/src attributes with unsafe protocols like
15
- # <tt>javascript:</tt>, while also protecting against attempts to use Unicode,
16
- # ASCII, and hex character references to work around these protocol filters.
17
- # All special characters will be escaped.
18
+ # It also strips href/src attributes with unsafe protocols like <tt>javascript:</tt>, while
19
+ # also protecting against attempts to use Unicode, ASCII, and hex character references to work
20
+ # around these protocol filters.
18
21
  #
19
- # The default sanitizer is Rails::Html::SafeListSanitizer. See {Rails HTML
22
+ # The default sanitizer is Rails::HTML5::SafeListSanitizer. See {Rails HTML
20
23
  # Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information.
21
24
  #
22
25
  # Custom sanitization rules can also be provided.
@@ -28,7 +31,7 @@ module ActionView
28
31
  #
29
32
  # * <tt>:tags</tt> - An array of allowed tags.
30
33
  # * <tt>:attributes</tt> - An array of allowed attributes.
31
- # * <tt>:scrubber</tt> - A {Rails::Html scrubber}[https://github.com/rails/rails-html-sanitizer]
34
+ # * <tt>:scrubber</tt> - A {Rails::HTML scrubber}[https://github.com/rails/rails-html-sanitizer]
32
35
  # or {Loofah::Scrubber}[https://github.com/flavorjones/loofah] object that
33
36
  # defines custom sanitization rules. A custom scrubber takes precedence over
34
37
  # custom tags and attributes.
@@ -43,9 +46,9 @@ module ActionView
43
46
  #
44
47
  # <%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %>
45
48
  #
46
- # Providing a custom Rails::Html scrubber:
49
+ # Providing a custom Rails::HTML scrubber:
47
50
  #
48
- # class CommentScrubber < Rails::Html::PermitScrubber
51
+ # class CommentScrubber < Rails::HTML::PermitScrubber
49
52
  # def initialize
50
53
  # super
51
54
  # self.tags = %w( form script comment blockquote )
@@ -60,7 +63,7 @@ module ActionView
60
63
  # <%= sanitize @comment.body, scrubber: CommentScrubber.new %>
61
64
  #
62
65
  # See {Rails HTML Sanitizer}[https://github.com/rails/rails-html-sanitizer] for
63
- # documentation about Rails::Html scrubbers.
66
+ # documentation about Rails::HTML scrubbers.
64
67
  #
65
68
  # Providing a custom Loofah::Scrubber:
66
69
  #
@@ -78,6 +81,22 @@ module ActionView
78
81
  # # In config/application.rb
79
82
  # config.action_view.sanitized_allowed_tags = ['strong', 'em', 'a']
80
83
  # config.action_view.sanitized_allowed_attributes = ['href', 'title']
84
+ #
85
+ # The default, starting in \Rails 7.1, is to use an HTML5 parser for sanitization (if it is
86
+ # available, see NOTE below). If you wish to revert back to the previous HTML4 behavior, you
87
+ # can do so by setting the following in your application configuration:
88
+ #
89
+ # # In config/application.rb
90
+ # config.action_view.sanitizer_vendor = Rails::HTML4::Sanitizer
91
+ #
92
+ # Or, if you're upgrading from a previous version of \Rails and wish to opt into the HTML5
93
+ # behavior:
94
+ #
95
+ # # In config/application.rb
96
+ # config.action_view.sanitizer_vendor = Rails::HTML5::Sanitizer
97
+ #
98
+ # NOTE: Rails::HTML5::Sanitizer is not supported on JRuby, so on JRuby platforms \Rails will
99
+ # fall back to use Rails::HTML4::Sanitizer.
81
100
  def sanitize(html, options = {})
82
101
  self.class.safe_list_sanitizer.sanitize(html, options)&.html_safe
83
102
  end
@@ -125,7 +144,7 @@ module ActionView
125
144
  attr_writer :full_sanitizer, :link_sanitizer, :safe_list_sanitizer
126
145
 
127
146
  def sanitizer_vendor
128
- Rails::Html::Sanitizer
147
+ ActionView::Helpers::SanitizeHelper.sanitizer_vendor
129
148
  end
130
149
 
131
150
  def sanitized_allowed_tags
@@ -136,7 +155,7 @@ module ActionView
136
155
  sanitizer_vendor.safe_list_sanitizer.allowed_attributes
137
156
  end
138
157
 
139
- # Gets the Rails::Html::FullSanitizer instance used by +strip_tags+. Replace with
158
+ # Gets the Rails::HTML::FullSanitizer instance used by +strip_tags+. Replace with
140
159
  # any object that responds to +sanitize+.
141
160
  #
142
161
  # class Application < Rails::Application
@@ -146,7 +165,7 @@ module ActionView
146
165
  @full_sanitizer ||= sanitizer_vendor.full_sanitizer.new
147
166
  end
148
167
 
149
- # Gets the Rails::Html::LinkSanitizer instance used by +strip_links+.
168
+ # Gets the Rails::HTML::LinkSanitizer instance used by +strip_links+.
150
169
  # Replace with any object that responds to +sanitize+.
151
170
  #
152
171
  # class Application < Rails::Application
@@ -156,7 +175,7 @@ module ActionView
156
175
  @link_sanitizer ||= sanitizer_vendor.link_sanitizer.new
157
176
  end
158
177
 
159
- # Gets the Rails::Html::SafeListSanitizer instance used by sanitize and +sanitize_css+.
178
+ # Gets the Rails::HTML::SafeListSanitizer instance used by sanitize and +sanitize_css+.
160
179
  # Replace with any object that responds to +sanitize+.
161
180
  #
162
181
  # class Application < Rails::Application
@@ -7,8 +7,9 @@ require "action_view/helpers/capture_helper"
7
7
  require "action_view/helpers/output_safety_helper"
8
8
 
9
9
  module ActionView
10
- # = Action View Tag Helpers
11
10
  module Helpers # :nodoc:
11
+ # = Action View Tag \Helpers
12
+ #
12
13
  # Provides methods to generate HTML tags programmatically both as a modern
13
14
  # HTML5 compliant builder style and legacy XHTML compliant tags.
14
15
  module TagHelper
@@ -65,9 +66,7 @@ module ActionView
65
66
  tag_string(:p, *arguments, **options, &block)
66
67
  end
67
68
 
68
- def tag_string(name, content = nil, **options, &block)
69
- escape = handle_deprecated_escape_options(options)
70
-
69
+ def tag_string(name, content = nil, escape: true, **options, &block)
71
70
  content = @view_context.capture(self, &block) if block_given?
72
71
  self_closing = SVG_SELF_CLOSING_ELEMENTS.include?(name)
73
72
  if (HTML_VOID_ELEMENTS.include?(name) || self_closing) && content.nil?
@@ -164,27 +163,6 @@ module ActionView
164
163
  true
165
164
  end
166
165
 
167
- def handle_deprecated_escape_options(options)
168
- # The option :escape_attributes has been merged into the options hash to be
169
- # able to warn when it is used, so we need to handle default values here.
170
- escape_option_provided = options.has_key?(:escape)
171
- escape_attributes_option_provided = options.has_key?(:escape_attributes)
172
-
173
- if escape_attributes_option_provided
174
- ActiveSupport::Deprecation.warn(<<~MSG)
175
- Use of the option :escape_attributes is deprecated. It currently \
176
- escapes both names and values of tags and attributes and it is \
177
- equivalent to :escape. If any of them are enabled, the escaping \
178
- is fully enabled.
179
- MSG
180
- end
181
-
182
- return true unless escape_option_provided || escape_attributes_option_provided
183
- escape_option = options.delete(:escape)
184
- escape_attributes_option = options.delete(:escape_attributes)
185
- escape_option || escape_attributes_option
186
- end
187
-
188
166
  def method_missing(called, *args, **options, &block)
189
167
  tag_string(called, *args, **options, &block)
190
168
  end
@@ -283,7 +261,7 @@ module ActionView
283
261
  #
284
262
  # === Legacy syntax
285
263
  #
286
- # The following format is for legacy syntax support. It will be deprecated in future versions of Rails.
264
+ # The following format is for legacy syntax support. It will be deprecated in future versions of \Rails.
287
265
  #
288
266
  # tag(name, options = nil, open = false, escape = true)
289
267
  #
@@ -386,7 +364,7 @@ module ActionView
386
364
  # token_list(nil, false, 123, "", "foo", { bar: true })
387
365
  # # => "123 foo bar"
388
366
  def token_list(*args)
389
- tokens = build_tag_values(*args).flat_map { |value| value.to_s.split(/\s+/) }.uniq
367
+ tokens = build_tag_values(*args).flat_map { |value| CGI.unescape_html(value.to_s).split(/\s+/) }.uniq
390
368
 
391
369
  safe_join(tokens, " ")
392
370
  end