Class: Jammit::Compressor

Inherits:
Object
  • Object
show all
Defined in:
lib/jammit/compressor.rb

Overview

Uses the YUI Compressor or Closure Compiler to compress JavaScript. Always uses YUI to compress CSS (Which means that Java must be installed.) Also knows how to create a concatenated JST file. If “embed_assets” is turned on, creates “mhtml” and “datauri” versions of all stylesheets, with all enabled assets inlined into the css.

Constant Summary collapse

EMBED_MIME_TYPES =

Mapping from extension to mime-type of all embeddable assets.

{
  '.png'  => 'image/png',
  '.jpg'  => 'image/jpeg',
  '.jpeg' => 'image/jpeg',
  '.gif'  => 'image/gif',
  '.tif'  => 'image/tiff',
  '.tiff' => 'image/tiff',
  '.ttf'  => 'application/x-font-ttf',
  '.otf'  => 'font/opentype',
  '.woff' => 'application/x-font-woff'
}
EMBED_EXTS =

Font extensions for which we allow embedding:

EMBED_MIME_TYPES.keys
EMBED_FONTS =
['.ttf', '.otf', '.woff']
MAX_IMAGE_SIZE =

(32k - padding) maximum length for data-uri assets (an IE8 limitation).

32700
EMBED_DETECTOR =

CSS asset-embedding regexes for URL rewriting.

/url\(['"]?([^\s)]+\.[a-z]+)(\?\d+)?['"]?\)/
EMBEDDABLE =
/[\A\/]embed\//
EMBED_REPLACER =
/url\(__EMBED__(.+?)(\?\d+)?\)/
MHTML_START =

MHTML file constants.

"/*\r\nContent-Type: multipart/related; boundary=\"MHTML_MARK\"\r\n\r\n"
MHTML_SEPARATOR =
"--MHTML_MARK\r\n"
MHTML_END =
"\r\n--MHTML_MARK--\r\n*/\r\n"
JST_START =

JST file constants.

"(function(){"
JST_END =
"})();"
JAVASCRIPT_COMPRESSORS =
{
  :jsmin    => Jammit.javascript_compressors.include?(:jsmin)  ? Jammit::JsminCompressor : nil,
  :yui      => Jammit.javascript_compressors.include?(:yui)  ? YUI::JavaScriptCompressor : nil,
  :closure  => Jammit.javascript_compressors.include?(:closure)  ? Closure::Compiler : nil,
  :uglifier => Jammit.javascript_compressors.include?(:uglifier) ? Jammit::Uglifier  : nil,
  :none     => Jammit::NoneCompressor
}
CSS_COMPRESSORS =
{
 :cssmin   => Jammit.css_compressors.include?(:cssmin) ? Jammit::CssminCompressor : nil,
 :yui      => Jammit.css_compressors.include?(:yui) ? YUI::CssCompressor : nil,
 :sass     => Jammit.css_compressors.include?(:sass) ? Jammit::SassCompressor : nil,
 :none     => Jammit::NoneCompressor
}
JAVASCRIPT_DEFAULT_OPTIONS =
{
  :jsmin    => {},
  :yui      => {:munge => true},
  :closure  => {},
  :uglifier => {:copyright => false},
  :none     => {}
}

Instance Method Summary collapse

Constructor Details

#initializeCompressor

CSS compression can be provided with YUI Compressor or sass. JS compression can be provided with YUI Compressor, Google Closure Compiler or UglifyJS.



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/jammit/compressor.rb', line 70

def initialize
  if Jammit.javascript_compressors.include?(:yui) || Jammit.javascript_compressors.include?(:closure) || Jammit.css_compressors.include?(:yui)
    Jammit.check_java_version
  end

  css_flavor      = Jammit.css_compressor || Jammit::DEFAULT_CSS_COMPRESSOR
  @css_compressor = CSS_COMPRESSORS[css_flavor].new(Jammit.css_compressor_options || {})
  js_flavor       = Jammit.javascript_compressor || Jammit::DEFAULT_JAVASCRIPT_COMPRESSOR
  @options        = JAVASCRIPT_DEFAULT_OPTIONS[js_flavor].merge(Jammit.compressor_options || {})
  @js_compressor  = JAVASCRIPT_COMPRESSORS[js_flavor].new(@options)
end

Instance Method Details

#compile_jst(paths) ⇒ Object

Compiles a single JST file by writing out a javascript that adds template properties to a top-level template namespace object. Adds a JST-compilation function to the top of the package, unless you’ve specified your own preferred function, or turned it off. JST templates are named with the basename of their file.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/jammit/compressor.rb', line 117

def compile_jst(paths)
  namespace   = Jammit.template_namespace
  paths       = paths.grep(Jammit.template_extension_matcher).sort
  base_path   = find_base_path(paths)
  compiled    = paths.map do |path|
    contents  = read_binary_file(path)
    contents  = contents.gsub(/\r?\n/, "\\n").gsub("'", '\\\\\'')
    name      = template_name(path, base_path)
    "#{namespace}['#{name}'] = #{Jammit.template_function}('#{contents}');"
  end
  compiler = Jammit.include_jst_script ? read_binary_file(DEFAULT_JST_SCRIPT) : '';
  setup_namespace = "#{namespace} = #{namespace} || {};"
  [JST_START, setup_namespace, compiler, compiled, JST_END].flatten.join("\n")
end

#compress_css(paths, variant = nil, asset_url = nil) ⇒ Object

Concatenate and compress a list of CSS stylesheets. When compressing a :datauri or :mhtml variant, post-processes the result to embed referenced assets.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/jammit/compressor.rb', line 96

def compress_css(paths, variant=nil, asset_url=nil)
  @asset_contents = {}
  css = concatenate_and_tag_assets(paths, variant)
  begin
    css = @css_compressor.compress(css) if Jammit.compress_assets
  rescue
    puts paths
  end
  case variant
  when nil      then return css
  when :datauri then return with_data_uris(css)
  when :mhtml   then return with_mhtml(css, asset_url)
  else raise PackageNotFound, "\"#{variant}\" is not a valid stylesheet variant"
  end
end

#compress_js(paths) ⇒ Object

Concatenate together a list of JavaScript paths, and pass them through the YUI Compressor (with munging enabled). JST can optionally be included.



84
85
86
87
88
89
90
91
# File 'lib/jammit/compressor.rb', line 84

def compress_js(paths)
  if (jst_paths = paths.grep(Jammit.template_extension_matcher)).empty?
    js = concatenate(paths)
  else
    js = concatenate(paths - jst_paths) + compile_jst(jst_paths)
  end
  Jammit.compress_assets ? @js_compressor.compress(js) : js
end