aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile2
-rw-r--r--actionpack/lib/abstract_controller/asset_paths.rb4
-rw-r--r--actionpack/lib/action_controller/railtie.rb1
-rw-r--r--actionpack/lib/action_view/helpers.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb14
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb14
-rw-r--r--actionpack/lib/action_view/helpers/sprockets_helper.rb85
-rw-r--r--actionpack/test/fixtures/sprockets/app/javascripts/application.js0
-rw-r--r--actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js0
-rw-r--r--actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js0
-rw-r--r--actionpack/test/fixtures/sprockets/app/stylesheets/application.css0
-rw-r--r--actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css0
-rw-r--r--actionpack/test/fixtures/sprockets/app/stylesheets/style.css0
-rw-r--r--actionpack/test/template/sprockets_helper_test.rb96
-rw-r--r--railties/lib/rails/application.rb32
-rw-r--r--railties/lib/rails/application/configuration.rb9
-rw-r--r--railties/lib/rails/application/finisher.rb21
-rw-r--r--railties/lib/rails/tasks.rb1
-rw-r--r--railties/lib/rails/tasks/assets.rake6
19 files changed, 278 insertions, 9 deletions
diff --git a/Gemfile b/Gemfile
index 879598c6db..414c688cad 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,6 +11,8 @@ end
gem "rack", :git => "git://github.com/rack/rack.git"
gem "rack-test", :git => "git://github.com/brynary/rack-test.git"
+gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git"
+
gem "rake", ">= 0.8.7"
gem "mocha", ">= 0.9.8"
diff --git a/actionpack/lib/abstract_controller/asset_paths.rb b/actionpack/lib/abstract_controller/asset_paths.rb
index 9ca2fb742f..ad14cd6d87 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, :stylesheets_dir
+ config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, :stylesheets_dir, :use_sprockets
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index f0c29825ba..0dd13fa9bf 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -21,6 +21,7 @@ module ActionController
paths = app.config.paths
options = app.config.action_controller
+ options.use_sprockets ||= app.config.assets.enabled
options.assets_dir ||= paths["public"].first
options.javascripts_dir ||= paths["public/javascripts"].first
options.stylesheets_dir ||= paths["public/stylesheets"].first
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index d338ce616a..cb1ab64121 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -22,6 +22,7 @@ module ActionView #:nodoc:
autoload :RecordTagHelper
autoload :SanitizeHelper
autoload :ScriptaculousHelper
+ autoload :SprocketsHelper
autoload :TagHelper
autoload :TextHelper
autoload :TranslationHelper
@@ -52,6 +53,7 @@ module ActionView #:nodoc:
include RecordTagHelper
include SanitizeHelper
include ScriptaculousHelper
+ include SprocketsHelper
include TagHelper
include TextHelper
include TranslationHelper
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
index 82bbfcc7d2..ed95f1c018 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
@@ -86,7 +86,11 @@ module ActionView
# javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr
# javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js
def javascript_path(source)
- asset_paths.compute_public_path(source, 'javascripts', 'js')
+ if config.use_sprockets
+ sprockets_javascript_path(source)
+ else
+ asset_paths.compute_public_path(source, 'javascripts', 'js')
+ end
end
alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
@@ -173,8 +177,12 @@ module ActionView
#
# javascript_include_tag :all, :cache => true, :recursive => true
def javascript_include_tag(*sources)
- @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths)
- @javascript_include.include_tag(*sources)
+ if config.use_sprockets
+ sprockets_javascript_include_tag(*sources)
+ else
+ @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths)
+ @javascript_include.include_tag(*sources)
+ end
end
end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
index a48c87b49a..a994afb65e 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
@@ -63,7 +63,11 @@ module ActionView
# stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style
# stylesheet_path "http://www.railsapplication.com/css/style.css" # => http://www.railsapplication.com/css/style.css
def stylesheet_path(source)
- asset_paths.compute_public_path(source, 'stylesheets', 'css')
+ if config.use_sprockets
+ sprockets_stylesheet_path(source)
+ else
+ asset_paths.compute_public_path(source, 'stylesheets', 'css')
+ end
end
alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route
@@ -136,8 +140,12 @@ module ActionView
# stylesheet_link_tag :all, :concat => true
#
def stylesheet_link_tag(*sources)
- @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths)
- @stylesheet_include.include_tag(*sources)
+ if config.use_sprockets
+ sprockets_stylesheet_link_tag(*sources)
+ else
+ @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths)
+ @stylesheet_include.include_tag(*sources)
+ end
end
end
diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb
new file mode 100644
index 0000000000..408a2030ab
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb
@@ -0,0 +1,85 @@
+require 'uri'
+
+module ActionView
+ module Helpers
+ module SprocketsHelper
+ def sprockets_javascript_path(source)
+ compute_sprockets_path source, 'assets', 'js'
+ end
+
+ def sprockets_javascript_include_tag(source, options = {})
+ options = {
+ 'type' => "text/javascript",
+ 'src' => sprockets_javascript_path(source)
+ }.merge(options.stringify_keys)
+
+ content_tag 'script', "", options
+ end
+
+ def sprockets_stylesheet_path(source)
+ compute_sprockets_path source, 'assets', 'css'
+ end
+
+ def sprockets_stylesheet_link_tag(source, options = {})
+ options = {
+ 'rel' => "stylesheet",
+ 'type' => "text/css",
+ 'media' => "screen",
+ 'href' => sprockets_stylesheet_path(source)
+ }.merge(options.stringify_keys)
+
+ tag 'link', options
+ end
+
+ private
+ def compute_sprockets_path(source, dir, default_ext)
+ source = source.to_s
+
+ return source if URI.parse(source).host
+
+ # Add /javscripts to relative paths
+ if source[0] != ?/
+ source = "/#{dir}/#{source}"
+ end
+
+ # Add default extension if there isn't one
+ if default_ext && File.extname(source).empty?
+ source = "#{source}.#{default_ext}"
+ end
+
+ # Fingerprint url
+ if source =~ /^\/#{dir}\/(.+)/
+ source = assets.path($1, config.perform_caching, dir)
+ end
+
+ host = compute_asset_host(source)
+
+ if controller.respond_to?(:request) && host && URI.parse(host).host
+ source = "#{controller.request.protocol}#{host}#{source}"
+ end
+
+ source
+ end
+
+ def compute_asset_host(source)
+ if host = config.asset_host
+ if host.is_a?(Proc) || 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)
+ end
+ else
+ (host =~ /%d/) ? host % (source.hash % 4) : host
+ end
+ end
+ end
+
+ def assets
+ Rails.application.assets
+ end
+ end
+ end
+end
diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/application.js b/actionpack/test/fixtures/sprockets/app/javascripts/application.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/test/fixtures/sprockets/app/javascripts/application.js
diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js b/actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js
diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js b/actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js
diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/application.css b/actionpack/test/fixtures/sprockets/app/stylesheets/application.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/test/fixtures/sprockets/app/stylesheets/application.css
diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css b/actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css
diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/style.css b/actionpack/test/fixtures/sprockets/app/stylesheets/style.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/test/fixtures/sprockets/app/stylesheets/style.css
diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb
new file mode 100644
index 0000000000..67aee86d02
--- /dev/null
+++ b/actionpack/test/template/sprockets_helper_test.rb
@@ -0,0 +1,96 @@
+require 'abstract_unit'
+require 'sprockets'
+
+class SprocketsHelperTest < ActionView::TestCase
+ tests ActionView::Helpers::SprocketsHelper
+
+ attr_accessor :assets
+
+ def setup
+ super
+
+ @controller = BasicController.new
+
+ @request = Class.new do
+ def protocol() 'http://' end
+ def ssl?() false end
+ def host_with_port() 'localhost' end
+ end.new
+
+ @controller.request = @request
+
+ @assets = Sprockets::Environment.new
+ @assets.paths << FIXTURES.join("sprockets/app/javascripts")
+ @assets.paths << FIXTURES.join("sprockets/app/stylesheets")
+
+ config.perform_caching = true
+ end
+
+ def url_for(*args)
+ "http://www.example.com"
+ end
+
+ test "javascript path" do
+ assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.js",
+ sprockets_javascript_path(:application)
+
+ assert_equal "/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js",
+ sprockets_javascript_path("xmlhr")
+ assert_equal "/assets/dir/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js",
+ sprockets_javascript_path("dir/xmlhr.js")
+
+ assert_equal "/dir/xmlhr.js",
+ sprockets_javascript_path("/dir/xmlhr")
+
+ assert_equal "http://www.railsapplication.com/js/xmlhr",
+ sprockets_javascript_path("http://www.railsapplication.com/js/xmlhr")
+ assert_equal "http://www.railsapplication.com/js/xmlhr.js",
+ sprockets_javascript_path("http://www.railsapplication.com/js/xmlhr.js")
+ end
+
+ test "javascript include tag" do
+ assert_equal '<script src="/assets/application-d41d8cd98f00b204e9800998ecf8427e.js" type="text/javascript"></script>',
+ sprockets_javascript_include_tag(:application)
+
+ assert_equal '<script src="/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js" type="text/javascript"></script>',
+ sprockets_javascript_include_tag("xmlhr")
+ assert_equal '<script src="/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js" type="text/javascript"></script>',
+ sprockets_javascript_include_tag("xmlhr.js")
+ assert_equal '<script src="http://www.railsapplication.com/xmlhr" type="text/javascript"></script>',
+ sprockets_javascript_include_tag("http://www.railsapplication.com/xmlhr")
+ end
+
+ test "stylesheet path" do
+ assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.css",
+ sprockets_stylesheet_path(:application)
+
+ assert_equal "/assets/style-d41d8cd98f00b204e9800998ecf8427e.css",
+ sprockets_stylesheet_path("style")
+ assert_equal "/assets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css",
+ sprockets_stylesheet_path("dir/style.css")
+ assert_equal "/dir/style.css",
+ sprockets_stylesheet_path("/dir/style.css")
+
+ assert_equal "http://www.railsapplication.com/css/style",
+ sprockets_stylesheet_path("http://www.railsapplication.com/css/style")
+ assert_equal "http://www.railsapplication.com/css/style.css",
+ sprockets_stylesheet_path("http://www.railsapplication.com/css/style.css")
+ end
+
+ test "stylesheet link tag" do
+ assert_equal '<link href="/assets/application-d41d8cd98f00b204e9800998ecf8427e.css" media="screen" rel="stylesheet" type="text/css" />',
+ sprockets_stylesheet_link_tag(:application)
+
+ assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="screen" rel="stylesheet" type="text/css" />',
+ sprockets_stylesheet_link_tag("style")
+ assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="screen" rel="stylesheet" type="text/css" />',
+ sprockets_stylesheet_link_tag("style.css")
+
+ assert_equal '<link href="http://www.railsapplication.com/style.css" media="screen" rel="stylesheet" type="text/css" />',
+ sprockets_stylesheet_link_tag("http://www.railsapplication.com/style.css")
+ assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="all" rel="stylesheet" type="text/css" />',
+ sprockets_stylesheet_link_tag("style", :media => "all")
+ assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="print" rel="stylesheet" type="text/css" />',
+ sprockets_stylesheet_link_tag("style", :media => "print")
+ end
+end
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 1b834275a7..92f03f06bf 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -137,6 +137,38 @@ module Rails
@config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd))
end
+ def assets
+ @assets ||= build_asset_environment
+ end
+ attr_writer :assets
+
+ def build_asset_environment
+ return unless config.assets.enabled
+ require 'sprockets'
+ env = Sprockets::Environment.new(root.to_s)
+ env.static_root = File.join(root.join("public"), config.assets.prefix)
+ env
+ end
+
+ initializer :add_sprockets_paths do |app|
+ if config.assets.enabled
+ paths = [
+ "app/javascripts",
+ "app/stylesheets",
+ "vendor/plugins/*/app/javascripts",
+ "vendor/plugins/*/app/stylesheets",
+ "vendor/plugins/*/javascripts",
+ "vendor/plugins/*/stylesheets"
+ ] + config.assets.paths
+
+ paths.each do |pattern|
+ Dir[app.root.join(pattern)].each do |dir|
+ app.assets.paths << dir
+ end
+ end
+ end
+ end
+
protected
def default_asset_path
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 23b0e765ae..4a042e0033 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -9,7 +9,8 @@ module Rails
:filter_parameters, :helpers_paths, :logger,
:preload_frameworks, :reload_plugins,
:secret_token, :serve_static_assets, :session_options,
- :time_zone, :whiny_nils, :force_ssl
+ :time_zone, :whiny_nils, :force_ssl,
+ :assets
attr_writer :log_level
@@ -29,6 +30,12 @@ module Rails
@log_level = nil
@middleware = app_middleware
@generators = app_generators
+
+ @assets = ActiveSupport::OrderedOptions.new
+ @assets.enabled = false
+ @assets.paths = []
+ @assets.precompile = []
+ @assets.prefix = "/assets"
end
def compiled_asset_path
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index a45b61c99c..bae464a840 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -33,6 +33,27 @@ module Rails
end
end
+ initializer :add_sprockets_route do |app|
+ assets = config.assets
+ if assets.enabled
+ app.routes.append do
+ mount app.assets => assets.prefix
+ end
+ end
+ end
+
+ initializer :set_sprockets_logger do |app|
+ if config.assets.enabled
+ app.assets.logger = Rails.logger
+ end
+ end
+
+ initializer :index_sprockets_environment do |app|
+ if config.assets.enabled && config.action_controller.perform_caching
+ app.assets = app.assets.index
+ end
+ end
+
initializer :build_middleware_stack do
build_middleware_stack
end
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index af52014728..4d09b0c2c0 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -3,6 +3,7 @@ $VERBOSE = nil
# Load Rails rakefile extensions
%w(
annotations
+ assets
documentation
framework
log
diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake
new file mode 100644
index 0000000000..396ce728a1
--- /dev/null
+++ b/railties/lib/rails/tasks/assets.rake
@@ -0,0 +1,6 @@
+namespace :assets do
+ task :compile => :environment do
+ assets = Rails.application.config.assets.precompile
+ Rails.application.assets.precompile(*assets)
+ end
+end