omg-actionview 8.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +25 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +40 -0
  5. data/app/assets/javascripts/rails-ujs.esm.js +686 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +316 -0
  8. data/lib/action_view/buffers.rb +165 -0
  9. data/lib/action_view/cache_expiry.rb +69 -0
  10. data/lib/action_view/context.rb +32 -0
  11. data/lib/action_view/dependency_tracker/erb_tracker.rb +159 -0
  12. data/lib/action_view/dependency_tracker/ruby_tracker.rb +43 -0
  13. data/lib/action_view/dependency_tracker/wildcard_resolver.rb +32 -0
  14. data/lib/action_view/dependency_tracker.rb +41 -0
  15. data/lib/action_view/deprecator.rb +7 -0
  16. data/lib/action_view/digestor.rb +130 -0
  17. data/lib/action_view/flows.rb +75 -0
  18. data/lib/action_view/gem_version.rb +17 -0
  19. data/lib/action_view/helpers/active_model_helper.rb +54 -0
  20. data/lib/action_view/helpers/asset_tag_helper.rb +680 -0
  21. data/lib/action_view/helpers/asset_url_helper.rb +473 -0
  22. data/lib/action_view/helpers/atom_feed_helper.rb +205 -0
  23. data/lib/action_view/helpers/cache_helper.rb +315 -0
  24. data/lib/action_view/helpers/capture_helper.rb +236 -0
  25. data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
  26. data/lib/action_view/helpers/controller_helper.rb +42 -0
  27. data/lib/action_view/helpers/csp_helper.rb +26 -0
  28. data/lib/action_view/helpers/csrf_helper.rb +35 -0
  29. data/lib/action_view/helpers/date_helper.rb +1266 -0
  30. data/lib/action_view/helpers/debug_helper.rb +38 -0
  31. data/lib/action_view/helpers/form_helper.rb +2765 -0
  32. data/lib/action_view/helpers/form_options_helper.rb +927 -0
  33. data/lib/action_view/helpers/form_tag_helper.rb +1088 -0
  34. data/lib/action_view/helpers/javascript_helper.rb +96 -0
  35. data/lib/action_view/helpers/number_helper.rb +165 -0
  36. data/lib/action_view/helpers/output_safety_helper.rb +70 -0
  37. data/lib/action_view/helpers/rendering_helper.rb +218 -0
  38. data/lib/action_view/helpers/sanitize_helper.rb +201 -0
  39. data/lib/action_view/helpers/tag_helper.rb +621 -0
  40. data/lib/action_view/helpers/tags/base.rb +138 -0
  41. data/lib/action_view/helpers/tags/check_box.rb +65 -0
  42. data/lib/action_view/helpers/tags/checkable.rb +18 -0
  43. data/lib/action_view/helpers/tags/collection_check_boxes.rb +37 -0
  44. data/lib/action_view/helpers/tags/collection_helpers.rb +118 -0
  45. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +31 -0
  46. data/lib/action_view/helpers/tags/collection_select.rb +33 -0
  47. data/lib/action_view/helpers/tags/color_field.rb +26 -0
  48. data/lib/action_view/helpers/tags/date_field.rb +14 -0
  49. data/lib/action_view/helpers/tags/date_select.rb +75 -0
  50. data/lib/action_view/helpers/tags/datetime_field.rb +39 -0
  51. data/lib/action_view/helpers/tags/datetime_local_field.rb +29 -0
  52. data/lib/action_view/helpers/tags/datetime_select.rb +10 -0
  53. data/lib/action_view/helpers/tags/email_field.rb +10 -0
  54. data/lib/action_view/helpers/tags/file_field.rb +26 -0
  55. data/lib/action_view/helpers/tags/grouped_collection_select.rb +34 -0
  56. data/lib/action_view/helpers/tags/hidden_field.rb +14 -0
  57. data/lib/action_view/helpers/tags/label.rb +84 -0
  58. data/lib/action_view/helpers/tags/month_field.rb +14 -0
  59. data/lib/action_view/helpers/tags/number_field.rb +20 -0
  60. data/lib/action_view/helpers/tags/password_field.rb +14 -0
  61. data/lib/action_view/helpers/tags/placeholderable.rb +24 -0
  62. data/lib/action_view/helpers/tags/radio_button.rb +32 -0
  63. data/lib/action_view/helpers/tags/range_field.rb +10 -0
  64. data/lib/action_view/helpers/tags/search_field.rb +27 -0
  65. data/lib/action_view/helpers/tags/select.rb +45 -0
  66. data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
  67. data/lib/action_view/helpers/tags/tel_field.rb +10 -0
  68. data/lib/action_view/helpers/tags/text_area.rb +24 -0
  69. data/lib/action_view/helpers/tags/text_field.rb +33 -0
  70. data/lib/action_view/helpers/tags/time_field.rb +23 -0
  71. data/lib/action_view/helpers/tags/time_select.rb +10 -0
  72. data/lib/action_view/helpers/tags/time_zone_select.rb +25 -0
  73. data/lib/action_view/helpers/tags/translator.rb +39 -0
  74. data/lib/action_view/helpers/tags/url_field.rb +10 -0
  75. data/lib/action_view/helpers/tags/week_field.rb +14 -0
  76. data/lib/action_view/helpers/tags/weekday_select.rb +31 -0
  77. data/lib/action_view/helpers/tags.rb +47 -0
  78. data/lib/action_view/helpers/text_helper.rb +568 -0
  79. data/lib/action_view/helpers/translation_helper.rb +161 -0
  80. data/lib/action_view/helpers/url_helper.rb +812 -0
  81. data/lib/action_view/helpers.rb +68 -0
  82. data/lib/action_view/layouts.rb +434 -0
  83. data/lib/action_view/locale/en.yml +56 -0
  84. data/lib/action_view/log_subscriber.rb +132 -0
  85. data/lib/action_view/lookup_context.rb +299 -0
  86. data/lib/action_view/model_naming.rb +14 -0
  87. data/lib/action_view/path_registry.rb +57 -0
  88. data/lib/action_view/path_set.rb +84 -0
  89. data/lib/action_view/railtie.rb +132 -0
  90. data/lib/action_view/record_identifier.rb +118 -0
  91. data/lib/action_view/render_parser/prism_render_parser.rb +139 -0
  92. data/lib/action_view/render_parser/ripper_render_parser.rb +350 -0
  93. data/lib/action_view/render_parser.rb +40 -0
  94. data/lib/action_view/renderer/abstract_renderer.rb +186 -0
  95. data/lib/action_view/renderer/collection_renderer.rb +204 -0
  96. data/lib/action_view/renderer/object_renderer.rb +34 -0
  97. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +120 -0
  98. data/lib/action_view/renderer/partial_renderer.rb +267 -0
  99. data/lib/action_view/renderer/renderer.rb +107 -0
  100. data/lib/action_view/renderer/streaming_template_renderer.rb +107 -0
  101. data/lib/action_view/renderer/template_renderer.rb +115 -0
  102. data/lib/action_view/rendering.rb +190 -0
  103. data/lib/action_view/routing_url_for.rb +149 -0
  104. data/lib/action_view/tasks/cache_digests.rake +25 -0
  105. data/lib/action_view/template/error.rb +264 -0
  106. data/lib/action_view/template/handlers/builder.rb +25 -0
  107. data/lib/action_view/template/handlers/erb/erubi.rb +85 -0
  108. data/lib/action_view/template/handlers/erb.rb +157 -0
  109. data/lib/action_view/template/handlers/html.rb +11 -0
  110. data/lib/action_view/template/handlers/raw.rb +11 -0
  111. data/lib/action_view/template/handlers.rb +66 -0
  112. data/lib/action_view/template/html.rb +33 -0
  113. data/lib/action_view/template/inline.rb +22 -0
  114. data/lib/action_view/template/raw_file.rb +25 -0
  115. data/lib/action_view/template/renderable.rb +30 -0
  116. data/lib/action_view/template/resolver.rb +212 -0
  117. data/lib/action_view/template/sources/file.rb +17 -0
  118. data/lib/action_view/template/sources.rb +13 -0
  119. data/lib/action_view/template/text.rb +32 -0
  120. data/lib/action_view/template/types.rb +50 -0
  121. data/lib/action_view/template.rb +580 -0
  122. data/lib/action_view/template_details.rb +66 -0
  123. data/lib/action_view/template_path.rb +66 -0
  124. data/lib/action_view/test_case.rb +449 -0
  125. data/lib/action_view/testing/resolvers.rb +44 -0
  126. data/lib/action_view/unbound_template.rb +67 -0
  127. data/lib/action_view/version.rb +10 -0
  128. data/lib/action_view/view_paths.rb +117 -0
  129. data/lib/action_view.rb +104 -0
  130. metadata +275 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class GroupedCollectionSelect < Base # :nodoc:
7
+ include SelectRenderer
8
+ include FormOptionsHelper
9
+
10
+ def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
11
+ @collection = collection
12
+ @group_method = group_method
13
+ @group_label_method = group_label_method
14
+ @option_key_method = option_key_method
15
+ @option_value_method = option_value_method
16
+ @html_options = html_options
17
+
18
+ super(object_name, method_name, template_object, options)
19
+ end
20
+
21
+ def render
22
+ option_tags_options = {
23
+ selected: @options.fetch(:selected) { value },
24
+ disabled: @options[:disabled]
25
+ }
26
+
27
+ select_content_tag(
28
+ option_groups_from_collection_for_select(@collection, @group_method, @group_label_method, @option_key_method, @option_value_method, option_tags_options), @options, @html_options
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class HiddenField < TextField # :nodoc:
7
+ def render
8
+ @options[:autocomplete] = "off"
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class Label < Base # :nodoc:
7
+ class LabelBuilder # :nodoc:
8
+ attr_reader :object
9
+
10
+ def initialize(template_object, object_name, method_name, object, tag_value)
11
+ @template_object = template_object
12
+ @object_name = object_name
13
+ @method_name = method_name
14
+ @object = object
15
+ @tag_value = tag_value
16
+ end
17
+
18
+ def translation
19
+ method_and_value = @tag_value.present? ? "#{@method_name}.#{@tag_value}" : @method_name
20
+
21
+ content ||= Translator
22
+ .new(object, @object_name, method_and_value, scope: "helpers.label")
23
+ .translate
24
+ content ||= @method_name.humanize
25
+
26
+ content
27
+ end
28
+
29
+ def to_s
30
+ translation
31
+ end
32
+ end
33
+
34
+ def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil)
35
+ options ||= {}
36
+
37
+ content_is_options = content_or_options.is_a?(Hash)
38
+ if content_is_options
39
+ options.merge! content_or_options
40
+ @content = nil
41
+ else
42
+ @content = content_or_options
43
+ end
44
+
45
+ super(object_name, method_name, template_object, options)
46
+ end
47
+
48
+ def render(&block)
49
+ options = @options.stringify_keys
50
+ tag_value = options.delete("value")
51
+ name_and_id = options.dup
52
+
53
+ if name_and_id["for"]
54
+ name_and_id["id"] = name_and_id["for"]
55
+ else
56
+ name_and_id.delete("id")
57
+ end
58
+
59
+ add_default_name_and_id_for_value(tag_value, name_and_id)
60
+ options.delete("index")
61
+ options.delete("namespace")
62
+ options["for"] = name_and_id["id"] unless options.key?("for")
63
+
64
+ builder = LabelBuilder.new(@template_object, @object_name, @method_name, @object, tag_value)
65
+
66
+ content = if block_given?
67
+ @template_object.capture(builder, &block)
68
+ elsif @content.present?
69
+ @content.to_s
70
+ else
71
+ render_component(builder)
72
+ end
73
+
74
+ label_tag(name_and_id["id"], content, options)
75
+ end
76
+
77
+ private
78
+ def render_component(builder)
79
+ builder.translation
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class MonthField < DatetimeField # :nodoc:
7
+ private
8
+ def format_datetime(value)
9
+ value&.strftime("%Y-%m")
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class NumberField < TextField # :nodoc:
7
+ def render
8
+ options = @options.stringify_keys
9
+
10
+ if range = options.delete("in") || options.delete("within")
11
+ options.update("min" => range.min, "max" => range.max)
12
+ end
13
+
14
+ @options = options
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class PasswordField < TextField # :nodoc:
7
+ def render
8
+ @options = { value: nil }.merge!(@options)
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ module Placeholderable # :nodoc:
7
+ def initialize(*)
8
+ super
9
+
10
+ if tag_value = @options[:placeholder]
11
+ placeholder = tag_value if tag_value.is_a?(String)
12
+ method_and_value = tag_value.is_a?(TrueClass) ? @method_name : "#{@method_name}.#{tag_value}"
13
+
14
+ placeholder ||= Tags::Translator
15
+ .new(object, @object_name, method_and_value, scope: "helpers.placeholder")
16
+ .translate
17
+ placeholder ||= @method_name.humanize
18
+ @options[:placeholder] = placeholder
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/helpers/tags/checkable"
4
+
5
+ module ActionView
6
+ module Helpers
7
+ module Tags # :nodoc:
8
+ class RadioButton < Base # :nodoc:
9
+ include Checkable
10
+
11
+ def initialize(object_name, method_name, template_object, tag_value, options)
12
+ @tag_value = tag_value
13
+ super(object_name, method_name, template_object, options)
14
+ end
15
+
16
+ def render
17
+ options = @options.stringify_keys
18
+ options["type"] = "radio"
19
+ options["value"] = @tag_value
20
+ options["checked"] = "checked" if input_checked?(options)
21
+ add_default_name_and_id_for_value(@tag_value, options)
22
+ tag("input", options)
23
+ end
24
+
25
+ private
26
+ def checked?(value)
27
+ value.to_s == @tag_value.to_s
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class RangeField < NumberField # :nodoc:
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class SearchField < TextField # :nodoc:
7
+ def render
8
+ options = @options.stringify_keys
9
+
10
+ if options["autosave"]
11
+ if options["autosave"] == true
12
+ options["autosave"] = request.host.split(".").reverse.join(".")
13
+ end
14
+ options["results"] ||= 10
15
+ end
16
+
17
+ if options["onsearch"]
18
+ options["incremental"] = true unless options.has_key?("incremental")
19
+ end
20
+
21
+ @options = options
22
+ super
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class Select < Base # :nodoc:
7
+ include SelectRenderer
8
+ include FormOptionsHelper
9
+
10
+ def initialize(object_name, method_name, template_object, choices, options, html_options)
11
+ @choices = block_given? ? template_object.capture { yield || "" } : choices
12
+ @choices = @choices.to_a if @choices.is_a?(Range)
13
+
14
+ @html_options = html_options
15
+
16
+ super(object_name, method_name, template_object, options)
17
+ end
18
+
19
+ def render
20
+ option_tags_options = {
21
+ selected: @options.fetch(:selected) { value.nil? ? "" : value },
22
+ disabled: @options[:disabled]
23
+ }
24
+
25
+ option_tags = if grouped_choices?
26
+ grouped_options_for_select(@choices, option_tags_options)
27
+ else
28
+ options_for_select(@choices, option_tags_options)
29
+ end
30
+
31
+ select_content_tag(option_tags, @options, @html_options)
32
+ end
33
+
34
+ private
35
+ # Grouped choices look like this:
36
+ #
37
+ # [nil, []]
38
+ # { nil => [] }
39
+ def grouped_choices?
40
+ !@choices.blank? && @choices.first.respond_to?(:second) && Array === @choices.first.second
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ module SelectRenderer # :nodoc:
7
+ private
8
+ def select_content_tag(option_tags, options, html_options)
9
+ html_options = html_options.stringify_keys
10
+ [:required, :multiple, :size].each do |prop|
11
+ html_options[prop.to_s] = options.delete(prop) if options.key?(prop) && !html_options.key?(prop.to_s)
12
+ end
13
+
14
+ add_default_name_and_id(html_options)
15
+
16
+ if placeholder_required?(html_options)
17
+ raise ArgumentError, "include_blank cannot be false for a required field." if options[:include_blank] == false
18
+ options[:include_blank] ||= true unless options[:prompt]
19
+ end
20
+
21
+ value = options.fetch(:selected) { value() }
22
+ select = content_tag("select", add_options(option_tags, options, value), html_options)
23
+
24
+ if html_options["multiple"] && options.fetch(:include_hidden, true)
25
+ tag("input", disabled: html_options["disabled"], name: html_options["name"], type: "hidden", value: "", autocomplete: "off") + select
26
+ else
27
+ select
28
+ end
29
+ end
30
+
31
+ def placeholder_required?(html_options)
32
+ # See https://html.spec.whatwg.org/multipage/forms.html#attr-select-required
33
+ html_options["required"] && !html_options["multiple"] && html_options.fetch("size", 1).to_i == 1
34
+ end
35
+
36
+ def add_options(option_tags, options, value = nil)
37
+ if options[:include_blank]
38
+ content = (options[:include_blank] if options[:include_blank].is_a?(String))
39
+ label = (" " unless content)
40
+ option_tags = tag_builder.content_tag_string("option", content, value: "", label: label) + "\n" + option_tags
41
+ end
42
+
43
+ if value.blank? && options[:prompt]
44
+ tag_options = { value: "" }.tap do |prompt_opts|
45
+ prompt_opts[:disabled] = true if options[:disabled] == ""
46
+ prompt_opts[:selected] = true if options[:selected] == ""
47
+ end
48
+ option_tags = tag_builder.content_tag_string("option", prompt_text(options[:prompt]), tag_options) + "\n" + option_tags
49
+ end
50
+
51
+ option_tags
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class TelField < TextField # :nodoc:
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/helpers/tags/placeholderable"
4
+
5
+ module ActionView
6
+ module Helpers
7
+ module Tags # :nodoc:
8
+ class TextArea < Base # :nodoc:
9
+ include Placeholderable
10
+
11
+ def render
12
+ options = @options.stringify_keys
13
+ add_default_name_and_id(options)
14
+
15
+ if size = options.delete("size")
16
+ options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
17
+ end
18
+
19
+ content_tag("textarea", options.delete("value") { value_before_type_cast }, options)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/helpers/tags/placeholderable"
4
+
5
+ module ActionView
6
+ module Helpers
7
+ module Tags # :nodoc:
8
+ class TextField < Base # :nodoc:
9
+ include Placeholderable
10
+
11
+ def render
12
+ options = @options.stringify_keys
13
+ options["size"] = options["maxlength"] unless options.key?("size")
14
+ options["type"] ||= field_type
15
+ options["value"] = options.fetch("value") { value_before_type_cast } unless field_type == "file"
16
+ add_default_name_and_id(options)
17
+ tag("input", options)
18
+ end
19
+
20
+ class << self
21
+ def field_type
22
+ @field_type ||= name.split("::").last.sub("Field", "").downcase
23
+ end
24
+ end
25
+
26
+ private
27
+ def field_type
28
+ self.class.field_type
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class TimeField < DatetimeField # :nodoc:
7
+ def initialize(object_name, method_name, template_object, options = {})
8
+ @include_seconds = options.delete(:include_seconds) { true }
9
+ super
10
+ end
11
+
12
+ private
13
+ def format_datetime(value)
14
+ if @include_seconds
15
+ value&.strftime("%T.%L")
16
+ else
17
+ value&.strftime("%H:%M")
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class TimeSelect < DateSelect # :nodoc:
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class TimeZoneSelect < Base # :nodoc:
7
+ include SelectRenderer
8
+ include FormOptionsHelper
9
+
10
+ def initialize(object_name, method_name, template_object, priority_zones, options, html_options)
11
+ @priority_zones = priority_zones
12
+ @html_options = html_options
13
+
14
+ super(object_name, method_name, template_object, options)
15
+ end
16
+
17
+ def render
18
+ select_content_tag(
19
+ time_zone_options_for_select(value || @options[:default], @priority_zones, @options[:model] || ActiveSupport::TimeZone), @options, @html_options
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class Translator # :nodoc:
7
+ def initialize(object, object_name, method_and_value, scope:)
8
+ @object_name = object_name.gsub(/\[(.*)_attributes\]\[\d+\]/, '.\1')
9
+ @method_and_value = method_and_value
10
+ @scope = scope
11
+ @model = object.respond_to?(:to_model) ? object.to_model : nil
12
+ end
13
+
14
+ def translate
15
+ translated_attribute = I18n.t("#{object_name}.#{method_and_value}", default: i18n_default, scope: scope).presence
16
+ translated_attribute || human_attribute_name
17
+ end
18
+
19
+ private
20
+ attr_reader :object_name, :method_and_value, :scope, :model
21
+
22
+ def i18n_default
23
+ if model
24
+ key = model.model_name.i18n_key
25
+ ["#{key}.#{method_and_value}".to_sym, ""]
26
+ else
27
+ ""
28
+ end
29
+ end
30
+
31
+ def human_attribute_name
32
+ if model && model.class.respond_to?(:human_attribute_name)
33
+ model.class.human_attribute_name(method_and_value)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class UrlField < TextField # :nodoc:
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class WeekField < DatetimeField # :nodoc:
7
+ private
8
+ def format_datetime(value)
9
+ value&.strftime("%Y-W%V")
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class WeekdaySelect < Base # :nodoc:
7
+ include SelectRenderer
8
+ include FormOptionsHelper
9
+
10
+ def initialize(object_name, method_name, template_object, options, html_options)
11
+ @html_options = html_options
12
+
13
+ super(object_name, method_name, template_object, options)
14
+ end
15
+
16
+ def render
17
+ select_content_tag(
18
+ weekday_options_for_select(
19
+ value || @options[:selected],
20
+ index_as_value: @options.fetch(:index_as_value, false),
21
+ day_format: @options.fetch(:day_format, :day_names),
22
+ beginning_of_week: @options.fetch(:beginning_of_week, Date.beginning_of_week)
23
+ ),
24
+ @options,
25
+ @html_options
26
+ )
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers # :nodoc:
5
+ module Tags # :nodoc:
6
+ extend ActiveSupport::Autoload
7
+
8
+ autoload :SelectRenderer
9
+
10
+ eager_autoload do
11
+ autoload :Base
12
+ autoload :Translator
13
+ autoload :CheckBox
14
+ autoload :CollectionCheckBoxes
15
+ autoload :CollectionRadioButtons
16
+ autoload :CollectionSelect
17
+ autoload :ColorField
18
+ autoload :DateField
19
+ autoload :DateSelect
20
+ autoload :DatetimeField
21
+ autoload :DatetimeLocalField
22
+ autoload :DatetimeSelect
23
+ autoload :EmailField
24
+ autoload :FileField
25
+ autoload :GroupedCollectionSelect
26
+ autoload :HiddenField
27
+ autoload :Label
28
+ autoload :MonthField
29
+ autoload :NumberField
30
+ autoload :PasswordField
31
+ autoload :RadioButton
32
+ autoload :RangeField
33
+ autoload :SearchField
34
+ autoload :Select
35
+ autoload :TelField
36
+ autoload :TextArea
37
+ autoload :TextField
38
+ autoload :TimeField
39
+ autoload :TimeSelect
40
+ autoload :TimeZoneSelect
41
+ autoload :UrlField
42
+ autoload :WeekField
43
+ autoload :WeekdaySelect
44
+ end
45
+ end
46
+ end
47
+ end