actionview 7.2.3.1 → 8.1.4.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +198 -109
- data/lib/action_view/base.rb +5 -2
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/dependency_tracker/erb_tracker.rb +37 -28
- data/lib/action_view/dependency_tracker/ruby_tracker.rb +3 -20
- data/lib/action_view/dependency_tracker/wildcard_resolver.rb +32 -0
- data/lib/action_view/dependency_tracker.rb +7 -1
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +21 -2
- data/lib/action_view/helpers/atom_feed_helper.rb +0 -2
- data/lib/action_view/helpers/cache_helper.rb +8 -0
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +6 -2
- data/lib/action_view/helpers/date_helper.rb +20 -3
- data/lib/action_view/helpers/form_helper.rb +77 -77
- data/lib/action_view/helpers/form_options_helper.rb +42 -36
- data/lib/action_view/helpers/form_tag_helper.rb +35 -25
- data/lib/action_view/helpers/javascript_helper.rb +5 -1
- data/lib/action_view/helpers/number_helper.rb +14 -0
- data/lib/action_view/helpers/rendering_helper.rb +160 -50
- data/lib/action_view/helpers/sanitize_helper.rb +12 -1
- data/lib/action_view/helpers/tag_helper.rb +70 -77
- data/lib/action_view/helpers/tags/base.rb +11 -9
- data/lib/action_view/helpers/tags/check_box.rb +9 -3
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +4 -3
- data/lib/action_view/helpers/tags/collection_helpers.rb +11 -1
- data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
- data/lib/action_view/helpers/tags/file_field.rb +7 -2
- data/lib/action_view/helpers/tags/hidden_field.rb +1 -1
- data/lib/action_view/helpers/tags/label.rb +3 -10
- data/lib/action_view/helpers/tags/radio_button.rb +1 -1
- data/lib/action_view/helpers/tags/select.rb +6 -1
- data/lib/action_view/helpers/tags/select_renderer.rb +6 -4
- data/lib/action_view/helpers/tags/text_area.rb +1 -1
- data/lib/action_view/helpers/tags/text_field.rb +1 -1
- data/lib/action_view/helpers/tags/week_field.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +23 -7
- data/lib/action_view/helpers/translation_helper.rb +6 -1
- data/lib/action_view/helpers/url_helper.rb +39 -13
- data/lib/action_view/layouts.rb +1 -1
- data/lib/action_view/locale/en.yml +3 -0
- data/lib/action_view/log_subscriber.rb +1 -4
- data/lib/action_view/railtie.rb +12 -1
- data/lib/action_view/record_identifier.rb +22 -1
- data/lib/action_view/render_parser/prism_render_parser.rb +13 -1
- data/lib/action_view/render_parser/ripper_render_parser.rb +10 -1
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +5 -1
- data/lib/action_view/renderer/partial_renderer.rb +16 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +8 -2
- data/lib/action_view/rendering.rb +2 -3
- data/lib/action_view/structured_event_subscriber.rb +97 -0
- data/lib/action_view/template/error.rb +7 -3
- data/lib/action_view/template/handlers/erb/erubi.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +37 -12
- data/lib/action_view/template/raw_file.rb +4 -0
- data/lib/action_view/template/resolver.rb +0 -1
- data/lib/action_view/template.rb +12 -6
- data/lib/action_view/test_case.rb +68 -55
- data/lib/action_view.rb +16 -0
- metadata +20 -26
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/structured_event_subscriber"
|
|
4
|
+
|
|
5
|
+
module ActionView
|
|
6
|
+
class StructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber # :nodoc:
|
|
7
|
+
VIEWS_PATTERN = /^app\/views\//
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@root = nil
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def render_template(event)
|
|
15
|
+
emit_debug_event("action_view.render_template",
|
|
16
|
+
identifier: from_rails_root(event.payload[:identifier]),
|
|
17
|
+
layout: from_rails_root(event.payload[:layout]),
|
|
18
|
+
duration_ms: event.duration.round(2),
|
|
19
|
+
gc_ms: event.gc_time.round(2),
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
debug_only :render_template
|
|
23
|
+
|
|
24
|
+
def render_partial(event)
|
|
25
|
+
emit_debug_event("action_view.render_partial",
|
|
26
|
+
identifier: from_rails_root(event.payload[:identifier]),
|
|
27
|
+
layout: from_rails_root(event.payload[:layout]),
|
|
28
|
+
duration_ms: event.duration.round(2),
|
|
29
|
+
gc_ms: event.gc_time.round(2),
|
|
30
|
+
cache_hit: event.payload[:cache_hit],
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
debug_only :render_partial
|
|
34
|
+
|
|
35
|
+
def render_layout(event)
|
|
36
|
+
emit_event("action_view.render_layout",
|
|
37
|
+
identifier: from_rails_root(event.payload[:identifier]),
|
|
38
|
+
duration_ms: event.duration.round(2),
|
|
39
|
+
gc_ms: event.gc_time.round(2),
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
debug_only :render_layout
|
|
43
|
+
|
|
44
|
+
def render_collection(event)
|
|
45
|
+
emit_debug_event("action_view.render_collection",
|
|
46
|
+
identifier: from_rails_root(event.payload[:identifier] || "templates"),
|
|
47
|
+
layout: from_rails_root(event.payload[:layout]),
|
|
48
|
+
duration_ms: event.duration.round(2),
|
|
49
|
+
gc_ms: event.gc_time.round(2),
|
|
50
|
+
cache_hits: event.payload[:cache_hits],
|
|
51
|
+
count: event.payload[:count],
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
debug_only :render_collection
|
|
55
|
+
|
|
56
|
+
module Utils # :nodoc:
|
|
57
|
+
private
|
|
58
|
+
def from_rails_root(string)
|
|
59
|
+
return unless string
|
|
60
|
+
|
|
61
|
+
string = string.sub("#{rails_root}/", "")
|
|
62
|
+
string.sub!(VIEWS_PATTERN, "")
|
|
63
|
+
string
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def rails_root # :doc:
|
|
67
|
+
@root ||= Rails.try(:root)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
include Utils
|
|
72
|
+
|
|
73
|
+
class Start # :nodoc:
|
|
74
|
+
include Utils
|
|
75
|
+
|
|
76
|
+
def start(name, id, payload)
|
|
77
|
+
ActiveSupport.event_reporter.debug("action_view.render_start",
|
|
78
|
+
is_layout: name == "render_layout.action_view",
|
|
79
|
+
identifier: from_rails_root(payload[:identifier]),
|
|
80
|
+
layout: from_rails_root(payload[:layout]),
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def finish(name, id, payload)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def self.attach_to(*)
|
|
89
|
+
ActiveSupport::Notifications.subscribe("render_template.action_view", Start.new)
|
|
90
|
+
ActiveSupport::Notifications.subscribe("render_layout.action_view", Start.new)
|
|
91
|
+
|
|
92
|
+
super
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
ActionView::StructuredEventSubscriber.attach_to :action_view
|
|
@@ -260,9 +260,13 @@ module ActionView
|
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
def message
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
if template.is_a?(Template::Inline)
|
|
264
|
+
<<~MESSAGE
|
|
265
|
+
Encountered a syntax error while rendering template: check #{@offending_code_string}
|
|
266
|
+
MESSAGE
|
|
267
|
+
else
|
|
268
|
+
"Encountered a syntax error while rendering template located at: #{template.short_identifier}"
|
|
269
|
+
end
|
|
266
270
|
end
|
|
267
271
|
|
|
268
272
|
def annotated_source_code
|
|
@@ -18,7 +18,7 @@ module ActionView
|
|
|
18
18
|
properties[:preamble] ||= ""
|
|
19
19
|
properties[:postamble] ||= "#{properties[:bufvar]}"
|
|
20
20
|
|
|
21
|
-
# Tell
|
|
21
|
+
# Tell Erubi whether the template will be compiled with `frozen_string_literal: true`
|
|
22
22
|
properties[:freeze_template_literals] = !Template.frozen_string_literal
|
|
23
23
|
|
|
24
24
|
properties[:escapefunc] = ""
|
|
@@ -40,17 +40,19 @@ module ActionView
|
|
|
40
40
|
|
|
41
41
|
# Translate an error location returned by ErrorHighlight to the correct
|
|
42
42
|
# source location inside the template.
|
|
43
|
-
def translate_location(spot,
|
|
44
|
-
|
|
43
|
+
def translate_location(spot, _backtrace_location, source)
|
|
44
|
+
compiled = spot[:script_lines]
|
|
45
|
+
highlight = compiled[spot[:first_lineno] - 1]&.byteslice((spot[:first_column] - 1)...spot[:last_column])
|
|
46
|
+
return nil if highlight.blank?
|
|
47
|
+
|
|
45
48
|
source_lines = source.lines
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
lineno_delta = find_lineno_offset(compiled, source_lines, highlight, spot[:first_lineno])
|
|
50
|
+
|
|
51
|
+
tokens = ::ERB::Util.tokenize(source_lines[spot[:first_lineno] - lineno_delta - 1])
|
|
52
|
+
column_delta = find_offset(spot[:snippet], tokens, spot[:first_column])
|
|
53
|
+
|
|
50
54
|
spot[:first_lineno] -= lineno_delta
|
|
51
55
|
spot[:last_lineno] -= lineno_delta
|
|
52
|
-
|
|
53
|
-
column_delta = spot[:first_column] - new_first_column
|
|
54
56
|
spot[:first_column] -= column_delta
|
|
55
57
|
spot[:last_column] -= column_delta
|
|
56
58
|
spot[:script_lines] = source_lines
|
|
@@ -84,7 +86,7 @@ module ActionView
|
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
if ActionView::Base.annotate_rendered_view_with_filenames && template.format == :html
|
|
87
|
-
options[:preamble] = "@output_buffer.safe_append='<!-- BEGIN #{template.short_identifier}
|
|
89
|
+
options[:preamble] = "@output_buffer.safe_append='<!-- BEGIN #{template.short_identifier}\n-->';"
|
|
88
90
|
options[:postamble] = "@output_buffer.safe_append='<!-- END #{template.short_identifier} -->';@output_buffer"
|
|
89
91
|
end
|
|
90
92
|
|
|
@@ -107,6 +109,28 @@ module ActionView
|
|
|
107
109
|
raise WrongEncodingError.new(string, string.encoding)
|
|
108
110
|
end
|
|
109
111
|
|
|
112
|
+
# Return the offset between the error lineno and the source lineno.
|
|
113
|
+
# Searches in reverse from the backtrace lineno so we have a better
|
|
114
|
+
# chance of finding the correct line
|
|
115
|
+
#
|
|
116
|
+
# The compiled template is likely to be longer than the source.
|
|
117
|
+
# Use the difference between the compiled and source sizes to
|
|
118
|
+
# determine the earliest line that could contain the highlight.
|
|
119
|
+
def find_lineno_offset(compiled, source_lines, highlight, error_lineno)
|
|
120
|
+
first_index = error_lineno - 1 - compiled.size + source_lines.size
|
|
121
|
+
first_index = 0 if first_index < 0
|
|
122
|
+
|
|
123
|
+
last_index = error_lineno - 1
|
|
124
|
+
last_index = source_lines.size - 1 if last_index >= source_lines.size
|
|
125
|
+
|
|
126
|
+
last_index.downto(first_index) do |line_index|
|
|
127
|
+
next unless source_lines[line_index].include?(highlight)
|
|
128
|
+
return error_lineno - 1 - line_index
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
raise LocationParsingError, "Couldn't find code snippet"
|
|
132
|
+
end
|
|
133
|
+
|
|
110
134
|
# Find which token in the source template spans the byte range that
|
|
111
135
|
# contains the error_column, then return the offset compared to the
|
|
112
136
|
# original source template.
|
|
@@ -137,7 +161,7 @@ module ActionView
|
|
|
137
161
|
matched_str = true
|
|
138
162
|
|
|
139
163
|
if name == :CODE && compiled.pos <= error_column && compiled.pos + str.bytesize >= error_column
|
|
140
|
-
return
|
|
164
|
+
return compiled.pos - offset
|
|
141
165
|
end
|
|
142
166
|
|
|
143
167
|
compiled.pos += str.bytesize
|
|
@@ -152,8 +176,9 @@ module ActionView
|
|
|
152
176
|
|
|
153
177
|
def offset_source_tokens(source_tokens)
|
|
154
178
|
source_offset = 0
|
|
155
|
-
with_offset = source_tokens.filter_map do |
|
|
156
|
-
result = [
|
|
179
|
+
with_offset = source_tokens.filter_map do |name, str|
|
|
180
|
+
result = [:CODE, str, source_offset] if name == :CODE || name == :PLAIN
|
|
181
|
+
result = [:TEXT, str, source_offset] if name == :TEXT
|
|
157
182
|
source_offset += str.bytesize
|
|
158
183
|
result
|
|
159
184
|
end
|
data/lib/action_view/template.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "thread"
|
|
4
3
|
require "delegate"
|
|
5
4
|
|
|
6
5
|
module ActionView
|
|
@@ -8,7 +7,7 @@ module ActionView
|
|
|
8
7
|
class Template
|
|
9
8
|
extend ActiveSupport::Autoload
|
|
10
9
|
|
|
11
|
-
STRICT_LOCALS_REGEX = /\#\s+locals:\s+\((
|
|
10
|
+
STRICT_LOCALS_REGEX = /\#\s+locals:\s+\((.*?)\)(?=\s*-?%>|\s*$)/m
|
|
12
11
|
|
|
13
12
|
# === Encodings in ActionView::Template
|
|
14
13
|
#
|
|
@@ -357,7 +356,7 @@ module ActionView
|
|
|
357
356
|
|
|
358
357
|
# This method is responsible for marking a template as having strict locals
|
|
359
358
|
# which means the template can only accept the locals defined in a magic
|
|
360
|
-
# comment. For example, if your template
|
|
359
|
+
# comment. For example, if your template accepts the locals +title+ and
|
|
361
360
|
# +comment_count+, add the following to your template file:
|
|
362
361
|
#
|
|
363
362
|
# <%# locals: (title: "Default title", comment_count: 0) %>
|
|
@@ -367,10 +366,16 @@ module ActionView
|
|
|
367
366
|
def strict_locals!
|
|
368
367
|
if @strict_locals == NONE
|
|
369
368
|
self.source.sub!(STRICT_LOCALS_REGEX, "")
|
|
370
|
-
@strict_locals = $1
|
|
369
|
+
@strict_locals = $1&.rstrip
|
|
371
370
|
|
|
372
371
|
return if @strict_locals.nil? # Magic comment not found
|
|
373
372
|
|
|
373
|
+
# Tag with the assumed encoding before encode! runs, same as
|
|
374
|
+
# encode! does for the source itself (see above).
|
|
375
|
+
if @strict_locals.encoding == Encoding::BINARY
|
|
376
|
+
@strict_locals.force_encoding(Encoding.default_external)
|
|
377
|
+
end
|
|
378
|
+
|
|
374
379
|
@strict_locals = "**nil" if @strict_locals.blank?
|
|
375
380
|
end
|
|
376
381
|
|
|
@@ -465,8 +470,9 @@ module ActionView
|
|
|
465
470
|
end
|
|
466
471
|
end_src
|
|
467
472
|
|
|
468
|
-
# Make sure the source is in the encoding of the returned code
|
|
469
|
-
|
|
473
|
+
# Make sure the source is in the encoding of the returned code.
|
|
474
|
+
# ASCII-only code has no encoding worth propagating.
|
|
475
|
+
source.force_encoding(code.encoding) unless code.ascii_only?
|
|
470
476
|
|
|
471
477
|
# In case we get back a String from a handler that is not in
|
|
472
478
|
# BINARY or the default_internal, encode it to the default_internal
|
|
@@ -60,7 +60,56 @@ module ActionView
|
|
|
60
60
|
include ActiveSupport::Testing::ConstantLookup
|
|
61
61
|
|
|
62
62
|
delegate :lookup_context, to: :controller
|
|
63
|
-
attr_accessor :controller, :request, :output_buffer
|
|
63
|
+
attr_accessor :controller, :request, :output_buffer
|
|
64
|
+
|
|
65
|
+
# Returns the content rendered by the last +render+ call.
|
|
66
|
+
#
|
|
67
|
+
# The returned object behaves like a string but also exposes a number of methods
|
|
68
|
+
# that allows you to parse the content string in formats registered using
|
|
69
|
+
# <tt>.register_parser</tt>.
|
|
70
|
+
#
|
|
71
|
+
# By default includes the following parsers:
|
|
72
|
+
#
|
|
73
|
+
# +.html+
|
|
74
|
+
#
|
|
75
|
+
# Parse the <tt>rendered</tt> content String into HTML. By default, this means
|
|
76
|
+
# a <tt>Nokogiri::XML::Node</tt>.
|
|
77
|
+
#
|
|
78
|
+
# test "renders HTML" do
|
|
79
|
+
# article = Article.create!(title: "Hello, world")
|
|
80
|
+
#
|
|
81
|
+
# render partial: "articles/article", locals: { article: article }
|
|
82
|
+
#
|
|
83
|
+
# assert_pattern { rendered.html.at("main h1") => { content: "Hello, world" } }
|
|
84
|
+
# end
|
|
85
|
+
#
|
|
86
|
+
# To parse the rendered content into a <tt>Capybara::Simple::Node</tt>,
|
|
87
|
+
# re-register an <tt>:html</tt> parser with a call to
|
|
88
|
+
# <tt>Capybara.string</tt>:
|
|
89
|
+
#
|
|
90
|
+
# register_parser :html, -> rendered { Capybara.string(rendered) }
|
|
91
|
+
#
|
|
92
|
+
# test "renders HTML" do
|
|
93
|
+
# article = Article.create!(title: "Hello, world")
|
|
94
|
+
#
|
|
95
|
+
# render partial: article
|
|
96
|
+
#
|
|
97
|
+
# rendered.html.assert_css "h1", text: "Hello, world"
|
|
98
|
+
# end
|
|
99
|
+
#
|
|
100
|
+
# +.json+
|
|
101
|
+
#
|
|
102
|
+
# Parse the <tt>rendered</tt> content String into JSON. By default, this means
|
|
103
|
+
# a <tt>ActiveSupport::HashWithIndifferentAccess</tt>.
|
|
104
|
+
#
|
|
105
|
+
# test "renders JSON" do
|
|
106
|
+
# article = Article.create!(title: "Hello, world")
|
|
107
|
+
#
|
|
108
|
+
# render formats: :json, partial: "articles/article", locals: { article: article }
|
|
109
|
+
#
|
|
110
|
+
# assert_pattern { rendered.json => { title: "Hello, world" } }
|
|
111
|
+
# end
|
|
112
|
+
attr_accessor :rendered
|
|
64
113
|
|
|
65
114
|
module ClassMethods
|
|
66
115
|
def inherited(descendant) # :nodoc:
|
|
@@ -223,7 +272,7 @@ module ActionView
|
|
|
223
272
|
@request = @controller.request
|
|
224
273
|
@view_flow = ActionView::OutputFlow.new
|
|
225
274
|
@output_buffer = ActionView::OutputBuffer.new
|
|
226
|
-
|
|
275
|
+
_reset_rendered
|
|
227
276
|
|
|
228
277
|
test_case_instance = self
|
|
229
278
|
controller_class.define_method(:_test_case) { test_case_instance }
|
|
@@ -235,65 +284,24 @@ module ActionView
|
|
|
235
284
|
|
|
236
285
|
def render(options = {}, local_assigns = {}, &block)
|
|
237
286
|
view.assign(view_assigns)
|
|
238
|
-
|
|
239
|
-
|
|
287
|
+
|
|
288
|
+
if @_rendering
|
|
289
|
+
view.render(options, local_assigns, &block)
|
|
290
|
+
else
|
|
291
|
+
_reset_rendered
|
|
292
|
+
@_rendering = true
|
|
293
|
+
output = view.render(options, local_assigns, &block)
|
|
294
|
+
@rendered << output
|
|
295
|
+
output
|
|
296
|
+
end
|
|
297
|
+
ensure
|
|
298
|
+
@_rendering = false unless @_rendering.nil?
|
|
240
299
|
end
|
|
241
300
|
|
|
242
301
|
def rendered_views
|
|
243
302
|
@_rendered_views ||= RenderedViewsCollection.new
|
|
244
303
|
end
|
|
245
304
|
|
|
246
|
-
##
|
|
247
|
-
# :method: rendered
|
|
248
|
-
#
|
|
249
|
-
# Returns the content rendered by the last +render+ call.
|
|
250
|
-
#
|
|
251
|
-
# The returned object behaves like a string but also exposes a number of methods
|
|
252
|
-
# that allows you to parse the content string in formats registered using
|
|
253
|
-
# <tt>.register_parser</tt>.
|
|
254
|
-
#
|
|
255
|
-
# By default includes the following parsers:
|
|
256
|
-
#
|
|
257
|
-
# +.html+
|
|
258
|
-
#
|
|
259
|
-
# Parse the <tt>rendered</tt> content String into HTML. By default, this means
|
|
260
|
-
# a <tt>Nokogiri::XML::Node</tt>.
|
|
261
|
-
#
|
|
262
|
-
# test "renders HTML" do
|
|
263
|
-
# article = Article.create!(title: "Hello, world")
|
|
264
|
-
#
|
|
265
|
-
# render partial: "articles/article", locals: { article: article }
|
|
266
|
-
#
|
|
267
|
-
# assert_pattern { rendered.html.at("main h1") => { content: "Hello, world" } }
|
|
268
|
-
# end
|
|
269
|
-
#
|
|
270
|
-
# To parse the rendered content into a <tt>Capybara::Simple::Node</tt>,
|
|
271
|
-
# re-register an <tt>:html</tt> parser with a call to
|
|
272
|
-
# <tt>Capybara.string</tt>:
|
|
273
|
-
#
|
|
274
|
-
# register_parser :html, -> rendered { Capybara.string(rendered) }
|
|
275
|
-
#
|
|
276
|
-
# test "renders HTML" do
|
|
277
|
-
# article = Article.create!(title: "Hello, world")
|
|
278
|
-
#
|
|
279
|
-
# render partial: article
|
|
280
|
-
#
|
|
281
|
-
# rendered.html.assert_css "h1", text: "Hello, world"
|
|
282
|
-
# end
|
|
283
|
-
#
|
|
284
|
-
# +.json+
|
|
285
|
-
#
|
|
286
|
-
# Parse the <tt>rendered</tt> content String into JSON. By default, this means
|
|
287
|
-
# a <tt>ActiveSupport::HashWithIndifferentAccess</tt>.
|
|
288
|
-
#
|
|
289
|
-
# test "renders JSON" do
|
|
290
|
-
# article = Article.create!(title: "Hello, world")
|
|
291
|
-
#
|
|
292
|
-
# render formats: :json, partial: "articles/article", locals: { article: article }
|
|
293
|
-
#
|
|
294
|
-
# assert_pattern { rendered.json => { title: "Hello, world" } }
|
|
295
|
-
# end
|
|
296
|
-
|
|
297
305
|
def _routes
|
|
298
306
|
@controller._routes if @controller.respond_to?(:_routes)
|
|
299
307
|
end
|
|
@@ -385,6 +393,7 @@ module ActionView
|
|
|
385
393
|
:@method_name,
|
|
386
394
|
:@output_buffer,
|
|
387
395
|
:@_partials,
|
|
396
|
+
:@_rendering,
|
|
388
397
|
:@passed,
|
|
389
398
|
:@rendered,
|
|
390
399
|
:@request,
|
|
@@ -414,6 +423,10 @@ module ActionView
|
|
|
414
423
|
end]
|
|
415
424
|
end
|
|
416
425
|
|
|
426
|
+
def _reset_rendered
|
|
427
|
+
@rendered = self.class.content_class.new(+"")
|
|
428
|
+
end
|
|
429
|
+
|
|
417
430
|
def method_missing(selector, ...)
|
|
418
431
|
begin
|
|
419
432
|
routes = @controller.respond_to?(:_routes) && @controller._routes
|
data/lib/action_view.rb
CHANGED
|
@@ -37,6 +37,7 @@ module ActionView
|
|
|
37
37
|
eager_autoload do
|
|
38
38
|
autoload :Base
|
|
39
39
|
autoload :Context
|
|
40
|
+
autoload :DependencyTracker
|
|
40
41
|
autoload :Digestor
|
|
41
42
|
autoload :Helpers
|
|
42
43
|
autoload :LookupContext
|
|
@@ -91,6 +92,21 @@ module ActionView
|
|
|
91
92
|
autoload :CacheExpiry
|
|
92
93
|
autoload :TestCase
|
|
93
94
|
|
|
95
|
+
singleton_class.attr_reader :render_tracker
|
|
96
|
+
|
|
97
|
+
def self.render_tracker=(value)
|
|
98
|
+
@render_tracker = value
|
|
99
|
+
case value
|
|
100
|
+
when :ruby
|
|
101
|
+
DependencyTracker.register_tracker :erb, DependencyTracker::RubyTracker
|
|
102
|
+
else
|
|
103
|
+
DependencyTracker.register_tracker :erb, DependencyTracker::ERBTracker
|
|
104
|
+
end
|
|
105
|
+
value
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
self.render_tracker = :regex
|
|
109
|
+
|
|
94
110
|
def self.eager_load!
|
|
95
111
|
super
|
|
96
112
|
ActionView::Helpers.eager_load!
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: actionview
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 8.1.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
@@ -15,28 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 8.1.4.1
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: cgi
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - ">="
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0'
|
|
33
|
-
type: :runtime
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - ">="
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0'
|
|
25
|
+
version: 8.1.4.1
|
|
40
26
|
- !ruby/object:Gem::Dependency
|
|
41
27
|
name: builder
|
|
42
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,6 +58,9 @@ dependencies:
|
|
|
72
58
|
- - "~>"
|
|
73
59
|
- !ruby/object:Gem::Version
|
|
74
60
|
version: '1.6'
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: 1.7.2
|
|
75
64
|
type: :runtime
|
|
76
65
|
prerelease: false
|
|
77
66
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -79,6 +68,9 @@ dependencies:
|
|
|
79
68
|
- - "~>"
|
|
80
69
|
- !ruby/object:Gem::Version
|
|
81
70
|
version: '1.6'
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: 1.7.2
|
|
82
74
|
- !ruby/object:Gem::Dependency
|
|
83
75
|
name: rails-dom-testing
|
|
84
76
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -99,28 +91,28 @@ dependencies:
|
|
|
99
91
|
requirements:
|
|
100
92
|
- - '='
|
|
101
93
|
- !ruby/object:Gem::Version
|
|
102
|
-
version:
|
|
94
|
+
version: 8.1.4.1
|
|
103
95
|
type: :development
|
|
104
96
|
prerelease: false
|
|
105
97
|
version_requirements: !ruby/object:Gem::Requirement
|
|
106
98
|
requirements:
|
|
107
99
|
- - '='
|
|
108
100
|
- !ruby/object:Gem::Version
|
|
109
|
-
version:
|
|
101
|
+
version: 8.1.4.1
|
|
110
102
|
- !ruby/object:Gem::Dependency
|
|
111
103
|
name: activemodel
|
|
112
104
|
requirement: !ruby/object:Gem::Requirement
|
|
113
105
|
requirements:
|
|
114
106
|
- - '='
|
|
115
107
|
- !ruby/object:Gem::Version
|
|
116
|
-
version:
|
|
108
|
+
version: 8.1.4.1
|
|
117
109
|
type: :development
|
|
118
110
|
prerelease: false
|
|
119
111
|
version_requirements: !ruby/object:Gem::Requirement
|
|
120
112
|
requirements:
|
|
121
113
|
- - '='
|
|
122
114
|
- !ruby/object:Gem::Version
|
|
123
|
-
version:
|
|
115
|
+
version: 8.1.4.1
|
|
124
116
|
description: Simple, battle-tested conventions and helpers for building web pages.
|
|
125
117
|
email: david@loudthinking.com
|
|
126
118
|
executables: []
|
|
@@ -140,6 +132,7 @@ files:
|
|
|
140
132
|
- lib/action_view/dependency_tracker.rb
|
|
141
133
|
- lib/action_view/dependency_tracker/erb_tracker.rb
|
|
142
134
|
- lib/action_view/dependency_tracker/ruby_tracker.rb
|
|
135
|
+
- lib/action_view/dependency_tracker/wildcard_resolver.rb
|
|
143
136
|
- lib/action_view/deprecator.rb
|
|
144
137
|
- lib/action_view/digestor.rb
|
|
145
138
|
- lib/action_view/flows.rb
|
|
@@ -229,6 +222,7 @@ files:
|
|
|
229
222
|
- lib/action_view/renderer/template_renderer.rb
|
|
230
223
|
- lib/action_view/rendering.rb
|
|
231
224
|
- lib/action_view/routing_url_for.rb
|
|
225
|
+
- lib/action_view/structured_event_subscriber.rb
|
|
232
226
|
- lib/action_view/tasks/cache_digests.rake
|
|
233
227
|
- lib/action_view/template.rb
|
|
234
228
|
- lib/action_view/template/error.rb
|
|
@@ -259,10 +253,10 @@ licenses:
|
|
|
259
253
|
- MIT
|
|
260
254
|
metadata:
|
|
261
255
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
|
262
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
|
263
|
-
documentation_uri: https://api.rubyonrails.org/
|
|
256
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.1.4.1/actionview/CHANGELOG.md
|
|
257
|
+
documentation_uri: https://api.rubyonrails.org/v8.1.4.1/
|
|
264
258
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
265
|
-
source_code_uri: https://github.com/rails/rails/tree/
|
|
259
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.1.4.1/actionview
|
|
266
260
|
rubygems_mfa_required: 'true'
|
|
267
261
|
rdoc_options: []
|
|
268
262
|
require_paths:
|
|
@@ -271,7 +265,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
271
265
|
requirements:
|
|
272
266
|
- - ">="
|
|
273
267
|
- !ruby/object:Gem::Version
|
|
274
|
-
version: 3.
|
|
268
|
+
version: 3.2.0
|
|
275
269
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
270
|
requirements:
|
|
277
271
|
- - ">="
|
|
@@ -279,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
279
273
|
version: '0'
|
|
280
274
|
requirements:
|
|
281
275
|
- none
|
|
282
|
-
rubygems_version: 4.0.
|
|
276
|
+
rubygems_version: 4.0.20
|
|
283
277
|
specification_version: 4
|
|
284
278
|
summary: Rendering framework putting the V in MVC (part of Rails).
|
|
285
279
|
test_files: []
|