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,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