actionview 4.2.11.1 → 5.2.7

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.

Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +108 -240
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -6
  5. data/lib/action_view/base.rb +38 -28
  6. data/lib/action_view/buffers.rb +3 -1
  7. data/lib/action_view/context.rb +3 -3
  8. data/lib/action_view/dependency_tracker.rb +54 -20
  9. data/lib/action_view/digestor.rb +94 -83
  10. data/lib/action_view/flows.rb +11 -11
  11. data/lib/action_view/gem_version.rb +5 -3
  12. data/lib/action_view/helpers/active_model_helper.rb +17 -11
  13. data/lib/action_view/helpers/asset_tag_helper.rb +244 -62
  14. data/lib/action_view/helpers/asset_url_helper.rb +170 -67
  15. data/lib/action_view/helpers/atom_feed_helper.rb +19 -17
  16. data/lib/action_view/helpers/cache_helper.rb +105 -42
  17. data/lib/action_view/helpers/capture_helper.rb +16 -13
  18. data/lib/action_view/helpers/controller_helper.rb +15 -4
  19. data/lib/action_view/helpers/csp_helper.rb +24 -0
  20. data/lib/action_view/helpers/csrf_helper.rb +7 -5
  21. data/lib/action_view/helpers/date_helper.rb +170 -112
  22. data/lib/action_view/helpers/debug_helper.rb +7 -6
  23. data/lib/action_view/helpers/form_helper.rb +521 -127
  24. data/lib/action_view/helpers/form_options_helper.rb +109 -63
  25. data/lib/action_view/helpers/form_tag_helper.rb +110 -67
  26. data/lib/action_view/helpers/javascript_helper.rb +27 -12
  27. data/lib/action_view/helpers/number_helper.rb +77 -58
  28. data/lib/action_view/helpers/output_safety_helper.rb +36 -4
  29. data/lib/action_view/helpers/record_tag_helper.rb +14 -99
  30. data/lib/action_view/helpers/rendering_helper.rb +6 -5
  31. data/lib/action_view/helpers/sanitize_helper.rb +20 -15
  32. data/lib/action_view/helpers/tag_helper.rb +198 -73
  33. data/lib/action_view/helpers/tags/base.rb +134 -97
  34. data/lib/action_view/helpers/tags/check_box.rb +20 -18
  35. data/lib/action_view/helpers/tags/checkable.rb +4 -2
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +12 -33
  37. data/lib/action_view/helpers/tags/collection_helpers.rb +70 -36
  38. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +6 -11
  39. data/lib/action_view/helpers/tags/collection_select.rb +4 -2
  40. data/lib/action_view/helpers/tags/color_field.rb +3 -1
  41. data/lib/action_view/helpers/tags/date_field.rb +2 -0
  42. data/lib/action_view/helpers/tags/date_select.rb +38 -36
  43. data/lib/action_view/helpers/tags/datetime_field.rb +4 -2
  44. data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -0
  45. data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
  46. data/lib/action_view/helpers/tags/email_field.rb +2 -0
  47. data/lib/action_view/helpers/tags/file_field.rb +2 -0
  48. data/lib/action_view/helpers/tags/grouped_collection_select.rb +4 -2
  49. data/lib/action_view/helpers/tags/hidden_field.rb +2 -0
  50. data/lib/action_view/helpers/tags/label.rb +3 -1
  51. data/lib/action_view/helpers/tags/month_field.rb +2 -0
  52. data/lib/action_view/helpers/tags/number_field.rb +2 -0
  53. data/lib/action_view/helpers/tags/password_field.rb +3 -1
  54. data/lib/action_view/helpers/tags/placeholderable.rb +3 -1
  55. data/lib/action_view/helpers/tags/radio_button.rb +7 -5
  56. data/lib/action_view/helpers/tags/range_field.rb +2 -0
  57. data/lib/action_view/helpers/tags/search_field.rb +14 -9
  58. data/lib/action_view/helpers/tags/select.rb +11 -9
  59. data/lib/action_view/helpers/tags/tel_field.rb +2 -0
  60. data/lib/action_view/helpers/tags/text_area.rb +4 -2
  61. data/lib/action_view/helpers/tags/text_field.rb +8 -7
  62. data/lib/action_view/helpers/tags/time_field.rb +2 -0
  63. data/lib/action_view/helpers/tags/time_select.rb +2 -0
  64. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
  65. data/lib/action_view/helpers/tags/translator.rb +17 -13
  66. data/lib/action_view/helpers/tags/url_field.rb +2 -0
  67. data/lib/action_view/helpers/tags/week_field.rb +2 -0
  68. data/lib/action_view/helpers/tags.rb +3 -1
  69. data/lib/action_view/helpers/text_helper.rb +55 -36
  70. data/lib/action_view/helpers/translation_helper.rb +74 -32
  71. data/lib/action_view/helpers/url_helper.rb +159 -104
  72. data/lib/action_view/helpers.rb +5 -1
  73. data/lib/action_view/layouts.rb +65 -58
  74. data/lib/action_view/log_subscriber.rb +60 -8
  75. data/lib/action_view/lookup_context.rb +80 -65
  76. data/lib/action_view/model_naming.rb +3 -1
  77. data/lib/action_view/path_set.rb +30 -19
  78. data/lib/action_view/railtie.rb +39 -6
  79. data/lib/action_view/record_identifier.rb +53 -25
  80. data/lib/action_view/renderer/abstract_renderer.rb +21 -15
  81. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +57 -0
  82. data/lib/action_view/renderer/partial_renderer.rb +218 -214
  83. data/lib/action_view/renderer/renderer.rb +8 -6
  84. data/lib/action_view/renderer/streaming_template_renderer.rb +50 -48
  85. data/lib/action_view/renderer/template_renderer.rb +67 -66
  86. data/lib/action_view/rendering.rb +19 -14
  87. data/lib/action_view/routing_url_for.rb +27 -17
  88. data/lib/action_view/tasks/cache_digests.rake +25 -0
  89. data/lib/action_view/template/error.rb +16 -16
  90. data/lib/action_view/template/handlers/builder.rb +10 -11
  91. data/lib/action_view/template/handlers/erb/erubi.rb +83 -0
  92. data/lib/action_view/template/handlers/erb.rb +9 -80
  93. data/lib/action_view/template/handlers/html.rb +11 -0
  94. data/lib/action_view/template/handlers/raw.rb +3 -3
  95. data/lib/action_view/template/handlers.rb +11 -7
  96. data/lib/action_view/template/html.rb +5 -5
  97. data/lib/action_view/template/resolver.rb +140 -115
  98. data/lib/action_view/template/text.rb +8 -9
  99. data/lib/action_view/template/types.rb +18 -18
  100. data/lib/action_view/template.rb +56 -31
  101. data/lib/action_view/test_case.rb +50 -29
  102. data/lib/action_view/testing/resolvers.rb +31 -31
  103. data/lib/action_view/version.rb +3 -1
  104. data/lib/action_view/view_paths.rb +28 -34
  105. data/lib/action_view.rb +8 -7
  106. data/lib/assets/compiled/rails-ujs.js +720 -0
  107. metadata +25 -24
  108. data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,10 +1,11 @@
1
- require 'fiber'
1
+ # frozen_string_literal: true
2
+
3
+ require "fiber"
2
4
 
3
5
  module ActionView
4
6
  # == TODO
5
7
  #
6
8
  # * Support streaming from child templates, partials and so on.
7
- # * Integrate exceptions with exceptron
8
9
  # * Rack::Cache needs to support streaming bodies
9
10
  class StreamingTemplateRenderer < TemplateRenderer #:nodoc:
10
11
  # A valid Rack::Body (i.e. it responds to each).
@@ -27,17 +28,16 @@ module ActionView
27
28
 
28
29
  private
29
30
 
30
- # This is the same logging logic as in ShowExceptions middleware.
31
- # TODO Once "exceptron" is in, refactor this piece to simply re-use exceptron.
32
- def log_error(exception) #:nodoc:
33
- logger = ActionView::Base.logger
34
- return unless logger
31
+ # This is the same logging logic as in ShowExceptions middleware.
32
+ def log_error(exception)
33
+ logger = ActionView::Base.logger
34
+ return unless logger
35
35
 
36
- message = "\n#{exception.class} (#{exception.message}):\n"
37
- message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
38
- message << " " << exception.backtrace.join("\n ")
39
- logger.fatal("#{message}\n\n")
40
- end
36
+ message = "\n#{exception.class} (#{exception.message}):\n".dup
37
+ message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
38
+ message << " " << exception.backtrace.join("\n ")
39
+ logger.fatal("#{message}\n\n")
40
+ end
41
41
  end
42
42
 
43
43
  # For streaming, instead of rendering a given a template, we return a Body
@@ -47,7 +47,7 @@ module ActionView
47
47
  return [super] unless layout_name && template.supports_streaming?
48
48
 
49
49
  locals ||= {}
50
- layout = layout_name && find_layout(layout_name, locals.keys)
50
+ layout = layout_name && find_layout(layout_name, locals.keys, [formats.first])
51
51
 
52
52
  Body.new do |buffer|
53
53
  delayed_render(buffer, template, layout, @view, locals)
@@ -56,48 +56,50 @@ module ActionView
56
56
 
57
57
  private
58
58
 
59
- def delayed_render(buffer, template, layout, view, locals)
60
- # Wrap the given buffer in the StreamingBuffer and pass it to the
61
- # underlying template handler. Now, every time something is concatenated
62
- # to the buffer, it is not appended to an array, but streamed straight
63
- # to the client.
64
- output = ActionView::StreamingBuffer.new(buffer)
65
- yielder = lambda { |*name| view._layout_for(*name) }
66
-
67
- instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
68
- fiber = Fiber.new do
69
- if layout
70
- layout.render(view, locals, output, &yielder)
71
- else
72
- # If you don't have a layout, just render the thing
73
- # and concatenate the final result. This is the same
74
- # as a layout with just <%= yield %>
75
- output.safe_concat view._layout_for
59
+ def delayed_render(buffer, template, layout, view, locals)
60
+ # Wrap the given buffer in the StreamingBuffer and pass it to the
61
+ # underlying template handler. Now, every time something is concatenated
62
+ # to the buffer, it is not appended to an array, but streamed straight
63
+ # to the client.
64
+ output = ActionView::StreamingBuffer.new(buffer)
65
+ yielder = lambda { |*name| view._layout_for(*name) }
66
+
67
+ instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
68
+ outer_config = I18n.config
69
+ fiber = Fiber.new do
70
+ I18n.config = outer_config
71
+ if layout
72
+ layout.render(view, locals, output, &yielder)
73
+ else
74
+ # If you don't have a layout, just render the thing
75
+ # and concatenate the final result. This is the same
76
+ # as a layout with just <%= yield %>
77
+ output.safe_concat view._layout_for
78
+ end
76
79
  end
77
- end
78
80
 
79
- # Set the view flow to support streaming. It will be aware
80
- # when to stop rendering the layout because it needs to search
81
- # something in the template and vice-versa.
82
- view.view_flow = StreamingFlow.new(view, fiber)
81
+ # Set the view flow to support streaming. It will be aware
82
+ # when to stop rendering the layout because it needs to search
83
+ # something in the template and vice-versa.
84
+ view.view_flow = StreamingFlow.new(view, fiber)
83
85
 
84
- # Yo! Start the fiber!
85
- fiber.resume
86
+ # Yo! Start the fiber!
87
+ fiber.resume
86
88
 
87
- # If the fiber is still alive, it means we need something
88
- # from the template, so start rendering it. If not, it means
89
- # the layout exited without requiring anything from the template.
90
- if fiber.alive?
91
- content = template.render(view, locals, &yielder)
89
+ # If the fiber is still alive, it means we need something
90
+ # from the template, so start rendering it. If not, it means
91
+ # the layout exited without requiring anything from the template.
92
+ if fiber.alive?
93
+ content = template.render(view, locals, &yielder)
92
94
 
93
- # Once rendering the template is done, sets its content in the :layout key.
94
- view.view_flow.set(:layout, content)
95
+ # Once rendering the template is done, sets its content in the :layout key.
96
+ view.view_flow.set(:layout, content)
95
97
 
96
- # In case the layout continues yielding, we need to resume
97
- # the fiber until all yields are handled.
98
- fiber.resume while fiber.alive?
98
+ # In case the layout continues yielding, we need to resume
99
+ # the fiber until all yields are handled.
100
+ fiber.resume while fiber.alive?
101
+ end
99
102
  end
100
103
  end
101
- end
102
104
  end
103
105
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/try'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/try"
2
4
 
3
5
  module ActionView
4
6
  class TemplateRenderer < AbstractRenderer #:nodoc:
@@ -16,86 +18,85 @@ module ActionView
16
18
 
17
19
  private
18
20
 
19
- # Determine the template to be rendered using the given options.
20
- def determine_template(options)
21
- keys = options.has_key?(:locals) ? options[:locals].keys : []
21
+ # Determine the template to be rendered using the given options.
22
+ def determine_template(options)
23
+ keys = options.has_key?(:locals) ? options[:locals].keys : []
22
24
 
23
- if options.key?(:body)
24
- Template::Text.new(options[:body])
25
- elsif options.key?(:text)
26
- Template::Text.new(options[:text], formats.first)
27
- elsif options.key?(:plain)
28
- Template::Text.new(options[:plain])
29
- elsif options.key?(:html)
30
- Template::HTML.new(options[:html], formats.first)
31
- elsif options.key?(:file)
32
- with_fallbacks { find_file(options[:file], nil, false, keys, @details) }
33
- elsif options.key?(:inline)
34
- handler = Template.handler_for_extension(options[:type] || "erb")
35
- Template.new(options[:inline], "inline template", handler, :locals => keys)
36
- elsif options.key?(:template)
37
- if options[:template].respond_to?(:render)
38
- options[:template]
25
+ if options.key?(:body)
26
+ Template::Text.new(options[:body])
27
+ elsif options.key?(:plain)
28
+ Template::Text.new(options[:plain])
29
+ elsif options.key?(:html)
30
+ Template::HTML.new(options[:html], formats.first)
31
+ elsif options.key?(:file)
32
+ with_fallbacks { find_file(options[:file], nil, false, keys, @details) }
33
+ elsif options.key?(:inline)
34
+ handler = Template.handler_for_extension(options[:type] || "erb")
35
+ Template.new(options[:inline], "inline template", handler, locals: keys)
36
+ elsif options.key?(:template)
37
+ if options[:template].respond_to?(:render)
38
+ options[:template]
39
+ else
40
+ find_template(options[:template], options[:prefixes], false, keys, @details)
41
+ end
39
42
  else
40
- find_template(options[:template], options[:prefixes], false, keys, @details)
43
+ raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :html or :body option."
41
44
  end
42
- else
43
- raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :text or :body option."
44
45
  end
45
- end
46
46
 
47
- # Renders the given template. A string representing the layout can be
48
- # supplied as well.
49
- def render_template(template, layout_name = nil, locals = nil) #:nodoc:
50
- view, locals = @view, locals || {}
47
+ # Renders the given template. A string representing the layout can be
48
+ # supplied as well.
49
+ def render_template(template, layout_name = nil, locals = nil)
50
+ view, locals = @view, locals || {}
51
51
 
52
- render_with_layout(layout_name, locals) do |layout|
53
- instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
54
- template.render(view, locals) { |*name| view._layout_for(*name) }
52
+ render_with_layout(layout_name, locals) do |layout|
53
+ instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
54
+ template.render(view, locals) { |*name| view._layout_for(*name) }
55
+ end
55
56
  end
56
57
  end
57
- end
58
58
 
59
- def render_with_layout(path, locals) #:nodoc:
60
- layout = path && find_layout(path, locals.keys)
61
- content = yield(layout)
59
+ def render_with_layout(path, locals)
60
+ layout = path && find_layout(path, locals.keys, [formats.first])
61
+ content = yield(layout)
62
62
 
63
- if layout
64
- view = @view
65
- view.view_flow.set(:layout, content)
66
- layout.render(view, locals){ |*name| view._layout_for(*name) }
67
- else
68
- content
63
+ if layout
64
+ view = @view
65
+ view.view_flow.set(:layout, content)
66
+ layout.render(view, locals) { |*name| view._layout_for(*name) }
67
+ else
68
+ content
69
+ end
69
70
  end
70
- end
71
71
 
72
- # This is the method which actually finds the layout using details in the lookup
73
- # context object. If no layout is found, it checks if at least a layout with
74
- # the given name exists across all details before raising the error.
75
- def find_layout(layout, keys)
76
- with_layout_format { resolve_layout(layout, keys) }
77
- end
72
+ # This is the method which actually finds the layout using details in the lookup
73
+ # context object. If no layout is found, it checks if at least a layout with
74
+ # the given name exists across all details before raising the error.
75
+ def find_layout(layout, keys, formats)
76
+ resolve_layout(layout, keys, formats)
77
+ end
78
78
 
79
- def resolve_layout(layout, keys)
80
- case layout
81
- when String
82
- begin
83
- if layout =~ /^\//
84
- with_fallbacks { find_template(layout, nil, false, keys, @details) }
85
- else
86
- find_template(layout, nil, false, keys, @details)
79
+ def resolve_layout(layout, keys, formats)
80
+ details = @details.dup
81
+ details[:formats] = formats
82
+
83
+ case layout
84
+ when String
85
+ begin
86
+ if layout.start_with?("/")
87
+ with_fallbacks { find_template(layout, nil, false, [], details) }
88
+ else
89
+ find_template(layout, nil, false, [], details)
90
+ end
91
+ rescue ActionView::MissingTemplate
92
+ all_details = @details.merge(formats: @lookup_context.default_formats)
93
+ raise unless template_exists?(layout, nil, false, [], all_details)
87
94
  end
88
- rescue ActionView::MissingTemplate
89
- all_details = @details.merge(:formats => @lookup_context.default_formats)
90
- raise unless template_exists?(layout, nil, false, keys, all_details)
95
+ when Proc
96
+ resolve_layout(layout.call(formats), keys, formats)
97
+ else
98
+ layout
91
99
  end
92
- when Proc
93
- resolve_layout(layout.call, keys)
94
- when FalseClass
95
- nil
96
- else
97
- layout
98
100
  end
99
- end
100
101
  end
101
102
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_view/view_paths"
2
4
 
3
5
  module ActionView
@@ -59,7 +61,7 @@ module ActionView
59
61
  @_view_context_class ||= self.class.view_context_class
60
62
  end
61
63
 
62
- # An instance of a view class. The default view class is ActionView::Base
64
+ # An instance of a view class. The default view class is ActionView::Base.
63
65
  #
64
66
  # The view class must have the following methods:
65
67
  # View.new[lookup_context, assigns, controller]
@@ -73,8 +75,7 @@ module ActionView
73
75
  end
74
76
 
75
77
  # Returns an object that is able to render templates.
76
- # :api: private
77
- def view_renderer
78
+ def view_renderer # :nodoc:
78
79
  @_view_renderer ||= ActionView::Renderer.new(lookup_context)
79
80
  end
80
81
 
@@ -84,24 +85,26 @@ module ActionView
84
85
  end
85
86
 
86
87
  def rendered_format
87
- Mime[lookup_context.rendered_format]
88
+ Template::Types[lookup_context.rendered_format]
88
89
  end
89
90
 
90
91
  private
91
92
 
92
93
  # Find and render a template based on the options given.
93
- # :api: private
94
- def _render_template(options) #:nodoc:
95
- variant = options[:variant]
94
+ def _render_template(options)
95
+ variant = options.delete(:variant)
96
+ assigns = options.delete(:assigns)
97
+ context = view_context
96
98
 
99
+ context.assign assigns if assigns
97
100
  lookup_context.rendered_format = nil if options[:formats]
98
101
  lookup_context.variants = variant if variant
99
102
 
100
- view_renderer.render(view_context, options)
103
+ view_renderer.render(context, options)
101
104
  end
102
105
 
103
- # Assign the rendered format to lookup context.
104
- def _process_format(format, options = {}) #:nodoc:
106
+ # Assign the rendered format to look up context.
107
+ def _process_format(format)
105
108
  super
106
109
  lookup_context.formats = [format.to_sym]
107
110
  lookup_context.rendered_format = lookup_context.formats.first
@@ -109,8 +112,7 @@ module ActionView
109
112
 
110
113
  # Normalize args by converting render "foo" to render :action => "foo" and
111
114
  # render "foo/bar" to render :template => "foo/bar".
112
- # :api: private
113
- def _normalize_args(action=nil, options={})
115
+ def _normalize_args(action = nil, options = {})
114
116
  options = super(action, options)
115
117
  case action
116
118
  when NilClass
@@ -121,14 +123,17 @@ module ActionView
121
123
  key = action.include?(?/) ? :template : :action
122
124
  options[key] = action
123
125
  else
124
- options[:partial] = action
126
+ if action.respond_to?(:permitted?) && action.permitted?
127
+ options = action
128
+ else
129
+ options[:partial] = action
130
+ end
125
131
  end
126
132
 
127
133
  options
128
134
  end
129
135
 
130
136
  # Normalize options.
131
- # :api: private
132
137
  def _normalize_options(options)
133
138
  options = super(options)
134
139
  if options[:partial] == true
@@ -1,8 +1,9 @@
1
- require 'action_dispatch/routing/polymorphic_routes'
1
+ # frozen_string_literal: true
2
+
3
+ require "action_dispatch/routing/polymorphic_routes"
2
4
 
3
5
  module ActionView
4
6
  module RoutingUrlFor
5
-
6
7
  # Returns the URL for the set of +options+ provided. This takes the
7
8
  # same options as +url_for+ in Action Controller (see the
8
9
  # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
@@ -32,7 +33,7 @@ module ActionView
32
33
  #
33
34
  # ==== Examples
34
35
  # <%= url_for(action: 'index') %>
35
- # # => /blog/
36
+ # # => /blogs/
36
37
  #
37
38
  # <%= url_for(action: 'find', controller: 'books') %>
38
39
  # # => /books/find
@@ -84,11 +85,13 @@ module ActionView
84
85
  when Hash
85
86
  options = options.symbolize_keys
86
87
  unless options.key?(:only_path)
87
- if options[:host].nil?
88
- options[:only_path] = _generate_paths_by_default
89
- else
90
- options[:only_path] = false
91
- end
88
+ options[:only_path] = only_path?(options[:host])
89
+ end
90
+
91
+ super(options)
92
+ when ActionController::Parameters
93
+ unless options.key?(:only_path)
94
+ options[:only_path] = only_path?(options[:host])
92
95
  end
93
96
 
94
97
  super(options)
@@ -121,15 +124,22 @@ module ActionView
121
124
  controller.url_options
122
125
  end
123
126
 
124
- def _routes_context #:nodoc:
125
- controller
126
- end
127
- protected :_routes_context
127
+ private
128
+ def _routes_context
129
+ controller
130
+ end
128
131
 
129
- def optimize_routes_generation? #:nodoc:
130
- controller.respond_to?(:optimize_routes_generation?, true) ?
131
- controller.optimize_routes_generation? : super
132
- end
133
- protected :optimize_routes_generation?
132
+ def optimize_routes_generation?
133
+ controller.respond_to?(:optimize_routes_generation?, true) ?
134
+ controller.optimize_routes_generation? : super
135
+ end
136
+
137
+ def _generate_paths_by_default
138
+ true
139
+ end
140
+
141
+ def only_path?(host)
142
+ _generate_paths_by_default unless host
143
+ end
134
144
  end
135
145
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :cache_digests do
4
+ desc "Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html)"
5
+ task nested_dependencies: :environment do
6
+ abort "You must provide TEMPLATE for the task to run" unless ENV["TEMPLATE"].present?
7
+ puts JSON.pretty_generate ActionView::Digestor.tree(CacheDigests.template_name, CacheDigests.finder).children.map(&:to_dep_map)
8
+ end
9
+
10
+ desc "Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html)"
11
+ task dependencies: :environment do
12
+ abort "You must provide TEMPLATE for the task to run" unless ENV["TEMPLATE"].present?
13
+ puts JSON.pretty_generate ActionView::Digestor.tree(CacheDigests.template_name, CacheDigests.finder).children.map(&:name)
14
+ end
15
+
16
+ class CacheDigests
17
+ def self.template_name
18
+ ENV["TEMPLATE"].split(".", 2).first
19
+ end
20
+
21
+ def self.finder
22
+ ApplicationController.new.lookup_context
23
+ end
24
+ end
25
+ end
@@ -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
@@ -35,10 +34,10 @@ module ActionView
35
34
  prefixes = Array(prefixes)
36
35
  template_type = if partial
37
36
  "partial"
38
- elsif path =~ /layouts/i
39
- 'layout'
37
+ elsif /layouts/i.match?(path)
38
+ "layout"
40
39
  else
41
- 'template'
40
+ "template"
42
41
  end
43
42
 
44
43
  if partial && path.present?
@@ -59,13 +58,14 @@ module ActionView
59
58
  class Error < ActionViewError #:nodoc:
60
59
  SOURCE_CODE_RADIUS = 3
61
60
 
62
- attr_reader :original_exception
61
+ # Override to prevent #cause resetting during re-raise.
62
+ attr_reader :cause
63
63
 
64
- def initialize(template, original_exception)
65
- super(original_exception.message)
66
- @template, @original_exception = template, original_exception
67
- @sub_templates = nil
68
- set_backtrace(original_exception.backtrace)
64
+ def initialize(template)
65
+ super($!.message)
66
+ set_backtrace($!.backtrace)
67
+ @cause = $!
68
+ @template, @sub_templates = template, nil
69
69
  end
70
70
 
71
71
  def file_name
@@ -75,7 +75,7 @@ module ActionView
75
75
  def sub_template_message
76
76
  if @sub_templates
77
77
  "Trace of template inclusion: " +
78
- @sub_templates.collect { |template| template.inspect }.join(", ")
78
+ @sub_templates.collect(&:inspect).join(", ")
79
79
  else
80
80
  ""
81
81
  end
@@ -119,18 +119,18 @@ module ActionView
119
119
  if line_number
120
120
  "on line ##{line_number} of "
121
121
  else
122
- 'in '
122
+ "in "
123
123
  end + file_name
124
124
  end
125
125
 
126
126
  def formatted_code_for(source_code, line_counter, indent, output)
127
- start_value = (output == :html) ? {} : ""
127
+ start_value = (output == :html) ? {} : []
128
128
  source_code.inject(start_value) do |result, line|
129
129
  line_counter += 1
130
130
  if output == :html
131
131
  result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line])
132
132
  else
133
- result << "%#{indent}s: %s\n" % [line_counter, line]
133
+ result << "%#{indent}s: %s" % [line_counter, line]
134
134
  end
135
135
  end
136
136
  end
@@ -1,26 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionView
2
4
  module Template::Handlers
3
5
  class Builder
4
- # Default format used by Builder.
5
- class_attribute :default_format
6
- self.default_format = :xml
6
+ class_attribute :default_format, default: :xml
7
7
 
8
8
  def call(template)
9
9
  require_engine
10
- "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
10
+ "xml = ::Builder::XmlMarkup.new(:indent => 2);" \
11
11
  "self.output_buffer = xml.target!;" +
12
12
  template.source +
13
13
  ";xml.target!;"
14
14
  end
15
15
 
16
- protected
17
-
18
- def require_engine
19
- @required ||= begin
20
- require "builder"
21
- true
16
+ private
17
+ def require_engine # :doc:
18
+ @required ||= begin
19
+ require "builder"
20
+ true
21
+ end
22
22
  end
23
- end
24
23
  end
25
24
  end
26
25
  end