actionpack 3.2.22.5 → 4.0.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 actionpack might be problematic. Click here for more details.

Files changed (265) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +641 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller.rb +1 -8
  6. data/lib/abstract_controller/asset_paths.rb +2 -2
  7. data/lib/abstract_controller/base.rb +39 -37
  8. data/lib/abstract_controller/callbacks.rb +101 -82
  9. data/lib/abstract_controller/collector.rb +7 -3
  10. data/lib/abstract_controller/helpers.rb +23 -11
  11. data/lib/abstract_controller/layouts.rb +68 -73
  12. data/lib/abstract_controller/logger.rb +1 -2
  13. data/lib/abstract_controller/rendering.rb +22 -13
  14. data/lib/abstract_controller/translation.rb +16 -1
  15. data/lib/abstract_controller/url_for.rb +6 -6
  16. data/lib/abstract_controller/view_paths.rb +1 -1
  17. data/lib/action_controller.rb +15 -6
  18. data/lib/action_controller/base.rb +46 -22
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/caching/fragments.rb +23 -53
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  23. data/lib/action_controller/log_subscriber.rb +11 -8
  24. data/lib/action_controller/metal.rb +16 -30
  25. data/lib/action_controller/metal/conditional_get.rb +76 -32
  26. data/lib/action_controller/metal/data_streaming.rb +20 -26
  27. data/lib/action_controller/metal/exceptions.rb +19 -6
  28. data/lib/action_controller/metal/flash.rb +24 -9
  29. data/lib/action_controller/metal/force_ssl.rb +32 -9
  30. data/lib/action_controller/metal/head.rb +25 -4
  31. data/lib/action_controller/metal/helpers.rb +6 -9
  32. data/lib/action_controller/metal/hide_actions.rb +1 -2
  33. data/lib/action_controller/metal/http_authentication.rb +105 -87
  34. data/lib/action_controller/metal/implicit_render.rb +1 -1
  35. data/lib/action_controller/metal/instrumentation.rb +2 -1
  36. data/lib/action_controller/metal/live.rb +141 -0
  37. data/lib/action_controller/metal/mime_responds.rb +161 -47
  38. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  39. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  40. data/lib/action_controller/metal/redirecting.rb +15 -20
  41. data/lib/action_controller/metal/renderers.rb +11 -9
  42. data/lib/action_controller/metal/rendering.rb +8 -0
  43. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  44. data/lib/action_controller/metal/responder.rb +20 -19
  45. data/lib/action_controller/metal/streaming.rb +12 -18
  46. data/lib/action_controller/metal/strong_parameters.rb +516 -0
  47. data/lib/action_controller/metal/testing.rb +13 -18
  48. data/lib/action_controller/metal/url_for.rb +27 -25
  49. data/lib/action_controller/model_naming.rb +12 -0
  50. data/lib/action_controller/railtie.rb +33 -17
  51. data/lib/action_controller/railties/helpers.rb +22 -0
  52. data/lib/action_controller/record_identifier.rb +18 -72
  53. data/lib/action_controller/test_case.rb +215 -123
  54. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  55. data/lib/action_dispatch.rb +27 -19
  56. data/lib/action_dispatch/http/cache.rb +63 -11
  57. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  58. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  59. data/lib/action_dispatch/http/headers.rb +27 -19
  60. data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
  61. data/lib/action_dispatch/http/mime_type.rb +145 -113
  62. data/lib/action_dispatch/http/mime_types.rb +1 -1
  63. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  64. data/lib/action_dispatch/http/parameters.rb +12 -5
  65. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  66. data/lib/action_dispatch/http/request.rb +49 -18
  67. data/lib/action_dispatch/http/response.rb +129 -35
  68. data/lib/action_dispatch/http/upload.rb +60 -17
  69. data/lib/action_dispatch/http/url.rb +53 -31
  70. data/lib/action_dispatch/journey.rb +5 -0
  71. data/lib/action_dispatch/journey/backwards.rb +5 -0
  72. data/lib/action_dispatch/journey/formatter.rb +146 -0
  73. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  74. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  75. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  76. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  77. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  78. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  79. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  80. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  81. data/lib/action_dispatch/journey/parser.rb +206 -0
  82. data/lib/action_dispatch/journey/parser.y +47 -0
  83. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  84. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  85. data/lib/action_dispatch/journey/route.rb +116 -0
  86. data/lib/action_dispatch/journey/router.rb +164 -0
  87. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  88. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  89. data/lib/action_dispatch/journey/routes.rb +75 -0
  90. data/lib/action_dispatch/journey/scanner.rb +61 -0
  91. data/lib/action_dispatch/journey/visitors.rb +189 -0
  92. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  93. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  94. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  95. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  96. data/lib/action_dispatch/middleware/cookies.rb +168 -57
  97. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  98. data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
  99. data/lib/action_dispatch/middleware/flash.rb +58 -58
  100. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  101. data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
  102. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  103. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  104. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  105. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  106. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  107. data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
  108. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  109. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  110. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  111. data/lib/action_dispatch/middleware/stack.rb +6 -1
  112. data/lib/action_dispatch/middleware/static.rb +5 -24
  113. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  114. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  115. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
  116. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  117. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  122. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  124. data/lib/action_dispatch/railtie.rb +16 -6
  125. data/lib/action_dispatch/request/session.rb +181 -0
  126. data/lib/action_dispatch/routing.rb +41 -40
  127. data/lib/action_dispatch/routing/inspector.rb +240 -0
  128. data/lib/action_dispatch/routing/mapper.rb +501 -273
  129. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  130. data/lib/action_dispatch/routing/redirection.rb +46 -29
  131. data/lib/action_dispatch/routing/route_set.rb +203 -164
  132. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  133. data/lib/action_dispatch/routing/url_for.rb +48 -33
  134. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  135. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  136. data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
  137. data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
  138. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  139. data/lib/action_dispatch/testing/integration.rb +41 -22
  140. data/lib/action_dispatch/testing/test_process.rb +9 -6
  141. data/lib/action_dispatch/testing/test_request.rb +7 -3
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_pack/version.rb +4 -4
  144. data/lib/action_view.rb +17 -8
  145. data/lib/action_view/base.rb +15 -34
  146. data/lib/action_view/buffers.rb +1 -1
  147. data/lib/action_view/context.rb +4 -4
  148. data/lib/action_view/dependency_tracker.rb +91 -0
  149. data/lib/action_view/digestor.rb +85 -0
  150. data/lib/action_view/flows.rb +1 -4
  151. data/lib/action_view/helpers.rb +2 -4
  152. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  153. data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
  154. data/lib/action_view/helpers/asset_url_helper.rb +354 -0
  155. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  156. data/lib/action_view/helpers/cache_helper.rb +150 -18
  157. data/lib/action_view/helpers/capture_helper.rb +42 -29
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  159. data/lib/action_view/helpers/date_helper.rb +268 -247
  160. data/lib/action_view/helpers/debug_helper.rb +10 -11
  161. data/lib/action_view/helpers/form_helper.rb +904 -547
  162. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  163. data/lib/action_view/helpers/form_tag_helper.rb +188 -88
  164. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  165. data/lib/action_view/helpers/number_helper.rb +148 -354
  166. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  167. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  168. data/lib/action_view/helpers/rendering_helper.rb +2 -4
  169. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  170. data/lib/action_view/helpers/tag_helper.rb +43 -37
  171. data/lib/action_view/helpers/tags.rb +39 -0
  172. data/lib/action_view/helpers/tags/base.rb +148 -0
  173. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  174. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  175. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  176. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  177. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  178. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  179. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  180. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  181. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  182. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  183. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  184. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  185. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  186. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  187. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  188. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  189. data/lib/action_view/helpers/tags/label.rb +65 -0
  190. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  191. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  192. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  193. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  194. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  195. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  196. data/lib/action_view/helpers/tags/select.rb +41 -0
  197. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  198. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  199. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  200. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  201. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  202. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  203. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  204. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  205. data/lib/action_view/helpers/text_helper.rb +126 -113
  206. data/lib/action_view/helpers/translation_helper.rb +32 -16
  207. data/lib/action_view/helpers/url_helper.rb +200 -271
  208. data/lib/action_view/locale/en.yml +1 -105
  209. data/lib/action_view/log_subscriber.rb +6 -4
  210. data/lib/action_view/lookup_context.rb +15 -39
  211. data/lib/action_view/model_naming.rb +12 -0
  212. data/lib/action_view/path_set.rb +9 -39
  213. data/lib/action_view/railtie.rb +6 -22
  214. data/lib/action_view/record_identifier.rb +84 -0
  215. data/lib/action_view/renderer/abstract_renderer.rb +10 -19
  216. data/lib/action_view/renderer/partial_renderer.rb +144 -81
  217. data/lib/action_view/renderer/renderer.rb +2 -19
  218. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  219. data/lib/action_view/renderer/template_renderer.rb +14 -13
  220. data/lib/action_view/routing_url_for.rb +107 -0
  221. data/lib/action_view/template.rb +22 -21
  222. data/lib/action_view/template/error.rb +22 -12
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/handlers/builder.rb +1 -1
  225. data/lib/action_view/template/handlers/erb.rb +11 -16
  226. data/lib/action_view/template/handlers/raw.rb +11 -0
  227. data/lib/action_view/template/resolver.rb +111 -83
  228. data/lib/action_view/template/text.rb +12 -8
  229. data/lib/action_view/template/types.rb +57 -0
  230. data/lib/action_view/test_case.rb +66 -43
  231. data/lib/action_view/testing/resolvers.rb +3 -2
  232. data/lib/action_view/vendor/html-scanner.rb +20 -0
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  235. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
  236. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
  237. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  238. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  239. metadata +135 -125
  240. data/lib/action_controller/caching/actions.rb +0 -185
  241. data/lib/action_controller/caching/pages.rb +0 -187
  242. data/lib/action_controller/caching/sweeping.rb +0 -97
  243. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  244. data/lib/action_controller/metal/compatibility.rb +0 -65
  245. data/lib/action_controller/metal/session_management.rb +0 -14
  246. data/lib/action_controller/railties/paths.rb +0 -25
  247. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  248. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  249. data/lib/action_dispatch/middleware/head.rb +0 -18
  250. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  251. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  252. data/lib/action_view/asset_paths.rb +0 -142
  253. data/lib/action_view/helpers/asset_paths.rb +0 -7
  254. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  255. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  256. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  257. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  258. data/lib/sprockets/assets.rake +0 -99
  259. data/lib/sprockets/bootstrap.rb +0 -37
  260. data/lib/sprockets/compressors.rb +0 -83
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  263. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  264. data/lib/sprockets/railtie.rb +0 -62
  265. data/lib/sprockets/static_compiler.rb +0 -56
@@ -3,7 +3,7 @@ module ActionView
3
3
  class Builder
4
4
  # Default format used by Builder.
5
5
  class_attribute :default_format
6
- self.default_format = Mime::XML
6
+ self.default_format = :xml
7
7
 
8
8
  def call(template)
9
9
  require_engine
@@ -1,5 +1,4 @@
1
1
  require 'action_dispatch/http/mime_type'
2
- require 'active_support/core_ext/class/attribute'
3
2
  require 'erubis'
4
3
 
5
4
  module ActionView
@@ -78,27 +77,23 @@ module ActionView
78
77
  end
79
78
 
80
79
  def call(template)
81
- if template.source.encoding_aware?
82
- # First, convert to BINARY, so in case the encoding is
83
- # wrong, we can still find an encoding tag
84
- # (<%# encoding %>) inside the String using a regular
85
- # expression
86
- template_source = template.source.dup.force_encoding("BINARY")
80
+ # First, convert to BINARY, so in case the encoding is
81
+ # wrong, we can still find an encoding tag
82
+ # (<%# encoding %>) inside the String using a regular
83
+ # expression
84
+ template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)
87
85
 
88
- erb = template_source.gsub(ENCODING_TAG, '')
89
- encoding = $2
86
+ erb = template_source.gsub(ENCODING_TAG, '')
87
+ encoding = $2
90
88
 
91
- erb.force_encoding valid_encoding(template.source.dup, encoding)
89
+ erb.force_encoding valid_encoding(template.source.dup, encoding)
92
90
 
93
- # Always make sure we return a String in the default_internal
94
- erb.encode!
95
- else
96
- erb = template.source.dup
97
- end
91
+ # Always make sure we return a String in the default_internal
92
+ erb.encode!
98
93
 
99
94
  self.class.erb_implementation.new(
100
95
  erb,
101
- :escape => (self.class.escape_whitelist.include? template.mime_type),
96
+ :escape => (self.class.escape_whitelist.include? template.type),
102
97
  :trim => (self.class.erb_trim_mode == "-")
103
98
  ).src
104
99
  end
@@ -0,0 +1,11 @@
1
+ module ActionView
2
+ module Template::Handlers
3
+ class Raw
4
+ def call(template)
5
+ escaped = template.source.gsub(':', '\:')
6
+
7
+ '%q:' + escaped + ':;'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,14 +1,15 @@
1
1
  require "pathname"
2
2
  require "active_support/core_ext/class"
3
- require "active_support/core_ext/io"
4
- require "active_support/core_ext/string/starts_ends_with"
3
+ require "active_support/core_ext/class/attribute_accessors"
5
4
  require "action_view/template"
5
+ require "thread"
6
+ require "thread_safe"
6
7
 
7
8
  module ActionView
8
9
  # = Action View Resolver
9
10
  class Resolver
10
11
  # Keeps all information about view path and builds virtual path.
11
- class Path < String
12
+ class Path
12
13
  attr_reader :name, :prefix, :partial, :virtual
13
14
  alias_method :partial?, :partial
14
15
 
@@ -20,8 +21,76 @@ module ActionView
20
21
  end
21
22
 
22
23
  def initialize(name, prefix, partial, virtual)
23
- @name, @prefix, @partial = name, prefix, partial
24
- super(virtual)
24
+ @name = name
25
+ @prefix = prefix
26
+ @partial = partial
27
+ @virtual = virtual
28
+ end
29
+
30
+ def to_str
31
+ @virtual
32
+ end
33
+ alias :to_s :to_str
34
+ end
35
+
36
+ # Threadsafe template cache
37
+ class Cache #:nodoc:
38
+ class SmallCache < ThreadSafe::Cache
39
+ def initialize(options = {})
40
+ super(options.merge(:initial_capacity => 2))
41
+ end
42
+ end
43
+
44
+ # preallocate all the default blocks for performance/memory consumption reasons
45
+ PARTIAL_BLOCK = lambda {|cache, partial| cache[partial] = SmallCache.new}
46
+ PREFIX_BLOCK = lambda {|cache, prefix| cache[prefix] = SmallCache.new(&PARTIAL_BLOCK)}
47
+ NAME_BLOCK = lambda {|cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK)}
48
+ KEY_BLOCK = lambda {|cache, key| cache[key] = SmallCache.new(&NAME_BLOCK)}
49
+
50
+ # usually a majority of template look ups return nothing, use this canonical preallocated array to safe memory
51
+ NO_TEMPLATES = [].freeze
52
+
53
+ def initialize
54
+ @data = SmallCache.new(&KEY_BLOCK)
55
+ end
56
+
57
+ # Cache the templates returned by the block
58
+ def cache(key, name, prefix, partial, locals)
59
+ if Resolver.caching?
60
+ @data[key][name][prefix][partial][locals] ||= canonical_no_templates(yield)
61
+ else
62
+ fresh_templates = yield
63
+ cached_templates = @data[key][name][prefix][partial][locals]
64
+
65
+ if templates_have_changed?(cached_templates, fresh_templates)
66
+ @data[key][name][prefix][partial][locals] = canonical_no_templates(fresh_templates)
67
+ else
68
+ cached_templates || NO_TEMPLATES
69
+ end
70
+ end
71
+ end
72
+
73
+ def clear
74
+ @data.clear
75
+ end
76
+
77
+ private
78
+
79
+ def canonical_no_templates(templates)
80
+ templates.empty? ? NO_TEMPLATES : templates
81
+ end
82
+
83
+ def templates_have_changed?(cached_templates, fresh_templates)
84
+ # if either the old or new template list is empty, we don't need to (and can't)
85
+ # compare modification times, and instead just check whether the lists are different
86
+ if cached_templates.blank? || fresh_templates.blank?
87
+ return fresh_templates.blank? != cached_templates.blank?
88
+ end
89
+
90
+ cached_templates_max_updated_at = cached_templates.map(&:updated_at).max
91
+
92
+ # if a template has changed, it will be now be newer than all the cached templates
93
+ fresh_templates.any? { |t| t.updated_at > cached_templates_max_updated_at }
25
94
  end
26
95
  end
27
96
 
@@ -33,36 +102,29 @@ module ActionView
33
102
  end
34
103
 
35
104
  def initialize
36
- @cached = Hash.new { |h1,k1| h1[k1] = Hash.new { |h2,k2|
37
- h2[k2] = Hash.new { |h3,k3| h3[k3] = Hash.new { |h4,k4| h4[k4] = {} } } } }
105
+ @cache = Cache.new
38
106
  end
39
107
 
40
108
  def clear_cache
41
- @cached.clear
109
+ @cache.clear
42
110
  end
43
111
 
44
112
  # Normalizes the arguments and passes it on to find_template.
45
113
  def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
46
114
  cached(key, [name, prefix, partial], details, locals) do
47
- find_templates(name, prefix, partial, details, false)
48
- end
49
- end
50
-
51
- def find_all_anywhere(name, prefix, partial=false, details={}, key=nil, locals=[])
52
- cached(key, [name, prefix, partial], details, locals) do
53
- find_templates(name, prefix, partial, details, true)
115
+ find_templates(name, prefix, partial, details)
54
116
  end
55
117
  end
56
118
 
57
119
  private
58
120
 
59
- delegate :caching?, :to => "self.class"
121
+ delegate :caching?, to: :class
60
122
 
61
123
  # This is what child classes implement. No defaults are needed
62
124
  # because Resolver guarantees that the arguments are present and
63
125
  # normalized.
64
- def find_templates(name, prefix, partial, details, outside_app_allowed = false)
65
- raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details, outside_app_allowed) method"
126
+ def find_templates(name, prefix, partial, details)
127
+ raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details) method"
66
128
  end
67
129
 
68
130
  # Helpers that builds a path. Useful for building virtual paths.
@@ -72,27 +134,18 @@ module ActionView
72
134
 
73
135
  # Handles templates caching. If a key is given and caching is on
74
136
  # always check the cache before hitting the resolver. Otherwise,
75
- # it always hits the resolver but check if the resolver is fresher
76
- # before returning it.
137
+ # it always hits the resolver but if the key is present, check if the
138
+ # resolver is fresher before returning it.
77
139
  def cached(key, path_info, details, locals) #:nodoc:
78
140
  name, prefix, partial = path_info
79
141
  locals = locals.map { |x| x.to_s }.sort!
80
142
 
81
- if key && caching?
82
- @cached[key][name][prefix][partial][locals] ||= decorate(yield, path_info, details, locals)
83
- else
84
- fresh = decorate(yield, path_info, details, locals)
85
- return fresh unless key
86
-
87
- scope = @cached[key][name][prefix][partial]
88
- cache = scope[locals]
89
- mtime = cache && cache.map(&:updated_at).max
90
-
91
- if !mtime || fresh.empty? || fresh.any? { |t| t.updated_at > mtime }
92
- scope[locals] = fresh
93
- else
94
- cache
143
+ if key
144
+ @cache.cache(key, name, prefix, partial, locals) do
145
+ decorate(yield, path_info, details, locals)
95
146
  end
147
+ else
148
+ decorate(yield, path_info, details, locals)
96
149
  end
97
150
  end
98
151
 
@@ -117,21 +170,23 @@ module ActionView
117
170
  super()
118
171
  end
119
172
 
120
- cattr_accessor :instance_reader => false, :instance_writer => false
121
-
122
173
  private
123
174
 
124
- def find_templates(name, prefix, partial, details, outside_app_allowed = false)
175
+ def find_templates(name, prefix, partial, details)
125
176
  path = Path.build(name, prefix, partial)
126
- query(path, details, details[:formats], outside_app_allowed)
177
+ query(path, details, details[:formats])
127
178
  end
128
179
 
129
- def query(path, details, formats, outside_app_allowed)
180
+ def query(path, details, formats)
130
181
  query = build_query(path, details)
131
182
 
132
- template_paths = find_template_paths query
183
+ # deals with case-insensitive file systems.
184
+ sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] }
133
185
 
134
- template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed
186
+ template_paths = Dir[query].reject { |filename|
187
+ File.directory?(filename) ||
188
+ !sanitizer[File.dirname(filename)].include?(filename)
189
+ }
135
190
 
136
191
  template_paths.map { |template|
137
192
  handler, format = extract_handler_and_format(template, formats)
@@ -144,36 +199,6 @@ module ActionView
144
199
  }
145
200
  end
146
201
 
147
- def reject_files_external_to_app(files)
148
- files.reject { |filename| !inside_path?(@path, filename) }
149
- end
150
-
151
- if RUBY_VERSION >= '2.2.0'
152
- def find_template_paths(query)
153
- Dir[query].reject { |filename|
154
- File.directory?(filename) ||
155
- # deals with case-insensitive file systems.
156
- !File.fnmatch(query, filename, File::FNM_EXTGLOB)
157
- }
158
- end
159
- else
160
- def find_template_paths(query)
161
- # deals with case-insensitive file systems.
162
- sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] }
163
-
164
- Dir[query].reject { |filename|
165
- File.directory?(filename) ||
166
- !sanitizer[File.dirname(filename)].include?(filename)
167
- }
168
- end
169
- end
170
-
171
- def inside_path?(path, filename)
172
- filename = File.expand_path(filename)
173
- path = File.join(path, '')
174
- filename.start_with?(path)
175
- end
176
-
177
202
  # Helper for building query glob string based on resolver's pattern.
178
203
  def build_query(path, details)
179
204
  query = @pattern.dup
@@ -206,13 +231,21 @@ module ActionView
206
231
  def extract_handler_and_format(path, default_formats)
207
232
  pieces = File.basename(path).split(".")
208
233
  pieces.shift
209
- handler = Template.handler_for_extension(pieces.pop)
210
- format = pieces.last && Mime[pieces.last]
234
+
235
+ extension = pieces.pop
236
+ unless extension
237
+ message = "The file #{path} did not specify a template handler. The default is currently ERB, " \
238
+ "but will change to RAW in the future."
239
+ ActiveSupport::Deprecation.warn message
240
+ end
241
+
242
+ handler = Template.handler_for_extension(extension)
243
+ format = pieces.last && Template::Types[pieces.last]
211
244
  [handler, format]
212
245
  end
213
246
  end
214
247
 
215
- # A resolver that loads files from the filesystem. It allows to set your own
248
+ # A resolver that loads files from the filesystem. It allows setting your own
216
249
  # resolving pattern. Such pattern can be a glob string supported by some variables.
217
250
  #
218
251
  # ==== Examples
@@ -228,7 +261,7 @@ module ActionView
228
261
  #
229
262
  # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{.:handlers,}")
230
263
  #
231
- # If you don't specify pattern then the default will be used.
264
+ # If you don't specify a pattern then the default will be used.
232
265
  #
233
266
  # In order to use any of the customized resolvers above in a Rails application, you just need
234
267
  # to configure ActionController::Base.view_paths in an initializer, for example:
@@ -240,10 +273,10 @@ module ActionView
240
273
  #
241
274
  # ==== Pattern format and variables
242
275
  #
243
- # Pattern have to be a valid glob string, and it allows you to use the
276
+ # Pattern has to be a valid glob string, and it allows you to use the
244
277
  # following variables:
245
278
  #
246
- # * <tt>:prefix</tt> - usualy the controller path
279
+ # * <tt>:prefix</tt> - usually the controller path
247
280
  # * <tt>:action</tt> - name of the action
248
281
  # * <tt>:locale</tt> - possible locale versions
249
282
  # * <tt>:formats</tt> - possible request formats (for example html, json, xml...)
@@ -271,12 +304,7 @@ module ActionView
271
304
  class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
272
305
  def build_query(path, details)
273
306
  exts = EXTENSIONS.map { |ext| details[ext] }
274
-
275
- if path.to_s.starts_with? @path.to_s
276
- query = escape_entry(path)
277
- else
278
- query = escape_entry(File.join(@path, path))
279
- end
307
+ query = escape_entry(File.join(@path, path))
280
308
 
281
309
  query + exts.map { |ext|
282
310
  "{#{ext.compact.uniq.map { |e| ".#{e}," }.join}}"
@@ -1,13 +1,13 @@
1
1
  module ActionView #:nodoc:
2
2
  # = Action View Text Template
3
3
  class Template
4
- class Text < String #:nodoc:
5
- attr_accessor :mime_type
4
+ class Text #:nodoc:
5
+ attr_accessor :type
6
6
 
7
- def initialize(string, mime_type = nil)
8
- super(string.to_s)
9
- @mime_type = Mime[mime_type] || mime_type if mime_type
10
- @mime_type ||= Mime::TEXT
7
+ def initialize(string, type = nil)
8
+ @string = string.to_s
9
+ @type = Types[type] || type if type
10
+ @type ||= Types[:text]
11
11
  end
12
12
 
13
13
  def identifier
@@ -18,12 +18,16 @@ module ActionView #:nodoc:
18
18
  'text template'
19
19
  end
20
20
 
21
+ def to_str
22
+ @string
23
+ end
24
+
21
25
  def render(*args)
22
- to_s
26
+ to_str
23
27
  end
24
28
 
25
29
  def formats
26
- [@mime_type.respond_to?(:ref) ? @mime_type.ref : @mime_type.to_s]
30
+ [@type.to_sym]
27
31
  end
28
32
  end
29
33
  end
@@ -0,0 +1,57 @@
1
+ require 'set'
2
+ require 'active_support/core_ext/class/attribute_accessors'
3
+
4
+ module ActionView
5
+ class Template
6
+ class Types
7
+ class Type
8
+ cattr_accessor :types
9
+ self.types = Set.new
10
+
11
+ def self.register(*t)
12
+ types.merge(t.map { |type| type.to_s })
13
+ end
14
+
15
+ register :html, :text, :js, :css, :xml, :json
16
+
17
+ def self.[](type)
18
+ return type if type.is_a?(self)
19
+
20
+ if type.is_a?(Symbol) || types.member?(type.to_s)
21
+ new(type)
22
+ end
23
+ end
24
+
25
+ attr_reader :symbol
26
+
27
+ def initialize(symbol)
28
+ @symbol = symbol.to_sym
29
+ end
30
+
31
+ delegate :to_s, :to_sym, :to => :symbol
32
+ alias to_str to_s
33
+
34
+ def ref
35
+ to_sym || to_s
36
+ end
37
+
38
+ def ==(type)
39
+ return false if type.blank?
40
+ symbol.to_sym == type.to_sym
41
+ end
42
+ end
43
+
44
+ cattr_accessor :type_klass
45
+
46
+ def self.delegate_to(klass)
47
+ self.type_klass = klass
48
+ end
49
+
50
+ delegate_to Type
51
+
52
+ def self.[](type)
53
+ type_klass[type]
54
+ end
55
+ end
56
+ end
57
+ end