actionview 6.1.7.10 → 7.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionview might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -409
- data/MIT-LICENSE +2 -1
- data/lib/action_view/base.rb +3 -3
- data/lib/action_view/buffers.rb +2 -2
- data/lib/action_view/cache_expiry.rb +46 -32
- data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
- data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
- data/lib/action_view/dependency_tracker.rb +6 -147
- data/lib/action_view/digestor.rb +7 -4
- data/lib/action_view/flows.rb +4 -4
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/active_model_helper.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +84 -29
- data/lib/action_view/helpers/asset_url_helper.rb +7 -7
- data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
- data/lib/action_view/helpers/cache_helper.rb +51 -3
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +2 -2
- data/lib/action_view/helpers/csp_helper.rb +1 -1
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +6 -7
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +72 -12
- data/lib/action_view/helpers/form_options_helper.rb +65 -33
- data/lib/action_view/helpers/form_tag_helper.rb +75 -32
- data/lib/action_view/helpers/javascript_helper.rb +3 -5
- data/lib/action_view/helpers/number_helper.rb +3 -4
- data/lib/action_view/helpers/output_safety_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +1 -1
- data/lib/action_view/helpers/sanitize_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +25 -44
- data/lib/action_view/helpers/tags/base.rb +3 -15
- data/lib/action_view/helpers/tags/check_box.rb +2 -2
- data/lib/action_view/helpers/tags/collection_select.rb +1 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +0 -4
- data/lib/action_view/helpers/tags/time_field.rb +10 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +27 -0
- data/lib/action_view/helpers/tags.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +24 -13
- data/lib/action_view/helpers/translation_helper.rb +1 -2
- data/lib/action_view/helpers/url_helper.rb +102 -77
- data/lib/action_view/helpers.rb +25 -25
- data/lib/action_view/lookup_context.rb +33 -52
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +16 -22
- data/lib/action_view/railtie.rb +14 -1
- data/lib/action_view/render_parser.rb +188 -0
- data/lib/action_view/renderer/abstract_renderer.rb +2 -2
- data/lib/action_view/renderer/partial_renderer.rb +0 -34
- data/lib/action_view/renderer/renderer.rb +4 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
- data/lib/action_view/renderer/template_renderer.rb +6 -2
- data/lib/action_view/rendering.rb +2 -2
- data/lib/action_view/ripper_ast_parser.rb +198 -0
- data/lib/action_view/routing_url_for.rb +1 -1
- data/lib/action_view/template/error.rb +108 -13
- data/lib/action_view/template/handlers/erb.rb +6 -0
- data/lib/action_view/template/handlers.rb +3 -3
- data/lib/action_view/template/html.rb +3 -3
- data/lib/action_view/template/inline.rb +3 -3
- data/lib/action_view/template/raw_file.rb +3 -3
- data/lib/action_view/template/resolver.rb +84 -311
- data/lib/action_view/template/text.rb +3 -3
- data/lib/action_view/template/types.rb +14 -12
- data/lib/action_view/template.rb +10 -1
- data/lib/action_view/template_details.rb +66 -0
- data/lib/action_view/template_path.rb +64 -0
- data/lib/action_view/test_case.rb +6 -2
- data/lib/action_view/testing/resolvers.rb +11 -12
- data/lib/action_view/unbound_template.rb +33 -7
- data/lib/action_view.rb +3 -4
- data/lib/assets/compiled/rails-ujs.js +5 -36
- metadata +22 -16
@@ -4,13 +4,13 @@ require "active_support/core_ext/enumerable"
|
|
4
4
|
|
5
5
|
module ActionView
|
6
6
|
# = Action View Errors
|
7
|
-
class ActionViewError < StandardError
|
7
|
+
class ActionViewError < StandardError # :nodoc:
|
8
8
|
end
|
9
9
|
|
10
|
-
class EncodingError < StandardError
|
10
|
+
class EncodingError < StandardError # :nodoc:
|
11
11
|
end
|
12
12
|
|
13
|
-
class WrongEncodingError < EncodingError
|
13
|
+
class WrongEncodingError < EncodingError # :nodoc:
|
14
14
|
def initialize(string, encoding)
|
15
15
|
@string, @encoding = string, encoding
|
16
16
|
end
|
@@ -26,12 +26,18 @@ module ActionView
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
class MissingTemplate < ActionViewError
|
30
|
-
attr_reader :path
|
29
|
+
class MissingTemplate < ActionViewError # :nodoc:
|
30
|
+
attr_reader :path, :paths, :prefixes, :partial
|
31
31
|
|
32
32
|
def initialize(paths, path, prefixes, partial, details, *)
|
33
|
+
if partial && path.present?
|
34
|
+
path = path.sub(%r{([^/]+)$}, "_\\1")
|
35
|
+
end
|
36
|
+
|
33
37
|
@path = path
|
34
|
-
|
38
|
+
@paths = paths
|
39
|
+
@prefixes = Array(prefixes)
|
40
|
+
@partial = partial
|
35
41
|
template_type = if partial
|
36
42
|
"partial"
|
37
43
|
elsif /layouts/i.match?(path)
|
@@ -40,22 +46,111 @@ module ActionView
|
|
40
46
|
"template"
|
41
47
|
end
|
42
48
|
|
43
|
-
|
44
|
-
path = path.sub(%r{([^/]+)$}, "_\\1")
|
45
|
-
end
|
46
|
-
searched_paths = prefixes.map { |prefix| [prefix, path].join("/") }
|
49
|
+
searched_paths = @prefixes.map { |prefix| [prefix, path].join("/") }
|
47
50
|
|
48
|
-
out = "Missing #{template_type} #{searched_paths.join(", ")} with #{details.inspect}
|
51
|
+
out = "Missing #{template_type} #{searched_paths.join(", ")} with #{details.inspect}.\n\nSearched in:\n"
|
49
52
|
out += paths.compact.map { |p| " * #{p.to_s.inspect}\n" }.join
|
50
53
|
super out
|
51
54
|
end
|
55
|
+
|
56
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::Jaro)
|
57
|
+
include DidYouMean::Correctable
|
58
|
+
|
59
|
+
class Results # :nodoc:
|
60
|
+
Result = Struct.new(:path, :score)
|
61
|
+
|
62
|
+
def initialize(size)
|
63
|
+
@size = size
|
64
|
+
@results = []
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_a
|
68
|
+
@results.map(&:path)
|
69
|
+
end
|
70
|
+
|
71
|
+
def should_record?(score)
|
72
|
+
if @results.size < @size
|
73
|
+
true
|
74
|
+
else
|
75
|
+
score < @results.last.score
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def add(path, score)
|
80
|
+
if should_record?(score)
|
81
|
+
@results << Result.new(path, score)
|
82
|
+
@results.sort_by!(&:score)
|
83
|
+
@results.pop if @results.size > @size
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Apps may have thousands of candidate templates so we attempt to
|
89
|
+
# generate the suggestions as efficiently as possible.
|
90
|
+
# First we split templates into prefixes and basenames, so that those can
|
91
|
+
# be matched separately.
|
92
|
+
def corrections
|
93
|
+
candidates = paths.flat_map(&:all_template_paths).uniq
|
94
|
+
|
95
|
+
if partial
|
96
|
+
candidates.select!(&:partial?)
|
97
|
+
else
|
98
|
+
candidates.reject!(&:partial?)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Group by possible prefixes
|
102
|
+
files_by_dir = candidates.group_by(&:prefix)
|
103
|
+
files_by_dir.transform_values! do |files|
|
104
|
+
files.map do |file|
|
105
|
+
# Remove prefix
|
106
|
+
File.basename(file.to_s)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# No suggestions if there's an exact match, but wrong details
|
111
|
+
if prefixes.any? { |prefix| files_by_dir[prefix]&.include?(path) }
|
112
|
+
return []
|
113
|
+
end
|
114
|
+
|
115
|
+
cached_distance = Hash.new do |h, args|
|
116
|
+
h[args] = -DidYouMean::Jaro.distance(*args)
|
117
|
+
end
|
118
|
+
|
119
|
+
results = Results.new(6)
|
120
|
+
|
121
|
+
files_by_dir.keys.index_with do |dirname|
|
122
|
+
prefixes.map do |prefix|
|
123
|
+
cached_distance[[prefix, dirname]]
|
124
|
+
end.min
|
125
|
+
end.sort_by(&:last).each do |dirname, dirweight|
|
126
|
+
# If our directory's score makes it impossible to find a better match
|
127
|
+
# we can prune this search branch.
|
128
|
+
next unless results.should_record?(dirweight - 1.0)
|
129
|
+
|
130
|
+
files = files_by_dir[dirname]
|
131
|
+
|
132
|
+
files.each do |file|
|
133
|
+
fileweight = cached_distance[[path, file]]
|
134
|
+
score = dirweight + fileweight
|
135
|
+
|
136
|
+
results.add(File.join(dirname, file), score)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if partial
|
141
|
+
results.to_a.map { |res| res.sub(%r{_([^/]+)\z}, "\\1") }
|
142
|
+
else
|
143
|
+
results.to_a
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
52
147
|
end
|
53
148
|
|
54
149
|
class Template
|
55
150
|
# The Template::Error exception is raised when the compilation or rendering of the template
|
56
151
|
# fails. This exception then gathers a bunch of intimate details and uses it to report a
|
57
152
|
# precise exception message.
|
58
|
-
class Error < ActionViewError
|
153
|
+
class Error < ActionViewError # :nodoc:
|
59
154
|
SOURCE_CODE_RADIUS = 3
|
60
155
|
|
61
156
|
# Override to prevent #cause resetting during re-raise.
|
@@ -134,7 +229,7 @@ module ActionView
|
|
134
229
|
|
135
230
|
TemplateError = Template::Error
|
136
231
|
|
137
|
-
class SyntaxErrorInTemplate < TemplateError
|
232
|
+
class SyntaxErrorInTemplate < TemplateError # :nodoc:
|
138
233
|
def initialize(template, offending_code_string)
|
139
234
|
@offending_code_string = offending_code_string
|
140
235
|
super(template)
|
@@ -16,6 +16,9 @@ module ActionView
|
|
16
16
|
# Do not escape templates of these mime types.
|
17
17
|
class_attribute :escape_ignore_list, default: ["text/plain"]
|
18
18
|
|
19
|
+
# Strip trailing newlines from rendered output
|
20
|
+
class_attribute :strip_trailing_newlines, default: false
|
21
|
+
|
19
22
|
ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
|
20
23
|
|
21
24
|
def self.call(template, source)
|
@@ -45,6 +48,9 @@ module ActionView
|
|
45
48
|
# Always make sure we return a String in the default_internal
|
46
49
|
erb.encode!
|
47
50
|
|
51
|
+
# Strip trailing newlines from the template if enabled
|
52
|
+
erb.chomp! if strip_trailing_newlines
|
53
|
+
|
48
54
|
options = {
|
49
55
|
escape: (self.class.escape_ignore_list.include? template.type),
|
50
56
|
trim: (self.class.erb_trim_mode == "-")
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActionView
|
3
|
+
module ActionView # :nodoc:
|
4
4
|
# = Action View Template Handlers
|
5
|
-
class Template
|
6
|
-
module Handlers
|
5
|
+
class Template # :nodoc:
|
6
|
+
module Handlers # :nodoc:
|
7
7
|
autoload :Raw, "action_view/template/handlers/raw"
|
8
8
|
autoload :ERB, "action_view/template/handlers/erb"
|
9
9
|
autoload :Html, "action_view/template/handlers/html"
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActionView
|
3
|
+
module ActionView # :nodoc:
|
4
4
|
# = Action View HTML Template
|
5
|
-
class Template
|
6
|
-
class HTML
|
5
|
+
class Template # :nodoc:
|
6
|
+
class HTML # :nodoc:
|
7
7
|
attr_reader :type
|
8
8
|
|
9
9
|
def initialize(string, type)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActionView
|
4
|
-
class Template
|
5
|
-
class Inline < Template
|
3
|
+
module ActionView # :nodoc:
|
4
|
+
class Template # :nodoc:
|
5
|
+
class Inline < Template # :nodoc:
|
6
6
|
# This finalizer is needed (and exactly with a proc inside another proc)
|
7
7
|
# otherwise templates leak in development.
|
8
8
|
Finalizer = proc do |method_name, mod| # :nodoc:
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActionView
|
3
|
+
module ActionView # :nodoc:
|
4
4
|
# = Action View RawFile Template
|
5
|
-
class Template
|
6
|
-
class RawFile
|
5
|
+
class Template # :nodoc:
|
6
|
+
class RawFile # :nodoc:
|
7
7
|
attr_accessor :type, :format
|
8
8
|
|
9
9
|
def initialize(filename)
|