require 'active_support/configurable' module ActiveAssets module ActiveExpansions class Expansions include AssetScope include TypeInferrable include ActiveSupport::Configurable include Configurable ActiveSupport.run_load_hooks(:active_expansions, self) def initialize @expansions = Hash.new(&method(:build_expansions_hash_with_defaults)) end def register(&blk) instance_eval(&blk) if block_given? self end def namespace(name, &blk) @current_namespace = name instance_eval(&blk) ensure @current_namespace = nil end def asset(path, options = {}) deferred_expansion_name, deferred_expansion_options = @deferred_expansion_config inferred_type, extension = inferred_type(path) options = HashWithIndifferentAccess.new(options).reverse_merge( :type => inferred_type || @current_type, :expansion_name => deferred_expansion_name, :group => @current_groups ) expansion_options = update_expansion_options(deferred_expansion_options || {}, options[:type]) # asset call below is executed in the scope of the ActiveAssets::Expansion @expansions[options[:type] || extension][options[:expansion_name]].configure(expansion_options) do asset(path, options) end end alias_method :a, :asset alias_method :_, :asset def expansion(name, options = {}, &blk) options = update_expansion_options(options) if options[:type].present? @expansions[options[:type]][name].configure(options, &blk) else defer_expansion(name, options, &blk) end end def javascripts Javascripts.new(@expansions[:js]) end def stylesheets Stylesheets.new(@expansions[:css]) end def all @expansions[:js].values + @expansions[:css].values end def clear @expansions.clear end private def defer_expansion(name, options, &blk) @deferred_expansion_config = [name, options] instance_eval(&blk) ensure @deferred_expansion_config = nil end def build_expansions_hash_with_defaults(expansions, expansion_type) raise Asset::AmbiguousContext.new(:type) if expansion_type.blank? raise Asset::InvalidAssetType.new(expansion_type) unless Asset::VALID_TYPES.include?(expansion_type.to_sym) expansions[expansion_type.to_sym] = build_typed_expansion_hash_with_defaults end def build_typed_expansion_hash_with_defaults Hash.new do |typed_expansions, expansion_name| raise Asset::AmbiguousContext.new(:name) if expansion_name.blank? typed_expansions[expansion_name] = Expansion.new(expansion_name) end end def update_expansion_options(options, asset_type = nil) o = options.reverse_merge(:type => @current_ytpe, :namespace => @current_namespace) o.update(:type => asset_type) if asset_type o end end end end