diff options
author | Joshua Peek <josh@joshpeek.com> | 2012-10-15 09:47:16 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2012-10-15 09:47:16 -0500 |
commit | 3db69909b9d4549128984c4c76f8a51eca3d79e6 (patch) | |
tree | 3ed089a244a737b89939b6db44fd89e4d51cb0dc | |
parent | 511382bfddb1400a461db84224369551ec93caa6 (diff) | |
download | rails-3db69909b9d4549128984c4c76f8a51eca3d79e6.tar.gz rails-3db69909b9d4549128984c4c76f8a51eca3d79e6.tar.bz2 rails-3db69909b9d4549128984c4c76f8a51eca3d79e6.zip |
:fire: Rails asset id support
-rw-r--r-- | actionpack/lib/abstract_controller/asset_paths.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/railtie.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/asset_id_helper.rb | 154 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/asset_tag_helper.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_view/railtie.rb | 8 | ||||
-rw-r--r-- | actionpack/test/template/asset_tag_helper_test.rb | 81 |
7 files changed, 2 insertions, 246 deletions
diff --git a/actionpack/lib/abstract_controller/asset_paths.rb b/actionpack/lib/abstract_controller/asset_paths.rb index 822254b1a4..e6170228d9 100644 --- a/actionpack/lib/abstract_controller/asset_paths.rb +++ b/actionpack/lib/abstract_controller/asset_paths.rb @@ -3,7 +3,7 @@ module AbstractController extend ActiveSupport::Concern included do - config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, + config_accessor :asset_host, :assets_dir, :javascripts_dir, :stylesheets_dir, :default_asset_host_protocol, :relative_url_root end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index ee0f053bad..3e44155f73 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -34,7 +34,6 @@ module ActionController options.stylesheets_dir ||= paths["public/stylesheets"].first # Ensure readers methods get compiled - options.asset_path ||= app.config.asset_path options.asset_host ||= app.config.asset_host options.relative_url_root ||= app.config.relative_url_root diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index cc14087189..dad50a58a1 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -3,7 +3,6 @@ module ActionView #:nodoc: extend ActiveSupport::Autoload autoload :ActiveModelHelper - autoload :AssetIdHelper autoload :AssetTagHelper autoload :AssetUrlHelper autoload :AtomFeedHelper diff --git a/actionpack/lib/action_view/helpers/asset_id_helper.rb b/actionpack/lib/action_view/helpers/asset_id_helper.rb deleted file mode 100644 index ba8e5e9050..0000000000 --- a/actionpack/lib/action_view/helpers/asset_id_helper.rb +++ /dev/null @@ -1,154 +0,0 @@ -require 'thread' -require 'active_support/core_ext/file' -require 'active_support/core_ext/module/attribute_accessors' - -module ActionView - # = Action View Asset Cache ID Helpers - # - # Rails appends asset's timestamps to public asset paths. This allows - # you to set a cache-expiration date for the asset far into the future, but - # still be able to instantly invalidate it by simply updating the file (and - # hence updating the timestamp, which then updates the URL as the timestamp - # is part of that, which in turn busts the cache). - # - # It's the responsibility of the web server you use to set the far-future - # expiration date on cache assets that you need to take advantage of this - # feature. Here's an example for Apache: - # - # # Asset Expiration - # ExpiresActive On - # <FilesMatch "\.(ico|gif|jpe?g|png|js|css)$"> - # ExpiresDefault "access plus 1 year" - # </FilesMatch> - # - # Also note that in order for this to work, all your application servers must - # return the same timestamps. This means that they must have their clocks - # synchronized. If one of them drifts out of sync, you'll see different - # timestamps at random and the cache won't work. In that case the browser - # will request the same assets over and over again even thought they didn't - # change. You can use something like Live HTTP Headers for Firefox to verify - # that the cache is indeed working. - # - # This strategy works well enough for most server setups and requires the - # least configuration, but if you deploy several application servers at - # different times - say to handle a temporary spike in load - then the - # asset time stamps will be out of sync. In a setup like this you may want - # to set the way that asset paths are generated yourself. - # - # Altering the asset paths that Rails generates can be done in two ways. - # The easiest is to define the RAILS_ASSET_ID environment variable. The - # contents of this variable will always be used in preference to - # calculated timestamps. A more complex but flexible way is to set - # <tt>ActionController::Base.config.asset_path</tt> to a proc - # that takes the unmodified asset path and returns the path needed for - # your asset caching to work. Typically you'd do something like this in - # <tt>config/environments/production.rb</tt>: - # - # # Normally you'd calculate RELEASE_NUMBER at startup. - # RELEASE_NUMBER = 12345 - # config.action_controller.asset_path = proc { |asset_path| - # "/release-#{RELEASE_NUMBER}#{asset_path}" - # } - # - # This example would cause the following behavior on all servers no - # matter when they were deployed: - # - # image_tag("rails.png") - # # => <img alt="Rails" src="/release-12345/images/rails.png" /> - # stylesheet_link_tag("application") - # # => <link href="/release-12345/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" /> - # - # Changing the asset_path does require that your web servers have - # knowledge of the asset template paths that you rewrite to so it's not - # suitable for out-of-the-box use. To use the example given above you - # could use something like this in your Apache VirtualHost configuration: - # - # <LocationMatch "^/release-\d+/(images|javascripts|stylesheets)/.*$"> - # # Some browsers still send conditional-GET requests if there's a - # # Last-Modified header or an ETag header even if they haven't - # # reached the expiry date sent in the Expires header. - # Header unset Last-Modified - # Header unset ETag - # FileETag None - # - # # Assets requested using a cache-busting filename should be served - # # only once and then cached for a really long time. The HTTP/1.1 - # # spec frowns on hugely-long expiration times though and suggests - # # that assets which never expire be served with an expiration date - # # 1 year from access. - # ExpiresActive On - # ExpiresDefault "access plus 1 year" - # </LocationMatch> - # - # # We use cached-busting location names with the far-future expires - # # headers to ensure that if a file does change it can force a new - # # request. The actual asset filenames are still the same though so we - # # need to rewrite the location from the cache-busting location to the - # # real asset location so that we can serve it. - # RewriteEngine On - # RewriteRule ^/release-\d+/(images|javascripts|stylesheets)/(.*)$ /$1/$2 [L] - # - module Helpers #:nodoc: - module AssetIdHelper - # You can enable or disable the asset tag ids cache. - # With the cache enabled, the asset tag helper methods will make fewer - # expensive file system calls (the default implementation checks the file - # system timestamp). However this prevents you from modifying any asset - # files while the server is running. - # - # ActionView::Helpers::AssetIdHelper.cache_asset_ids = false - mattr_accessor :cache_asset_ids - - # Add or change an asset id in the asset id cache. This can be used - # for SASS on Heroku. - # :api: public - def add_to_asset_ids_cache(source, asset_id) - self.asset_ids_cache_guard.synchronize do - self.asset_ids_cache[source] = asset_id - end - end - - mattr_accessor :asset_ids_cache - self.asset_ids_cache = {} - - mattr_accessor :asset_ids_cache_guard - self.asset_ids_cache_guard = Mutex.new - - # Use the RAILS_ASSET_ID environment variable or the source's - # modification time as its cache-busting asset id. - def rails_asset_id(source) - if asset_id = ENV["RAILS_ASSET_ID"] - asset_id - else - if self.cache_asset_ids && (asset_id = self.asset_ids_cache[source]) - asset_id - else - path = File.join(config.assets_dir, source) - asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : '' - - if self.cache_asset_ids - add_to_asset_ids_cache(source, asset_id) - end - - asset_id - end - end - end - - # Override +compute_asset_path+ to add asset id query strings to - # generated urls. See +compute_asset_path+ in AssetUrlHelper. - def compute_asset_path(source, options = {}) - source = super(source, options) - path = config.asset_path - - if path && path.respond_to?(:call) - path.call(source) - elsif path && path.is_a?(String) - path % [source] - elsif asset_id = rails_asset_id(source) - asset_id.empty? ? source : "#{source}?#{asset_id}" - end - end - end - end -end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 3beea2eb7c..4eac6514df 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -19,7 +19,6 @@ module ActionView extend ActiveSupport::Concern include AssetUrlHelper - include AssetIdHelper include TagHelper # Returns an HTML script tag for each of the +sources+ provided. diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb index 2d5f664402..3875d88a9f 100644 --- a/actionpack/lib/action_view/railtie.rb +++ b/actionpack/lib/action_view/railtie.rb @@ -20,14 +20,6 @@ module ActionView ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger } end - initializer "action_view.cache_asset_ids" do |app| - unless app.config.cache_classes - ActiveSupport.on_load(:action_view) do - ActionView::Helpers::AssetIdHelper.cache_asset_ids = false - end - end - end - initializer "action_view.set_configs" do |app| ActiveSupport.on_load(:action_view) do app.config.action_view.each do |k,v| diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 8435db3166..30bd5c159c 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -35,10 +35,6 @@ class AssetTagHelperTest < ActionView::TestCase "http://www.example.com" end - def teardown - ENV.delete('RAILS_ASSET_ID') - end - AssetPathToTag = { %(asset_path("foo")) => %(/foo), %(asset_path("style.css")) => %(/style.css), @@ -291,7 +287,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_asset_path_tag - ENV["RAILS_ASSET_ID"] = "" AssetPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -323,8 +318,7 @@ class AssetTagHelperTest < ActionView::TestCase UrlToJavascriptToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end - def test_javascript_include_tag_with_blank_asset_id - ENV["RAILS_ASSET_ID"] = "" + def test_javascript_include_tag JavascriptIncludeToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -343,7 +337,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_stylesheet_path - ENV["RAILS_ASSET_ID"] = "" StylePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -352,7 +345,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_stylesheet_url - ENV["RAILS_ASSET_ID"] = "" StyleUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -361,7 +353,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_stylesheet_link_tag - ENV["RAILS_ASSET_ID"] = "" StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -376,7 +367,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_stylesheet_link_tag_is_html_safe - ENV["RAILS_ASSET_ID"] = "" assert stylesheet_link_tag('dir/file').html_safe? assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe? end @@ -386,7 +376,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_stylesheet_link_tag_should_not_output_the_same_asset_twice - ENV["RAILS_ASSET_ID"] = "" assert_dom_equal %(<link href="/stylesheets/wellington.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/amsterdam.css" media="screen" rel="stylesheet" />), stylesheet_link_tag('wellington', 'wellington', 'amsterdam') end @@ -428,21 +417,6 @@ class AssetTagHelperTest < ActionView::TestCase FaviconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end - def test_image_tag_windows_behaviour - old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1" - # This simulates the behavior of File#exist? on windows when testing a file ending in "." - # If the file "rails.png" exists, windows will return true when asked if "rails.png." exists (notice trailing ".") - # OS X, linux etc will return false in this case. - File.stubs(:exist?).with('template/../fixtures/public/images/rails.png.').returns(true) - assert_equal '<img alt="Rails" src="/images/rails.png?1" />', image_tag('rails.png') - ensure - if old_asset_id - ENV["RAILS_ASSET_ID"] = old_asset_id - else - ENV.delete("RAILS_ASSET_ID") - end - end - def test_video_path VideoPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -491,27 +465,6 @@ class AssetTagHelperTest < ActionView::TestCase assert_equal({:autoplay => true}, options) end - def test_timebased_asset_id - expected_time = File.mtime(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).to_i.to_s - assert_equal %(<img alt="Rails" src="/images/rails.png?#{expected_time}" />), image_tag("rails.png") - end - - def test_string_asset_id - @controller.config.asset_path = "/assets.v12345%s" - - expected_path = "/assets.v12345/images/rails.png" - assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png") - end - - def test_proc_asset_id - @controller.config.asset_path = Proc.new do |asset_path| - "/assets.v12345#{asset_path}" - end - - expected_path = "/assets.v12345/images/rails.png" - assert_equal %(<img alt="Rails" src="#{expected_path}" />), image_tag("rails.png") - end - def test_image_tag_interpreting_email_cid_correctly # An inline image has no need for an alt tag to be automatically generated from the cid: assert_equal '<img src="cid:thi%25%25sis@acontentid" />', image_tag("cid:thi%25%25sis@acontentid") @@ -521,37 +474,6 @@ class AssetTagHelperTest < ActionView::TestCase assert_equal '<img alt="Image" src="cid:thi%25%25sis@acontentid" />', image_tag("cid:thi%25%25sis@acontentid", :alt => "Image") end - def test_timebased_asset_id_with_relative_url_root - @controller.config.relative_url_root = "/collaboration/hieraki" - expected_time = File.mtime(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).to_i.to_s - assert_equal %(<img alt="Rails" src="#{@controller.config.relative_url_root}/images/rails.png?#{expected_time}" />), image_tag("rails.png") - end - - # Same as above, but with script_name - def test_timebased_asset_id_with_script_name - @request.script_name = "/collaboration/hieraki" - expected_time = File.mtime(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).to_i.to_s - assert_equal %(<img alt="Rails" src="#{@request.script_name}/images/rails.png?#{expected_time}" />), image_tag("rails.png") - end - - def test_should_skip_asset_id_on_complete_url - assert_equal %(<img alt="Rails" src="http://www.example.com/rails.png" />), image_tag("http://www.example.com/rails.png") - end - - def test_should_skip_asset_id_on_scheme_relative_url - assert_equal %(<img alt="Rails" src="//www.example.com/rails.png" />), image_tag("//www.example.com/rails.png") - end - - def test_should_use_preset_asset_id - ENV["RAILS_ASSET_ID"] = "4500" - assert_equal %(<img alt="Rails" src="/images/rails.png?4500" />), image_tag("rails.png") - end - - def test_preset_empty_asset_id - ENV["RAILS_ASSET_ID"] = "" - assert_equal %(<img alt="Rails" src="/images/rails.png" />), image_tag("rails.png") - end - def test_should_not_modify_source_string source = '/images/rails.png' copy = source.dup @@ -560,7 +482,6 @@ class AssetTagHelperTest < ActionView::TestCase end def test_caching_image_path_with_caching_and_proc_asset_host_using_request - ENV['RAILS_ASSET_ID'] = '' @controller.config.asset_host = Proc.new do |source, request| if request.ssl? "#{request.protocol}#{request.host_with_port}" |