actionview 5.1.4 → 6.1.1
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 +5 -5
- data/CHANGELOG.md +199 -168
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -5
- data/lib/action_view.rb +10 -4
- data/lib/action_view/base.rb +87 -23
- data/lib/action_view/buffers.rb +17 -0
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +7 -11
- data/lib/action_view/dependency_tracker.rb +12 -4
- data/lib/action_view/digestor.rb +24 -23
- data/lib/action_view/flows.rb +2 -1
- data/lib/action_view/gem_version.rb +4 -2
- data/lib/action_view/helpers.rb +4 -2
- data/lib/action_view/helpers/active_model_helper.rb +9 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +220 -57
- data/lib/action_view/helpers/asset_url_helper.rb +28 -23
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -2
- data/lib/action_view/helpers/cache_helper.rb +39 -28
- data/lib/action_view/helpers/capture_helper.rb +13 -7
- data/lib/action_view/helpers/controller_helper.rb +3 -1
- data/lib/action_view/helpers/csp_helper.rb +26 -0
- data/lib/action_view/helpers/csrf_helper.rb +5 -3
- data/lib/action_view/helpers/date_helper.rb +78 -33
- data/lib/action_view/helpers/debug_helper.rb +4 -2
- data/lib/action_view/helpers/form_helper.rb +357 -106
- data/lib/action_view/helpers/form_options_helper.rb +45 -39
- data/lib/action_view/helpers/form_tag_helper.rb +42 -27
- data/lib/action_view/helpers/javascript_helper.rb +28 -12
- data/lib/action_view/helpers/number_helper.rb +16 -8
- data/lib/action_view/helpers/output_safety_helper.rb +3 -1
- data/lib/action_view/helpers/rendering_helper.rb +20 -9
- data/lib/action_view/helpers/sanitize_helper.rb +15 -19
- data/lib/action_view/helpers/tag_helper.rb +100 -24
- data/lib/action_view/helpers/tags.rb +3 -1
- data/lib/action_view/helpers/tags/base.rb +30 -21
- data/lib/action_view/helpers/tags/check_box.rb +3 -2
- data/lib/action_view/helpers/tags/checkable.rb +4 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +2 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +2 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +2 -1
- data/lib/action_view/helpers/tags/collection_select.rb +3 -1
- data/lib/action_view/helpers/tags/color_field.rb +4 -3
- data/lib/action_view/helpers/tags/date_field.rb +3 -2
- data/lib/action_view/helpers/tags/date_select.rb +5 -4
- data/lib/action_view/helpers/tags/datetime_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_local_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
- data/lib/action_view/helpers/tags/email_field.rb +2 -0
- data/lib/action_view/helpers/tags/file_field.rb +2 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +2 -0
- data/lib/action_view/helpers/tags/label.rb +6 -5
- data/lib/action_view/helpers/tags/month_field.rb +3 -2
- data/lib/action_view/helpers/tags/number_field.rb +2 -0
- data/lib/action_view/helpers/tags/password_field.rb +2 -0
- data/lib/action_view/helpers/tags/placeholderable.rb +2 -0
- data/lib/action_view/helpers/tags/radio_button.rb +3 -2
- data/lib/action_view/helpers/tags/range_field.rb +2 -0
- data/lib/action_view/helpers/tags/search_field.rb +2 -0
- data/lib/action_view/helpers/tags/select.rb +4 -3
- data/lib/action_view/helpers/tags/tel_field.rb +2 -0
- data/lib/action_view/helpers/tags/text_area.rb +3 -1
- data/lib/action_view/helpers/tags/text_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_select.rb +2 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
- data/lib/action_view/helpers/tags/translator.rb +3 -6
- data/lib/action_view/helpers/tags/url_field.rb +2 -0
- data/lib/action_view/helpers/tags/week_field.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +11 -10
- data/lib/action_view/helpers/translation_helper.rb +102 -52
- data/lib/action_view/helpers/url_helper.rb +150 -32
- data/lib/action_view/layouts.rb +15 -15
- data/lib/action_view/log_subscriber.rb +32 -15
- data/lib/action_view/lookup_context.rb +67 -39
- data/lib/action_view/model_naming.rb +2 -0
- data/lib/action_view/path_set.rb +5 -12
- data/lib/action_view/railtie.rb +46 -21
- data/lib/action_view/record_identifier.rb +4 -3
- data/lib/action_view/renderer/abstract_renderer.rb +144 -11
- data/lib/action_view/renderer/collection_renderer.rb +196 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer.rb +33 -283
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +64 -17
- data/lib/action_view/renderer/renderer.rb +61 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +14 -8
- data/lib/action_view/renderer/template_renderer.rb +36 -26
- data/lib/action_view/rendering.rb +57 -38
- data/lib/action_view/routing_url_for.rb +15 -12
- data/lib/action_view/tasks/cache_digests.rake +2 -0
- data/lib/action_view/template.rb +69 -76
- data/lib/action_view/template/error.rb +32 -18
- data/lib/action_view/template/handlers.rb +4 -2
- data/lib/action_view/template/handlers/builder.rb +5 -6
- data/lib/action_view/template/handlers/erb.rb +20 -19
- data/lib/action_view/template/handlers/erb/erubi.rb +17 -9
- data/lib/action_view/template/handlers/html.rb +3 -1
- data/lib/action_view/template/handlers/raw.rb +4 -2
- data/lib/action_view/template/html.rb +8 -7
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +25 -0
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +194 -152
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/text.rb +5 -4
- data/lib/action_view/template/types.rb +3 -1
- data/lib/action_view/test_case.rb +38 -30
- data/lib/action_view/testing/resolvers.rb +20 -27
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/version.rb +2 -0
- data/lib/action_view/view_paths.rb +61 -40
- data/lib/assets/compiled/rails-ujs.js +84 -23
- metadata +34 -23
- data/lib/action_view/helpers/record_tag_helper.rb +0 -21
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +0 -9
- data/lib/action_view/template/handlers/erb/erubis.rb +0 -81
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_dispatch/routing/polymorphic_routes"
|
2
4
|
|
3
5
|
module ActionView
|
@@ -82,29 +84,28 @@ module ActionView
|
|
82
84
|
super(only_path: _generate_paths_by_default)
|
83
85
|
when Hash
|
84
86
|
options = options.symbolize_keys
|
85
|
-
|
86
|
-
options[:only_path] = only_path?(options[:host])
|
87
|
-
end
|
87
|
+
ensure_only_path_option(options)
|
88
88
|
|
89
89
|
super(options)
|
90
90
|
when ActionController::Parameters
|
91
|
-
|
92
|
-
options[:only_path] = only_path?(options[:host])
|
93
|
-
end
|
91
|
+
ensure_only_path_option(options)
|
94
92
|
|
95
93
|
super(options)
|
96
94
|
when :back
|
97
95
|
_back_url
|
98
96
|
when Array
|
99
97
|
components = options.dup
|
100
|
-
|
101
|
-
|
98
|
+
options = components.extract_options!
|
99
|
+
ensure_only_path_option(options)
|
100
|
+
|
101
|
+
if options[:only_path]
|
102
|
+
polymorphic_path(components, options)
|
102
103
|
else
|
103
|
-
polymorphic_url(components,
|
104
|
+
polymorphic_url(components, options)
|
104
105
|
end
|
105
106
|
else
|
106
107
|
method = _generate_paths_by_default ? :path : :url
|
107
|
-
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.
|
108
|
+
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.public_send(method)
|
108
109
|
|
109
110
|
case options
|
110
111
|
when Symbol
|
@@ -136,8 +137,10 @@ module ActionView
|
|
136
137
|
true
|
137
138
|
end
|
138
139
|
|
139
|
-
def
|
140
|
-
|
140
|
+
def ensure_only_path_option(options)
|
141
|
+
unless options.key?(:only_path)
|
142
|
+
options[:only_path] = _generate_paths_by_default unless options[:host]
|
143
|
+
end
|
141
144
|
end
|
142
145
|
end
|
143
146
|
end
|
data/lib/action_view/template.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
require "thread"
|
4
|
+
require "delegate"
|
4
5
|
|
5
6
|
module ActionView
|
6
7
|
# = Action View Template
|
@@ -101,41 +102,37 @@ module ActionView
|
|
101
102
|
|
102
103
|
eager_autoload do
|
103
104
|
autoload :Error
|
105
|
+
autoload :RawFile
|
106
|
+
autoload :Renderable
|
104
107
|
autoload :Handlers
|
105
108
|
autoload :HTML
|
109
|
+
autoload :Inline
|
110
|
+
autoload :Sources
|
106
111
|
autoload :Text
|
107
112
|
autoload :Types
|
108
113
|
end
|
109
114
|
|
110
115
|
extend Template::Handlers
|
111
116
|
|
112
|
-
|
113
|
-
|
114
|
-
attr_reader :source, :identifier, :handler, :original_encoding, :updated_at
|
115
|
-
|
116
|
-
# This finalizer is needed (and exactly with a proc inside another proc)
|
117
|
-
# otherwise templates leak in development.
|
118
|
-
Finalizer = proc do |method_name, mod| # :nodoc:
|
119
|
-
proc do
|
120
|
-
mod.module_eval do
|
121
|
-
remove_possible_method method_name
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def initialize(source, identifier, handler, details)
|
127
|
-
format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
|
117
|
+
attr_reader :identifier, :handler
|
118
|
+
attr_reader :variable, :format, :variant, :locals, :virtual_path
|
128
119
|
|
120
|
+
def initialize(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil)
|
129
121
|
@source = source
|
130
122
|
@identifier = identifier
|
131
123
|
@handler = handler
|
132
124
|
@compiled = false
|
133
|
-
@
|
134
|
-
@
|
135
|
-
|
136
|
-
@
|
137
|
-
|
138
|
-
|
125
|
+
@locals = locals
|
126
|
+
@virtual_path = virtual_path
|
127
|
+
|
128
|
+
@variable = if @virtual_path
|
129
|
+
base = @virtual_path.end_with?("/") ? "" : ::File.basename(@virtual_path)
|
130
|
+
base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
131
|
+
$1.to_sym
|
132
|
+
end
|
133
|
+
|
134
|
+
@format = format
|
135
|
+
@variant = variant
|
139
136
|
@compile_mutex = Mutex.new
|
140
137
|
end
|
141
138
|
|
@@ -151,40 +148,29 @@ module ActionView
|
|
151
148
|
# This method is instrumented as "!render_template.action_view". Notice that
|
152
149
|
# we use a bang in this instrumentation because you don't want to
|
153
150
|
# consume this in production. This is only slow if it's being listened to.
|
154
|
-
def render(view, locals, buffer =
|
151
|
+
def render(view, locals, buffer = ActionView::OutputBuffer.new, add_to_stack: true, &block)
|
155
152
|
instrument_render_template do
|
156
153
|
compile!(view)
|
157
|
-
view.
|
154
|
+
view._run(method_name, self, locals, buffer, add_to_stack: add_to_stack, &block)
|
158
155
|
end
|
159
156
|
rescue => e
|
160
157
|
handle_render_error(view, e)
|
161
158
|
end
|
162
159
|
|
163
160
|
def type
|
164
|
-
@type ||= Types[
|
161
|
+
@type ||= Types[format]
|
165
162
|
end
|
166
163
|
|
167
|
-
|
168
|
-
|
169
|
-
# This method is useful if you have a template object but it does not contain its source
|
170
|
-
# anymore since it was already compiled. In such cases, all you need to do is to call
|
171
|
-
# refresh passing in the view object.
|
172
|
-
#
|
173
|
-
# Notice this method raises an error if the template to be refreshed does not have a
|
174
|
-
# virtual path set (true just for inline templates).
|
175
|
-
def refresh(view)
|
176
|
-
raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path
|
177
|
-
lookup = view.lookup_context
|
178
|
-
pieces = @virtual_path.split("/")
|
179
|
-
name = pieces.pop
|
180
|
-
partial = !!name.sub!(/^_/, "")
|
181
|
-
lookup.disable_cache do
|
182
|
-
lookup.find_template(name, [ pieces.join("/") ], partial, @locals)
|
183
|
-
end
|
164
|
+
def short_identifier
|
165
|
+
@short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier
|
184
166
|
end
|
185
167
|
|
186
168
|
def inspect
|
187
|
-
|
169
|
+
"#<#{self.class.name} #{short_identifier} locals=#{@locals.inspect}>"
|
170
|
+
end
|
171
|
+
|
172
|
+
def source
|
173
|
+
@source.to_s
|
188
174
|
end
|
189
175
|
|
190
176
|
# This method is responsible for properly setting the encoding of the
|
@@ -198,7 +184,9 @@ module ActionView
|
|
198
184
|
# before passing the source on to the template engine, leaving a
|
199
185
|
# blank line in its stead.
|
200
186
|
def encode!
|
201
|
-
|
187
|
+
source = self.source
|
188
|
+
|
189
|
+
return source unless source.encoding == Encoding::BINARY
|
202
190
|
|
203
191
|
# Look for # encoding: *. If we find one, we'll encode the
|
204
192
|
# String in that encoding, otherwise, we'll use the
|
@@ -231,8 +219,20 @@ module ActionView
|
|
231
219
|
end
|
232
220
|
end
|
233
221
|
|
234
|
-
private
|
235
222
|
|
223
|
+
# Exceptions are marshalled when using the parallel test runner with DRb, so we need
|
224
|
+
# to ensure that references to the template object can be marshalled as well. This means forgoing
|
225
|
+
# the marshalling of the compiler mutex and instantiating that again on unmarshalling.
|
226
|
+
def marshal_dump # :nodoc:
|
227
|
+
[ @source, @identifier, @handler, @compiled, @locals, @virtual_path, @format, @variant ]
|
228
|
+
end
|
229
|
+
|
230
|
+
def marshal_load(array) # :nodoc:
|
231
|
+
@source, @identifier, @handler, @compiled, @locals, @virtual_path, @format, @variant = *array
|
232
|
+
@compile_mutex = Mutex.new
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
236
|
# Compile a template. This method ensures a template is compiled
|
237
237
|
# just once and removes the source after it is compiled.
|
238
238
|
def compile!(view)
|
@@ -247,19 +247,12 @@ module ActionView
|
|
247
247
|
# re-compilation
|
248
248
|
return if @compiled
|
249
249
|
|
250
|
-
|
251
|
-
mod = ActionView::CompiledTemplates
|
252
|
-
else
|
253
|
-
mod = view.singleton_class
|
254
|
-
end
|
250
|
+
mod = view.compiled_method_container
|
255
251
|
|
256
252
|
instrument("!compile_template") do
|
257
253
|
compile(mod)
|
258
254
|
end
|
259
255
|
|
260
|
-
# Just discard the source if we have a virtual path. This
|
261
|
-
# means we can get the template back.
|
262
|
-
@source = nil if @virtual_path
|
263
256
|
@compiled = true
|
264
257
|
end
|
265
258
|
end
|
@@ -277,16 +270,15 @@ module ActionView
|
|
277
270
|
# In general, this means that templates will be UTF-8 inside of Rails,
|
278
271
|
# regardless of the original source encoding.
|
279
272
|
def compile(mod)
|
280
|
-
encode!
|
281
|
-
code = @handler.call(self)
|
273
|
+
source = encode!
|
274
|
+
code = @handler.call(self, source)
|
282
275
|
|
283
276
|
# Make sure that the resulting String to be eval'd is in the
|
284
277
|
# encoding of the code
|
285
|
-
|
278
|
+
original_source = source
|
279
|
+
source = +<<-end_src
|
286
280
|
def #{method_name}(local_assigns, output_buffer)
|
287
|
-
|
288
|
-
ensure
|
289
|
-
@virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
|
281
|
+
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
|
290
282
|
end
|
291
283
|
end_src
|
292
284
|
|
@@ -301,11 +293,17 @@ module ActionView
|
|
301
293
|
# handler is valid in the default_internal. This is for handlers
|
302
294
|
# that handle encoding but screw up
|
303
295
|
unless source.valid_encoding?
|
304
|
-
raise WrongEncodingError.new(
|
296
|
+
raise WrongEncodingError.new(source, Encoding.default_internal)
|
305
297
|
end
|
306
298
|
|
307
|
-
|
308
|
-
|
299
|
+
begin
|
300
|
+
mod.module_eval(source, identifier, 0)
|
301
|
+
rescue SyntaxError
|
302
|
+
# Account for when code in the template is not syntactically valid; e.g. if we're using
|
303
|
+
# ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
|
304
|
+
# the result into the template, but missing an end parenthesis.
|
305
|
+
raise SyntaxErrorInTemplate.new(self, original_source)
|
306
|
+
end
|
309
307
|
end
|
310
308
|
|
311
309
|
def handle_render_error(view, e)
|
@@ -313,12 +311,7 @@ module ActionView
|
|
313
311
|
e.sub_template_of(self)
|
314
312
|
raise e
|
315
313
|
else
|
316
|
-
|
317
|
-
unless template.source
|
318
|
-
template = refresh(view)
|
319
|
-
template.encode!
|
320
|
-
end
|
321
|
-
raise Template::Error.new(template)
|
314
|
+
raise Template::Error.new(self)
|
322
315
|
end
|
323
316
|
end
|
324
317
|
|
@@ -328,20 +321,20 @@ module ActionView
|
|
328
321
|
locals = @locals - Module::RUBY_RESERVED_KEYWORDS
|
329
322
|
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
|
330
323
|
|
331
|
-
#
|
332
|
-
locals.each_with_object("") { |key, code| code << "#{key} = #{key} =
|
324
|
+
# Assign for the same variable is to suppress unused variable warning
|
325
|
+
locals.each_with_object(+"") { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
|
333
326
|
end
|
334
327
|
|
335
328
|
def method_name
|
336
329
|
@method_name ||= begin
|
337
|
-
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
338
|
-
m.tr!("-"
|
330
|
+
m = +"_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
|
331
|
+
m.tr!("-", "_")
|
339
332
|
m
|
340
333
|
end
|
341
334
|
end
|
342
335
|
|
343
336
|
def identifier_method_name
|
344
|
-
|
337
|
+
short_identifier.tr("^a-z_", "_")
|
345
338
|
end
|
346
339
|
|
347
340
|
def instrument(action, &block) # :doc:
|
@@ -349,7 +342,7 @@ module ActionView
|
|
349
342
|
end
|
350
343
|
|
351
344
|
def instrument_render_template(&block)
|
352
|
-
ActiveSupport::Notifications.instrument("!render_template.action_view"
|
345
|
+
ActiveSupport::Notifications.instrument("!render_template.action_view", instrument_payload, &block)
|
353
346
|
end
|
354
347
|
|
355
348
|
def instrument_payload
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/enumerable"
|
2
4
|
|
3
5
|
module ActionView
|
@@ -8,9 +10,6 @@ module ActionView
|
|
8
10
|
class EncodingError < StandardError #:nodoc:
|
9
11
|
end
|
10
12
|
|
11
|
-
class MissingRequestError < StandardError #:nodoc:
|
12
|
-
end
|
13
|
-
|
14
13
|
class WrongEncodingError < EncodingError #:nodoc:
|
15
14
|
def initialize(string, encoding)
|
16
15
|
@string, @encoding = string, encoding
|
@@ -82,19 +81,19 @@ module ActionView
|
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
85
|
-
def source_extract(indentation = 0
|
86
|
-
return unless num = line_number
|
84
|
+
def source_extract(indentation = 0)
|
85
|
+
return [] unless num = line_number
|
87
86
|
num = num.to_i
|
88
87
|
|
89
|
-
source_code = @template.
|
88
|
+
source_code = @template.encode!.split("\n")
|
90
89
|
|
91
90
|
start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
|
92
91
|
end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
|
93
92
|
|
94
93
|
indent = end_on_line.to_s.size + indentation
|
95
|
-
return unless source_code = source_code[start_on_line..end_on_line]
|
94
|
+
return [] unless source_code = source_code[start_on_line..end_on_line]
|
96
95
|
|
97
|
-
formatted_code_for(source_code, start_on_line, indent
|
96
|
+
formatted_code_for(source_code, start_on_line, indent)
|
98
97
|
end
|
99
98
|
|
100
99
|
def sub_template_of(template_path)
|
@@ -110,12 +109,11 @@ module ActionView
|
|
110
109
|
end
|
111
110
|
end
|
112
111
|
|
113
|
-
def
|
112
|
+
def annotated_source_code
|
114
113
|
source_extract(4)
|
115
114
|
end
|
116
115
|
|
117
116
|
private
|
118
|
-
|
119
117
|
def source_location
|
120
118
|
if line_number
|
121
119
|
"on line ##{line_number} of "
|
@@ -124,19 +122,35 @@ module ActionView
|
|
124
122
|
end + file_name
|
125
123
|
end
|
126
124
|
|
127
|
-
def formatted_code_for(source_code, line_counter, indent
|
128
|
-
|
129
|
-
source_code.
|
125
|
+
def formatted_code_for(source_code, line_counter, indent)
|
126
|
+
indent_template = "%#{indent}s: %s"
|
127
|
+
source_code.map do |line|
|
130
128
|
line_counter += 1
|
131
|
-
|
132
|
-
result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line])
|
133
|
-
else
|
134
|
-
result << "%#{indent}s: %s" % [line_counter, line]
|
135
|
-
end
|
129
|
+
indent_template % [line_counter, line]
|
136
130
|
end
|
137
131
|
end
|
138
132
|
end
|
139
133
|
end
|
140
134
|
|
141
135
|
TemplateError = Template::Error
|
136
|
+
|
137
|
+
class SyntaxErrorInTemplate < TemplateError #:nodoc
|
138
|
+
def initialize(template, offending_code_string)
|
139
|
+
@offending_code_string = offending_code_string
|
140
|
+
super(template)
|
141
|
+
end
|
142
|
+
|
143
|
+
def message
|
144
|
+
<<~MESSAGE
|
145
|
+
Encountered a syntax error while rendering template: check #{@offending_code_string}
|
146
|
+
MESSAGE
|
147
|
+
end
|
148
|
+
|
149
|
+
def annotated_source_code
|
150
|
+
@offending_code_string.split("\n").map.with_index(1) { |line, index|
|
151
|
+
indentation = " " * 4
|
152
|
+
"#{index}:#{indentation}#{line}"
|
153
|
+
}
|
154
|
+
end
|
155
|
+
end
|
142
156
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionView #:nodoc:
|
2
4
|
# = Action View Template Handlers
|
3
|
-
class Template
|
5
|
+
class Template #:nodoc:
|
4
6
|
module Handlers #:nodoc:
|
5
7
|
autoload :Raw, "action_view/template/handlers/raw"
|
6
8
|
autoload :ERB, "action_view/template/handlers/erb"
|
@@ -12,7 +14,7 @@ module ActionView #:nodoc:
|
|
12
14
|
base.register_template_handler :erb, ERB.new
|
13
15
|
base.register_template_handler :html, Html.new
|
14
16
|
base.register_template_handler :builder, Builder.new
|
15
|
-
base.register_template_handler :ruby,
|
17
|
+
base.register_template_handler :ruby, lambda { |_, source| source }
|
16
18
|
end
|
17
19
|
|
18
20
|
@@template_handlers = {}
|
@@ -1,20 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionView
|
2
4
|
module Template::Handlers
|
3
5
|
class Builder
|
4
|
-
|
5
|
-
class_attribute :default_format
|
6
|
-
self.default_format = :xml
|
6
|
+
class_attribute :default_format, default: :xml
|
7
7
|
|
8
|
-
def call(template)
|
8
|
+
def call(template, source)
|
9
9
|
require_engine
|
10
10
|
"xml = ::Builder::XmlMarkup.new(:indent => 2);" \
|
11
11
|
"self.output_buffer = xml.target!;" +
|
12
|
-
|
12
|
+
source +
|
13
13
|
";xml.target!;"
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
17
|
-
|
18
17
|
def require_engine # :doc:
|
19
18
|
@required ||= begin
|
20
19
|
require "builder"
|