aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorChris Eppstein <chris@eppsteins.net>2011-06-27 13:48:36 -0700
committerChris Eppstein <chris@eppsteins.net>2011-06-27 13:48:36 -0700
commit96137e8bd0a0094d26cc0cf6f86642487a60735f (patch)
tree377fc0a665c7c84c2c01f3d9cd0534dabc107d3a /actionpack/lib
parent266b80c7b28c7587ab1c75aae6e3288e2f6c1aba (diff)
downloadrails-96137e8bd0a0094d26cc0cf6f86642487a60735f.tar.gz
rails-96137e8bd0a0094d26cc0cf6f86642487a60735f.tar.bz2
rails-96137e8bd0a0094d26cc0cf6f86642487a60735f.zip
Add asset_url helper and refactor the asset paths so that asset hosts can be used during asset precompilation.
Conflicts: actionpack/lib/action_view/asset_paths.rb actionpack/lib/sprockets/helpers/rails_helper.rb actionpack/test/template/sprockets_helper_test.rb
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_view/asset_paths.rb72
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb23
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb19
3 files changed, 75 insertions, 39 deletions
diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb
index 2b1fe545a6..4974bd5426 100644
--- a/actionpack/lib/action_view/asset_paths.rb
+++ b/actionpack/lib/action_view/asset_paths.rb
@@ -4,7 +4,7 @@ module ActionView
class AssetPaths #:nodoc:
attr_reader :config, :controller
- def initialize(config, controller)
+ def initialize(config, controller = nil)
@config = config
@controller = controller
end
@@ -19,15 +19,17 @@ module ActionView
source = rewrite_extension(source, dir, ext) if ext
source = rewrite_asset_path(source, dir)
-
- if controller && include_host
- has_request = controller.respond_to?(:request)
- source = rewrite_host_and_protocol(source, has_request)
- end
-
+ source = rewrite_relative_url_root(source, relative_url_root) if has_request?
+ source = rewrite_host_and_protocol(source) if include_host
source
end
+ # Return the filesystem path for the source
+ def compute_source_path(source, dir, ext)
+ source = rewrite_extension(source, dir, ext) if ext
+ File.join(config.assets_dir, dir, source)
+ end
+
def is_uri?(path)
path =~ %r{^[-a-z]+://|^cid:|^//}
end
@@ -46,13 +48,14 @@ module ActionView
relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source
end
- def rewrite_host_and_protocol(source, has_request)
- source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request
+ def has_request?
+ controller.respond_to?(:request)
+ end
+
+ def rewrite_host_and_protocol(source)
host = compute_asset_host(source)
- if has_request && host && !is_uri?(host)
- host = "#{controller.request.protocol}#{host}"
- end
- "#{host}#{source}"
+ host = "//#{host}" if host && !is_uri?(host)
+ host.nil? ? source : "#{host}#{source}"
end
# Pick an asset host for this source. Returns +nil+ if no host is set,
@@ -61,19 +64,48 @@ module ActionView
# or the value returned from invoking call on an object responding to call
# (proc or otherwise).
def compute_asset_host(source)
- if host = config.asset_host
+ if host = asset_host_config
if host.respond_to?(:call)
- case host.is_a?(Proc) ? host.arity : host.method(:call).arity
- when 2
- request = controller.respond_to?(:request) && controller.request
- host.call(source, request)
- else
- host.call(source)
+ args = [source]
+ arity = arity_of(host)
+ if arity > 1 && !has_request?
+ raise ActionController::RoutingError, "This asset host cannot be computed without a request in scope. Remove the second argument to your asset_host Proc if you do not need the request."
end
+ args << current_request if (arity > 1 || arity < 0) && has_request?
+ host.call(*args)
else
(host =~ /%d/) ? host % (source.hash % 4) : host
end
end
end
+
+ def relative_url_root
+ if controller.respond_to?(:config) && controller.config
+ controller.config.relative_url_root
+ elsif config.respond_to?(:action_controller) && config.action_controller
+ config.action_controller.relative_url_root
+ elsif Rails.respond_to?(:application) && Rails.application.config
+ Rails.application.config.action_controller.relative_url_root
+ end
+ end
+
+ def asset_host_config
+ if config.respond_to?(:asset_host)
+ config.asset_host
+ elsif Rails.respond_to?(:application)
+ Rails.application.config.action_controller.asset_host
+ end
+ end
+
+ # Returns the current request if one exists.
+ def current_request
+ controller.request if has_request?
+ end
+
+ # Returns the arity of a callable
+ def arity_of(callable)
+ callable.respond_to?(:arity) ? callable.arity : callable.method(:call).arity
+ end
+
end
end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb
index e4662a2919..16d8f3f893 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb
@@ -60,12 +60,16 @@ module ActionView
private
- def path_to_asset(source, include_host = true)
- asset_paths.compute_public_path(source, asset_name.to_s.pluralize, extension, include_host)
+ def path_to_asset(source)
+ asset_paths.compute_public_path(source, asset_name.to_s.pluralize, extension)
+ end
+
+ def path_to_asset_source(source)
+ asset_paths.compute_source_path(source, asset_name.to_s.pluralize, extension)
end
def compute_paths(*args)
- expand_sources(*args).collect { |source| asset_paths.compute_public_path(source, asset_name.pluralize, extension, false) }
+ expand_sources(*args).collect { |source| path_to_asset_source(source) }
end
def expand_sources(sources, recursive)
@@ -92,7 +96,7 @@ module ActionView
def ensure_sources!(sources)
sources.each do |source|
- asset_file_path!(path_to_asset(source, false))
+ asset_file_path!(path_to_asset_source(source))
end
end
@@ -123,19 +127,14 @@ module ActionView
# Set mtime to the latest of the combined files to allow for
# consistent ETag without a shared filesystem.
- mt = asset_paths.map { |p| File.mtime(asset_file_path(p)) }.max
+ mt = asset_paths.map { |p| File.mtime(asset_file_path!(p)) }.max
File.utime(mt, mt, joined_asset_path)
end
- def asset_file_path(path)
- File.join(config.assets_dir, path.split('?').first)
- end
-
- def asset_file_path!(path, error_if_file_is_uri = false)
- if asset_paths.is_uri?(path)
+ def asset_file_path!(absolute_path, error_if_file_is_uri = false)
+ if asset_paths.is_uri?(absolute_path)
raise(Errno::ENOENT, "Asset file #{path} is uri and cannot be merged into single file") if error_if_file_is_uri
else
- absolute_path = asset_file_path(path)
raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
return absolute_path
end
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index 9f1f0f3b68..ef7cf9e051 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -58,23 +58,28 @@ module Sprockets
end.join("\n").html_safe
end
+ def asset_path(source, default_ext = nil, body = false)
+ source = source.logical_path if source.respond_to?(:logical_path)
+ path = asset_paths.compute_public_path(source, 'assets', default_ext)
+ body ? "#{path}?body=1" : path
+ end
+
private
def debug_assets?
params[:debug_assets] == '1' ||
params[:debug_assets] == 'true'
end
- def asset_path(source, default_ext = nil, body = false)
- source = source.logical_path if source.respond_to?(:logical_path)
- path = asset_paths.compute_public_path(source, Rails.application.config.assets.prefix, default_ext, true)
- body ? "#{path}?body=1" : path
- end
-
class AssetPaths < ::ActionView::AssetPaths #:nodoc:
def compute_public_path(source, dir, ext=nil, include_host=true)
super(source, Rails.application.config.assets.prefix, ext, include_host)
end
+ # Return the filesystem path for the source
+ def compute_source_path(source, ext)
+ asset_for(source, ext)
+ end
+
def asset_for(source, ext)
source = source.to_s
return nil if is_uri?(source)
@@ -104,7 +109,7 @@ module Sprockets
# When included in Sprockets::Context, we need to ask the top-level config as the controller is not available
def performing_caching?
- @config ? @config.perform_caching : Rails.application.config.action_controller.perform_caching
+ @config ? @config.perform_caching : Rails.application.config.action_controller.perform_caching
end
end
end