提交 607829a3 编写于 作者: J Joshua Peek

Remove old asset tag concatenation

Use sprockets, jammit, or some other asset bundler
上级 27683b52
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/file'
require 'action_view/helpers/tag_helper'
module ActionView
module Helpers
module AssetTagHelper
class AssetIncludeTag #:nodoc:
include TagHelper
attr_reader :config, :asset_paths
class_attribute :expansions
def self.inherited(base)
base.expansions = { }
end
def initialize(config, asset_paths)
@config = config
@asset_paths = asset_paths
end
def asset_name
raise NotImplementedError
end
def extension
raise NotImplementedError
end
def custom_dir
raise NotImplementedError
end
def asset_tag(source, options)
raise NotImplementedError
end
def include_tag(*sources)
options = sources.extract_options!.stringify_keys
concat = options.delete("concat")
cache = concat || options.delete("cache")
recursive = options.delete("recursive")
if concat || (config.perform_caching && cache)
joined_name = (cache == true ? "all" : cache) + ".#{extension}"
joined_path = File.join((joined_name[/^#{File::SEPARATOR}/] ? config.assets_dir : custom_dir), joined_name)
unless config.perform_caching && File.exists?(joined_path)
write_asset_file_contents(joined_path, compute_paths(sources, recursive))
end
asset_tag(joined_name, options)
else
sources = expand_sources(sources, recursive)
ensure_sources!(sources) if cache
sources.collect { |source| asset_tag(source, options) }.join("\n").html_safe
end
end
private
def path_to_asset(source, options = {})
asset_paths.compute_public_path(source, asset_name.to_s.pluralize, options.merge(:ext => 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| path_to_asset_source(source) }
end
def expand_sources(sources, recursive)
if sources.first == :all
collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}")
else
sources.inject([]) do |list, source|
determined_source = determine_source(source, expansions)
update_source_list(list, determined_source)
end
end
end
def update_source_list(list, source)
case source
when String
list.delete(source)
list << source
when Array
updated_sources = source - list
list.concat(updated_sources)
end
end
def ensure_sources!(sources)
sources.each do |source|
asset_file_path!(path_to_asset_source(source))
end
end
def collect_asset_files(*path)
dir = path.first
Dir[File.join(*path.compact)].collect do |file|
file[-(file.size - dir.size - 1)..-1].sub(/\.\w+$/, '')
end.sort
end
def determine_source(source, collection)
case source
when Symbol
collection[source] || raise(ArgumentError, "No expansion found for #{source.inspect}")
else
source
end
end
def join_asset_file_contents(paths)
paths.collect { |path| File.read(asset_file_path!(path, true)) }.join("\n\n")
end
def write_asset_file_contents(joined_asset_path, asset_paths)
FileUtils.mkdir_p(File.dirname(joined_asset_path))
File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
# 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
File.utime(mt, mt, joined_asset_path)
end
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
raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
return absolute_path
end
end
end
end
end
end
require 'active_support/core_ext/file'
require 'action_view/helpers/asset_tag_helpers/asset_include_tag'
module ActionView
module Helpers
module AssetTagHelper
class JavascriptIncludeTag < AssetIncludeTag #:nodoc:
def asset_name
'javascript'
end
def extension
'js'
end
def asset_tag(source, options)
content_tag("script", "", { "src" => path_to_asset(source) }.merge(options))
end
def custom_dir
config.javascripts_dir
end
private
def expand_sources(sources, recursive = false)
if sources.include?(:all)
all_asset_files = (collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}") - ['application'])
add_application_js(all_asset_files, sources)
((determine_source(:defaults, expansions).dup & all_asset_files) + all_asset_files).uniq
else
expanded_sources = sources.inject([]) do |list, source|
determined_source = determine_source(source, expansions)
update_source_list(list, determined_source)
end
add_application_js(expanded_sources, sources)
expanded_sources
end
end
def add_application_js(expanded_sources, sources)
if (sources.include?(:defaults) || sources.include?(:all)) && File.exist?(File.join(custom_dir, "application.#{extension}"))
expanded_sources.delete('application')
expanded_sources << "application"
end
end
end
module JavascriptTagHelpers
extend ActiveSupport::Concern
module ClassMethods
# Register one or more javascript files to be included when <tt>symbol</tt>
# is passed to <tt>javascript_include_tag</tt>. This method is typically intended
# to be called from plugin initialization to register javascript files
# that the plugin installed in <tt>public/javascripts</tt>.
#
# ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"]
#
# javascript_include_tag :monkey # =>
# <script src="/javascripts/head.js"></script>
# <script src="/javascripts/body.js"></script>
# <script src="/javascripts/tail.js"></script>
def register_javascript_expansion(expansions)
js_expansions = JavascriptIncludeTag.expansions
expansions.each do |key, values|
js_expansions[key] = (js_expansions[key] || []) | Array(values)
end
end
end
# Computes the path to a javascript asset in the public javascripts directory.
# If the +source+ filename has no extension, .js will be appended (except for explicit URIs)
# Full paths from the document root will be passed through.
......@@ -101,15 +36,6 @@ def javascript_url(source)
#
# When passing paths, the ".js" extension is optional.
#
# If the application is not using the asset pipeline, to include the default JavaScript
# expansion pass <tt>:defaults</tt> as source. By default, <tt>:defaults</tt> loads jQuery,
# and that can be overridden in <tt>config/application.rb</tt>:
#
# config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js)
#
# When using <tt>:defaults</tt> or <tt>:all</tt>, if an <tt>application.js</tt> file exists
# in <tt>public/javascripts</tt> it will be included as well at the end.
#
# You can modify the HTML attributes of the script tag by passing a hash as the
# last argument.
#
......@@ -129,65 +55,14 @@ def javascript_url(source)
# javascript_include_tag "http://www.example.com/xmlhr.js"
# # => <script src="http://www.example.com/xmlhr.js"></script>
#
# javascript_include_tag :defaults
# # => <script src="/javascripts/jquery.js?1284139606"></script>
# # <script src="/javascripts/rails.js?1284139606"></script>
# # <script src="/javascripts/application.js?1284139606"></script>
#
# Note: The application.js file is only referenced if it exists
#
# You can also include all JavaScripts in the +javascripts+ directory using <tt>:all</tt> as the source:
#
# javascript_include_tag :all
# # => <script src="/javascripts/jquery.js?1284139606"></script>
# # <script src="/javascripts/rails.js?1284139606"></script>
# # <script src="/javascripts/shop.js?1284139606"></script>
# # <script src="/javascripts/checkout.js?1284139606"></script>
# # <script src="/javascripts/application.js?1284139606"></script>
#
# Note that your defaults of choice will be included first, so they will be available to all subsequently
# included files.
#
# If you want Rails to search in all the subdirectories under <tt>public/javascripts</tt>, you should
# explicitly set <tt>:recursive</tt>:
#
# javascript_include_tag :all, :recursive => true
#
# == Caching multiple JavaScripts into one
#
# You can also cache multiple JavaScripts into one file, which requires less HTTP connections to download
# and can better be compressed by gzip (leading to faster transfers). Caching will only happen if
# <tt>config.perform_caching</tt> is set to true (which is the case by default for the Rails
# production environment, but not for the development environment).
#
# # assuming config.perform_caching is false
# javascript_include_tag :all, :cache => true
# # => <script src="/javascripts/jquery.js?1284139606"></script>
# # <script src="/javascripts/rails.js?1284139606"></script>
# # <script src="/javascripts/shop.js?1284139606"></script>
# # <script src="/javascripts/checkout.js?1284139606"></script>
# # <script src="/javascripts/application.js?1284139606"></script>
#
# # assuming config.perform_caching is true
# javascript_include_tag :all, :cache => true
# # => <script src="/javascripts/all.js?1344139789"></script>
#
# # assuming config.perform_caching is false
# javascript_include_tag "jquery", "cart", "checkout", :cache => "shop"
# # => <script src="/javascripts/jquery.js?1284139606"></script>
# # <script src="/javascripts/cart.js?1289139157"></script>
# # <script src="/javascripts/checkout.js?1299139816"></script>
#
# # assuming config.perform_caching is true
# javascript_include_tag "jquery", "cart", "checkout", :cache => "shop"
# # => <script src="/javascripts/shop.js?1299139816"></script>
#
# The <tt>:recursive</tt> option is also available for caching:
#
# 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)
options = sources.extract_options!.stringify_keys
sources.dup.map { |source|
tag_options = {
"src" => path_to_javascript(source)
}.merge(options)
content_tag(:script, "", tag_options)
}.join("\n").html_safe
end
end
end
......
require 'active_support/core_ext/file'
require 'action_view/helpers/asset_tag_helpers/asset_include_tag'
module ActionView
module Helpers
module AssetTagHelper
class StylesheetIncludeTag < AssetIncludeTag #:nodoc:
def asset_name
'stylesheet'
end
def extension
'css'
end
def asset_tag(source, options)
# We force the :request protocol here to avoid a double-download bug in IE7 and IE8
tag("link", { "rel" => "stylesheet", "media" => "screen", "href" => path_to_asset(source, :protocol => :request) }.merge(options))
end
def custom_dir
config.stylesheets_dir
end
end
module StylesheetTagHelpers
extend ActiveSupport::Concern
module ClassMethods
# Register one or more stylesheet files to be included when <tt>symbol</tt>
# is passed to <tt>stylesheet_link_tag</tt>. This method is typically intended
# to be called from plugin initialization to register stylesheet files
# that the plugin installed in <tt>public/stylesheets</tt>.
#
# ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]
#
# stylesheet_link_tag :monkey # =>
# <link href="/stylesheets/head.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/body.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" />
def register_stylesheet_expansion(expansions)
style_expansions = StylesheetIncludeTag.expansions
expansions.each do |key, values|
style_expansions[key] = (style_expansions[key] || []) | Array(values)
end
end
end
# Computes the path to a stylesheet asset in the public stylesheets directory.
# If the +source+ filename has no extension, <tt>.css</tt> will be appended (except for explicit URIs).
# Full paths from the document root will be passed through.
......@@ -96,56 +54,18 @@ def stylesheet_url(source)
# <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" />
# <link href="/css/stylish.css" media="screen" rel="stylesheet" />
#
# You can also include all styles in the stylesheets directory using <tt>:all</tt> as the source:
#
# stylesheet_link_tag :all # =>
# <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" />
#
# If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set <tt>:recursive</tt>:
#
# stylesheet_link_tag :all, :recursive => true
#
# == Caching multiple stylesheets into one
#
# You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be
# compressed by gzip (leading to faster transfers). Caching will only happen if +config.perform_caching+
# is set to true (which is the case by default for the Rails production environment, but not for the development
# environment). Examples:
#
# stylesheet_link_tag :all, :cache => true # when config.perform_caching is false =>
# <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag :all, :cache => true # when config.perform_caching is true =>
# <link href="/stylesheets/all.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is false =>
# <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is true =>
# <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" />
#
# The <tt>:recursive</tt> option is also available for caching:
#
# stylesheet_link_tag :all, :cache => true, :recursive => true
#
# To force concatenation (even in development mode) set <tt>:concat</tt> to true. This is useful if
# you have too many stylesheets for IE to load.
#
# stylesheet_link_tag :all, :concat => true
#
def stylesheet_link_tag(*sources)
@stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths)
@stylesheet_include.include_tag(*sources)
options = sources.extract_options!.stringify_keys
sources.uniq.map { |source|
tag_options = {
"rel" => "stylesheet",
"media" => "screen",
"href" => path_to_stylesheet(source)
}.merge(options)
tag(:link, tag_options)
}.join("\n").html_safe
end
end
end
end
end
......@@ -30,18 +30,6 @@ class Railtie < Rails::Railtie
end
end
initializer "action_view.javascript_expansions" do |app|
ActiveSupport.on_load(:action_view) do
ActionView::Helpers::AssetTagHelper.register_javascript_expansion(
app.config.action_view.delete(:javascript_expansions)
)
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion(
app.config.action_view.delete(:stylesheet_expansions)
)
end
end
initializer "action_view.set_configs" do |app|
ActiveSupport.on_load(:action_view) do
app.config.action_view.each do |k,v|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册