actionview 4.1.16 → 4.2.0.beta1
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 +85 -483
- data/README.rdoc +7 -2
- data/lib/action_view.rb +0 -1
- data/lib/action_view/base.rb +2 -10
- data/lib/action_view/digestor.rb +1 -1
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +32 -25
- data/lib/action_view/helpers/asset_url_helper.rb +29 -18
- data/lib/action_view/helpers/cache_helper.rb +2 -2
- data/lib/action_view/helpers/capture_helper.rb +1 -12
- data/lib/action_view/helpers/date_helper.rb +16 -12
- data/lib/action_view/helpers/debug_helper.rb +7 -11
- data/lib/action_view/helpers/form_helper.rb +65 -13
- data/lib/action_view/helpers/form_options_helper.rb +3 -3
- data/lib/action_view/helpers/form_tag_helper.rb +137 -28
- data/lib/action_view/helpers/javascript_helper.rb +7 -1
- data/lib/action_view/helpers/number_helper.rb +8 -10
- data/lib/action_view/helpers/output_safety_helper.rb +6 -6
- data/lib/action_view/helpers/rendering_helper.rb +6 -6
- data/lib/action_view/helpers/sanitize_helper.rb +67 -109
- data/lib/action_view/helpers/tag_helper.rb +15 -5
- data/lib/action_view/helpers/tags/base.rb +1 -1
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +5 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +1 -1
- data/lib/action_view/helpers/tags/datetime_field.rb +10 -2
- data/lib/action_view/helpers/tags/label.rb +3 -3
- data/lib/action_view/helpers/tags/placeholderable.rb +32 -0
- data/lib/action_view/helpers/tags/text_area.rb +4 -0
- data/lib/action_view/helpers/tags/text_field.rb +4 -1
- data/lib/action_view/helpers/tags/week_field.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +25 -8
- data/lib/action_view/helpers/translation_helper.rb +29 -25
- data/lib/action_view/helpers/url_helper.rb +13 -14
- data/lib/action_view/log_subscriber.rb +5 -5
- data/lib/action_view/lookup_context.rb +6 -12
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +7 -19
- data/lib/action_view/renderer/abstract_renderer.rb +5 -3
- data/lib/action_view/renderer/partial_renderer.rb +76 -38
- data/lib/action_view/renderer/renderer.rb +0 -4
- data/lib/action_view/renderer/template_renderer.rb +5 -6
- data/lib/action_view/rendering.rb +7 -6
- data/lib/action_view/routing_url_for.rb +13 -5
- data/lib/action_view/tasks/dependencies.rake +7 -9
- data/lib/action_view/template/handlers.rb +9 -0
- data/lib/action_view/template/resolver.rb +7 -24
- data/lib/action_view/test_case.rb +13 -7
- data/lib/action_view/testing/resolvers.rb +2 -2
- data/lib/action_view/view_paths.rb +26 -15
- metadata +52 -18
- data/lib/action_view/vendor/html-scanner.rb +0 -20
- data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
- data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
- data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
- data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
- data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
- data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
@@ -15,7 +15,7 @@ module ActionView
|
|
15
15
|
# that new object is called in turn. This abstracts the setup and rendering
|
16
16
|
# into a separate classes for partials and templates.
|
17
17
|
class AbstractRenderer #:nodoc:
|
18
|
-
delegate :find_template, :
|
18
|
+
delegate :find_template, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context
|
19
19
|
|
20
20
|
def initialize(lookup_context)
|
21
21
|
@lookup_context = lookup_context
|
@@ -29,8 +29,9 @@ module ActionView
|
|
29
29
|
|
30
30
|
def extract_details(options)
|
31
31
|
@lookup_context.registered_details.each_with_object({}) do |key, details|
|
32
|
-
|
33
|
-
|
32
|
+
value = options[key]
|
33
|
+
|
34
|
+
details[key] = Array(value) if value
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -41,6 +42,7 @@ module ActionView
|
|
41
42
|
def prepend_formats(formats)
|
42
43
|
formats = Array(formats)
|
43
44
|
return if formats.empty? || @lookup_context.html_fallback_for_js
|
45
|
+
|
44
46
|
@lookup_context.formats = formats | @lookup_context.formats
|
45
47
|
end
|
46
48
|
end
|
@@ -1,6 +1,33 @@
|
|
1
1
|
require 'thread_safe'
|
2
2
|
|
3
3
|
module ActionView
|
4
|
+
class PartialIteration
|
5
|
+
# The number of iterations that will be done by the partial.
|
6
|
+
attr_reader :size
|
7
|
+
|
8
|
+
# The current iteration of the partial.
|
9
|
+
attr_reader :index
|
10
|
+
|
11
|
+
def initialize(size)
|
12
|
+
@size = size
|
13
|
+
@index = 0
|
14
|
+
end
|
15
|
+
|
16
|
+
# Check if this is the first iteration of the partial.
|
17
|
+
def first?
|
18
|
+
index == 0
|
19
|
+
end
|
20
|
+
|
21
|
+
# Check if this is the last iteration of the partial.
|
22
|
+
def last?
|
23
|
+
index == size - 1
|
24
|
+
end
|
25
|
+
|
26
|
+
def iterate! # :nodoc:
|
27
|
+
@index += 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
4
31
|
# = Action View Partials
|
5
32
|
#
|
6
33
|
# There's also a convenience method for rendering sub templates within the current controller that depends on a
|
@@ -56,8 +83,12 @@ module ActionView
|
|
56
83
|
# <%= render partial: "ad", collection: @advertisements %>
|
57
84
|
#
|
58
85
|
# This will render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display. An
|
59
|
-
# iteration
|
60
|
-
# +
|
86
|
+
# iteration object will automatically be made available to the template with a name of the form
|
87
|
+
# +partial_name_iteration+. The iteration object has knowledge about which index the current object has in
|
88
|
+
# the collection and the total size of the collection. The iteration object also has two convenience methods,
|
89
|
+
# +first?+ and +last?+. In the case of the example above, the template would be fed +ad_iteration+.
|
90
|
+
# For backwards compatibility the +partial_name_counter+ is still present and is mapped to the iteration's
|
91
|
+
# +index+ method.
|
61
92
|
#
|
62
93
|
# The <tt>:as</tt> option may be used when rendering partials.
|
63
94
|
#
|
@@ -281,6 +312,8 @@ module ActionView
|
|
281
312
|
end
|
282
313
|
end
|
283
314
|
|
315
|
+
private
|
316
|
+
|
284
317
|
def render_collection
|
285
318
|
return nil if @collection.blank?
|
286
319
|
|
@@ -322,37 +355,39 @@ module ActionView
|
|
322
355
|
# respond to +to_partial_path+ in order to setup the path.
|
323
356
|
def setup(context, options, block)
|
324
357
|
@view = context
|
325
|
-
partial = options[:partial]
|
326
|
-
|
327
358
|
@options = options
|
328
|
-
@locals = options[:locals] || {}
|
329
359
|
@block = block
|
360
|
+
|
361
|
+
@locals = options[:locals] || {}
|
330
362
|
@details = extract_details(options)
|
331
363
|
|
332
364
|
prepend_formats(options[:formats])
|
333
365
|
|
366
|
+
partial = options[:partial]
|
367
|
+
|
334
368
|
if String === partial
|
335
|
-
@object = options[:object]
|
369
|
+
@object = options[:object]
|
370
|
+
@collection = collection_from_options
|
336
371
|
@path = partial
|
337
|
-
@collection = collection
|
338
372
|
else
|
339
373
|
@object = partial
|
374
|
+
@collection = collection_from_object || collection_from_options
|
340
375
|
|
341
|
-
if @collection
|
376
|
+
if @collection
|
342
377
|
paths = @collection_data = @collection.map { |o| partial_path(o) }
|
343
|
-
@path = paths.uniq.
|
378
|
+
@path = paths.uniq.one? ? paths.first : nil
|
344
379
|
else
|
345
380
|
@path = partial_path
|
346
381
|
end
|
347
382
|
end
|
348
383
|
|
349
384
|
if as = options[:as]
|
350
|
-
|
385
|
+
raise_invalid_identifier(as) unless as.to_s =~ /\A[a-z_]\w*\z/
|
351
386
|
as = as.to_sym
|
352
387
|
end
|
353
388
|
|
354
389
|
if @path
|
355
|
-
@variable, @variable_counter = retrieve_variable(@path, as)
|
390
|
+
@variable, @variable_counter, @variable_iteration = retrieve_variable(@path, as)
|
356
391
|
@template_keys = retrieve_template_keys
|
357
392
|
else
|
358
393
|
paths.map! { |path| retrieve_variable(path, as).unshift(path) }
|
@@ -361,7 +396,7 @@ module ActionView
|
|
361
396
|
self
|
362
397
|
end
|
363
398
|
|
364
|
-
def
|
399
|
+
def collection_from_options
|
365
400
|
if @options.key?(:collection)
|
366
401
|
collection = @options[:collection]
|
367
402
|
collection.respond_to?(:to_ary) ? collection.to_ary : []
|
@@ -373,9 +408,7 @@ module ActionView
|
|
373
408
|
end
|
374
409
|
|
375
410
|
def find_partial
|
376
|
-
|
377
|
-
find_template(path, @template_keys)
|
378
|
-
end
|
411
|
+
find_template(@path, @template_keys) if @path
|
379
412
|
end
|
380
413
|
|
381
414
|
def find_template(path, locals)
|
@@ -385,19 +418,22 @@ module ActionView
|
|
385
418
|
|
386
419
|
def collection_with_template
|
387
420
|
view, locals, template = @view, @locals, @template
|
388
|
-
as, counter = @variable, @variable_counter
|
421
|
+
as, counter, iteration = @variable, @variable_counter, @variable_iteration
|
389
422
|
|
390
423
|
if layout = @options[:layout]
|
391
424
|
layout = find_template(layout, @template_keys)
|
392
425
|
end
|
393
426
|
|
394
|
-
|
427
|
+
partial_iteration = PartialIteration.new(@collection.size)
|
428
|
+
locals[iteration] = partial_iteration
|
429
|
+
|
395
430
|
@collection.map do |object|
|
396
|
-
locals[as]
|
397
|
-
locals[counter]
|
431
|
+
locals[as] = object
|
432
|
+
locals[counter] = partial_iteration.index
|
398
433
|
|
399
434
|
content = template.render(view, locals)
|
400
435
|
content = layout.render(view, locals) { content } if layout
|
436
|
+
partial_iteration.iterate!
|
401
437
|
content
|
402
438
|
end
|
403
439
|
end
|
@@ -407,16 +443,20 @@ module ActionView
|
|
407
443
|
cache = {}
|
408
444
|
keys = @locals.keys
|
409
445
|
|
410
|
-
|
446
|
+
partial_iteration = PartialIteration.new(@collection.size)
|
447
|
+
|
411
448
|
@collection.map do |object|
|
412
|
-
index
|
413
|
-
path, as, counter = collection_data[index]
|
449
|
+
index = partial_iteration.index
|
450
|
+
path, as, counter, iteration = collection_data[index]
|
414
451
|
|
415
|
-
locals[as]
|
416
|
-
locals[counter]
|
452
|
+
locals[as] = object
|
453
|
+
locals[counter] = index
|
454
|
+
locals[iteration] = partial_iteration
|
417
455
|
|
418
456
|
template = (cache[path] ||= find_template(path, keys + [as, counter]))
|
419
|
-
template.render(view, locals)
|
457
|
+
content = template.render(view, locals)
|
458
|
+
partial_iteration.iterate!
|
459
|
+
content
|
420
460
|
end
|
421
461
|
end
|
422
462
|
|
@@ -466,8 +506,11 @@ module ActionView
|
|
466
506
|
|
467
507
|
def retrieve_template_keys
|
468
508
|
keys = @locals.keys
|
469
|
-
keys << @variable if
|
470
|
-
|
509
|
+
keys << @variable if @object || @collection
|
510
|
+
if @collection
|
511
|
+
keys << @variable_counter
|
512
|
+
keys << @variable_iteration
|
513
|
+
end
|
471
514
|
keys
|
472
515
|
end
|
473
516
|
|
@@ -477,24 +520,19 @@ module ActionView
|
|
477
520
|
raise_invalid_identifier(path) unless base =~ /\A_?([a-z]\w*)(\.\w+)*\z/
|
478
521
|
$1.to_sym
|
479
522
|
end
|
480
|
-
|
481
|
-
|
523
|
+
if @collection
|
524
|
+
variable_counter = :"#{variable}_counter"
|
525
|
+
variable_iteration = :"#{variable}_iteration"
|
526
|
+
end
|
527
|
+
[variable, variable_counter, variable_iteration]
|
482
528
|
end
|
483
529
|
|
484
530
|
IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " +
|
485
|
-
"make sure your partial name starts with underscore, " +
|
486
|
-
"and is followed by any combination of letters, numbers and underscores."
|
487
|
-
|
488
|
-
OPTION_AS_ERROR_MESSAGE = "The value (%s) of the option `as` is not a valid Ruby identifier; " +
|
489
|
-
"make sure it starts with lowercase letter, " +
|
531
|
+
"make sure your partial name starts with a lowercase letter or underscore, " +
|
490
532
|
"and is followed by any combination of letters, numbers and underscores."
|
491
533
|
|
492
534
|
def raise_invalid_identifier(path)
|
493
535
|
raise ArgumentError.new(IDENTIFIER_ERROR_MESSAGE % (path))
|
494
536
|
end
|
495
|
-
|
496
|
-
def raise_invalid_option_as(as)
|
497
|
-
raise ArgumentError.new(OPTION_AS_ERROR_MESSAGE % (as))
|
498
|
-
end
|
499
537
|
end
|
500
538
|
end
|
@@ -17,10 +17,6 @@ module ActionView
|
|
17
17
|
|
18
18
|
# Main render entry point shared by AV and AC.
|
19
19
|
def render(context, options)
|
20
|
-
if options.respond_to?(:permitted?) && !options.permitted?
|
21
|
-
raise ArgumentError, "render parameters are not permitted"
|
22
|
-
end
|
23
|
-
|
24
20
|
if options.key?(:partial)
|
25
21
|
render_partial(context, options)
|
26
22
|
else
|
@@ -6,19 +6,18 @@ module ActionView
|
|
6
6
|
@view = context
|
7
7
|
@details = extract_details(options)
|
8
8
|
template = determine_template(options)
|
9
|
-
context = @lookup_context
|
10
9
|
|
11
10
|
prepend_formats(template.formats)
|
12
11
|
|
13
|
-
|
14
|
-
context.rendered_format = template.formats.first || formats.first
|
15
|
-
end
|
12
|
+
@lookup_context.rendered_format ||= (template.formats.first || formats.first)
|
16
13
|
|
17
14
|
render_template(template, options[:layout], options[:locals])
|
18
15
|
end
|
19
16
|
|
17
|
+
private
|
18
|
+
|
20
19
|
# Determine the template to be rendered using the given options.
|
21
|
-
def determine_template(options)
|
20
|
+
def determine_template(options)
|
22
21
|
keys = options.fetch(:locals, {}).keys
|
23
22
|
|
24
23
|
if options.key?(:body)
|
@@ -30,7 +29,7 @@ module ActionView
|
|
30
29
|
elsif options.key?(:html)
|
31
30
|
Template::HTML.new(options[:html], formats.first)
|
32
31
|
elsif options.key?(:file)
|
33
|
-
with_fallbacks {
|
32
|
+
with_fallbacks { find_template(options[:file], nil, false, keys, @details) }
|
34
33
|
elsif options.key?(:inline)
|
35
34
|
handler = Template.handler_for_extension(options[:type] || "erb")
|
36
35
|
Template.new(options[:inline], "inline template", handler, :locals => keys)
|
@@ -35,12 +35,13 @@ module ActionView
|
|
35
35
|
module ClassMethods
|
36
36
|
def view_context_class
|
37
37
|
@view_context_class ||= begin
|
38
|
-
|
38
|
+
include_path_helpers = supports_path?
|
39
|
+
routes = respond_to?(:_routes) && _routes
|
39
40
|
helpers = respond_to?(:_helpers) && _helpers
|
40
41
|
|
41
42
|
Class.new(ActionView::Base) do
|
42
43
|
if routes
|
43
|
-
include routes.url_helpers
|
44
|
+
include routes.url_helpers(include_path_helpers)
|
44
45
|
include routes.mounted_helpers
|
45
46
|
end
|
46
47
|
|
@@ -62,8 +63,8 @@ module ActionView
|
|
62
63
|
#
|
63
64
|
# The view class must have the following methods:
|
64
65
|
# View.new[lookup_context, assigns, controller]
|
65
|
-
# Create a new ActionView instance for a controller
|
66
|
-
# View#render
|
66
|
+
# Create a new ActionView instance for a controller and we can also pass the arguments.
|
67
|
+
# View#render(option)
|
67
68
|
# Returns String with the rendered template
|
68
69
|
#
|
69
70
|
# Override this method in a module to change the default behavior.
|
@@ -107,7 +108,7 @@ module ActionView
|
|
107
108
|
end
|
108
109
|
|
109
110
|
# Normalize args by converting render "foo" to render :action => "foo" and
|
110
|
-
# render "foo/bar" to render :
|
111
|
+
# render "foo/bar" to render :file => "foo/bar".
|
111
112
|
# :api: private
|
112
113
|
def _normalize_args(action=nil, options={})
|
113
114
|
options = super(action, options)
|
@@ -117,7 +118,7 @@ module ActionView
|
|
117
118
|
options = action
|
118
119
|
when String, Symbol
|
119
120
|
action = action.to_s
|
120
|
-
key = action.include?(?/) ? :
|
121
|
+
key = action.include?(?/) ? :file : :action
|
121
122
|
options[key] = action
|
122
123
|
else
|
123
124
|
options[:partial] = action
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'action_dispatch/routing/polymorphic_routes'
|
2
|
+
|
1
3
|
module ActionView
|
2
4
|
module RoutingUrlFor
|
3
5
|
|
@@ -77,16 +79,22 @@ module ActionView
|
|
77
79
|
case options
|
78
80
|
when String
|
79
81
|
options
|
80
|
-
when nil
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
when nil
|
83
|
+
super({:only_path => true})
|
84
|
+
when Hash
|
85
|
+
options = options.symbolize_keys
|
86
|
+
options[:only_path] = options[:host].nil? unless options.key?(:only_path)
|
87
|
+
super(options)
|
84
88
|
when :back
|
85
89
|
_back_url
|
90
|
+
when Symbol
|
91
|
+
ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_string_call self, options
|
86
92
|
when Array
|
87
93
|
polymorphic_path(options, options.extract_options!)
|
94
|
+
when Class
|
95
|
+
ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_class_call self, options
|
88
96
|
else
|
89
|
-
|
97
|
+
ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call self, options
|
90
98
|
end
|
91
99
|
end
|
92
100
|
|
@@ -2,22 +2,20 @@ namespace :cache_digests do
|
|
2
2
|
desc 'Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html)'
|
3
3
|
task :nested_dependencies => :environment do
|
4
4
|
abort 'You must provide TEMPLATE for the task to run' unless ENV['TEMPLATE'].present?
|
5
|
-
puts JSON.pretty_generate ActionView::Digestor.new(name:
|
5
|
+
puts JSON.pretty_generate ActionView::Digestor.new(name: template_name, finder: finder).nested_dependencies
|
6
6
|
end
|
7
7
|
|
8
8
|
desc 'Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html)'
|
9
9
|
task :dependencies => :environment do
|
10
10
|
abort 'You must provide TEMPLATE for the task to run' unless ENV['TEMPLATE'].present?
|
11
|
-
puts JSON.pretty_generate ActionView::Digestor.new(name:
|
11
|
+
puts JSON.pretty_generate ActionView::Digestor.new(name: template_name, finder: finder).dependencies
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
14
|
+
def template_name
|
15
|
+
ENV['TEMPLATE'].split('.', 2).first
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
18
|
+
def finder
|
19
|
+
ApplicationController.new.lookup_context
|
22
20
|
end
|
23
21
|
end
|
@@ -32,6 +32,15 @@ module ActionView #:nodoc:
|
|
32
32
|
@@template_extensions = nil
|
33
33
|
end
|
34
34
|
|
35
|
+
# Opposite to register_template_handler.
|
36
|
+
def unregister_template_handler(*extensions)
|
37
|
+
extensions.each do |extension|
|
38
|
+
handler = @@template_handlers.delete extension.to_sym
|
39
|
+
@@default_template_handlers = nil if @@default_template_handlers == handler
|
40
|
+
end
|
41
|
+
@@template_extensions = nil
|
42
|
+
end
|
43
|
+
|
35
44
|
def template_handler_extensions
|
36
45
|
@@template_handlers.keys.map {|key| key.to_s }.sort
|
37
46
|
end
|
@@ -112,13 +112,7 @@ module ActionView
|
|
112
112
|
# Normalizes the arguments and passes it on to find_templates.
|
113
113
|
def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
|
114
114
|
cached(key, [name, prefix, partial], details, locals) do
|
115
|
-
find_templates(name, prefix, partial, details
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def find_all_anywhere(name, prefix, partial=false, details={}, key=nil, locals=[])
|
120
|
-
cached(key, [name, prefix, partial], details, locals) do
|
121
|
-
find_templates(name, prefix, partial, details, true)
|
115
|
+
find_templates(name, prefix, partial, details)
|
122
116
|
end
|
123
117
|
end
|
124
118
|
|
@@ -129,8 +123,8 @@ module ActionView
|
|
129
123
|
# This is what child classes implement. No defaults are needed
|
130
124
|
# because Resolver guarantees that the arguments are present and
|
131
125
|
# normalized.
|
132
|
-
def find_templates(name, prefix, partial, details
|
133
|
-
raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details
|
126
|
+
def find_templates(name, prefix, partial, details)
|
127
|
+
raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details) method"
|
134
128
|
end
|
135
129
|
|
136
130
|
# Helpers that builds a path. Useful for building virtual paths.
|
@@ -179,16 +173,15 @@ module ActionView
|
|
179
173
|
|
180
174
|
private
|
181
175
|
|
182
|
-
def find_templates(name, prefix, partial, details
|
176
|
+
def find_templates(name, prefix, partial, details)
|
183
177
|
path = Path.build(name, prefix, partial)
|
184
|
-
query(path, details, details[:formats]
|
178
|
+
query(path, details, details[:formats])
|
185
179
|
end
|
186
180
|
|
187
|
-
def query(path, details, formats
|
181
|
+
def query(path, details, formats)
|
188
182
|
query = build_query(path, details)
|
189
183
|
|
190
184
|
template_paths = find_template_paths query
|
191
|
-
template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed
|
192
185
|
|
193
186
|
template_paths.map { |template|
|
194
187
|
handler, format, variant = extract_handler_and_format_and_variant(template, formats)
|
@@ -203,10 +196,6 @@ module ActionView
|
|
203
196
|
}
|
204
197
|
end
|
205
198
|
|
206
|
-
def reject_files_external_to_app(files)
|
207
|
-
files.reject { |filename| !inside_path?(@path, filename) }
|
208
|
-
end
|
209
|
-
|
210
199
|
if RUBY_VERSION >= '2.2.0'
|
211
200
|
def find_template_paths(query)
|
212
201
|
Dir[query].reject { |filename|
|
@@ -227,12 +216,6 @@ module ActionView
|
|
227
216
|
end
|
228
217
|
end
|
229
218
|
|
230
|
-
def inside_path?(path, filename)
|
231
|
-
filename = File.expand_path(filename)
|
232
|
-
path = File.join(path, '')
|
233
|
-
filename.start_with?(path)
|
234
|
-
end
|
235
|
-
|
236
219
|
# Helper for building query glob string based on resolver's pattern.
|
237
220
|
def build_query(path, details)
|
238
221
|
query = @pattern.dup
|
@@ -259,7 +242,7 @@ module ActionView
|
|
259
242
|
File.mtime(p)
|
260
243
|
end
|
261
244
|
|
262
|
-
# Extract handler and
|
245
|
+
# Extract handler, formats and variant from path. If a format cannot be found neither
|
263
246
|
# from the path, or the handler, we should return the array of formats given
|
264
247
|
# to the resolver.
|
265
248
|
def extract_handler_and_format_and_variant(path, default_formats)
|