require 'jsmin' require File.join(File.dirname(__FILE__), 'js', 'vendors') module AssetHat # Methods for minifying JavaScript. module JS # A list of supported minification # engine names. ENGINES = [:weak, :jsmin] # A list of supported # 3rd-party JavaScript plugin/vendor names. VENDORS = Vendors::VENDORS # Returns the expected path for the minified version of a JS asset: # # AssetHat::JS.min_filepath('public/javascripts/bundles/application.js') # # => 'public/javascripts/bundles/application.min.js' def self.min_filepath(filepath) AssetHat.min_filepath(filepath, 'js') end # Accepts a string of JS, and returns that JS minified. Options: # # [engine] Default is :jsmin; see # Engines.jsmin. # Allowed values are in ENGINES. def self.minify(input_string, options={}) options.reverse_merge!(:engine => :jsmin) engine = options[:engine].to_sym unless ENGINES.include?(engine) raise %Q{ Unknown JS minification engine '#{engine}'. Allowed: #{ENGINES.map{ |e| "'#{e}'" }.join(', ')} }.strip.gsub(/\s+/, ' ') and return end AssetHat::JS::Engines.send(engine, input_string) end # Swappable JavaScript minification engines. module Engines # Barebones JavaScript minification engine that: # - Skips leading/trailing whitespace for each line, excluding line # breaks; and # - Removes one-line comments that had no actual code on that line. def self.weak(input_string) input = StringIO.new(input_string) output = StringIO.new input.each do |line| # Remove indentation and trailing whitespace line.strip! next if line.blank? # Skip single-line comments next if !(line =~ /^\/\//).nil? # TODO: Also skip single-line comments that began mid-line, but not # inside a string or regex # TODO: Skip multi-line comments # - Should not strip from within a string or regex # - Should not strip comments that begin with `/*!` (e.g., licenses) output.write(line + "\n") end output.rewind output.read end # JavaScript minification engine that simply uses the JSMin gem, a Ruby # port of Crockford's JSMin. # # Sources: # - http://github.com/rgrove/jsmin # - http://rubygems.org/gems/jsmin def self.jsmin(input_string) JSMin.minify(input_string) end end # module Engines end end