actionpack 3.2.22.5 → 5.2.4

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 (271) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +279 -603
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -297
  5. data/lib/abstract_controller/asset_paths.rb +4 -2
  6. data/lib/abstract_controller/base.rb +82 -52
  7. data/lib/abstract_controller/caching/fragments.rb +166 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +117 -103
  10. data/lib/abstract_controller/collector.rb +18 -7
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +65 -38
  13. data/lib/abstract_controller/logger.rb +3 -2
  14. data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
  15. data/lib/abstract_controller/rendering.rb +77 -129
  16. data/lib/abstract_controller/translation.rb +21 -3
  17. data/lib/abstract_controller/url_for.rb +9 -7
  18. data/lib/abstract_controller.rb +12 -13
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/base.rb +81 -40
  22. data/lib/action_controller/caching.rb +22 -62
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +30 -18
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +190 -47
  27. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  28. data/lib/action_controller/metal/cookies.rb +3 -3
  29. data/lib/action_controller/metal/data_streaming.rb +40 -65
  30. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  31. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  32. data/lib/action_controller/metal/exceptions.rb +19 -12
  33. data/lib/action_controller/metal/flash.rb +42 -9
  34. data/lib/action_controller/metal/force_ssl.rb +79 -19
  35. data/lib/action_controller/metal/head.rb +35 -10
  36. data/lib/action_controller/metal/helpers.rb +31 -21
  37. data/lib/action_controller/metal/http_authentication.rb +182 -134
  38. data/lib/action_controller/metal/implicit_render.rb +62 -8
  39. data/lib/action_controller/metal/instrumentation.rb +28 -26
  40. data/lib/action_controller/metal/live.rb +312 -0
  41. data/lib/action_controller/metal/mime_responds.rb +159 -163
  42. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  43. data/lib/action_controller/metal/params_wrapper.rb +146 -93
  44. data/lib/action_controller/metal/redirecting.rb +80 -56
  45. data/lib/action_controller/metal/renderers.rb +119 -47
  46. data/lib/action_controller/metal/rendering.rb +89 -32
  47. data/lib/action_controller/metal/request_forgery_protection.rb +373 -41
  48. data/lib/action_controller/metal/rescue.rb +9 -16
  49. data/lib/action_controller/metal/streaming.rb +39 -45
  50. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  51. data/lib/action_controller/metal/testing.rb +8 -29
  52. data/lib/action_controller/metal/url_for.rb +43 -32
  53. data/lib/action_controller/metal.rb +112 -106
  54. data/lib/action_controller/railtie.rb +56 -18
  55. data/lib/action_controller/railties/helpers.rb +24 -0
  56. data/lib/action_controller/renderer.rb +117 -0
  57. data/lib/action_controller/template_assertions.rb +11 -0
  58. data/lib/action_controller/test_case.rb +402 -347
  59. data/lib/action_controller.rb +31 -30
  60. data/lib/action_dispatch/http/cache.rb +133 -34
  61. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +40 -24
  63. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  64. data/lib/action_dispatch/http/headers.rb +117 -16
  65. data/lib/action_dispatch/http/mime_negotiation.rb +98 -33
  66. data/lib/action_dispatch/http/mime_type.rb +198 -146
  67. data/lib/action_dispatch/http/mime_types.rb +22 -7
  68. data/lib/action_dispatch/http/parameter_filter.rb +61 -49
  69. data/lib/action_dispatch/http/parameters.rb +94 -51
  70. data/lib/action_dispatch/http/rack_cache.rb +4 -3
  71. data/lib/action_dispatch/http/request.rb +262 -117
  72. data/lib/action_dispatch/http/response.rb +400 -86
  73. data/lib/action_dispatch/http/upload.rb +66 -29
  74. data/lib/action_dispatch/http/url.rb +232 -60
  75. data/lib/action_dispatch/journey/formatter.rb +189 -0
  76. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  77. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  78. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  79. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  80. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  81. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  82. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  83. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  84. data/lib/action_dispatch/journey/parser.rb +199 -0
  85. data/lib/action_dispatch/journey/parser.y +50 -0
  86. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  87. data/lib/action_dispatch/journey/path/pattern.rb +199 -0
  88. data/lib/action_dispatch/journey/route.rb +203 -0
  89. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  90. data/lib/action_dispatch/journey/router.rb +156 -0
  91. data/lib/action_dispatch/journey/routes.rb +82 -0
  92. data/lib/action_dispatch/journey/scanner.rb +64 -0
  93. data/lib/action_dispatch/journey/visitors.rb +268 -0
  94. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  95. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  96. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  97. data/lib/action_dispatch/journey.rb +7 -0
  98. data/lib/action_dispatch/middleware/callbacks.rb +17 -13
  99. data/lib/action_dispatch/middleware/cookies.rb +494 -162
  100. data/lib/action_dispatch/middleware/debug_exceptions.rb +176 -53
  101. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  102. data/lib/action_dispatch/middleware/exception_wrapper.rb +103 -38
  103. data/lib/action_dispatch/middleware/executor.rb +21 -0
  104. data/lib/action_dispatch/middleware/flash.rb +128 -91
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +43 -16
  106. data/lib/action_dispatch/middleware/reloader.rb +6 -83
  107. data/lib/action_dispatch/middleware/remote_ip.rb +151 -49
  108. data/lib/action_dispatch/middleware/request_id.rb +19 -15
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +38 -34
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -9
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +94 -44
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -4
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +36 -61
  114. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  115. data/lib/action_dispatch/middleware/stack.rb +33 -41
  116. data/lib/action_dispatch/middleware/static.rb +92 -48
  117. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +134 -5
  128. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  136. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  138. data/lib/action_dispatch/railtie.rb +29 -8
  139. data/lib/action_dispatch/request/session.rb +234 -0
  140. data/lib/action_dispatch/request/utils.rb +78 -0
  141. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  142. data/lib/action_dispatch/routing/inspector.rb +225 -0
  143. data/lib/action_dispatch/routing/mapper.rb +1329 -582
  144. data/lib/action_dispatch/routing/polymorphic_routes.rb +237 -94
  145. data/lib/action_dispatch/routing/redirection.rb +120 -50
  146. data/lib/action_dispatch/routing/route_set.rb +545 -322
  147. data/lib/action_dispatch/routing/routes_proxy.rb +37 -7
  148. data/lib/action_dispatch/routing/url_for.rb +103 -34
  149. data/lib/action_dispatch/routing.rb +66 -99
  150. data/lib/action_dispatch/system_test_case.rb +147 -0
  151. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  152. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  153. data/lib/action_dispatch/system_testing/server.rb +31 -0
  154. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  158. data/lib/action_dispatch/testing/assertions/response.rb +53 -42
  159. data/lib/action_dispatch/testing/assertions/routing.rb +79 -74
  160. data/lib/action_dispatch/testing/assertions.rb +15 -9
  161. data/lib/action_dispatch/testing/integration.rb +361 -207
  162. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  163. data/lib/action_dispatch/testing/test_process.rb +28 -19
  164. data/lib/action_dispatch/testing/test_request.rb +30 -33
  165. data/lib/action_dispatch/testing/test_response.rb +35 -11
  166. data/lib/action_dispatch.rb +42 -32
  167. data/lib/action_pack/gem_version.rb +17 -0
  168. data/lib/action_pack/version.rb +7 -7
  169. data/lib/action_pack.rb +4 -2
  170. metadata +116 -175
  171. data/lib/abstract_controller/layouts.rb +0 -423
  172. data/lib/abstract_controller/view_paths.rb +0 -96
  173. data/lib/action_controller/caching/actions.rb +0 -185
  174. data/lib/action_controller/caching/fragments.rb +0 -127
  175. data/lib/action_controller/caching/pages.rb +0 -187
  176. data/lib/action_controller/caching/sweeping.rb +0 -97
  177. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  178. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  179. data/lib/action_controller/deprecated.rb +0 -3
  180. data/lib/action_controller/metal/compatibility.rb +0 -65
  181. data/lib/action_controller/metal/hide_actions.rb +0 -41
  182. data/lib/action_controller/metal/rack_delegation.rb +0 -26
  183. data/lib/action_controller/metal/responder.rb +0 -286
  184. data/lib/action_controller/metal/session_management.rb +0 -14
  185. data/lib/action_controller/middleware.rb +0 -39
  186. data/lib/action_controller/railties/paths.rb +0 -25
  187. data/lib/action_controller/record_identifier.rb +0 -85
  188. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  189. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  190. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  191. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  192. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  193. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  194. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  195. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  196. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  197. data/lib/action_dispatch/middleware/head.rb +0 -18
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -75
  199. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  200. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  201. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  202. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  203. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  204. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  205. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  206. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  207. data/lib/action_dispatch/testing/assertions/dom.rb +0 -37
  208. data/lib/action_dispatch/testing/assertions/selector.rb +0 -435
  209. data/lib/action_dispatch/testing/assertions/tag.rb +0 -138
  210. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  211. data/lib/action_view/asset_paths.rb +0 -142
  212. data/lib/action_view/base.rb +0 -220
  213. data/lib/action_view/buffers.rb +0 -43
  214. data/lib/action_view/context.rb +0 -36
  215. data/lib/action_view/flows.rb +0 -79
  216. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  217. data/lib/action_view/helpers/asset_paths.rb +0 -7
  218. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  219. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  220. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  221. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  222. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  223. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  224. data/lib/action_view/helpers/cache_helper.rb +0 -64
  225. data/lib/action_view/helpers/capture_helper.rb +0 -203
  226. data/lib/action_view/helpers/controller_helper.rb +0 -25
  227. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  228. data/lib/action_view/helpers/date_helper.rb +0 -1062
  229. data/lib/action_view/helpers/debug_helper.rb +0 -40
  230. data/lib/action_view/helpers/form_helper.rb +0 -1486
  231. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  232. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  233. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  234. data/lib/action_view/helpers/number_helper.rb +0 -622
  235. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  236. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  237. data/lib/action_view/helpers/rendering_helper.rb +0 -92
  238. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  239. data/lib/action_view/helpers/tag_helper.rb +0 -167
  240. data/lib/action_view/helpers/text_helper.rb +0 -426
  241. data/lib/action_view/helpers/translation_helper.rb +0 -91
  242. data/lib/action_view/helpers/url_helper.rb +0 -693
  243. data/lib/action_view/helpers.rb +0 -60
  244. data/lib/action_view/locale/en.yml +0 -160
  245. data/lib/action_view/log_subscriber.rb +0 -28
  246. data/lib/action_view/lookup_context.rb +0 -258
  247. data/lib/action_view/path_set.rb +0 -101
  248. data/lib/action_view/railtie.rb +0 -55
  249. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  250. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  251. data/lib/action_view/renderer/renderer.rb +0 -61
  252. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  253. data/lib/action_view/renderer/template_renderer.rb +0 -95
  254. data/lib/action_view/template/error.rb +0 -128
  255. data/lib/action_view/template/handlers/builder.rb +0 -26
  256. data/lib/action_view/template/handlers/erb.rb +0 -125
  257. data/lib/action_view/template/handlers.rb +0 -50
  258. data/lib/action_view/template/resolver.rb +0 -298
  259. data/lib/action_view/template/text.rb +0 -30
  260. data/lib/action_view/template.rb +0 -337
  261. data/lib/action_view/test_case.rb +0 -246
  262. data/lib/action_view/testing/resolvers.rb +0 -49
  263. data/lib/action_view.rb +0 -84
  264. data/lib/sprockets/assets.rake +0 -99
  265. data/lib/sprockets/bootstrap.rb +0 -37
  266. data/lib/sprockets/compressors.rb +0 -83
  267. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  268. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  269. data/lib/sprockets/helpers.rb +0 -6
  270. data/lib/sprockets/railtie.rb +0 -62
  271. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,457 +0,0 @@
1
- require 'action_view/helpers/asset_tag_helpers/javascript_tag_helpers'
2
- require 'action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers'
3
- require 'action_view/helpers/asset_tag_helpers/asset_paths'
4
- require 'action_view/helpers/tag_helper'
5
-
6
- module ActionView
7
- # = Action View Asset Tag Helpers
8
- module Helpers #:nodoc:
9
- # This module provides methods for generating HTML that links views to assets such
10
- # as images, javascripts, stylesheets, and feeds. These methods do not verify
11
- # the assets exist before linking to them:
12
- #
13
- # image_tag("rails.png")
14
- # # => <img alt="Rails" src="/images/rails.png?1230601161" />
15
- # stylesheet_link_tag("application")
16
- # # => <link href="/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
17
- #
18
- # === Using asset hosts
19
- #
20
- # By default, Rails links to these assets on the current host in the public
21
- # folder, but you can direct Rails to link to assets from a dedicated asset
22
- # server by setting ActionController::Base.asset_host in the application
23
- # configuration, typically in <tt>config/environments/production.rb</tt>.
24
- # For example, you'd define <tt>assets.example.com</tt> to be your asset
25
- # host this way:
26
- #
27
- # ActionController::Base.asset_host = "assets.example.com"
28
- #
29
- # Helpers take that into account:
30
- #
31
- # image_tag("rails.png")
32
- # # => <img alt="Rails" src="http://assets.example.com/images/rails.png?1230601161" />
33
- # stylesheet_link_tag("application")
34
- # # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
35
- #
36
- # Browsers typically open at most two simultaneous connections to a single
37
- # host, which means your assets often have to wait for other assets to finish
38
- # downloading. You can alleviate this by using a <tt>%d</tt> wildcard in the
39
- # +asset_host+. For example, "assets%d.example.com". If that wildcard is
40
- # present Rails distributes asset requests among the corresponding four hosts
41
- # "assets0.example.com", ..., "assets3.example.com". With this trick browsers
42
- # will open eight simultaneous connections rather than two.
43
- #
44
- # image_tag("rails.png")
45
- # # => <img alt="Rails" src="http://assets0.example.com/images/rails.png?1230601161" />
46
- # stylesheet_link_tag("application")
47
- # # => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
48
- #
49
- # To do this, you can either setup four actual hosts, or you can use wildcard
50
- # DNS to CNAME the wildcard to a single asset host. You can read more about
51
- # setting up your DNS CNAME records from your ISP.
52
- #
53
- # Note: This is purely a browser performance optimization and is not meant
54
- # for server load balancing. See http://www.die.net/musings/page_load_time/
55
- # for background.
56
- #
57
- # Alternatively, you can exert more control over the asset host by setting
58
- # +asset_host+ to a proc like this:
59
- #
60
- # ActionController::Base.asset_host = Proc.new { |source|
61
- # "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
62
- # }
63
- # image_tag("rails.png")
64
- # # => <img alt="Rails" src="http://assets1.example.com/images/rails.png?1230601161" />
65
- # stylesheet_link_tag("application")
66
- # # => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
67
- #
68
- # The example above generates "http://assets1.example.com" and
69
- # "http://assets2.example.com". This option is useful for example if
70
- # you need fewer/more than four hosts, custom host names, etc.
71
- #
72
- # As you see the proc takes a +source+ parameter. That's a string with the
73
- # absolute path of the asset with any extensions and timestamps in place,
74
- # for example "/images/rails.png?1230601161".
75
- #
76
- # ActionController::Base.asset_host = Proc.new { |source|
77
- # if source.starts_with?('/images')
78
- # "http://images.example.com"
79
- # else
80
- # "http://assets.example.com"
81
- # end
82
- # }
83
- # image_tag("rails.png")
84
- # # => <img alt="Rails" src="http://images.example.com/images/rails.png?1230601161" />
85
- # stylesheet_link_tag("application")
86
- # # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
87
- #
88
- # Alternatively you may ask for a second parameter +request+. That one is
89
- # particularly useful for serving assets from an SSL-protected page. The
90
- # example proc below disables asset hosting for HTTPS connections, while
91
- # still sending assets for plain HTTP requests from asset hosts. If you don't
92
- # have SSL certificates for each of the asset hosts this technique allows you
93
- # to avoid warnings in the client about mixed media.
94
- #
95
- # ActionController::Base.asset_host = Proc.new { |source, request|
96
- # if request.ssl?
97
- # "#{request.protocol}#{request.host_with_port}"
98
- # else
99
- # "#{request.protocol}assets.example.com"
100
- # end
101
- # }
102
- #
103
- # You can also implement a custom asset host object that responds to +call+
104
- # and takes either one or two parameters just like the proc.
105
- #
106
- # config.action_controller.asset_host = AssetHostingWithMinimumSsl.new(
107
- # "http://asset%d.example.com", "https://asset1.example.com"
108
- # )
109
- #
110
- # === Customizing the asset path
111
- #
112
- # By default, Rails appends asset's timestamps to all asset paths. This allows
113
- # you to set a cache-expiration date for the asset far into the future, but
114
- # still be able to instantly invalidate it by simply updating the file (and
115
- # hence updating the timestamp, which then updates the URL as the timestamp
116
- # is part of that, which in turn busts the cache).
117
- #
118
- # It's the responsibility of the web server you use to set the far-future
119
- # expiration date on cache assets that you need to take advantage of this
120
- # feature. Here's an example for Apache:
121
- #
122
- # # Asset Expiration
123
- # ExpiresActive On
124
- # <FilesMatch "\.(ico|gif|jpe?g|png|js|css)$">
125
- # ExpiresDefault "access plus 1 year"
126
- # </FilesMatch>
127
- #
128
- # Also note that in order for this to work, all your application servers must
129
- # return the same timestamps. This means that they must have their clocks
130
- # synchronized. If one of them drifts out of sync, you'll see different
131
- # timestamps at random and the cache won't work. In that case the browser
132
- # will request the same assets over and over again even thought they didn't
133
- # change. You can use something like Live HTTP Headers for Firefox to verify
134
- # that the cache is indeed working.
135
- #
136
- # This strategy works well enough for most server setups and requires the
137
- # least configuration, but if you deploy several application servers at
138
- # different times - say to handle a temporary spike in load - then the
139
- # asset time stamps will be out of sync. In a setup like this you may want
140
- # to set the way that asset paths are generated yourself.
141
- #
142
- # Altering the asset paths that Rails generates can be done in two ways.
143
- # The easiest is to define the RAILS_ASSET_ID environment variable. The
144
- # contents of this variable will always be used in preference to
145
- # calculated timestamps. A more complex but flexible way is to set
146
- # <tt>ActionController::Base.config.asset_path</tt> to a proc
147
- # that takes the unmodified asset path and returns the path needed for
148
- # your asset caching to work. Typically you'd do something like this in
149
- # <tt>config/environments/production.rb</tt>:
150
- #
151
- # # Normally you'd calculate RELEASE_NUMBER at startup.
152
- # RELEASE_NUMBER = 12345
153
- # config.action_controller.asset_path = proc { |asset_path|
154
- # "/release-#{RELEASE_NUMBER}#{asset_path}"
155
- # }
156
- #
157
- # This example would cause the following behavior on all servers no
158
- # matter when they were deployed:
159
- #
160
- # image_tag("rails.png")
161
- # # => <img alt="Rails" src="/release-12345/images/rails.png" />
162
- # stylesheet_link_tag("application")
163
- # # => <link href="/release-12345/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
164
- #
165
- # Changing the asset_path does require that your web servers have
166
- # knowledge of the asset template paths that you rewrite to so it's not
167
- # suitable for out-of-the-box use. To use the example given above you
168
- # could use something like this in your Apache VirtualHost configuration:
169
- #
170
- # <LocationMatch "^/release-\d+/(images|javascripts|stylesheets)/.*$">
171
- # # Some browsers still send conditional-GET requests if there's a
172
- # # Last-Modified header or an ETag header even if they haven't
173
- # # reached the expiry date sent in the Expires header.
174
- # Header unset Last-Modified
175
- # Header unset ETag
176
- # FileETag None
177
- #
178
- # # Assets requested using a cache-busting filename should be served
179
- # # only once and then cached for a really long time. The HTTP/1.1
180
- # # spec frowns on hugely-long expiration times though and suggests
181
- # # that assets which never expire be served with an expiration date
182
- # # 1 year from access.
183
- # ExpiresActive On
184
- # ExpiresDefault "access plus 1 year"
185
- # </LocationMatch>
186
- #
187
- # # We use cached-busting location names with the far-future expires
188
- # # headers to ensure that if a file does change it can force a new
189
- # # request. The actual asset filenames are still the same though so we
190
- # # need to rewrite the location from the cache-busting location to the
191
- # # real asset location so that we can serve it.
192
- # RewriteEngine On
193
- # RewriteRule ^/release-\d+/(images|javascripts|stylesheets)/(.*)$ /$1/$2 [L]
194
- module AssetTagHelper
195
- include TagHelper
196
- include JavascriptTagHelpers
197
- include StylesheetTagHelpers
198
- # Returns a link tag that browsers and news readers can use to auto-detect
199
- # an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or
200
- # <tt>:atom</tt>. Control the link options in url_for format using the
201
- # +url_options+. You can modify the LINK tag itself in +tag_options+.
202
- #
203
- # ==== Options
204
- # * <tt>:rel</tt> - Specify the relation of this link, defaults to "alternate"
205
- # * <tt>:type</tt> - Override the auto-generated mime type
206
- # * <tt>:title</tt> - Specify the title of the link, defaults to the +type+
207
- #
208
- # ==== Examples
209
- # auto_discovery_link_tag # =>
210
- # <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
211
- # auto_discovery_link_tag(:atom) # =>
212
- # <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.currenthost.com/controller/action" />
213
- # auto_discovery_link_tag(:rss, {:action => "feed"}) # =>
214
- # <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/feed" />
215
- # auto_discovery_link_tag(:rss, {:action => "feed"}, {:title => "My RSS"}) # =>
216
- # <link rel="alternate" type="application/rss+xml" title="My RSS" href="http://www.currenthost.com/controller/feed" />
217
- # auto_discovery_link_tag(:rss, {:controller => "news", :action => "feed"}) # =>
218
- # <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/news/feed" />
219
- # auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "Example RSS"}) # =>
220
- # <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed" />
221
- def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
222
- tag(
223
- "link",
224
- "rel" => tag_options[:rel] || "alternate",
225
- "type" => tag_options[:type] || Mime::Type.lookup_by_extension(type.to_s).to_s,
226
- "title" => tag_options[:title] || type.to_s.upcase,
227
- "href" => url_options.is_a?(Hash) ? url_for(url_options.merge(:only_path => false)) : url_options
228
- )
229
- end
230
-
231
- # <%= favicon_link_tag %>
232
- #
233
- # generates
234
- #
235
- # <link href="/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
236
- #
237
- # You may specify a different file in the first argument:
238
- #
239
- # <%= favicon_link_tag '/myicon.ico' %>
240
- #
241
- # That's passed to +path_to_image+ as is, so it gives
242
- #
243
- # <link href="/myicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
244
- #
245
- # The helper accepts an additional options hash where you can override "rel" and "type".
246
- #
247
- # For example, Mobile Safari looks for a different LINK tag, pointing to an image that
248
- # will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad.
249
- # The following call would generate such a tag:
250
- #
251
- # <%= favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png' %>
252
- #
253
- def favicon_link_tag(source='/favicon.ico', options={})
254
- tag('link', {
255
- :rel => 'shortcut icon',
256
- :type => 'image/vnd.microsoft.icon',
257
- :href => path_to_image(source)
258
- }.merge(options.symbolize_keys))
259
- end
260
-
261
- # Computes the path to an image asset in the public images directory.
262
- # Full paths from the document root will be passed through.
263
- # Used internally by +image_tag+ to build the image path:
264
- #
265
- # image_path("edit") # => "/images/edit"
266
- # image_path("edit.png") # => "/images/edit.png"
267
- # image_path("icons/edit.png") # => "/images/icons/edit.png"
268
- # image_path("/icons/edit.png") # => "/icons/edit.png"
269
- # image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png"
270
- #
271
- # If you have images as application resources this method may conflict with their named routes.
272
- # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and
273
- # plugin authors are encouraged to do so.
274
- def image_path(source)
275
- source.present? ? asset_paths.compute_public_path(source, 'images') : ""
276
- end
277
- alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
278
-
279
- # Computes the path to a video asset in the public videos directory.
280
- # Full paths from the document root will be passed through.
281
- # Used internally by +video_tag+ to build the video path.
282
- #
283
- # ==== Examples
284
- # video_path("hd") # => /videos/hd
285
- # video_path("hd.avi") # => /videos/hd.avi
286
- # video_path("trailers/hd.avi") # => /videos/trailers/hd.avi
287
- # video_path("/trailers/hd.avi") # => /trailers/hd.avi
288
- # video_path("http://www.example.com/vid/hd.avi") # => http://www.example.com/vid/hd.avi
289
- def video_path(source)
290
- asset_paths.compute_public_path(source, 'videos')
291
- end
292
- alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route
293
-
294
- # Computes the path to an audio asset in the public audios directory.
295
- # Full paths from the document root will be passed through.
296
- # Used internally by +audio_tag+ to build the audio path.
297
- #
298
- # ==== Examples
299
- # audio_path("horse") # => /audios/horse
300
- # audio_path("horse.wav") # => /audios/horse.wav
301
- # audio_path("sounds/horse.wav") # => /audios/sounds/horse.wav
302
- # audio_path("/sounds/horse.wav") # => /sounds/horse.wav
303
- # audio_path("http://www.example.com/sounds/horse.wav") # => http://www.example.com/sounds/horse.wav
304
- def audio_path(source)
305
- asset_paths.compute_public_path(source, 'audios')
306
- end
307
- alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route
308
-
309
- # Computes the path to a font asset in the public fonts directory.
310
- # Full paths from the document root will be passed through.
311
- #
312
- # ==== Examples
313
- # font_path("font") # => /fonts/font
314
- # font_path("font.ttf") # => /fonts/font.ttf
315
- # font_path("dir/font.ttf") # => /fonts/dir/font.ttf
316
- # font_path("/dir/font.ttf") # => /dir/font.ttf
317
- # font_path("http://www.example.com/dir/font.ttf") # => http://www.example.com/dir/font.ttf
318
- def font_path(source)
319
- asset_paths.compute_public_path(source, 'fonts')
320
- end
321
- alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route
322
-
323
- # Returns an html image tag for the +source+. The +source+ can be a full
324
- # path or a file that exists in your public images directory.
325
- #
326
- # ==== Options
327
- # You can add HTML attributes using the +options+. The +options+ supports
328
- # three additional keys for convenience and conformance:
329
- #
330
- # * <tt>:alt</tt> - If no alt text is given, the file name part of the
331
- # +source+ is used (capitalized and without the extension)
332
- # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
333
- # width="30" and height="45". <tt>:size</tt> will be ignored if the
334
- # value is not in the correct format.
335
- # * <tt>:mouseover</tt> - Set an alternate image to be used when the onmouseover
336
- # event is fired, and sets the original image to be replaced onmouseout.
337
- # This can be used to implement an easy image toggle that fires on onmouseover.
338
- #
339
- # ==== Examples
340
- # image_tag("icon") # =>
341
- # <img src="/images/icon" alt="Icon" />
342
- # image_tag("icon.png") # =>
343
- # <img src="/images/icon.png" alt="Icon" />
344
- # image_tag("icon.png", :size => "16x10", :alt => "Edit Entry") # =>
345
- # <img src="/images/icon.png" width="16" height="10" alt="Edit Entry" />
346
- # image_tag("/icons/icon.gif", :size => "16x16") # =>
347
- # <img src="/icons/icon.gif" width="16" height="16" alt="Icon" />
348
- # image_tag("/icons/icon.gif", :height => '32', :width => '32') # =>
349
- # <img alt="Icon" height="32" src="/icons/icon.gif" width="32" />
350
- # image_tag("/icons/icon.gif", :class => "menu_icon") # =>
351
- # <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
352
- # image_tag("mouse.png", :mouseover => "/images/mouse_over.png") # =>
353
- # <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" />
354
- # image_tag("mouse.png", :mouseover => image_path("mouse_over.png")) # =>
355
- # <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" />
356
- def image_tag(source, options = {})
357
- options.symbolize_keys!
358
-
359
- src = options[:src] = path_to_image(source)
360
-
361
- unless src =~ /^(?:cid|data):/ || src.blank?
362
- options[:alt] = options.fetch(:alt){ image_alt(src) }
363
- end
364
-
365
- if size = options.delete(:size)
366
- options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
367
- end
368
-
369
- if mouseover = options.delete(:mouseover)
370
- options[:onmouseover] = "this.src='#{path_to_image(mouseover)}'"
371
- options[:onmouseout] = "this.src='#{src}'"
372
- end
373
-
374
- tag("img", options)
375
- end
376
-
377
- def image_alt(src)
378
- File.basename(src, '.*').sub(/-[[:xdigit:]]{32}\z/, '').capitalize
379
- end
380
-
381
- # Returns an html video tag for the +sources+. If +sources+ is a string,
382
- # a single video tag will be returned. If +sources+ is an array, a video
383
- # tag with nested source tags for each source will be returned. The
384
- # +sources+ can be full paths or files that exists in your public videos
385
- # directory.
386
- #
387
- # ==== Options
388
- # You can add HTML attributes using the +options+. The +options+ supports
389
- # two additional keys for convenience and conformance:
390
- #
391
- # * <tt>:poster</tt> - Set an image (like a screenshot) to be shown
392
- # before the video loads. The path is calculated like the +src+ of +image_tag+.
393
- # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
394
- # width="30" and height="45". <tt>:size</tt> will be ignored if the
395
- # value is not in the correct format.
396
- #
397
- # ==== Examples
398
- # video_tag("trailer") # =>
399
- # <video src="/videos/trailer" />
400
- # video_tag("trailer.ogg") # =>
401
- # <video src="/videos/trailer.ogg" />
402
- # video_tag("trailer.ogg", :controls => true, :autobuffer => true) # =>
403
- # <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" />
404
- # video_tag("trailer.m4v", :size => "16x10", :poster => "screenshot.png") # =>
405
- # <video src="/videos/trailer.m4v" width="16" height="10" poster="/images/screenshot.png" />
406
- # video_tag("/trailers/hd.avi", :size => "16x16") # =>
407
- # <video src="/trailers/hd.avi" width="16" height="16" />
408
- # video_tag("/trailers/hd.avi", :height => '32', :width => '32') # =>
409
- # <video height="32" src="/trailers/hd.avi" width="32" />
410
- # video_tag(["trailer.ogg", "trailer.flv"]) # =>
411
- # <video><source src="trailer.ogg" /><source src="trailer.ogg" /><source src="trailer.flv" /></video>
412
- # video_tag(["trailer.ogg", "trailer.flv"] :size => "160x120") # =>
413
- # <video height="120" width="160"><source src="trailer.ogg" /><source src="trailer.flv" /></video>
414
- def video_tag(sources, options = {})
415
- options.symbolize_keys!
416
-
417
- options[:poster] = path_to_image(options[:poster]) if options[:poster]
418
-
419
- if size = options.delete(:size)
420
- options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
421
- end
422
-
423
- if sources.is_a?(Array)
424
- content_tag("video", options) do
425
- sources.map { |source| tag("source", :src => source) }.join.html_safe
426
- end
427
- else
428
- options[:src] = path_to_video(sources)
429
- tag("video", options)
430
- end
431
- end
432
-
433
- # Returns an html audio tag for the +source+.
434
- # The +source+ can be full path or file that exists in
435
- # your public audios directory.
436
- #
437
- # ==== Examples
438
- # audio_tag("sound") # =>
439
- # <audio src="/audios/sound" />
440
- # audio_tag("sound.wav") # =>
441
- # <audio src="/audios/sound.wav" />
442
- # audio_tag("sound.wav", :autoplay => true, :controls => true) # =>
443
- # <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav" />
444
- def audio_tag(source, options = {})
445
- options.symbolize_keys!
446
- options[:src] = path_to_audio(source)
447
- tag("audio", options)
448
- end
449
-
450
- private
451
-
452
- def asset_paths
453
- @asset_paths ||= AssetTagHelper::AssetPaths.new(config, controller)
454
- end
455
- end
456
- end
457
- end
@@ -1,146 +0,0 @@
1
- require 'active_support/core_ext/class/attribute'
2
- require 'active_support/core_ext/string/inflections'
3
- require 'active_support/core_ext/file'
4
- require 'action_view/helpers/tag_helper'
5
-
6
- module ActionView
7
- module Helpers
8
- module AssetTagHelper
9
-
10
- class AssetIncludeTag
11
- include TagHelper
12
-
13
- attr_reader :config, :asset_paths
14
- class_attribute :expansions
15
-
16
- def self.inherited(base)
17
- base.expansions = { }
18
- end
19
-
20
- def initialize(config, asset_paths)
21
- @config = config
22
- @asset_paths = asset_paths
23
- end
24
-
25
- def asset_name
26
- raise NotImplementedError
27
- end
28
-
29
- def extension
30
- raise NotImplementedError
31
- end
32
-
33
- def custom_dir
34
- raise NotImplementedError
35
- end
36
-
37
- def asset_tag(source, options)
38
- raise NotImplementedError
39
- end
40
-
41
- def include_tag(*sources)
42
- options = sources.extract_options!.stringify_keys
43
- concat = options.delete("concat")
44
- cache = concat || options.delete("cache")
45
- recursive = options.delete("recursive")
46
-
47
- if concat || (config.perform_caching && cache)
48
- joined_name = (cache == true ? "all" : cache) + ".#{extension}"
49
- joined_path = File.join((joined_name[/^#{File::SEPARATOR}/] ? config.assets_dir : custom_dir), joined_name)
50
- unless config.perform_caching && File.exists?(joined_path)
51
- write_asset_file_contents(joined_path, compute_paths(sources, recursive))
52
- end
53
- asset_tag(joined_name, options)
54
- else
55
- sources = expand_sources(sources, recursive)
56
- ensure_sources!(sources) if cache
57
- sources.collect { |source| asset_tag(source, options) }.join("\n").html_safe
58
- end
59
- end
60
-
61
- private
62
-
63
- def path_to_asset(source, options = {})
64
- asset_paths.compute_public_path(source, asset_name.to_s.pluralize, options.merge(:ext => extension))
65
- end
66
-
67
- def path_to_asset_source(source)
68
- asset_paths.compute_source_path(source, asset_name.to_s.pluralize, extension)
69
- end
70
-
71
- def compute_paths(*args)
72
- expand_sources(*args).collect { |source| path_to_asset_source(source) }
73
- end
74
-
75
- def expand_sources(sources, recursive)
76
- if sources.first == :all
77
- collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}")
78
- else
79
- sources.inject([]) do |list, source|
80
- determined_source = determine_source(source, expansions)
81
- update_source_list(list, determined_source)
82
- end
83
- end
84
- end
85
-
86
- def update_source_list(list, source)
87
- case source
88
- when String
89
- list.delete(source)
90
- list << source
91
- when Array
92
- updated_sources = source - list
93
- list.concat(updated_sources)
94
- end
95
- end
96
-
97
- def ensure_sources!(sources)
98
- sources.each do |source|
99
- asset_file_path!(path_to_asset_source(source))
100
- end
101
- end
102
-
103
- def collect_asset_files(*path)
104
- dir = path.first
105
-
106
- Dir[File.join(*path.compact)].collect do |file|
107
- file[-(file.size - dir.size - 1)..-1].sub(/\.\w+$/, '')
108
- end.sort
109
- end
110
-
111
- def determine_source(source, collection)
112
- case source
113
- when Symbol
114
- collection[source] || raise(ArgumentError, "No expansion found for #{source.inspect}")
115
- else
116
- source
117
- end
118
- end
119
-
120
- def join_asset_file_contents(paths)
121
- paths.collect { |path| File.read(asset_file_path!(path, true)) }.join("\n\n")
122
- end
123
-
124
- def write_asset_file_contents(joined_asset_path, asset_paths)
125
- FileUtils.mkdir_p(File.dirname(joined_asset_path))
126
- File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
127
-
128
- # Set mtime to the latest of the combined files to allow for
129
- # consistent ETag without a shared filesystem.
130
- mt = asset_paths.map { |p| File.mtime(asset_file_path!(p)) }.max
131
- File.utime(mt, mt, joined_asset_path)
132
- end
133
-
134
- def asset_file_path!(absolute_path, error_if_file_is_uri = false)
135
- if asset_paths.is_uri?(absolute_path)
136
- raise(Errno::ENOENT, "Asset file #{path} is uri and cannot be merged into single file") if error_if_file_is_uri
137
- else
138
- raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
139
- return absolute_path
140
- end
141
- end
142
- end
143
-
144
- end
145
- end
146
- end