actionview 6.1.7.2 → 7.0.5

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +265 -261
  3. data/MIT-LICENSE +1 -0
  4. data/lib/action_view/base.rb +4 -7
  5. data/lib/action_view/buffers.rb +2 -2
  6. data/lib/action_view/cache_expiry.rb +46 -32
  7. data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
  8. data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
  9. data/lib/action_view/dependency_tracker.rb +6 -147
  10. data/lib/action_view/digestor.rb +7 -4
  11. data/lib/action_view/flows.rb +4 -4
  12. data/lib/action_view/gem_version.rb +5 -5
  13. data/lib/action_view/helpers/active_model_helper.rb +2 -2
  14. data/lib/action_view/helpers/asset_tag_helper.rb +95 -39
  15. data/lib/action_view/helpers/asset_url_helper.rb +16 -16
  16. data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
  17. data/lib/action_view/helpers/cache_helper.rb +52 -3
  18. data/lib/action_view/helpers/capture_helper.rb +4 -4
  19. data/lib/action_view/helpers/controller_helper.rb +2 -2
  20. data/lib/action_view/helpers/csp_helper.rb +1 -1
  21. data/lib/action_view/helpers/csrf_helper.rb +2 -2
  22. data/lib/action_view/helpers/date_helper.rb +111 -43
  23. data/lib/action_view/helpers/debug_helper.rb +3 -1
  24. data/lib/action_view/helpers/form_helper.rb +211 -85
  25. data/lib/action_view/helpers/form_options_helper.rb +70 -33
  26. data/lib/action_view/helpers/form_tag_helper.rb +150 -53
  27. data/lib/action_view/helpers/javascript_helper.rb +3 -5
  28. data/lib/action_view/helpers/number_helper.rb +17 -16
  29. data/lib/action_view/helpers/output_safety_helper.rb +4 -4
  30. data/lib/action_view/helpers/rendering_helper.rb +5 -6
  31. data/lib/action_view/helpers/sanitize_helper.rb +3 -3
  32. data/lib/action_view/helpers/tag_helper.rb +37 -8
  33. data/lib/action_view/helpers/tags/base.rb +5 -25
  34. data/lib/action_view/helpers/tags/check_box.rb +1 -1
  35. data/lib/action_view/helpers/tags/collection_select.rb +1 -1
  36. data/lib/action_view/helpers/tags/file_field.rb +16 -0
  37. data/lib/action_view/helpers/tags/select.rb +1 -1
  38. data/lib/action_view/helpers/tags/time_field.rb +10 -1
  39. data/lib/action_view/helpers/tags/weekday_select.rb +28 -0
  40. data/lib/action_view/helpers/tags.rb +3 -2
  41. data/lib/action_view/helpers/text_helper.rb +25 -14
  42. data/lib/action_view/helpers/translation_helper.rb +12 -43
  43. data/lib/action_view/helpers/url_helper.rb +194 -123
  44. data/lib/action_view/helpers.rb +25 -25
  45. data/lib/action_view/layouts.rb +7 -4
  46. data/lib/action_view/lookup_context.rb +33 -52
  47. data/lib/action_view/model_naming.rb +2 -2
  48. data/lib/action_view/path_set.rb +16 -22
  49. data/lib/action_view/railtie.rb +19 -7
  50. data/lib/action_view/record_identifier.rb +1 -1
  51. data/lib/action_view/render_parser.rb +188 -0
  52. data/lib/action_view/renderer/abstract_renderer.rb +2 -2
  53. data/lib/action_view/renderer/partial_renderer.rb +1 -35
  54. data/lib/action_view/renderer/renderer.rb +4 -4
  55. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
  56. data/lib/action_view/renderer/template_renderer.rb +6 -2
  57. data/lib/action_view/rendering.rb +3 -3
  58. data/lib/action_view/ripper_ast_parser.rb +198 -0
  59. data/lib/action_view/routing_url_for.rb +8 -5
  60. data/lib/action_view/template/error.rb +108 -13
  61. data/lib/action_view/template/handlers/erb.rb +6 -0
  62. data/lib/action_view/template/handlers.rb +3 -3
  63. data/lib/action_view/template/html.rb +3 -3
  64. data/lib/action_view/template/inline.rb +3 -3
  65. data/lib/action_view/template/raw_file.rb +3 -3
  66. data/lib/action_view/template/resolver.rb +89 -314
  67. data/lib/action_view/template/text.rb +3 -3
  68. data/lib/action_view/template/types.rb +14 -12
  69. data/lib/action_view/template.rb +18 -2
  70. data/lib/action_view/template_details.rb +66 -0
  71. data/lib/action_view/template_path.rb +64 -0
  72. data/lib/action_view/test_case.rb +7 -3
  73. data/lib/action_view/testing/resolvers.rb +11 -12
  74. data/lib/action_view/unbound_template.rb +33 -7
  75. data/lib/action_view/version.rb +1 -1
  76. data/lib/action_view/view_paths.rb +4 -4
  77. data/lib/action_view.rb +2 -3
  78. data/lib/assets/compiled/rails-ujs.js +36 -5
  79. metadata +23 -16
@@ -9,7 +9,7 @@ require "active_support/core_ext/object/acts_like"
9
9
  require "active_support/core_ext/object/with_options"
10
10
 
11
11
  module ActionView
12
- module Helpers #:nodoc:
12
+ module Helpers # :nodoc:
13
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
@@ -26,7 +26,7 @@ module ActionView
26
26
  MINUTES_IN_QUARTER_YEAR = 131400
27
27
  MINUTES_IN_THREE_QUARTERS_YEAR = 394200
28
28
 
29
- # Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds.
29
+ # Reports the approximate distance in time between two Time, Date, or DateTime objects or integers as seconds.
30
30
  # Pass <tt>include_seconds: true</tt> if you want more detailed approximations when distance < 1 min, 29 secs.
31
31
  # Distances are reported based on the following table:
32
32
  #
@@ -140,7 +140,7 @@ module ActionView
140
140
  minute_offset_for_leap_year = leap_years * 1440
141
141
  # Discount the leap year days when calculating year distance.
142
142
  # e.g. if there are 20 leap year days between 2 dates having the same day
143
- # and month then the based on 365 days calculation
143
+ # and month then based on 365 days calculation
144
144
  # the distance in years will come out to over 80 years when in written
145
145
  # English it would read better as about 80 years.
146
146
  minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
@@ -206,6 +206,7 @@ module ActionView
206
206
  # you are creating new record. While editing existing record, <tt>:end_year</tt> defaults to
207
207
  # the current selected year plus 5.
208
208
  # * <tt>:year_format</tt> - Set format of years for year select. Lambda should be passed.
209
+ # * <tt>:day_format</tt> - Set format of days for day select. Lambda should be passed.
209
210
  # * <tt>:discard_day</tt> - Set to true if you don't want to show a day select. This includes the day
210
211
  # as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the
211
212
  # first of the given month in order to not create invalid dates like 31 February.
@@ -279,6 +280,9 @@ module ActionView
279
280
  # # Generates a date select with custom year format.
280
281
  # date_select("article", "written_on", year_format: ->(year) { "Heisei #{year - 1988}" })
281
282
  #
283
+ # # Generates a date select with custom day format.
284
+ # date_select("article", "written_on", day_format: ->(day) { day.ordinalize })
285
+ #
282
286
  # The selects are prepared for multi-parameter assignment to an Active Record object.
283
287
  #
284
288
  # 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
@@ -287,12 +291,12 @@ module ActionView
287
291
  Tags::DateSelect.new(object_name, method, self, options, html_options).render
288
292
  end
289
293
 
290
- # Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a
294
+ # Returns a set of select tags (one for hour, minute, and optionally second) pre-selected for accessing a
291
295
  # specified time-based attribute (identified by +method+) on an object assigned to the template (identified by
292
296
  # +object+). You can include the seconds with <tt>:include_seconds</tt>. You can get hours in the AM/PM format
293
297
  # with <tt>:ampm</tt> option.
294
298
  #
295
- # This method will also generate 3 input hidden tags, for the actual year, month and day unless the option
299
+ # This method will also generate 3 input hidden tags, for the actual year, month, and day unless the option
296
300
  # <tt>:ignore_date</tt> is set to +true+. If you set the <tt>:ignore_date</tt> to +true+, you must have a
297
301
  # +date_select+ on the same method within the form otherwise an exception will be raised.
298
302
  #
@@ -699,7 +703,7 @@ module ActionView
699
703
  end
700
704
  end
701
705
 
702
- class DateTimeSelector #:nodoc:
706
+ class DateTimeSelector # :nodoc:
703
707
  include ActionView::Helpers::TagHelper
704
708
 
705
709
  DEFAULT_PREFIX = "date"
@@ -811,7 +815,7 @@ module ActionView
811
815
  if @options[:use_hidden] || @options[:discard_day]
812
816
  build_hidden(:day, day || 1)
813
817
  else
814
- build_options_and_select(:day, day, start: 1, end: 31, leading_zeros: false, use_two_digit_numbers: @options[:use_two_digit_numbers])
818
+ build_select(:day, build_day_options(day))
815
819
  end
816
820
  end
817
821
 
@@ -867,6 +871,10 @@ module ActionView
867
871
  end
868
872
  end
869
873
 
874
+ def prompt_text(prompt, type)
875
+ prompt.kind_of?(String) ? prompt : I18n.translate(:"datetime.prompts.#{type}", locale: @options[:locale])
876
+ end
877
+
870
878
  # If the day is hidden, the day should be set to the 1st so all month and year choices are
871
879
  # valid. Otherwise, February 31st or February 29th, 2011 can be selected, which are invalid.
872
880
  def set_day_if_discarded
@@ -880,7 +888,7 @@ module ActionView
880
888
  def month_names
881
889
  @month_names ||= begin
882
890
  month_names = @options[:use_month_names] || translated_month_names
883
- month_names.unshift(nil) if month_names.size < 13
891
+ month_names = [nil, *month_names] if month_names.size < 13
884
892
  month_names
885
893
  end
886
894
  end
@@ -899,6 +907,27 @@ module ActionView
899
907
  I18n.translate(key, locale: @options[:locale])
900
908
  end
901
909
 
910
+ # Looks up day names by number.
911
+ #
912
+ # day_name(1) # => 1
913
+ #
914
+ # If the <tt>use_two_digit_numbers: true</tt> option is passed to DateTimeSelector:
915
+ #
916
+ # day_name(1) # => "01"
917
+ #
918
+ # If the <tt>day_format: ->(day) { day.ordinalize }</tt> option is passed to DateTimeSelector:
919
+ #
920
+ # day_name(1) # => "1st"
921
+ def day_name(number)
922
+ if day_format_lambda = @options[:day_format]
923
+ day_format_lambda.call(number)
924
+ elsif @options[:use_two_digit_numbers]
925
+ "%02d" % number
926
+ else
927
+ number
928
+ end
929
+ end
930
+
902
931
  # Looks up month names by number (1-based):
903
932
  #
904
933
  # month_name(1) # => "January"
@@ -972,22 +1001,25 @@ module ActionView
972
1001
  end
973
1002
 
974
1003
  # Build select option HTML from date value and options.
975
- # build_options(15, start: 1, end: 31)
976
- # => "<option value="1">1</option>
977
- # <option value="2">2</option>
978
- # <option value="3">3</option>..."
979
1004
  #
980
- # If <tt>use_two_digit_numbers: true</tt> option is passed
981
- # build_options(15, start: 1, end: 31, use_two_digit_numbers: true)
982
- # => "<option value="1">01</option>
983
- # <option value="2">02</option>
984
- # <option value="3">03</option>..."
1005
+ # build_options(15, start: 1, end: 31)
1006
+ # => "<option value="1">1</option>
1007
+ # <option value="2">2</option>
1008
+ # <option value="3">3</option>..."
1009
+ #
1010
+ # If <tt>use_two_digit_numbers: true</tt> option is passed:
1011
+ #
1012
+ # build_options(15, start: 1, end: 31, use_two_digit_numbers: true)
1013
+ # => "<option value="1">01</option>
1014
+ # <option value="2">02</option>
1015
+ # <option value="3">03</option>..."
1016
+ #
1017
+ # If <tt>:step</tt> options is passed:
985
1018
  #
986
- # If <tt>:step</tt> options is passed
987
- # build_options(15, start: 1, end: 31, step: 2)
988
- # => "<option value="1">1</option>
989
- # <option value="3">3</option>
990
- # <option value="5">5</option>..."
1019
+ # build_options(15, start: 1, end: 31, step: 2)
1020
+ # => "<option value="1">1</option>
1021
+ # <option value="3">3</option>
1022
+ # <option value="5">5</option>..."
991
1023
  def build_options(selected, options = {})
992
1024
  options = {
993
1025
  leading_zeros: true, ampm: false, use_two_digit_numbers: false
@@ -1011,18 +1043,50 @@ module ActionView
1011
1043
  (select_options.join("\n") + "\n").html_safe
1012
1044
  end
1013
1045
 
1046
+ # Build select option HTML for day.
1047
+ #
1048
+ # build_day_options(2)
1049
+ # => "<option value="1">1</option>
1050
+ # <option value="2" selected="selected">2</option>
1051
+ # <option value="3">3</option>..."
1052
+ #
1053
+ # If <tt>day_format: ->(day) { day.ordinalize }</tt> option is passed to DateTimeSelector
1054
+ #
1055
+ # build_day_options(2)
1056
+ # => "<option value="1">1st</option>
1057
+ # <option value="2" selected="selected">2nd</option>
1058
+ # <option value="3">3rd</option>..."
1059
+ #
1060
+ # If <tt>use_two_digit_numbers: true</tt> option is passed to DateTimeSelector
1061
+ #
1062
+ # build_day_options(2)
1063
+ # => "<option value="1">01</option>
1064
+ # <option value="2" selected="selected">02</option>
1065
+ # <option value="3">03</option>..."
1066
+ def build_day_options(selected)
1067
+ select_options = []
1068
+ (1..31).each do |value|
1069
+ tag_options = { value: value }
1070
+ tag_options[:selected] = "selected" if selected == value
1071
+ text = day_name(value)
1072
+ select_options << content_tag("option", text, tag_options)
1073
+ end
1074
+
1075
+ (select_options.join("\n") + "\n").html_safe
1076
+ end
1077
+
1014
1078
  # Build select option HTML for year.
1015
1079
  # If <tt>year_format</tt> option is not passed
1016
- # build_year_options(1998, start: 1998, end: 2000)
1017
- # => "<option value="1998" selected="selected">1998</option>
1018
- # <option value="1999">1999</option>
1019
- # <option value="2000">2000</option>"
1080
+ # build_year_options(1998, start: 1998, end: 2000)
1081
+ # => "<option value="1998" selected="selected">1998</option>
1082
+ # <option value="1999">1999</option>
1083
+ # <option value="2000">2000</option>"
1020
1084
  #
1021
1085
  # If <tt>year_format</tt> option is passed
1022
- # build_year_options(1998, start: 1998, end: 2000, year_format: ->year { "Heisei #{ year - 1988 }" })
1023
- # => "<option value="1998" selected="selected">Heisei 10</option>
1024
- # <option value="1999">Heisei 11</option>
1025
- # <option value="2000">Heisei 12</option>"
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>"
1026
1090
  def build_year_options(selected, options = {})
1027
1091
  start = options.delete(:start)
1028
1092
  stop = options.delete(:end)
@@ -1040,10 +1104,11 @@ module ActionView
1040
1104
  end
1041
1105
 
1042
1106
  # Builds select tag from date type and HTML select options.
1043
- # build_select(:month, "<option value="1">January</option>...")
1044
- # => "<select id="post_written_on_2i" name="post[written_on(2i)]">
1045
- # <option value="1">January</option>...
1046
- # </select>"
1107
+ #
1108
+ # build_select(:month, "<option value="1">January</option>...")
1109
+ # => "<select id="post_written_on_2i" name="post[written_on(2i)]">
1110
+ # <option value="1">January</option>...
1111
+ # </select>"
1047
1112
  def build_select(type, select_options_as_html)
1048
1113
  select_options = {
1049
1114
  id: input_id_from_type(type),
@@ -1060,9 +1125,10 @@ module ActionView
1060
1125
  (content_tag("select", select_html.html_safe, select_options) + "\n").html_safe
1061
1126
  end
1062
1127
 
1063
- # Builds the css class value for the select element
1064
- # css_class_attribute(:year, 'date optional', { year: 'my-year' })
1065
- # => "date optional my-year"
1128
+ # Builds the CSS class value for the select element.
1129
+ #
1130
+ # css_class_attribute(:year, 'date optional', { year: 'my-year' })
1131
+ # => "date optional my-year"
1066
1132
  def css_class_attribute(type, html_options_class, options) # :nodoc:
1067
1133
  css_class = \
1068
1134
  case options
@@ -1076,8 +1142,9 @@ module ActionView
1076
1142
  end
1077
1143
 
1078
1144
  # Builds a prompt option tag with supplied options or from default options.
1079
- # prompt_option_tag(:month, prompt: 'Select month')
1080
- # => "<option value="">Select month</option>"
1145
+ #
1146
+ # prompt_option_tag(:month, prompt: 'Select month')
1147
+ # => "<option value="">Select month</option>"
1081
1148
  def prompt_option_tag(type, options)
1082
1149
  prompt = \
1083
1150
  case options
@@ -1090,12 +1157,13 @@ module ActionView
1090
1157
  I18n.translate(:"datetime.prompts.#{type}", locale: @options[:locale])
1091
1158
  end
1092
1159
 
1093
- prompt ? content_tag("option", prompt, value: "") : ""
1160
+ prompt ? content_tag("option", prompt_text(prompt, type), value: "") : ""
1094
1161
  end
1095
1162
 
1096
1163
  # Builds hidden input tag for date part and value.
1097
- # build_hidden(:year, 2008)
1098
- # => "<input id="post_written_on_1i" name="post[written_on(1i)]" type="hidden" value="2008" />"
1164
+ #
1165
+ # build_hidden(:year, 2008)
1166
+ # => "<input type="hidden" id="date_year" name="date[year]" value="2008" autocomplete="off" />"
1099
1167
  def build_hidden(type, value)
1100
1168
  select_options = {
1101
1169
  type: "hidden",
@@ -1126,7 +1194,7 @@ module ActionView
1126
1194
  # Returns the id attribute for the input tag.
1127
1195
  # => "post_written_on_1i"
1128
1196
  def input_id_from_type(type)
1129
- id = input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, "_").gsub(/[\]\)]/, "")
1197
+ id = input_name_from_type(type).gsub(/([\[(])|(\]\[)/, "_").gsub(/[\])]/, "")
1130
1198
  id = @options[:namespace] + "_" + id if @options[:namespace]
1131
1199
 
1132
1200
  id
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "action_view/helpers/tag_helper"
4
+
3
5
  module ActionView
4
6
  # = Action View Debug Helper
5
7
  #
6
8
  # Provides a set of methods for making it easier to debug Rails objects.
7
- module Helpers #:nodoc:
9
+ module Helpers # :nodoc:
8
10
  module DebugHelper
9
11
  include TagHelper
10
12