module Sinatra module AssetPack # A package. # # == Common usage # # package = assets.packages['application.css'] # # package.files # List of local files # package.paths # List of URI paths # # package.type # :css or :js # package.css? # package.js? # # package.path # '/css/application.css' => where to serve the compressed file # # package.to_development_html # package.to_production_html # class Package include HtmlHelpers include BusterHelpers def initialize(assets, name, type, path, filespecs) @assets = assets # Options instance @name = name # "application" @type = type # :js or :css @path = path # '/js/app.js' -- where to served the compressed file @filespecs = filespecs # [ '/js/*.js' ] end attr_reader :type attr_reader :path attr_reader :filespecs attr_reader :name # Returns a list of URIs def paths_and_files list = @assets.glob(@filespecs, :preserve => true) list.reject! { |path, file| @assets.ignored?(path) } list end def files paths_and_files.values end def paths paths_and_files.keys end def mtime BusterHelpers.mtime_for(files) end # Returns the regex for the route, including cache buster crap. def route_regex re = @path.gsub(/(.[^.]+)$/) { |ext| "(?:\.[0-9]+)?#{ext}" } /^#{re}$/ end def to_development_html(options={}) paths_and_files.map { |path, file| path = add_cache_buster(path, file) # app.css => app.829378.css link_tag(path, options) }.join("\n") end # The URI path of the minified file (with cache buster) def production_path add_cache_buster @path, *files end def to_production_html(options={}) link_tag production_path, options end def minify engine = @assets.send(:"#{@type}_compression") options = @assets.send(:"#{@type}_compression_options") Compressor.compress combined, @type, engine, options end # The cache hash. def hash if @assets.app.development? "#{name}.#{type}/#{mtime}" else "#{name}.#{type}" end end def combined session = Rack::Test::Session.new(@assets.app) paths.map { |path| result = session.get(path) if result.body.respond_to?(:force_encoding) response_encoding = result.content_type.split(/;\s*charset\s*=\s*/).last.upcase rescue 'ASCII-8BIT' result.body.force_encoding(response_encoding).encode(Encoding.default_external || 'ASCII-8BIT') if result.status == 200 else result.body if result.status == 200 end }.join("\n") end def js?() @type == :js; end def css?() @type == :css; end private def link_tag(file, options={}) context = options[:context] host = options[:host] file_path = HtmlHelpers.get_file_uri(file, @assets) file_path = "#{context}#{file_path}" unless context.nil? || context.empty? file_path = "#{host}#{file_path}" unless host.nil? || host.empty? options_copy = options.clone options_copy.delete(:context) options_copy.delete(:host) if js? "" elsif css? "" end end end end end