Changeset 6161
- Timestamp:
- 02/18/07 06:44:20 (2 years ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_view/helpers/asset_tag_helper.rb (modified) (8 diffs)
- trunk/actionpack/test/template/asset_tag_helper_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r6159 r6161 1 1 *SVN* 2 3 * Work around the two connection per host browser limit: use asset%d.myapp.com to distribute asset requests among asset[0123].myapp.com. Use a DNS wildcard or CNAMEs to map these hosts to your asset server. See http://www.die.net/musings/page_load_time/ for background. [Jeremy Kemper] 2 4 3 5 * Added default mime type for CSS (Mime::CSS) [DHH] trunk/actionpack/lib/action_view/helpers/asset_tag_helper.rb
r6057 r6161 12 12 # 13 13 # ActionController::Base.asset_host = "http://assets.example.com" 14 # image_tag("rails.png") 14 # image_tag("rails.png") 15 15 # => <img src="http://assets.example.com/images/rails.png" alt="Rails" /> 16 16 # stylesheet_include_tag("application") 17 17 # => <link href="http://assets.example.com/stylesheets/application.css" media="screen" rel="Stylesheet" type="text/css" /> 18 # 19 # Since browsers typically open at most two connections to a single host, 20 # your assets often wait in single file for their turn to load. 21 # 22 # Use a %d wildcard in asset_host (asset%d.myapp.com) to automatically 23 # distribute asset requests among four hosts (asset0-asset3.myapp.com) 24 # so browsers will open eight connections rather than two. Use wildcard 25 # DNS to CNAME the wildcard to your real asset host. 26 # 27 # Note: this is purely a browser performance optimization and is not meant 28 # for server load balancing. See http://www.die.net/musings/page_load_time/ 29 # for background. 18 30 module AssetTagHelper 19 31 # Returns a link tag that browsers and news readers can use to auto-detect 20 # an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or 32 # an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or 21 33 # <tt>:atom</tt>. Control the link options in url_for format using the 22 34 # +url_options+. You can modify the LINK tag itself in +tag_options+. … … 37 49 def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {}) 38 50 tag( 39 "link", 51 "link", 40 52 "rel" => tag_options[:rel] || "alternate", 41 53 "type" => tag_options[:type] || Mime::Type.lookup_by_extension(type.to_s).to_s, … … 54 66 # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js 55 67 def javascript_path(source) 56 compute_public_path(source, 'javascripts', 'js') 68 compute_public_path(source, 'javascripts', 'js') 57 69 end 58 70 … … 65 77 # current page or you can pass the full path relative to your document 66 78 # root. To include the Prototype and Scriptaculous javascript libraries in 67 # your application, pass <tt>:defaults</tt> as the source. When using 68 # :defaults, if an <tt>application.js</tt> file exists in your public 69 # javascripts directory, it will be included as well. You can modify the 70 # html attributes of the script tag by passing a hash as the last argument. 79 # your application, pass <tt>:defaults</tt> as the source. When using 80 # :defaults, if an <tt>application.js</tt> file exists in your public 81 # javascripts directory, it will be included as well. You can modify the 82 # html attributes of the script tag by passing a hash as the last argument. 71 83 # 72 84 # javascript_include_tag "xmlhr" # => … … 85 97 options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { } 86 98 87 if sources.include?(:defaults) 88 sources = sources[0..(sources.index(:defaults))] + 89 @@javascript_default_sources.dup + 99 if sources.include?(:defaults) 100 sources = sources[0..(sources.index(:defaults))] + 101 @@javascript_default_sources.dup + 90 102 sources[(sources.index(:defaults) + 1)..sources.length] 91 103 92 sources.delete(:defaults) 93 sources << "application" if defined?(RAILS_ROOT) && File.exists?("#{RAILS_ROOT}/public/javascripts/application.js") 104 sources.delete(:defaults) 105 sources << "application" if defined?(RAILS_ROOT) && File.exists?("#{RAILS_ROOT}/public/javascripts/application.js") 94 106 end 95 107 96 108 sources.collect do |source| 97 source = javascript_path(source) 109 source = javascript_path(source) 98 110 content_tag("script", "", { "type" => "text/javascript", "src" => source }.merge(options)) 99 111 end.join("\n") 100 112 end 101 113 102 114 # Register one or more additional JavaScript files to be included when 103 115 # <tt>javascript_include_tag :defaults</tt> is called. This method is 104 # only intended to be called from plugin initialization to register additional 116 # only intended to be called from plugin initialization to register additional 105 117 # .js files that the plugin installed in <tt>public/javascripts</tt>. 106 118 def self.register_javascript_include_default(*sources) 107 119 @@javascript_default_sources.concat(sources) 108 120 end 109 121 110 122 def self.reset_javascript_include_default #:nodoc: 111 123 @@javascript_default_sources = JAVASCRIPT_DEFAULT_SOURCES.dup … … 166 178 167 179 # Returns an html image tag for the +source+. The +source+ can be a full 168 # path or a file that exists in your public images directory. Note that 180 # path or a file that exists in your public images directory. Note that 169 181 # specifying a filename without the extension is now deprecated in Rails. 170 182 # You can add html attributes using the +options+. The +options+ supports 171 183 # two additional keys for convienence and conformance: 172 184 # 173 # * <tt>:alt</tt> - If no alt text is given, the file name part of the 185 # * <tt>:alt</tt> - If no alt text is given, the file name part of the 174 186 # +source+ is used (capitalized and without the extension) 175 # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes 187 # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes 176 188 # width="30" and height="45". <tt>:size</tt> will be ignored if the 177 189 # value is not in the correct format. … … 185 197 def image_tag(source, options = {}) 186 198 options.symbolize_keys! 187 199 188 200 options[:src] = image_path(source) 189 201 options[:alt] ||= File.basename(options[:src], '.*').split('.').first.capitalize 190 202 191 203 if options[:size] 192 204 options[:width], options[:height] = options[:size].split("x") if options[:size] =~ %r{^\d+x\d+$} … … 196 208 tag("img", options) 197 209 end 198 210 199 211 private 212 # Add the .ext if not present. Return full URLs otherwise untouched. 213 # Prefix with /dir/ if lacking a leading /. Account for relative URL 214 # roots. Rewrite the asset path for cache-busting asset ids. Include 215 # a single or wildcarded asset host if configured. 200 216 def compute_public_path(source, dir, ext) 201 source = source.dup 202 source << ".#{ext}" if File.extname(source).blank? 203 unless source =~ %r{^[-a-z]+://} 217 source += ".#{ext}" if File.extname(source).blank? 218 if source =~ %r{^[-a-z]+://} 219 source 220 else 204 221 source = "/#{dir}/#{source}" unless source[0] == ?/ 205 asset_id = rails_asset_id(source)206 source << '?' + asset_id if defined?(RAILS_ROOT) && !asset_id.blank?207 source = "#{ActionController::Base.asset_host}#{@controller.request.relative_url_root}#{source}"222 source = "#{@controller.request.relative_url_root}#{source}" 223 rewrite_asset_path!(source) 224 "#{compute_asset_host(source)}#{source}" 208 225 end 209 source 210 end 211 226 end 227 228 # Pick an asset host for this source. Returns nil if no host is set, 229 # the host if no wildcard is set, or the host interpolated with the 230 # numbers 0-3 if it contains %d. The number is the source hash mod 4. 231 def compute_asset_host(source) 232 if host = ActionController::Base.asset_host 233 host % (source.hash % 4) 234 end 235 end 236 237 # Use the RAILS_ASSET_ID environment variable or the source's 238 # modification time as its cache-busting asset id. 212 239 def rails_asset_id(source) 213 ENV["RAILS_ASSET_ID"] || 240 ENV["RAILS_ASSET_ID"] || 214 241 File.mtime("#{RAILS_ROOT}/public/#{source}").to_i.to_s rescue "" 242 end 243 244 # Break out the asset path rewrite so you wish to put the asset id 245 # someplace other than the query string. 246 def rewrite_asset_path!(source) 247 asset_id = rails_asset_id(source) 248 source << "?#{asset_id}" if defined?(RAILS_ROOT) && !asset_id.blank? 215 249 end 216 250 end trunk/actionpack/test/template/asset_tag_helper_test.rb
r6057 r6161 224 224 ActionController::Base.asset_host = "" 225 225 end 226 227 def test_should_wildcard_asset_host_between_zero_and_four 228 ActionController::Base.asset_host = 'http://a%d.example.com' 229 assert_match %r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_path('xml.png') 230 ensure 231 ActionController::Base.asset_host = nil 232 end 226 233 end