actionpack 3.0.20 → 3.1.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 (161) hide show
  1. data/CHANGELOG +88 -142
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +5 -6
  4. data/lib/abstract_controller.rb +1 -0
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +24 -19
  7. data/lib/abstract_controller/callbacks.rb +19 -19
  8. data/lib/abstract_controller/helpers.rb +11 -13
  9. data/lib/abstract_controller/layouts.rb +4 -5
  10. data/lib/abstract_controller/railties/routes_helpers.rb +18 -0
  11. data/lib/abstract_controller/rendering.rb +34 -31
  12. data/lib/abstract_controller/url_for.rb +27 -0
  13. data/lib/abstract_controller/view_paths.rb +31 -6
  14. data/lib/action_controller.rb +5 -3
  15. data/lib/action_controller/base.rb +15 -16
  16. data/lib/action_controller/caching.rb +2 -2
  17. data/lib/action_controller/caching/actions.rb +11 -12
  18. data/lib/action_controller/caching/fragments.rb +41 -19
  19. data/lib/action_controller/caching/pages.rb +3 -9
  20. data/lib/action_controller/caching/sweeping.rb +0 -1
  21. data/lib/action_controller/deprecated.rb +1 -1
  22. data/lib/action_controller/log_subscriber.rb +1 -1
  23. data/lib/action_controller/metal.rb +78 -20
  24. data/lib/action_controller/metal/compatibility.rb +0 -9
  25. data/lib/action_controller/metal/conditional_get.rb +9 -9
  26. data/lib/action_controller/metal/data_streaming.rb +145 -0
  27. data/lib/action_controller/metal/force_ssl.rb +35 -0
  28. data/lib/action_controller/metal/head.rb +1 -1
  29. data/lib/action_controller/metal/helpers.rb +37 -44
  30. data/lib/action_controller/metal/hide_actions.rb +2 -3
  31. data/lib/action_controller/metal/http_authentication.rb +41 -38
  32. data/lib/action_controller/metal/implicit_render.rb +13 -13
  33. data/lib/action_controller/metal/instrumentation.rb +2 -2
  34. data/lib/action_controller/metal/mime_responds.rb +25 -19
  35. data/lib/action_controller/metal/params_wrapper.rb +224 -0
  36. data/lib/action_controller/metal/redirecting.rb +6 -2
  37. data/lib/action_controller/metal/renderers.rb +50 -36
  38. data/lib/action_controller/metal/rendering.rb +34 -25
  39. data/lib/action_controller/metal/request_forgery_protection.rb +18 -36
  40. data/lib/action_controller/metal/responder.rb +47 -12
  41. data/lib/action_controller/metal/streaming.rb +244 -138
  42. data/lib/action_controller/metal/testing.rb +0 -9
  43. data/lib/action_controller/metal/url_for.rb +12 -14
  44. data/lib/action_controller/railtie.rb +19 -37
  45. data/lib/action_controller/railties/paths.rb +24 -0
  46. data/lib/action_controller/record_identifier.rb +4 -10
  47. data/lib/action_controller/test_case.rb +36 -19
  48. data/lib/action_controller/vendor/html-scanner/html/node.rb +5 -5
  49. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +3 -3
  50. data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -0
  51. data/lib/action_dispatch.rb +4 -1
  52. data/lib/action_dispatch/http/cache.rb +5 -32
  53. data/lib/action_dispatch/http/filter_parameters.rb +3 -1
  54. data/lib/action_dispatch/http/mime_negotiation.rb +22 -3
  55. data/lib/action_dispatch/http/mime_type.rb +45 -5
  56. data/lib/action_dispatch/http/rack_cache.rb +58 -0
  57. data/lib/action_dispatch/http/request.rb +27 -41
  58. data/lib/action_dispatch/http/response.rb +56 -54
  59. data/lib/action_dispatch/http/upload.rb +1 -11
  60. data/lib/action_dispatch/http/url.rb +102 -42
  61. data/lib/action_dispatch/middleware/callbacks.rb +8 -25
  62. data/lib/action_dispatch/middleware/closed_error.rb +7 -0
  63. data/lib/action_dispatch/middleware/cookies.rb +37 -15
  64. data/lib/action_dispatch/middleware/flash.rb +80 -11
  65. data/lib/action_dispatch/middleware/params_parser.rb +2 -2
  66. data/lib/action_dispatch/middleware/reloader.rb +76 -0
  67. data/lib/action_dispatch/middleware/session/abstract_store.rb +56 -226
  68. data/lib/action_dispatch/middleware/session/cookie_store.rb +20 -44
  69. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -46
  70. data/lib/action_dispatch/middleware/show_exceptions.rb +15 -2
  71. data/lib/action_dispatch/middleware/stack.rb +50 -17
  72. data/lib/action_dispatch/middleware/static.rb +41 -29
  73. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +3 -3
  74. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
  75. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +3 -3
  76. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -2
  77. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +2 -6
  78. data/lib/action_dispatch/railtie.rb +8 -0
  79. data/lib/action_dispatch/routing.rb +13 -1
  80. data/lib/action_dispatch/routing/mapper.rb +345 -227
  81. data/lib/action_dispatch/routing/polymorphic_routes.rb +33 -13
  82. data/lib/action_dispatch/routing/redirection.rb +110 -0
  83. data/lib/action_dispatch/routing/route.rb +15 -13
  84. data/lib/action_dispatch/routing/route_set.rb +116 -90
  85. data/lib/action_dispatch/routing/routes_proxy.rb +35 -0
  86. data/lib/action_dispatch/routing/url_for.rb +25 -1
  87. data/lib/action_dispatch/testing/assertions/response.rb +8 -10
  88. data/lib/action_dispatch/testing/assertions/routing.rb +15 -15
  89. data/lib/action_dispatch/testing/assertions/selector.rb +13 -220
  90. data/lib/action_dispatch/testing/integration.rb +37 -28
  91. data/lib/action_dispatch/testing/performance_test.rb +1 -3
  92. data/lib/action_dispatch/testing/test_process.rb +1 -1
  93. data/lib/action_dispatch/testing/test_request.rb +9 -3
  94. data/lib/action_dispatch/testing/test_response.rb +4 -111
  95. data/lib/action_pack.rb +1 -1
  96. data/lib/action_pack/version.rb +3 -3
  97. data/lib/action_view.rb +39 -24
  98. data/lib/action_view/base.rb +61 -86
  99. data/lib/action_view/buffers.rb +43 -0
  100. data/lib/action_view/context.rb +21 -24
  101. data/lib/action_view/flows.rb +79 -0
  102. data/lib/action_view/helpers.rb +8 -6
  103. data/lib/action_view/helpers/active_model_helper.rb +0 -23
  104. data/lib/action_view/helpers/asset_paths.rb +79 -0
  105. data/lib/action_view/helpers/asset_tag_helper.rb +30 -500
  106. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +147 -0
  107. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +101 -0
  108. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +200 -0
  109. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +152 -0
  110. data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
  111. data/lib/action_view/helpers/cache_helper.rb +11 -19
  112. data/lib/action_view/helpers/capture_helper.rb +19 -8
  113. data/lib/action_view/helpers/controller_helper.rb +21 -0
  114. data/lib/action_view/helpers/csrf_helper.rb +22 -4
  115. data/lib/action_view/helpers/date_helper.rb +36 -22
  116. data/lib/action_view/helpers/form_helper.rb +199 -113
  117. data/lib/action_view/helpers/form_options_helper.rb +10 -11
  118. data/lib/action_view/helpers/form_tag_helper.rb +94 -22
  119. data/lib/action_view/helpers/javascript_helper.rb +24 -107
  120. data/lib/action_view/helpers/number_helper.rb +36 -33
  121. data/lib/action_view/helpers/output_safety_helper.rb +38 -0
  122. data/lib/action_view/helpers/record_tag_helper.rb +6 -6
  123. data/lib/action_view/helpers/rendering_helper.rb +90 -0
  124. data/lib/action_view/helpers/sanitize_helper.rb +2 -2
  125. data/lib/action_view/helpers/sprockets_helper.rb +69 -0
  126. data/lib/action_view/helpers/tag_helper.rb +34 -12
  127. data/lib/action_view/helpers/text_helper.rb +30 -145
  128. data/lib/action_view/helpers/translation_helper.rb +10 -17
  129. data/lib/action_view/helpers/url_helper.rb +70 -67
  130. data/lib/action_view/locale/en.yml +1 -1
  131. data/lib/action_view/lookup_context.rb +36 -14
  132. data/lib/action_view/{paths.rb → path_set.rb} +9 -8
  133. data/lib/action_view/railtie.rb +12 -4
  134. data/lib/action_view/renderer/abstract_renderer.rb +36 -0
  135. data/lib/action_view/{render/partials.rb → renderer/partial_renderer.rb} +147 -146
  136. data/lib/action_view/renderer/renderer.rb +54 -0
  137. data/lib/action_view/renderer/streaming_template_renderer.rb +106 -0
  138. data/lib/action_view/renderer/template_renderer.rb +74 -0
  139. data/lib/action_view/template.rb +91 -54
  140. data/lib/action_view/template/error.rb +11 -8
  141. data/lib/action_view/template/handler.rb +9 -1
  142. data/lib/action_view/template/handlers.rb +9 -9
  143. data/lib/action_view/template/handlers/builder.rb +4 -4
  144. data/lib/action_view/template/handlers/erb.rb +21 -41
  145. data/lib/action_view/template/resolver.rb +171 -57
  146. data/lib/action_view/template/text.rb +0 -4
  147. data/lib/action_view/test_case.rb +32 -16
  148. data/lib/action_view/testing/resolvers.rb +16 -10
  149. data/lib/sprockets/railtie.rb +100 -0
  150. metadata +162 -140
  151. checksums.yaml +0 -7
  152. data/lib/action_controller/deprecated/base.rb +0 -143
  153. data/lib/action_controller/deprecated/dispatcher.rb +0 -28
  154. data/lib/action_controller/deprecated/url_writer.rb +0 -14
  155. data/lib/action_dispatch/routing/deprecated_mapper.rb +0 -525
  156. data/lib/action_view/helpers/prototype_helper.rb +0 -851
  157. data/lib/action_view/helpers/raw_output_helper.rb +0 -18
  158. data/lib/action_view/helpers/scriptaculous_helper.rb +0 -263
  159. data/lib/action_view/render/layouts.rb +0 -83
  160. data/lib/action_view/render/rendering.rb +0 -67
  161. data/lib/action_view/template/handlers/rjs.rb +0 -17
@@ -0,0 +1,79 @@
1
+ require 'active_support/core_ext/file'
2
+ require 'action_view/helpers/asset_paths'
3
+
4
+ module ActionView
5
+ module Helpers
6
+
7
+ class AssetPaths #:nodoc:
8
+ attr_reader :config, :controller
9
+
10
+ def initialize(config, controller)
11
+ @config = config
12
+ @controller = controller
13
+ end
14
+
15
+ # Add the extension +ext+ if not present. Return full or scheme-relative URLs otherwise untouched.
16
+ # Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
17
+ # roots. Rewrite the asset path for cache-busting asset ids. Include
18
+ # asset host, if configured, with the correct request protocol.
19
+ def compute_public_path(source, dir, ext = nil, include_host = true)
20
+ source = source.to_s
21
+ return source if is_uri?(source)
22
+
23
+ source = rewrite_extension(source, dir, ext) if ext
24
+ source = rewrite_asset_path(source, dir)
25
+
26
+ if controller && include_host
27
+ has_request = controller.respond_to?(:request)
28
+ source = rewrite_host_and_protocol(source, has_request)
29
+ end
30
+
31
+ source
32
+ end
33
+
34
+ def is_uri?(path)
35
+ path =~ %r{^[-a-z]+://|^cid:|^//}
36
+ end
37
+
38
+ private
39
+
40
+ def rewrite_extension(source, dir, ext)
41
+ raise NotImplementedError
42
+ end
43
+
44
+ def rewrite_asset_path(source, path = nil)
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def rewrite_host_and_protocol(source, has_request)
49
+ host = compute_asset_host(source)
50
+ if has_request && host && !is_uri?(host)
51
+ host = "#{controller.request.protocol}#{host}"
52
+ end
53
+ "#{host}#{source}"
54
+ end
55
+
56
+ # Pick an asset host for this source. Returns +nil+ if no host is set,
57
+ # the host if no wildcard is set, the host interpolated with the
58
+ # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4),
59
+ # or the value returned from invoking the proc if it's a proc or the value from
60
+ # invoking call if it's an object responding to call.
61
+ def compute_asset_host(source)
62
+ if host = config.asset_host
63
+ if host.is_a?(Proc) || host.respond_to?(:call)
64
+ case host.is_a?(Proc) ? host.arity : host.method(:call).arity
65
+ when 2
66
+ request = controller.respond_to?(:request) && controller.request
67
+ host.call(source, request)
68
+ else
69
+ host.call(source)
70
+ end
71
+ else
72
+ (host =~ /%d/) ? host % (source.hash % 4) : host
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -1,9 +1,6 @@
1
- require 'thread'
2
- require 'cgi'
3
- require 'action_view/helpers/url_helper'
4
- require 'action_view/helpers/tag_helper'
5
- require 'active_support/core_ext/file'
6
- require 'active_support/core_ext/object/blank'
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'
7
4
 
8
5
  module ActionView
9
6
  # = Action View Asset Tag Helpers
@@ -60,7 +57,7 @@ module ActionView
60
57
  # +asset_host+ to a proc like this:
61
58
  #
62
59
  # ActionController::Base.asset_host = Proc.new { |source|
63
- # "http://assets#{source.hash % 2 + 1}.example.com"
60
+ # "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
64
61
  # }
65
62
  # image_tag("rails.png")
66
63
  # # => <img alt="Rails" src="http://assets1.example.com/images/rails.png?1230601161" />
@@ -152,7 +149,7 @@ module ActionView
152
149
  #
153
150
  # # Normally you'd calculate RELEASE_NUMBER at startup.
154
151
  # RELEASE_NUMBER = 12345
155
- # config.action_controller.asset_path_template = proc { |asset_path|
152
+ # config.action_controller.asset_path = proc { |asset_path|
156
153
  # "/release-#{RELEASE_NUMBER}#{asset_path}"
157
154
  # }
158
155
  #
@@ -194,20 +191,8 @@ module ActionView
194
191
  # RewriteEngine On
195
192
  # RewriteRule ^/release-\d+/(images|javascripts|stylesheets)/(.*)$ /$1/$2 [L]
196
193
  module AssetTagHelper
197
- mattr_reader :javascript_expansions
198
- @@javascript_expansions = { }
199
-
200
- mattr_reader :stylesheet_expansions
201
- @@stylesheet_expansions = {}
202
-
203
- # You can enable or disable the asset tag timestamps cache.
204
- # With the cache enabled, the asset tag helper methods will make fewer
205
- # expensive file system calls. However this prevents you from modifying
206
- # any asset files while the server is running.
207
- #
208
- # ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
209
- mattr_accessor :cache_asset_timestamps
210
-
194
+ include JavascriptTagHelpers
195
+ include StylesheetTagHelpers
211
196
  # Returns a link tag that browsers and news readers can use to auto-detect
212
197
  # an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or
213
198
  # <tt>:atom</tt>. Control the link options in url_for format using the
@@ -241,279 +226,6 @@ module ActionView
241
226
  )
242
227
  end
243
228
 
244
- # Computes the path to a javascript asset in the public javascripts directory.
245
- # If the +source+ filename has no extension, .js will be appended (except for explicit URIs)
246
- # Full paths from the document root will be passed through.
247
- # Used internally by javascript_include_tag to build the script path.
248
- #
249
- # ==== Examples
250
- # javascript_path "xmlhr" # => /javascripts/xmlhr.js
251
- # javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js
252
- # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js
253
- # javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr
254
- # javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js
255
- def javascript_path(source)
256
- compute_public_path(source, 'javascripts', 'js')
257
- end
258
- alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
259
-
260
- # Returns an html script tag for each of the +sources+ provided. You
261
- # can pass in the filename (.js extension is optional) of javascript files
262
- # that exist in your public/javascripts directory for inclusion into the
263
- # current page or you can pass the full path relative to your document
264
- # root. To include the Prototype and Scriptaculous javascript libraries in
265
- # your application, pass <tt>:defaults</tt> as the source. When using
266
- # <tt>:defaults</tt>, if an application.js file exists in your public
267
- # javascripts directory, it will be included as well. You can modify the
268
- # html attributes of the script tag by passing a hash as the last argument.
269
- #
270
- # ==== Examples
271
- # javascript_include_tag "xmlhr" # =>
272
- # <script type="text/javascript" src="/javascripts/xmlhr.js"></script>
273
- #
274
- # javascript_include_tag "xmlhr.js" # =>
275
- # <script type="text/javascript" src="/javascripts/xmlhr.js"></script>
276
- #
277
- # javascript_include_tag "common.javascript", "/elsewhere/cools" # =>
278
- # <script type="text/javascript" src="/javascripts/common.javascript"></script>
279
- # <script type="text/javascript" src="/elsewhere/cools.js"></script>
280
- #
281
- # javascript_include_tag "http://www.railsapplication.com/xmlhr" # =>
282
- # <script type="text/javascript" src="http://www.railsapplication.com/xmlhr.js"></script>
283
- #
284
- # javascript_include_tag "http://www.railsapplication.com/xmlhr.js" # =>
285
- # <script type="text/javascript" src="http://www.railsapplication.com/xmlhr.js"></script>
286
- #
287
- # javascript_include_tag :defaults # =>
288
- # <script type="text/javascript" src="/javascripts/prototype.js"></script>
289
- # <script type="text/javascript" src="/javascripts/effects.js"></script>
290
- # ...
291
- # <script type="text/javascript" src="/javascripts/application.js"></script>
292
- #
293
- # * = The application.js file is only referenced if it exists
294
- #
295
- # Though it's not really recommended practice, if you need to extend the default JavaScript set for any reason
296
- # (e.g., you're going to be using a certain .js file in every action), then take a look at the register_javascript_include_default method.
297
- #
298
- # You can also include all javascripts in the javascripts directory using <tt>:all</tt> as the source:
299
- #
300
- # javascript_include_tag :all # =>
301
- # <script type="text/javascript" src="/javascripts/prototype.js"></script>
302
- # <script type="text/javascript" src="/javascripts/effects.js"></script>
303
- # ...
304
- # <script type="text/javascript" src="/javascripts/application.js"></script>
305
- # <script type="text/javascript" src="/javascripts/shop.js"></script>
306
- # <script type="text/javascript" src="/javascripts/checkout.js"></script>
307
- #
308
- # Note that the default javascript files will be included first. So Prototype and Scriptaculous are available to
309
- # all subsequently included files.
310
- #
311
- # If you want Rails to search in all the subdirectories under javascripts, you should explicitly set <tt>:recursive</tt>:
312
- #
313
- # javascript_include_tag :all, :recursive => true
314
- #
315
- # == Caching multiple javascripts into one
316
- #
317
- # You can also cache multiple javascripts into one file, which requires less HTTP connections to download and can better be
318
- # compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
319
- # is set to <tt>true</tt> (which is the case by default for the Rails production environment, but not for the development
320
- # environment).
321
- #
322
- # ==== Examples
323
- # javascript_include_tag :all, :cache => true # when config.perform_caching is false =>
324
- # <script type="text/javascript" src="/javascripts/prototype.js"></script>
325
- # <script type="text/javascript" src="/javascripts/effects.js"></script>
326
- # ...
327
- # <script type="text/javascript" src="/javascripts/application.js"></script>
328
- # <script type="text/javascript" src="/javascripts/shop.js"></script>
329
- # <script type="text/javascript" src="/javascripts/checkout.js"></script>
330
- #
331
- # javascript_include_tag :all, :cache => true # when config.perform_caching is true =>
332
- # <script type="text/javascript" src="/javascripts/all.js"></script>
333
- #
334
- # javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is false =>
335
- # <script type="text/javascript" src="/javascripts/prototype.js"></script>
336
- # <script type="text/javascript" src="/javascripts/cart.js"></script>
337
- # <script type="text/javascript" src="/javascripts/checkout.js"></script>
338
- #
339
- # javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is true =>
340
- # <script type="text/javascript" src="/javascripts/shop.js"></script>
341
- #
342
- # The <tt>:recursive</tt> option is also available for caching:
343
- #
344
- # javascript_include_tag :all, :cache => true, :recursive => true
345
- def javascript_include_tag(*sources)
346
- options = sources.extract_options!.stringify_keys
347
- concat = options.delete("concat")
348
- cache = concat || options.delete("cache")
349
- recursive = options.delete("recursive")
350
-
351
- if concat || (config.perform_caching && cache)
352
- joined_javascript_name = (cache == true ? "all" : cache) + ".js"
353
- joined_javascript_path = File.join(joined_javascript_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.javascripts_dir, joined_javascript_name)
354
-
355
- unless config.perform_caching && File.exists?(joined_javascript_path)
356
- write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive))
357
- end
358
- javascript_src_tag(joined_javascript_name, options)
359
- else
360
- sources = expand_javascript_sources(sources, recursive)
361
- ensure_javascript_sources!(sources) if cache
362
- sources.collect { |source| javascript_src_tag(source, options) }.join("\n").html_safe
363
- end
364
- end
365
-
366
- # Register one or more javascript files to be included when <tt>symbol</tt>
367
- # is passed to <tt>javascript_include_tag</tt>. This method is typically intended
368
- # to be called from plugin initialization to register javascript files
369
- # that the plugin installed in <tt>public/javascripts</tt>.
370
- #
371
- # ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"]
372
- #
373
- # javascript_include_tag :monkey # =>
374
- # <script type="text/javascript" src="/javascripts/head.js"></script>
375
- # <script type="text/javascript" src="/javascripts/body.js"></script>
376
- # <script type="text/javascript" src="/javascripts/tail.js"></script>
377
- def self.register_javascript_expansion(expansions)
378
- expansions.each do |key, values|
379
- @@javascript_expansions[key] = (@@javascript_expansions[key] || []) | Array(values)
380
- end
381
- end
382
-
383
- # Register one or more stylesheet files to be included when <tt>symbol</tt>
384
- # is passed to <tt>stylesheet_link_tag</tt>. This method is typically intended
385
- # to be called from plugin initialization to register stylesheet files
386
- # that the plugin installed in <tt>public/stylesheets</tt>.
387
- #
388
- # ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]
389
- #
390
- # stylesheet_link_tag :monkey # =>
391
- # <link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />
392
- # <link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />
393
- # <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />
394
- def self.register_stylesheet_expansion(expansions)
395
- expansions.each do |key, values|
396
- @@stylesheet_expansions[key] = (@@stylesheet_expansions[key] || []) | Array(values)
397
- end
398
- end
399
-
400
- def self.reset_javascript_include_default
401
- ActiveSupport::Deprecation.warn "reset_javascript_include_default is deprecated. Please manipulate " \
402
- "config.action_view.javascript_expansions[:defaults] directly", caller
403
- self.javascript_expansions[:defaults] = ['prototype', 'effects', 'dragdrop', 'controls', 'rails']
404
- end
405
-
406
- def self.register_javascript_include_default(*args)
407
- ActiveSupport::Deprecation.warn "register_javascript_include_default is deprecated. Please " \
408
- "manipulate config.action_view.javascript_expansions[:defaults] directly", caller
409
- self.javascript_expansions[:defaults].concat args
410
- end
411
-
412
- # Computes the path to a stylesheet asset in the public stylesheets directory.
413
- # If the +source+ filename has no extension, <tt>.css</tt> will be appended (except for explicit URIs).
414
- # Full paths from the document root will be passed through.
415
- # Used internally by +stylesheet_link_tag+ to build the stylesheet path.
416
- #
417
- # ==== Examples
418
- # stylesheet_path "style" # => /stylesheets/style.css
419
- # stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css
420
- # stylesheet_path "/dir/style.css" # => /dir/style.css
421
- # stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style
422
- # stylesheet_path "http://www.railsapplication.com/css/style.css" # => http://www.railsapplication.com/css/style.css
423
- def stylesheet_path(source)
424
- compute_public_path(source, 'stylesheets', 'css')
425
- end
426
- alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route
427
-
428
- # Returns a stylesheet link tag for the sources specified as arguments. If
429
- # you don't specify an extension, <tt>.css</tt> will be appended automatically.
430
- # You can modify the link attributes by passing a hash as the last argument.
431
- #
432
- # ==== Examples
433
- # stylesheet_link_tag "style" # =>
434
- # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
435
- #
436
- # stylesheet_link_tag "style.css" # =>
437
- # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
438
- #
439
- # stylesheet_link_tag "http://www.railsapplication.com/style.css" # =>
440
- # <link href="http://www.railsapplication.com/style.css" media="screen" rel="stylesheet" type="text/css" />
441
- #
442
- # stylesheet_link_tag "style", :media => "all" # =>
443
- # <link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" />
444
- #
445
- # stylesheet_link_tag "style", :media => "print" # =>
446
- # <link href="/stylesheets/style.css" media="print" rel="stylesheet" type="text/css" />
447
- #
448
- # stylesheet_link_tag "random.styles", "/css/stylish" # =>
449
- # <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />
450
- # <link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" />
451
- #
452
- # You can also include all styles in the stylesheets directory using <tt>:all</tt> as the source:
453
- #
454
- # stylesheet_link_tag :all # =>
455
- # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" type="text/css" />
456
- # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" />
457
- # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />
458
- #
459
- # If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set <tt>:recursive</tt>:
460
- #
461
- # stylesheet_link_tag :all, :recursive => true
462
- #
463
- # == Caching multiple stylesheets into one
464
- #
465
- # You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be
466
- # compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
467
- # is set to true (which is the case by default for the Rails production environment, but not for the development
468
- # environment). Examples:
469
- #
470
- # ==== Examples
471
- # stylesheet_link_tag :all, :cache => true # when config.perform_caching is false =>
472
- # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" type="text/css" />
473
- # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" />
474
- # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />
475
- #
476
- # stylesheet_link_tag :all, :cache => true # when config.perform_caching is true =>
477
- # <link href="/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />
478
- #
479
- # stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is false =>
480
- # <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" type="text/css" />
481
- # <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" type="text/css" />
482
- # <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" type="text/css" />
483
- #
484
- # stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is true =>
485
- # <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" type="text/css" />
486
- #
487
- # The <tt>:recursive</tt> option is also available for caching:
488
- #
489
- # stylesheet_link_tag :all, :cache => true, :recursive => true
490
- #
491
- # To force concatenation (even in development mode) set <tt>:concat</tt> to true. This is useful if
492
- # you have too many stylesheets for IE to load.
493
- #
494
- # stylesheet_link_tag :all, :concat => true
495
- #
496
- def stylesheet_link_tag(*sources)
497
- options = sources.extract_options!.stringify_keys
498
- concat = options.delete("concat")
499
- cache = concat || options.delete("cache")
500
- recursive = options.delete("recursive")
501
-
502
- if concat || (config.perform_caching && cache)
503
- joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
504
- joined_stylesheet_path = File.join(joined_stylesheet_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.stylesheets_dir, joined_stylesheet_name)
505
-
506
- unless config.perform_caching && File.exists?(joined_stylesheet_path)
507
- write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive))
508
- end
509
- stylesheet_tag(joined_stylesheet_name, options)
510
- else
511
- sources = expand_stylesheet_sources(sources, recursive)
512
- ensure_stylesheet_sources!(sources) if cache
513
- sources.collect { |source| stylesheet_tag(source, options) }.join("\n").html_safe
514
- end
515
- end
516
-
517
229
  # Web browsers cache favicons. If you just throw a <tt>favicon.ico</tt> into the document
518
230
  # root of your application and it changes later, clients that have it in their cache
519
231
  # won't see the update. Using this helper prevents that because it appends an asset ID:
@@ -556,13 +268,17 @@ module ActionView
556
268
  # image_path("edit.png") # => "/images/edit.png"
557
269
  # image_path("icons/edit.png") # => "/images/icons/edit.png"
558
270
  # image_path("/icons/edit.png") # => "/icons/edit.png"
559
- # image_path("http://www.railsapplication.com/img/edit.png") # => "http://www.railsapplication.com/img/edit.png"
271
+ # image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png"
560
272
  #
561
273
  # If you have images as application resources this method may conflict with their named routes.
562
274
  # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and
563
275
  # plugin authors are encouraged to do so.
564
276
  def image_path(source)
565
- compute_public_path(source, 'images')
277
+ if config.use_sprockets
278
+ asset_path(source)
279
+ else
280
+ asset_paths.compute_public_path(source, 'images')
281
+ end
566
282
  end
567
283
  alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
568
284
 
@@ -575,9 +291,13 @@ module ActionView
575
291
  # video_path("hd.avi") # => /videos/hd.avi
576
292
  # video_path("trailers/hd.avi") # => /videos/trailers/hd.avi
577
293
  # video_path("/trailers/hd.avi") # => /trailers/hd.avi
578
- # video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi
294
+ # video_path("http://www.example.com/vid/hd.avi") # => http://www.example.com/vid/hd.avi
579
295
  def video_path(source)
580
- compute_public_path(source, 'videos')
296
+ if config.use_sprockets
297
+ asset_path(source)
298
+ else
299
+ asset_paths.compute_public_path(source, 'videos')
300
+ end
581
301
  end
582
302
  alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route
583
303
 
@@ -587,12 +307,16 @@ module ActionView
587
307
  #
588
308
  # ==== Examples
589
309
  # audio_path("horse") # => /audios/horse
590
- # audio_path("horse.wav") # => /audios/horse.avi
591
- # audio_path("sounds/horse.wav") # => /audios/sounds/horse.avi
592
- # audio_path("/sounds/horse.wav") # => /sounds/horse.avi
593
- # audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav
310
+ # audio_path("horse.wav") # => /audios/horse.wav
311
+ # audio_path("sounds/horse.wav") # => /audios/sounds/horse.wav
312
+ # audio_path("/sounds/horse.wav") # => /sounds/horse.wav
313
+ # audio_path("http://www.example.com/sounds/horse.wav") # => http://www.example.com/sounds/horse.wav
594
314
  def audio_path(source)
595
- compute_public_path(source, 'audios')
315
+ if config.use_sprockets
316
+ asset_path(source)
317
+ else
318
+ asset_paths.compute_public_path(source, 'audios')
319
+ end
596
320
  end
597
321
  alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route
598
322
 
@@ -721,202 +445,8 @@ module ActionView
721
445
 
722
446
  private
723
447
 
724
- def rewrite_extension?(source, dir, ext)
725
- source_ext = File.extname(source)[1..-1]
726
- ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}"))))
727
- end
728
-
729
- def rewrite_host_and_protocol(source, has_request)
730
- host = compute_asset_host(source)
731
- if has_request && host.present? && !is_uri?(host)
732
- host = "#{controller.request.protocol}#{host}"
733
- end
734
- "#{host}#{source}"
735
- end
736
-
737
- # Add the the extension +ext+ if not present. Return full URLs otherwise untouched.
738
- # Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
739
- # roots. Rewrite the asset path for cache-busting asset ids. Include
740
- # asset host, if configured, with the correct request protocol.
741
- def compute_public_path(source, dir, ext = nil, include_host = true)
742
- return source if is_uri?(source)
743
-
744
- source += ".#{ext}" if rewrite_extension?(source, dir, ext)
745
- source = "/#{dir}/#{source}" unless source.start_with? '/'
746
- source = rewrite_asset_path(source, config.asset_path)
747
-
748
- has_request = controller.respond_to?(:request)
749
- if has_request && include_host && !source.start_with?(controller.config.relative_url_root)
750
- source = "#{controller.config.relative_url_root}#{source}"
751
- end
752
- source = rewrite_host_and_protocol(source, has_request) if include_host
753
-
754
- source
755
- end
756
-
757
- def is_uri?(path)
758
- path =~ %r{^[-a-z]+://|^cid:}
759
- end
760
-
761
- # Pick an asset host for this source. Returns +nil+ if no host is set,
762
- # the host if no wildcard is set, the host interpolated with the
763
- # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4),
764
- # or the value returned from invoking the proc if it's a proc or the value from
765
- # invoking call if it's an object responding to call.
766
- def compute_asset_host(source)
767
- if host = config.asset_host
768
- if host.is_a?(Proc) || host.respond_to?(:call)
769
- case host.is_a?(Proc) ? host.arity : host.method(:call).arity
770
- when 2
771
- request = controller.respond_to?(:request) && controller.request
772
- host.call(source, request)
773
- else
774
- host.call(source)
775
- end
776
- else
777
- (host =~ /%d/) ? host % (source.hash % 4) : host
778
- end
779
- end
780
- end
781
-
782
- @@asset_timestamps_cache = {}
783
- @@asset_timestamps_cache_guard = Mutex.new
784
-
785
- # Use the RAILS_ASSET_ID environment variable or the source's
786
- # modification time as its cache-busting asset id.
787
- def rails_asset_id(source)
788
- if asset_id = ENV["RAILS_ASSET_ID"]
789
- asset_id
790
- else
791
- if @@cache_asset_timestamps && (asset_id = @@asset_timestamps_cache[source])
792
- asset_id
793
- else
794
- path = File.join(config.assets_dir, source)
795
- asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : ''
796
-
797
- if @@cache_asset_timestamps
798
- @@asset_timestamps_cache_guard.synchronize do
799
- @@asset_timestamps_cache[source] = asset_id
800
- end
801
- end
802
-
803
- asset_id
804
- end
805
- end
806
- end
807
-
808
- # Break out the asset path rewrite in case plugins wish to put the asset id
809
- # someplace other than the query string.
810
- def rewrite_asset_path(source, path = nil)
811
- if path && path.respond_to?(:call)
812
- return path.call(source)
813
- elsif path && path.is_a?(String)
814
- return path % [source]
815
- end
816
-
817
- asset_id = rails_asset_id(source)
818
- if asset_id.blank?
819
- source
820
- else
821
- source + "?#{asset_id}"
822
- end
823
- end
824
-
825
- def javascript_src_tag(source, options)
826
- content_tag("script", "", { "type" => Mime::JS, "src" => path_to_javascript(source) }.merge(options))
827
- end
828
-
829
- def stylesheet_tag(source, options)
830
- tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => html_escape(path_to_stylesheet(source)) }.merge(options), false, false)
831
- end
832
-
833
- def compute_javascript_paths(*args)
834
- expand_javascript_sources(*args).collect { |source| compute_public_path(source, 'javascripts', 'js', false) }
835
- end
836
-
837
- def compute_stylesheet_paths(*args)
838
- expand_stylesheet_sources(*args).collect { |source| compute_public_path(source, 'stylesheets', 'css', false) }
839
- end
840
-
841
- def expand_javascript_sources(sources, recursive = false)
842
- if sources.include?(:all)
843
- all_javascript_files = (collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js') - ['application']) << 'application'
844
- ((determine_source(:defaults, @@javascript_expansions).dup & all_javascript_files) + all_javascript_files).uniq
845
- else
846
- expanded_sources = sources.collect do |source|
847
- determine_source(source, @@javascript_expansions)
848
- end.flatten
849
- expanded_sources << "application" if sources.include?(:defaults) && File.exist?(File.join(config.javascripts_dir, "application.js"))
850
- expanded_sources
851
- end
852
- end
853
-
854
- def expand_stylesheet_sources(sources, recursive)
855
- if sources.first == :all
856
- collect_asset_files(config.stylesheets_dir, ('**' if recursive), '*.css')
857
- else
858
- sources.collect do |source|
859
- determine_source(source, @@stylesheet_expansions)
860
- end.flatten
861
- end
862
- end
863
-
864
- def determine_source(source, collection)
865
- case source
866
- when Symbol
867
- collection[source] || raise(ArgumentError, "No expansion found for #{source.inspect}")
868
- else
869
- source
870
- end
871
- end
872
-
873
- def ensure_stylesheet_sources!(sources)
874
- sources.each do |source|
875
- asset_file_path!(compute_public_path(source, 'stylesheets', 'css', false))
876
- end
877
- return sources
878
- end
879
-
880
- def ensure_javascript_sources!(sources)
881
- sources.each do |source|
882
- asset_file_path!(compute_public_path(source, 'javascripts', 'js', false))
883
- end
884
- return sources
885
- end
886
-
887
- def join_asset_file_contents(paths)
888
- paths.collect { |path| File.read(asset_file_path!(path)) }.join("\n\n")
889
- end
890
-
891
- def write_asset_file_contents(joined_asset_path, asset_paths)
892
-
893
- FileUtils.mkdir_p(File.dirname(joined_asset_path))
894
- File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
895
-
896
- # Set mtime to the latest of the combined files to allow for
897
- # consistent ETag without a shared filesystem.
898
- mt = asset_paths.map { |p| File.mtime(asset_file_path(p)) }.max
899
- File.utime(mt, mt, joined_asset_path)
900
- end
901
-
902
- def asset_file_path(path)
903
- File.join(config.assets_dir, path.split('?').first)
904
- end
905
-
906
- def asset_file_path!(path)
907
- unless is_uri?(path)
908
- absolute_path = asset_file_path(path)
909
- raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
910
- return absolute_path
911
- end
912
- end
913
-
914
- def collect_asset_files(*path)
915
- dir = path.first
916
-
917
- Dir[File.join(*path.compact)].collect do |file|
918
- file[-(file.size - dir.size - 1)..-1].sub(/\.\w+$/, '')
919
- end.sort
448
+ def asset_paths
449
+ @asset_paths ||= AssetTagHelper::AssetPaths.new(config, controller)
920
450
  end
921
451
  end
922
452
  end