ghazel-yui-compressor 0.9.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "rubygems"
2
+ require "rake/gempackagetask"
3
+ require "rake/rdoctask"
4
+ require "rake/testtask"
5
+
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new do |t|
9
+ t.libs += ["lib", "test"]
10
+ t.test_files = FileList["test/*_test.rb"]
11
+ t.verbose = true
12
+ end
13
+
14
+ Rake::RDocTask.new do |t|
15
+ t.rdoc_files.include("README.rdoc", "lib/**/*.rb")
16
+ end
17
+
18
+ Rake::GemPackageTask.new(eval(IO.read(File.join(File.dirname(__FILE__), "yui-compressor.gemspec")))) do |pkg|
19
+ pkg.need_zip = true
20
+ pkg.need_tar = true
21
+ end
@@ -0,0 +1,204 @@
1
+ require "open3"
2
+ require "stringio"
3
+
4
+ module YUI #:nodoc:
5
+ class Compressor
6
+ VERSION = "0.9.4"
7
+
8
+ class Error < StandardError; end
9
+ class OptionError < Error; end
10
+ class RuntimeError < Error; end
11
+
12
+ attr_reader :options, :command
13
+
14
+ def self.default_options #:nodoc:
15
+ { :charset => "utf-8", :line_break => nil }
16
+ end
17
+
18
+ def self.compressor_type #:nodoc:
19
+ raise Error, "create a CssCompressor or JavaScriptCompressor instead"
20
+ end
21
+
22
+ def initialize(options = {}) #:nodoc:
23
+ @options = self.class.default_options.merge(options)
24
+ @command = [path_to_java, "-jar", path_to_jar_file, *(command_option_for_type + command_options)]
25
+ @command = @command.flatten.join(' ') if ENV['OS'] == 'Windows_NT'
26
+ end
27
+
28
+ # Compress a stream or string of code with YUI Compressor. (A stream is
29
+ # any object that responds to +read+ and +close+ like an IO.) If a block
30
+ # is given, you can read the compressed code from the block's argument.
31
+ # Otherwise, +compress+ returns a string of compressed code.
32
+ #
33
+ # ==== Example: Compress CSS
34
+ # compressor = YUI::CssCompressor.new
35
+ # compressor.compress(<<-END_CSS)
36
+ # div.error {
37
+ # color: red;
38
+ # }
39
+ # div.warning {
40
+ # display: none;
41
+ # }
42
+ # END_CSS
43
+ # # => "div.error{color:red;}div.warning{display:none;}"
44
+ #
45
+ # ==== Example: Compress JavaScript
46
+ # compressor = YUI::JavaScriptCompressor.new
47
+ # compressor.compress('(function () { var foo = {}; foo["bar"] = "baz"; })()')
48
+ # # => "(function(){var foo={};foo.bar=\"baz\"})();"
49
+ #
50
+ # ==== Example: Compress and gzip a file on disk
51
+ # File.open("my.js", "r") do |source|
52
+ # Zlib::GzipWriter.open("my.js.gz", "w") do |gzip|
53
+ # compressor.compress(source) do |compressed|
54
+ # while buffer = compressed.read(4096)
55
+ # gzip.write(buffer)
56
+ # end
57
+ # end
58
+ # end
59
+ # end
60
+ #
61
+ def compress(stream_or_string)
62
+ streamify(stream_or_string) do |stream|
63
+ Open3.popen3(*command) do |stdin, stdout, stderr|
64
+ begin
65
+ stdin.binmode
66
+ transfer(stream, stdin)
67
+
68
+ if block_given?
69
+ yield stdout
70
+ else
71
+ stdout.read
72
+ end
73
+
74
+ rescue Exception => e
75
+ raise RuntimeError, "compression failed"
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ private
82
+ def command_options
83
+ options.inject([]) do |command_options, (name, argument)|
84
+ method = begin
85
+ method(:"command_option_for_#{name}")
86
+ rescue NameError
87
+ raise OptionError, "undefined option #{name.inspect}"
88
+ end
89
+
90
+ command_options.concat(method.call(argument))
91
+ end
92
+ end
93
+
94
+ def path_to_java
95
+ options.delete(:java) || "java"
96
+ end
97
+
98
+ def path_to_jar_file
99
+ options.delete(:jar_file) || File.join(File.dirname(__FILE__), *%w".. yuicompressor-2.4.4.jar")
100
+ end
101
+
102
+ def streamify(stream_or_string)
103
+ if stream_or_string.respond_to?(:read)
104
+ yield stream_or_string
105
+ else
106
+ yield StringIO.new(stream_or_string.to_s)
107
+ end
108
+ end
109
+
110
+ def transfer(from_stream, to_stream)
111
+ while buffer = from_stream.read(4096)
112
+ to_stream.write(buffer)
113
+ end
114
+ to_stream.close
115
+ end
116
+
117
+ def command_option_for_type
118
+ ["--type", self.class.compressor_type.to_s]
119
+ end
120
+
121
+ def command_option_for_charset(charset)
122
+ ["--charset", charset.to_s]
123
+ end
124
+
125
+ def command_option_for_line_break(line_break)
126
+ line_break ? ["--line-break", line_break.to_s] : []
127
+ end
128
+ end
129
+
130
+ class CssCompressor < Compressor
131
+ def self.compressor_type #:nodoc:
132
+ "css"
133
+ end
134
+
135
+ # Creates a new YUI::CssCompressor for minifying CSS code.
136
+ #
137
+ # Options are:
138
+ #
139
+ # <tt>:charset</tt>:: Specifies the character encoding to use. Defaults to
140
+ # <tt>"utf-8"</tt>.
141
+ # <tt>:line_break</tt>:: By default, CSS will be compressed onto a single
142
+ # line. Use this option to specify the maximum
143
+ # number of characters in each line before a newline
144
+ # is added. If <tt>:line_break</tt> is 0, a newline
145
+ # is added after each CSS rule.
146
+ #
147
+ def initialize(options = {})
148
+ super
149
+ end
150
+ end
151
+
152
+ class JavaScriptCompressor < Compressor
153
+ def self.compressor_type #:nodoc:
154
+ "js"
155
+ end
156
+
157
+ def self.default_options #:nodoc:
158
+ super.merge(
159
+ :munge => false,
160
+ :optimize => true,
161
+ :preserve_semicolons => false
162
+ )
163
+ end
164
+
165
+ # Creates a new YUI::JavaScriptCompressor for minifying JavaScript code.
166
+ #
167
+ # Options are:
168
+ #
169
+ # <tt>:charset</tt>:: Specifies the character encoding to use. Defaults to
170
+ # <tt>"utf-8"</tt>.
171
+ # <tt>:line_break</tt>:: By default, JavaScript will be compressed onto a
172
+ # single line. Use this option to specify the
173
+ # maximum number of characters in each line before a
174
+ # newline is added. If <tt>:line_break</tt> is 0, a
175
+ # newline is added after each JavaScript statement.
176
+ # <tt>:munge</tt>:: Specifies whether YUI Compressor should shorten local
177
+ # variable names when possible. Defaults to +false+.
178
+ # <tt>:optimize</tt>:: Specifies whether YUI Compressor should optimize
179
+ # JavaScript object property access and object literal
180
+ # declarations to use as few characters as possible.
181
+ # Defaults to +true+.
182
+ # <tt>:preserve_semicolons</tt>:: Defaults to +false+. If +true+, YUI
183
+ # Compressor will ensure semicolons exist
184
+ # after each statement to appease tools like
185
+ # JSLint.
186
+ #
187
+ def initialize(options = {})
188
+ super
189
+ end
190
+
191
+ private
192
+ def command_option_for_munge(munge)
193
+ munge ? [] : ["--nomunge"]
194
+ end
195
+
196
+ def command_option_for_optimize(optimize)
197
+ optimize ? [] : ["--disable-optimizations"]
198
+ end
199
+
200
+ def command_option_for_preserve_semicolons(preserve_semicolons)
201
+ preserve_semicolons ? ["--preserve-semi"] : []
202
+ end
203
+ end
204
+ end
Binary file
@@ -0,0 +1,99 @@
1
+ require "test/unit"
2
+ require "yui/compressor"
3
+
4
+ module YUI
5
+ class CompressorTest < Test::Unit::TestCase
6
+ FIXTURE_CSS = <<-END_CSS
7
+ div.warning {
8
+ display: none;
9
+ }
10
+
11
+ div.error {
12
+ background: red;
13
+ color: white;
14
+ }
15
+
16
+ @media screen and (max-device-width: 640px) {
17
+ body { font-size: 90%; }
18
+ }
19
+ END_CSS
20
+
21
+ FIXTURE_JS = <<-END_JS
22
+ // here's a comment
23
+ var Foo = { "a": 1 };
24
+ Foo["bar"] = (function(baz) {
25
+ /* here's a
26
+ multiline comment */
27
+ if (false) {
28
+ doSomething();
29
+ } else {
30
+ for (var index = 0; index < baz.length; index++) {
31
+ doSomething(baz[index]);
32
+ }
33
+ }
34
+ })("hello");
35
+ END_JS
36
+
37
+ def test_compressor_should_raise_when_instantiated
38
+ assert_raises YUI::Compressor::Error do
39
+ YUI::Compressor.new
40
+ end
41
+ end
42
+
43
+ def test_css_should_be_compressed
44
+ @compressor = YUI::CssCompressor.new
45
+ assert_equal "div.warning{display:none}div.error{background:red;color:white}@media screen and (max-device-width:640px){body{font-size:90%}}", @compressor.compress(FIXTURE_CSS)
46
+ end
47
+
48
+ def test_js_should_be_compressed
49
+ @compressor = YUI::JavaScriptCompressor.new
50
+ assert_equal "var Foo={a:1};Foo.bar=(function(baz){if(false){doSomething()}else{for(var index=0;index<baz.length;index++){doSomething(baz[index])}}})(\"hello\");", @compressor.compress(FIXTURE_JS)
51
+ end
52
+
53
+ def test_compress_should_raise_when_an_unknown_option_is_specified
54
+ assert_raises YUI::Compressor::OptionError do
55
+ @compressor = YUI::CssCompressor.new(:foo => "bar")
56
+ @compressor.compress(FIXTURE_JS)
57
+ end
58
+ end
59
+
60
+ def test_compress_should_accept_an_io_argument
61
+ @compressor = YUI::CssCompressor.new
62
+ assert_equal "div.warning{display:none}div.error{background:red;color:white}@media screen and (max-device-width:640px){body{font-size:90%}}", @compressor.compress(StringIO.new(FIXTURE_CSS))
63
+ end
64
+
65
+ def test_compress_should_accept_a_block_and_yield_an_io
66
+ @compressor = YUI::CssCompressor.new
67
+ @compressor.compress(FIXTURE_CSS) do |stream|
68
+ assert_kind_of IO, stream
69
+ assert_equal "div.warning{display:none}div.error{background:red;color:white}@media screen and (max-device-width:640px){body{font-size:90%}}", stream.read
70
+ end
71
+ end
72
+
73
+ def test_line_break_option_should_insert_line_breaks_in_css
74
+ @compressor = YUI::CssCompressor.new(:line_break => 0)
75
+ assert_equal "div.warning{display:none}\ndiv.error{background:red;color:white}\n@media screen and (max-device-width:640px){body{font-size:90%}\n}", @compressor.compress(FIXTURE_CSS)
76
+
77
+ end
78
+
79
+ def test_line_break_option_should_insert_line_breaks_in_js
80
+ @compressor = YUI::JavaScriptCompressor.new(:line_break => 0)
81
+ assert_equal "var Foo={a:1};\nFoo.bar=(function(baz){if(false){doSomething()\n}else{for(var index=0;\nindex<baz.length;\nindex++){doSomething(baz[index])\n}}})(\"hello\");", @compressor.compress(FIXTURE_JS)
82
+ end
83
+
84
+ def test_munge_option_should_munge_local_variable_names
85
+ @compressor = YUI::JavaScriptCompressor.new(:munge => true)
86
+ assert_equal "var Foo={a:1};Foo.bar=(function(b){if(false){doSomething()}else{for(var a=0;a<b.length;a++){doSomething(b[a])}}})(\"hello\");", @compressor.compress(FIXTURE_JS)
87
+ end
88
+
89
+ def test_optimize_option_should_not_modify_property_accesses_or_object_literal_keys_when_false
90
+ @compressor = YUI::JavaScriptCompressor.new(:optimize => false)
91
+ assert_equal "var Foo={\"a\":1};Foo[\"bar\"]=(function(baz){if(false){doSomething()}else{for(var index=0;index<baz.length;index++){doSomething(baz[index])}}})(\"hello\");", @compressor.compress(FIXTURE_JS)
92
+ end
93
+
94
+ def test_preserve_semicolons_option_should_preserve_semicolons
95
+ @compressor = YUI::JavaScriptCompressor.new(:preserve_semicolons => true)
96
+ assert_equal "var Foo={a:1};Foo.bar=(function(baz){if(false){doSomething();}else{for(var index=0;index<baz.length;index++){doSomething(baz[index]);}}})(\"hello\");", @compressor.compress(FIXTURE_JS)
97
+ end
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghazel-yui-compressor
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 9
9
+ - 4
10
+ - 1
11
+ version: 0.9.4.1
12
+ platform: ruby
13
+ authors:
14
+ - Sam Stephenson
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-02-20 00:00:00 -08:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: A Ruby interface to YUI Compressor for minifying JavaScript and CSS assets.
24
+ email: sstephenson@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - Rakefile
33
+ - lib/yui/compressor.rb
34
+ - lib/yuicompressor-2.4.4.jar
35
+ - test/compressor_test.rb
36
+ has_rdoc: true
37
+ homepage: http://github.com/sstephenson/ruby-yui-compressor/
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project: yui
66
+ rubygems_version: 1.4.2
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: JavaScript and CSS minification library
70
+ test_files:
71
+ - test/compressor_test.rb