actionview 4.1.13 → 6.1.3.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.

Files changed (124) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +181 -359
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +12 -6
  5. data/lib/action_view/base.rb +115 -43
  6. data/lib/action_view/buffers.rb +22 -4
  7. data/lib/action_view/cache_expiry.rb +52 -0
  8. data/lib/action_view/context.rb +8 -12
  9. data/lib/action_view/dependency_tracker.rb +61 -21
  10. data/lib/action_view/digestor.rb +89 -84
  11. data/lib/action_view/flows.rb +12 -13
  12. data/lib/action_view/gem_version.rb +6 -4
  13. data/lib/action_view/helpers/active_model_helper.rb +16 -11
  14. data/lib/action_view/helpers/asset_tag_helper.rb +311 -105
  15. data/lib/action_view/helpers/asset_url_helper.rb +197 -80
  16. data/lib/action_view/helpers/atom_feed_helper.rb +20 -17
  17. data/lib/action_view/helpers/cache_helper.rb +109 -45
  18. data/lib/action_view/helpers/capture_helper.rb +20 -22
  19. data/lib/action_view/helpers/controller_helper.rb +15 -4
  20. data/lib/action_view/helpers/csp_helper.rb +26 -0
  21. data/lib/action_view/helpers/csrf_helper.rb +8 -6
  22. data/lib/action_view/helpers/date_helper.rb +245 -140
  23. data/lib/action_view/helpers/debug_helper.rb +14 -17
  24. data/lib/action_view/helpers/form_helper.rb +875 -148
  25. data/lib/action_view/helpers/form_options_helper.rb +128 -82
  26. data/lib/action_view/helpers/form_tag_helper.rb +253 -91
  27. data/lib/action_view/helpers/javascript_helper.rb +37 -15
  28. data/lib/action_view/helpers/number_helper.rb +100 -77
  29. data/lib/action_view/helpers/output_safety_helper.rb +42 -10
  30. data/lib/action_view/helpers/rendering_helper.rb +26 -15
  31. data/lib/action_view/helpers/sanitize_helper.rb +79 -164
  32. data/lib/action_view/helpers/tag_helper.rb +277 -64
  33. data/lib/action_view/helpers/tags/base.rb +143 -92
  34. data/lib/action_view/helpers/tags/check_box.rb +20 -19
  35. data/lib/action_view/helpers/tags/checkable.rb +4 -2
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +12 -30
  37. data/lib/action_view/helpers/tags/collection_helpers.rb +69 -36
  38. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +6 -12
  39. data/lib/action_view/helpers/tags/collection_select.rb +4 -2
  40. data/lib/action_view/helpers/tags/color_field.rb +4 -3
  41. data/lib/action_view/helpers/tags/date_field.rb +3 -2
  42. data/lib/action_view/helpers/tags/date_select.rb +38 -37
  43. data/lib/action_view/helpers/tags/datetime_field.rb +14 -5
  44. data/lib/action_view/helpers/tags/datetime_local_field.rb +3 -2
  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 +41 -22
  51. data/lib/action_view/helpers/tags/month_field.rb +3 -2
  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 +24 -0
  55. data/lib/action_view/helpers/tags/radio_button.rb +7 -6
  56. data/lib/action_view/helpers/tags/range_field.rb +2 -0
  57. data/lib/action_view/helpers/tags/search_field.rb +3 -0
  58. data/lib/action_view/helpers/tags/select.rb +11 -10
  59. data/lib/action_view/helpers/tags/tel_field.rb +2 -0
  60. data/lib/action_view/helpers/tags/text_area.rb +7 -1
  61. data/lib/action_view/helpers/tags/text_field.rb +11 -7
  62. data/lib/action_view/helpers/tags/time_field.rb +3 -2
  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 +39 -0
  66. data/lib/action_view/helpers/tags/url_field.rb +2 -0
  67. data/lib/action_view/helpers/tags/week_field.rb +3 -2
  68. data/lib/action_view/helpers/tags.rb +4 -1
  69. data/lib/action_view/helpers/text_helper.rb +80 -45
  70. data/lib/action_view/helpers/translation_helper.rb +148 -67
  71. data/lib/action_view/helpers/url_helper.rb +289 -147
  72. data/lib/action_view/helpers.rb +5 -3
  73. data/lib/action_view/layouts.rb +68 -63
  74. data/lib/action_view/log_subscriber.rb +80 -13
  75. data/lib/action_view/lookup_context.rb +137 -92
  76. data/lib/action_view/model_naming.rb +4 -2
  77. data/lib/action_view/path_set.rb +30 -16
  78. data/lib/action_view/railtie.rb +62 -13
  79. data/lib/action_view/record_identifier.rb +53 -26
  80. data/lib/action_view/renderer/abstract_renderer.rb +152 -13
  81. data/lib/action_view/renderer/collection_renderer.rb +196 -0
  82. data/lib/action_view/renderer/object_renderer.rb +34 -0
  83. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +102 -0
  84. data/lib/action_view/renderer/partial_renderer.rb +61 -261
  85. data/lib/action_view/renderer/renderer.rb +67 -6
  86. data/lib/action_view/renderer/streaming_template_renderer.rb +58 -54
  87. data/lib/action_view/renderer/template_renderer.rb +83 -75
  88. data/lib/action_view/rendering.rb +73 -46
  89. data/lib/action_view/routing_url_for.rb +54 -17
  90. data/lib/action_view/tasks/cache_digests.rake +25 -0
  91. data/lib/action_view/template/error.rb +44 -29
  92. data/lib/action_view/template/handlers/builder.rb +12 -13
  93. data/lib/action_view/template/handlers/erb/erubi.rb +89 -0
  94. data/lib/action_view/template/handlers/erb.rb +23 -89
  95. data/lib/action_view/template/handlers/html.rb +11 -0
  96. data/lib/action_view/template/handlers/raw.rb +4 -4
  97. data/lib/action_view/template/handlers.rb +22 -9
  98. data/lib/action_view/template/html.rb +10 -11
  99. data/lib/action_view/template/inline.rb +22 -0
  100. data/lib/action_view/template/raw_file.rb +25 -0
  101. data/lib/action_view/template/renderable.rb +24 -0
  102. data/lib/action_view/template/resolver.rb +267 -181
  103. data/lib/action_view/template/sources/file.rb +17 -0
  104. data/lib/action_view/template/sources.rb +13 -0
  105. data/lib/action_view/template/text.rb +8 -10
  106. data/lib/action_view/template/types.rb +18 -18
  107. data/lib/action_view/template.rb +109 -99
  108. data/lib/action_view/test_case.rb +73 -53
  109. data/lib/action_view/testing/resolvers.rb +24 -33
  110. data/lib/action_view/unbound_template.rb +31 -0
  111. data/lib/action_view/version.rb +3 -1
  112. data/lib/action_view/view_paths.rb +74 -44
  113. data/lib/action_view.rb +14 -9
  114. data/lib/assets/compiled/rails-ujs.js +746 -0
  115. metadata +71 -26
  116. data/lib/action_view/helpers/record_tag_helper.rb +0 -108
  117. data/lib/action_view/tasks/dependencies.rake +0 -23
  118. data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
  119. data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
  120. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
  121. data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
  122. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
  123. data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
  124. data/lib/action_view/vendor/html-scanner.rb +0 -20
@@ -1,7 +1,11 @@
1
- require 'active_support/core_ext/module/remove_method'
2
- require 'action_controller'
3
- require 'action_controller/test_case'
4
- require 'action_view'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
+ require "action_controller"
5
+ require "action_controller/test_case"
6
+ require "action_view"
7
+
8
+ require "rails-dom-testing"
5
9
 
6
10
  module ActionView
7
11
  # = Action View Test Case
@@ -12,21 +16,22 @@ module ActionView
12
16
  attr_accessor :request, :response, :params
13
17
 
14
18
  class << self
15
- attr_writer :controller_path
19
+ # Overrides AbstractController::Base#controller_path
20
+ attr_accessor :controller_path
16
21
  end
17
22
 
18
23
  def controller_path=(path)
19
- self.class.controller_path=(path)
24
+ self.class.controller_path = path
20
25
  end
21
26
 
22
27
  def initialize
23
28
  super
24
29
  self.class.controller_path = ""
25
- @request = ActionController::TestRequest.new
26
- @response = ActionController::TestResponse.new
30
+ @request = ActionController::TestRequest.create(self.class)
31
+ @response = ActionDispatch::TestResponse.new
27
32
 
28
- @request.env.delete('PATH_INFO')
29
- @params = {}
33
+ @request.env.delete("PATH_INFO")
34
+ @params = ActionController::Parameters.new
30
35
  end
31
36
  end
32
37
 
@@ -34,6 +39,7 @@ module ActionView
34
39
  extend ActiveSupport::Concern
35
40
 
36
41
  include ActionDispatch::Assertions, ActionDispatch::TestProcess
42
+ include Rails::Dom::Testing::Assertions
37
43
  include ActionController::TemplateAssertions
38
44
  include ActionView::Context
39
45
 
@@ -46,7 +52,7 @@ module ActionView
46
52
 
47
53
  include ActiveSupport::Testing::ConstantLookup
48
54
 
49
- delegate :lookup_context, :to => :controller
55
+ delegate :lookup_context, to: :controller
50
56
  attr_accessor :controller, :output_buffer, :rendered
51
57
 
52
58
  module ClassMethods
@@ -68,10 +74,11 @@ module ActionView
68
74
  def helper_method(*methods)
69
75
  # Almost a duplicate from ActionController::Helpers
70
76
  methods.flatten.each do |method|
71
- _helpers.module_eval <<-end_eval
77
+ _helpers_for_modification.module_eval <<-end_eval, __FILE__, __LINE__ + 1
72
78
  def #{method}(*args, &block) # def current_user(*args, &block)
73
- _test_case.send(%(#{method}), *args, &block) # _test_case.send(%(current_user), *args, &block)
79
+ _test_case.send(:'#{method}', *args, &block) # _test_case.send(:'current_user', *args, &block)
74
80
  end # end
81
+ ruby2_keywords(:'#{method}') if respond_to?(:ruby2_keywords, true)
75
82
  end_eval
76
83
  end
77
84
  end
@@ -88,22 +95,24 @@ module ActionView
88
95
  end
89
96
 
90
97
  private
91
-
92
98
  def include_helper_modules!
93
99
  helper(helper_class) if helper_class
94
100
  include _helpers
95
101
  end
96
-
97
102
  end
98
103
 
99
104
  def setup_with_controller
100
- @controller = ActionView::TestCase::TestController.new
105
+ controller_class = Class.new(ActionView::TestCase::TestController)
106
+ @controller = controller_class.new
101
107
  @request = @controller.request
102
- @output_buffer = ActiveSupport::SafeBuffer.new
103
- @rendered = ''
108
+ @view_flow = ActionView::OutputFlow.new
109
+ # empty string ensures buffer has UTF-8 encoding as
110
+ # new without arguments returns ASCII-8BIT encoded buffer like String#new
111
+ @output_buffer = ActiveSupport::SafeBuffer.new ""
112
+ @rendered = +""
104
113
 
105
- make_test_case_available_to_view!
106
- say_no_to_protect_against_forgery!
114
+ test_case_instance = self
115
+ controller_class.define_method(:_test_case) { test_case_instance }
107
116
  end
108
117
 
109
118
  def config
@@ -120,6 +129,11 @@ module ActionView
120
129
  @_rendered_views ||= RenderedViewsCollection.new
121
130
  end
122
131
 
132
+ def _routes
133
+ @controller._routes if @controller.respond_to?(:_routes)
134
+ end
135
+
136
+ # Need to experiment if this priority is the best one: rendered => output_buffer
123
137
  class RenderedViewsCollection
124
138
  def initialize
125
139
  @rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
@@ -140,43 +154,32 @@ module ActionView
140
154
 
141
155
  def view_rendered?(view, expected_locals)
142
156
  locals_for(view).any? do |actual_locals|
143
- expected_locals.all? {|key, value| value == actual_locals[key] }
157
+ expected_locals.all? { |key, value| value == actual_locals[key] }
144
158
  end
145
159
  end
146
160
  end
147
161
 
148
162
  included do
149
163
  setup :setup_with_controller
150
- end
151
-
152
- private
164
+ ActiveSupport.run_load_hooks(:action_view_test_case, self)
153
165
 
154
- # Support the selector assertions
155
- #
156
- # Need to experiment if this priority is the best one: rendered => output_buffer
157
- def response_from_page
158
- HTML::Document.new(@rendered.blank? ? @output_buffer : @rendered).root
159
- end
160
-
161
- def say_no_to_protect_against_forgery!
162
- _helpers.module_eval do
163
- remove_possible_method :protect_against_forgery?
166
+ helper do
164
167
  def protect_against_forgery?
165
168
  false
166
169
  end
167
- end
168
- end
169
170
 
170
- def make_test_case_available_to_view!
171
- test_case_instance = self
172
- _helpers.module_eval do
173
- unless private_method_defined?(:_test_case)
174
- define_method(:_test_case) { test_case_instance }
175
- private :_test_case
171
+ def _test_case
172
+ controller._test_case
176
173
  end
177
174
  end
178
175
  end
179
176
 
177
+ private
178
+ # Need to experiment if this priority is the best one: rendered => output_buffer
179
+ def document_root_element
180
+ Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
181
+ end
182
+
180
183
  module Locals
181
184
  attr_accessor :rendered_views
182
185
 
@@ -200,10 +203,10 @@ module ActionView
200
203
  def view
201
204
  @view ||= begin
202
205
  view = @controller.view_context
203
- view.singleton_class.send :include, _helpers
206
+ view.singleton_class.include(_helpers)
204
207
  view.extend(Locals)
205
- view.rendered_views = self.rendered_views
206
- view.output_buffer = self.output_buffer
208
+ view.rendered_views = rendered_views
209
+ view.output_buffer = output_buffer
207
210
  view
208
211
  end
209
212
  end
@@ -235,7 +238,10 @@ module ActionView
235
238
  :@options,
236
239
  :@test_passed,
237
240
  :@view,
238
- :@view_context_class
241
+ :@view_context_class,
242
+ :@view_flow,
243
+ :@_subscribers,
244
+ :@html_document
239
245
  ]
240
246
 
241
247
  def _user_defined_ivars
@@ -252,19 +258,33 @@ module ActionView
252
258
  end]
253
259
  end
254
260
 
255
- def _routes
256
- @controller._routes if @controller.respond_to?(:_routes)
257
- end
258
-
259
261
  def method_missing(selector, *args)
260
- if @controller.respond_to?(:_routes) &&
261
- ( @controller._routes.named_routes.helpers.include?(selector) ||
262
- @controller._routes.mounted_helpers.method_defined?(selector) )
262
+ begin
263
+ routes = @controller.respond_to?(:_routes) && @controller._routes
264
+ rescue
265
+ # Don't call routes, if there is an error on _routes call
266
+ end
267
+
268
+ if routes &&
269
+ (routes.named_routes.route_defined?(selector) ||
270
+ routes.mounted_helpers.method_defined?(selector))
263
271
  @controller.__send__(selector, *args)
264
272
  else
265
273
  super
266
274
  end
267
275
  end
276
+
277
+ def respond_to_missing?(name, include_private = false)
278
+ begin
279
+ routes = defined?(@controller) && @controller.respond_to?(:_routes) && @controller._routes
280
+ rescue
281
+ # Don't call routes, if there is an error on _routes call
282
+ end
283
+
284
+ routes &&
285
+ (routes.named_routes.route_defined?(name) ||
286
+ routes.mounted_helpers.method_defined?(name))
287
+ end
268
288
  end
269
289
 
270
290
  include Behavior
@@ -1,54 +1,45 @@
1
- require 'action_view/template/resolver'
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/template/resolver"
2
4
 
3
5
  module ActionView #:nodoc:
4
6
  # Use FixtureResolver in your tests to simulate the presence of files on the
5
7
  # file system. This is used internally by Rails' own test suite, and is
6
8
  # useful for testing extensions that have no way of knowing what the file
7
9
  # system will look like at runtime.
8
- class FixtureResolver < PathResolver
9
- attr_reader :hash
10
-
11
- def initialize(hash = {}, pattern=nil)
12
- super(pattern)
10
+ class FixtureResolver < OptimizedFileSystemResolver
11
+ def initialize(hash = {})
12
+ super("")
13
13
  @hash = hash
14
+ @path = ""
14
15
  end
15
16
 
16
- def to_s
17
- @hash.keys.join(', ')
17
+ def data
18
+ @hash
18
19
  end
19
20
 
20
- private
21
+ def to_s
22
+ @hash.keys.join(", ")
23
+ end
21
24
 
22
- def query(path, exts, formats)
23
- query = ""
24
- EXTENSIONS.each_key do |ext|
25
- query << '(' << exts[ext].map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)'
25
+ private
26
+ def find_candidate_template_paths(path)
27
+ @hash.keys.select do |fixture|
28
+ fixture.start_with?(path.virtual)
29
+ end.map do |fixture|
30
+ "/#{fixture}"
31
+ end
26
32
  end
27
- query = /^(#{Regexp.escape(path)})#{query}$/
28
33
 
29
- templates = []
30
- @hash.each do |_path, array|
31
- source, updated_at = array
32
- next unless _path =~ query
33
- handler, format, variant = extract_handler_and_format_and_variant(_path, formats)
34
- templates << Template.new(source, _path, handler,
35
- :virtual_path => path.virtual,
36
- :format => format,
37
- :variant => variant,
38
- :updated_at => updated_at
39
- )
34
+ def source_for_template(template)
35
+ @hash[template[1..template.size]]
40
36
  end
41
-
42
- templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
43
- end
44
37
  end
45
38
 
46
39
  class NullResolver < PathResolver
47
- def query(path, exts, formats)
48
- handler, format, variant = extract_handler_and_format_and_variant(path, formats)
49
- [ActionView::Template.new("Template generated by Null Resolver", path, handler, :virtual_path => path, :format => format, :variant => variant)]
40
+ def query(path, exts, _, locals, cache:)
41
+ handler, format, variant = extract_handler_and_format_and_variant(path)
42
+ [ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: format, variant: variant, locals: locals)]
50
43
  end
51
44
  end
52
-
53
45
  end
54
-
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+
5
+ module ActionView
6
+ class UnboundTemplate
7
+ def initialize(source, identifier, handler, options)
8
+ @source = source
9
+ @identifier = identifier
10
+ @handler = handler
11
+ @options = options
12
+
13
+ @templates = Concurrent::Map.new(initial_capacity: 2)
14
+ end
15
+
16
+ def bind_locals(locals)
17
+ @templates[locals] ||= build_template(locals)
18
+ end
19
+
20
+ private
21
+ def build_template(locals)
22
+ options = @options.merge(locals: locals)
23
+ Template.new(
24
+ @source,
25
+ @identifier,
26
+ @handler,
27
+ **options
28
+ )
29
+ end
30
+ end
31
+ end
@@ -1,4 +1,6 @@
1
- require_relative 'gem_version'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gem_version"
2
4
 
3
5
  module ActionView
4
6
  # Returns the version of the currently loaded ActionView as a <tt>Gem::Version</tt>
@@ -1,63 +1,33 @@
1
- require 'action_view/base'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActionView
4
4
  module ViewPaths
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- class_attribute :_view_paths
9
- self._view_paths = ActionView::PathSet.new
10
- self._view_paths.freeze
8
+ ViewPaths.set_view_paths(self, ActionView::PathSet.new.freeze)
11
9
  end
12
10
 
13
- delegate :template_exists?, :view_paths, :formats, :formats=,
14
- :locale, :locale=, :to => :lookup_context
11
+ delegate :template_exists?, :any_templates?, :view_paths, :formats, :formats=,
12
+ :locale, :locale=, to: :lookup_context
15
13
 
16
14
  module ClassMethods
17
- def parent_prefixes
18
- @parent_prefixes ||= begin
19
- parent_controller = superclass
20
- prefixes = []
21
-
22
- until parent_controller.abstract?
23
- prefixes << parent_controller.controller_path
24
- parent_controller = parent_controller.superclass
25
- end
26
-
27
- prefixes
28
- end
15
+ def _view_paths
16
+ ViewPaths.get_view_paths(self)
29
17
  end
30
- end
31
18
 
32
- # The prefixes used in render "foo" shortcuts.
33
- def _prefixes
34
- @_prefixes ||= begin
35
- parent_prefixes = self.class.parent_prefixes
36
- parent_prefixes.dup.unshift(controller_path)
19
+ def _view_paths=(paths)
20
+ ViewPaths.set_view_paths(self, paths)
37
21
  end
38
- end
39
-
40
- # LookupContext is the object responsible to hold all information required to lookup
41
- # templates, i.e. view paths and details. Check ActionView::LookupContext for more
42
- # information.
43
- def lookup_context
44
- @_lookup_context ||=
45
- ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
46
- end
47
-
48
- def details_for_lookup
49
- { }
50
- end
51
22
 
52
- def append_view_path(path)
53
- lookup_context.view_paths.push(*path)
54
- end
23
+ def _prefixes # :nodoc:
24
+ @_prefixes ||= begin
25
+ return local_prefixes if superclass.abstract?
55
26
 
56
- def prepend_view_path(path)
57
- lookup_context.view_paths.unshift(*path)
58
- end
27
+ local_prefixes + superclass._prefixes
28
+ end
29
+ end
59
30
 
60
- module ClassMethods
61
31
  # Append a path to the list of view paths for this controller.
62
32
  #
63
33
  # ==== Parameters
@@ -91,6 +61,66 @@ module ActionView
91
61
  def view_paths=(paths)
92
62
  self._view_paths = ActionView::PathSet.new(Array(paths))
93
63
  end
64
+
65
+ private
66
+ # Override this method in your controller if you want to change paths prefixes for finding views.
67
+ # Prefixes defined here will still be added to parents' <tt>._prefixes</tt>.
68
+ def local_prefixes
69
+ [controller_path]
70
+ end
71
+ end
72
+
73
+ # :stopdoc:
74
+ @all_view_paths = {}
75
+
76
+ def self.get_view_paths(klass)
77
+ @all_view_paths[klass] || get_view_paths(klass.superclass)
78
+ end
79
+
80
+ def self.set_view_paths(klass, paths)
81
+ @all_view_paths[klass] = paths
82
+ end
83
+
84
+ def self.all_view_paths
85
+ @all_view_paths.values.uniq
86
+ end
87
+ # :startdoc:
88
+
89
+ # The prefixes used in render "foo" shortcuts.
90
+ def _prefixes # :nodoc:
91
+ self.class._prefixes
92
+ end
93
+
94
+ # <tt>LookupContext</tt> is the object responsible for holding all
95
+ # information required for looking up templates, i.e. view paths and
96
+ # details. Check <tt>ActionView::LookupContext</tt> for more information.
97
+ def lookup_context
98
+ @_lookup_context ||=
99
+ ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
100
+ end
101
+
102
+ def details_for_lookup
103
+ {}
104
+ end
105
+
106
+ # Append a path to the list of view paths for the current <tt>LookupContext</tt>.
107
+ #
108
+ # ==== Parameters
109
+ # * <tt>path</tt> - If a String is provided, it gets converted into
110
+ # the default view path. You may also provide a custom view path
111
+ # (see ActionView::PathSet for more information)
112
+ def append_view_path(path)
113
+ lookup_context.view_paths.push(*path)
114
+ end
115
+
116
+ # Prepend a path to the list of view paths for the current <tt>LookupContext</tt>.
117
+ #
118
+ # ==== Parameters
119
+ # * <tt>path</tt> - If a String is provided, it gets converted into
120
+ # the default view path. You may also provide a custom view path
121
+ # (see ActionView::PathSet for more information)
122
+ def prepend_view_path(path)
123
+ lookup_context.view_paths.unshift(*path)
94
124
  end
95
125
  end
96
126
  end