omg-actionview 8.0.0.alpha1

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 (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,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ class Template
5
+ # = Action View Renderable Template for objects that respond to #render_in
6
+ class Renderable # :nodoc:
7
+ def initialize(renderable)
8
+ @renderable = renderable
9
+ end
10
+
11
+ def identifier
12
+ @renderable.class.name
13
+ end
14
+
15
+ def render(context, *args)
16
+ @renderable.render_in(context)
17
+ rescue NoMethodError
18
+ if !@renderable.respond_to?(:render_in)
19
+ raise ArgumentError, "'#{@renderable.inspect}' is not a renderable object. It must implement #render_in."
20
+ else
21
+ raise
22
+ end
23
+ end
24
+
25
+ def format
26
+ @renderable.try(:format)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "active_support/core_ext/class"
5
+ require "active_support/core_ext/module/attribute_accessors"
6
+ require "action_view/template"
7
+ require "concurrent/map"
8
+
9
+ module ActionView
10
+ # = Action View Resolver
11
+ class Resolver
12
+ class PathParser # :nodoc:
13
+ ParsedPath = Struct.new(:path, :details)
14
+
15
+ def build_path_regex
16
+ handlers = Regexp.union(Template::Handlers.extensions.map(&:to_s))
17
+ formats = Regexp.union(Template::Types.symbols.map(&:to_s))
18
+ available_locales = I18n.available_locales.map(&:to_s)
19
+ regular_locales = [/[a-z]{2}(?:[-_][A-Z]{2})?/]
20
+ locales = Regexp.union(available_locales + regular_locales)
21
+ variants = "[^.]*"
22
+
23
+ %r{
24
+ \A
25
+ (?:(?<prefix>.*)/)?
26
+ (?<partial>_)?
27
+ (?<action>.*?)
28
+ (?:\.(?<locale>#{locales}))??
29
+ (?:\.(?<format>#{formats}))??
30
+ (?:\+(?<variant>#{variants}))??
31
+ (?:\.(?<handler>#{handlers}))?
32
+ \z
33
+ }x
34
+ end
35
+
36
+ def parse(path)
37
+ @regex ||= build_path_regex
38
+ match = @regex.match(path)
39
+ path = TemplatePath.build(match[:action], match[:prefix] || "", !!match[:partial])
40
+ details = TemplateDetails.new(
41
+ match[:locale]&.to_sym,
42
+ match[:handler]&.to_sym,
43
+ match[:format]&.to_sym,
44
+ match[:variant]&.to_sym
45
+ )
46
+ ParsedPath.new(path, details)
47
+ end
48
+ end
49
+
50
+ cattr_accessor :caching, default: true
51
+
52
+ class << self
53
+ alias :caching? :caching
54
+ end
55
+
56
+ def clear_cache
57
+ end
58
+
59
+ # Normalizes the arguments and passes it on to find_templates.
60
+ def find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = [])
61
+ _find_all(name, prefix, partial, details, key, locals)
62
+ end
63
+
64
+ def built_templates # :nodoc:
65
+ # Used for error pages
66
+ []
67
+ end
68
+
69
+ def all_template_paths # :nodoc:
70
+ # Not implemented by default
71
+ []
72
+ end
73
+
74
+ private
75
+ def _find_all(name, prefix, partial, details, key, locals)
76
+ find_templates(name, prefix, partial, details, locals)
77
+ end
78
+
79
+ delegate :caching?, to: :class
80
+
81
+ # This is what child classes implement. No defaults are needed
82
+ # because Resolver guarantees that the arguments are present and
83
+ # normalized.
84
+ def find_templates(name, prefix, partial, details, locals = [])
85
+ raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details, locals = []) method"
86
+ end
87
+ end
88
+
89
+ # A resolver that loads files from the filesystem.
90
+ class FileSystemResolver < Resolver
91
+ attr_reader :path
92
+
93
+ def initialize(path)
94
+ raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
95
+ @unbound_templates = Concurrent::Map.new
96
+ @path_parser = PathParser.new
97
+ @path = File.expand_path(path)
98
+ super()
99
+ end
100
+
101
+ def clear_cache
102
+ @unbound_templates.clear
103
+ @path_parser = PathParser.new
104
+ super
105
+ end
106
+
107
+ def to_s
108
+ @path.to_s
109
+ end
110
+ alias :to_path :to_s
111
+
112
+ def eql?(resolver)
113
+ self.class.equal?(resolver.class) && to_path == resolver.to_path
114
+ end
115
+ alias :== :eql?
116
+
117
+ def all_template_paths # :nodoc:
118
+ paths = template_glob("**/*")
119
+ paths.map do |filename|
120
+ filename.from(@path.size + 1).remove(/\.[^\/]*\z/)
121
+ end.uniq.map do |filename|
122
+ TemplatePath.parse(filename)
123
+ end
124
+ end
125
+
126
+ def built_templates # :nodoc:
127
+ @unbound_templates.values.flatten.flat_map(&:built_templates)
128
+ end
129
+
130
+ private
131
+ def _find_all(name, prefix, partial, details, key, locals)
132
+ requested_details = key || TemplateDetails::Requested.new(**details)
133
+ cache = key ? @unbound_templates : Concurrent::Map.new
134
+
135
+ unbound_templates =
136
+ cache.compute_if_absent(TemplatePath.virtual(name, prefix, partial)) do
137
+ path = TemplatePath.build(name, prefix, partial)
138
+ unbound_templates_from_path(path)
139
+ end
140
+
141
+ filter_and_sort_by_details(unbound_templates, requested_details).map do |unbound_template|
142
+ unbound_template.bind_locals(locals)
143
+ end
144
+ end
145
+
146
+ def source_for_template(template)
147
+ Template::Sources::File.new(template)
148
+ end
149
+
150
+ def build_unbound_template(template)
151
+ parsed = @path_parser.parse(template.from(@path.size + 1))
152
+ details = parsed.details
153
+ source = source_for_template(template)
154
+
155
+ UnboundTemplate.new(
156
+ source,
157
+ template,
158
+ details: details,
159
+ virtual_path: parsed.path.virtual,
160
+ )
161
+ end
162
+
163
+ def unbound_templates_from_path(path)
164
+ if path.name.include?(".")
165
+ return []
166
+ end
167
+
168
+ # Instead of checking for every possible path, as our other globs would
169
+ # do, scan the directory for files with the right prefix.
170
+ paths = template_glob("#{escape_entry(path.to_s)}*")
171
+
172
+ paths.map do |path|
173
+ build_unbound_template(path)
174
+ end.select do |template|
175
+ # Select for exact virtual path match, including case sensitivity
176
+ template.virtual_path == path.virtual
177
+ end
178
+ end
179
+
180
+ def filter_and_sort_by_details(templates, requested_details)
181
+ filtered_templates = templates.select do |template|
182
+ template.details.matches?(requested_details)
183
+ end
184
+
185
+ if filtered_templates.count > 1
186
+ filtered_templates.sort_by! do |template|
187
+ template.details.sort_key_for(requested_details)
188
+ end
189
+ end
190
+
191
+ filtered_templates
192
+ end
193
+
194
+ # Safe glob within @path
195
+ def template_glob(glob)
196
+ query = File.join(escape_entry(@path), glob)
197
+ path_with_slash = File.join(@path, "")
198
+
199
+ Dir.glob(query).filter_map do |filename|
200
+ filename = File.expand_path(filename)
201
+ next if File.directory?(filename)
202
+ next unless filename.start_with?(path_with_slash)
203
+
204
+ filename
205
+ end
206
+ end
207
+
208
+ def escape_entry(entry)
209
+ entry.gsub(/[*?{}\[\]]/, '\\\\\\&')
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ class Template
5
+ module Sources
6
+ class File
7
+ def initialize(filename)
8
+ @filename = filename
9
+ end
10
+
11
+ def to_s
12
+ ::File.binread @filename
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ class Template
5
+ module Sources
6
+ extend ActiveSupport::Autoload
7
+
8
+ eager_autoload do
9
+ autoload :File
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView # :nodoc:
4
+ class Template # :nodoc:
5
+ # = Action View Text Template
6
+ class Text # :nodoc:
7
+ attr_accessor :type
8
+
9
+ def initialize(string)
10
+ @string = string.to_s
11
+ end
12
+
13
+ def identifier
14
+ "text template"
15
+ end
16
+
17
+ alias_method :inspect, :identifier
18
+
19
+ def to_str
20
+ @string
21
+ end
22
+
23
+ def render(*args)
24
+ to_str
25
+ end
26
+
27
+ def format
28
+ :text
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+
5
+ module ActionView
6
+ class Template # :nodoc:
7
+ # SimpleType is mostly just a stub implementation for when Action View
8
+ # is used without Action Dispatch.
9
+ class SimpleType # :nodoc:
10
+ @symbols = [ :html, :text, :js, :css, :xml, :json ]
11
+ class << self
12
+ attr_reader :symbols
13
+
14
+ def [](type)
15
+ if type.is_a?(self)
16
+ type
17
+ else
18
+ new(type)
19
+ end
20
+ end
21
+
22
+ def valid_symbols?(symbols) # :nodoc
23
+ symbols.all? { |s| @symbols.include?(s) }
24
+ end
25
+ end
26
+
27
+ attr_reader :symbol
28
+
29
+ def initialize(symbol)
30
+ @symbol = symbol.to_sym
31
+ end
32
+
33
+ def to_s
34
+ @symbol.to_s
35
+ end
36
+ alias to_str to_s
37
+
38
+ def ref
39
+ @symbol
40
+ end
41
+ alias to_sym ref
42
+
43
+ def ==(type)
44
+ @symbol == type.to_sym unless type.blank?
45
+ end
46
+ end
47
+
48
+ Types = SimpleType # :nodoc:
49
+ end
50
+ end