From 038808ba1a6927189c4a11b7b77ba9a724dd5532 Mon Sep 17 00:00:00 2001
From: Guillermo Iguaran <guilleiguaran@gmail.com>
Date: Sat, 24 Sep 2011 18:01:08 -0500
Subject: Add public API for register new js and css compressors for Sprockets

---
 actionpack/lib/sprockets/bootstrap.rb        | 34 ++------------------
 actionpack/lib/sprockets/compressors.rb      | 46 ++++++++++++++++++++++++++++
 actionpack/lib/sprockets/railtie.rb          |  1 +
 actionpack/test/template/compressors_test.rb | 29 ++++++++++++++++++
 4 files changed, 79 insertions(+), 31 deletions(-)
 create mode 100644 actionpack/test/template/compressors_test.rb

diff --git a/actionpack/lib/sprockets/bootstrap.rb b/actionpack/lib/sprockets/bootstrap.rb
index ed1ed09374..395b264fe7 100644
--- a/actionpack/lib/sprockets/bootstrap.rb
+++ b/actionpack/lib/sprockets/bootstrap.rb
@@ -15,11 +15,11 @@ module Sprockets
         # temporarily hardcode default JS compressor to uglify. Soon, it will work
         # the same as SCSS, where a default plugin sets the default.
         unless config.assets.js_compressor == false
-          app.assets.js_compressor = LazyCompressor.new { expand_js_compressor(config.assets.js_compressor || :uglifier) }
+          app.assets.js_compressor = LazyCompressor.new { Sprockets::Compressors.registered_js_compressor(config.assets.js_compressor || :uglifier) }
         end
 
         unless config.assets.css_compressor == false
-          app.assets.css_compressor = LazyCompressor.new { expand_css_compressor(config.assets.css_compressor) }
+          app.assets.css_compressor = LazyCompressor.new { Sprockets::Compressors.registered_css_compressor(config.assets.css_compressor) }
         end
       end
 
@@ -33,33 +33,5 @@ module Sprockets
         app.assets = app.assets.index
       end
     end
-
-    protected
-
-    def expand_js_compressor(sym)
-      case sym
-      when :closure
-        require 'closure-compiler'
-        Closure::Compiler.new
-      when :uglifier
-        require 'uglifier'
-        Uglifier.new
-      when :yui
-        require 'yui/compressor'
-        YUI::JavaScriptCompressor.new
-      else
-        sym
-      end
-    end
-
-    def expand_css_compressor(sym)
-      case sym
-      when :yui
-        require 'yui/compressor'
-        YUI::CssCompressor.new
-      else
-        sym
-      end
-    end
   end
-end
\ No newline at end of file
+end
diff --git a/actionpack/lib/sprockets/compressors.rb b/actionpack/lib/sprockets/compressors.rb
index 351eff1085..cb3e13314b 100644
--- a/actionpack/lib/sprockets/compressors.rb
+++ b/actionpack/lib/sprockets/compressors.rb
@@ -1,4 +1,50 @@
 module Sprockets
+  module Compressors
+    @@css_compressors = {}
+    @@js_compressors = {}
+    @@default_css_compressor = nil
+    @@default_js_compressor = nil
+
+    def self.register_css_compressor(name, klass, options = {})
+      @@default_css_compressor = name.to_sym if options[:default] || @@default_css_compressor.nil?
+      @@css_compressors[name.to_sym] = {:klass => klass.to_s, :require => options[:require]}
+    end
+
+    def self.register_js_compressor(name, klass, options = {})
+      @@default_js_compressor = name.to_sym if options[:default] || @@default_js_compressor.nil?
+      @@js_compressors[name.to_sym] = {:klass => klass.to_s, :require => options[:require]}
+    end
+
+    def self.registered_css_compressor(name)
+      if name.respond_to?(:to_sym)
+        compressor = @@css_compressors[name.to_sym] || @@css_compressors[@@default_css_compressor]
+        require compressor[:require] if compressor[:require]
+        compressor[:klass].constantize.new
+      else
+        name
+      end
+    end
+
+    def self.registered_js_compressor(name)
+      if name.respond_to?(:to_sym)
+        compressor = @@js_compressors[name.to_sym] || @@js_compressors[@@default_js_compressor]
+        require compressor[:require] if compressor[:require]
+        compressor[:klass].constantize.new
+      else
+        name
+      end
+    end
+
+    # The default compressors must be registered in default plugins (ex. Sass-Rails)
+    register_css_compressor(:scss, 'Sass::Rails::Compressor', :require => 'sass/rails/compressor', :default => true)
+    register_js_compressor(:uglifier, 'Uglifier', :require => 'uglifier', :default => true)
+
+    # Automaticaly register some compressors
+    register_css_compressor(:yui, 'YUI::CssCompressor', :require => 'yui/compressor')
+    register_js_compressor(:closure, 'Closure::Compiler', :require => 'closure-compiler')
+    register_js_compressor(:yui, 'YUI::JavaScriptCompressor', :require => 'yui/compressor')
+  end
+
   # An asset compressor which does nothing.
   #
   # This compressor simply returns the asset as-is, without any compression
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index edcd4c1113..6b67fb1d2d 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -1,6 +1,7 @@
 module Sprockets
   autoload :Bootstrap,      "sprockets/bootstrap"
   autoload :Helpers,        "sprockets/helpers"
+  autoload :Compressors,    "sprockets/compressors"
   autoload :LazyCompressor, "sprockets/compressors"
   autoload :NullCompressor, "sprockets/compressors"
   autoload :StaticCompiler, "sprockets/static_compiler"
diff --git a/actionpack/test/template/compressors_test.rb b/actionpack/test/template/compressors_test.rb
new file mode 100644
index 0000000000..583a1455ba
--- /dev/null
+++ b/actionpack/test/template/compressors_test.rb
@@ -0,0 +1,29 @@
+require 'abstract_unit'
+require 'rails/railtie'
+require 'sprockets/railtie'
+
+class CompressorsTest < ActiveSupport::TestCase
+  def test_register_css_compressor
+    Sprockets::Compressors.register_css_compressor(:null, Sprockets::NullCompressor)
+    compressor = Sprockets::Compressors.registered_css_compressor(:null)
+    assert_kind_of Sprockets::NullCompressor, compressor
+  end
+
+  def test_register_js_compressor
+    Sprockets::Compressors.register_js_compressor(:uglifier, 'Uglifier', :require => 'uglifier')
+    compressor = Sprockets::Compressors.registered_js_compressor(:uglifier)
+    assert_kind_of Uglifier, compressor
+  end
+
+  def test_register_default_css_compressor
+    Sprockets::Compressors.register_css_compressor(:null, Sprockets::NullCompressor, :default => true)
+    compressor = Sprockets::Compressors.registered_css_compressor(:default)
+    assert_kind_of Sprockets::NullCompressor, compressor
+  end
+
+  def test_register_default_js_compressor
+    Sprockets::Compressors.register_js_compressor(:null, Sprockets::NullCompressor, :default => true)
+    compressor = Sprockets::Compressors.registered_js_compressor(:default)
+    assert_kind_of Sprockets::NullCompressor, compressor
+  end
+end
-- 
cgit v1.2.3