ruby-clean-css 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/.gitmodules +3 -0
  2. data/EXAMPLE.md +25 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +30 -0
  5. data/LICENSE +19 -0
  6. data/README.md +106 -0
  7. data/lib/javascript/clean-css/.gitignore +4 -0
  8. data/lib/javascript/clean-css/.jshintignore +3 -0
  9. data/lib/javascript/clean-css/.jshintrc +14 -0
  10. data/lib/javascript/clean-css/.travis.yml +11 -0
  11. data/lib/javascript/clean-css/History.md +556 -0
  12. data/lib/javascript/clean-css/LICENSE +19 -0
  13. data/lib/javascript/clean-css/README.md +218 -0
  14. data/lib/javascript/clean-css/bin/cleancss +157 -0
  15. data/lib/javascript/clean-css/index.js +1 -0
  16. data/lib/javascript/clean-css/lib/clean.js +426 -0
  17. data/lib/javascript/clean-css/lib/colors/hsl-to-hex.js +64 -0
  18. data/lib/javascript/clean-css/lib/colors/long-to-short-hex.js +12 -0
  19. data/lib/javascript/clean-css/lib/colors/rgb-to-hex.js +14 -0
  20. data/lib/javascript/clean-css/lib/colors/shortener.js +174 -0
  21. data/lib/javascript/clean-css/lib/images/url-rebase.js +32 -0
  22. data/lib/javascript/clean-css/lib/images/url-rewriter.js +60 -0
  23. data/lib/javascript/clean-css/lib/imports/inliner.js +319 -0
  24. data/lib/javascript/clean-css/lib/properties/optimizer.js +276 -0
  25. data/lib/javascript/clean-css/lib/properties/override-compactor.js +116 -0
  26. data/lib/javascript/clean-css/lib/properties/processable.js +859 -0
  27. data/lib/javascript/clean-css/lib/properties/scanner.js +20 -0
  28. data/lib/javascript/clean-css/lib/properties/shorthand-compactor.js +244 -0
  29. data/lib/javascript/clean-css/lib/properties/token.js +184 -0
  30. data/lib/javascript/clean-css/lib/properties/validator.js +140 -0
  31. data/lib/javascript/clean-css/lib/selectors/empty-removal.js +30 -0
  32. data/lib/javascript/clean-css/lib/selectors/optimizer.js +341 -0
  33. data/lib/javascript/clean-css/lib/selectors/tokenizer.js +168 -0
  34. data/lib/javascript/clean-css/lib/text/comments.js +83 -0
  35. data/lib/javascript/clean-css/lib/text/escape-store.js +32 -0
  36. data/lib/javascript/clean-css/lib/text/expressions.js +73 -0
  37. data/lib/javascript/clean-css/lib/text/free.js +26 -0
  38. data/lib/javascript/clean-css/lib/text/name-quotes.js +37 -0
  39. data/lib/javascript/clean-css/lib/text/quote-scanner.js +91 -0
  40. data/lib/javascript/clean-css/lib/text/splitter.js +35 -0
  41. data/lib/javascript/clean-css/lib/text/urls.js +41 -0
  42. data/lib/javascript/clean-css/package.json +50 -0
  43. data/lib/javascript/clean-css/test/batch-test.js +56 -0
  44. data/lib/javascript/clean-css/test/bench.js +11 -0
  45. data/lib/javascript/clean-css/test/binary-test.js +323 -0
  46. data/lib/javascript/clean-css/test/data-bench/_partial.css +1 -0
  47. data/lib/javascript/clean-css/test/data-bench/complex.css +4 -0
  48. data/lib/javascript/clean-css/test/data/129-assets/assets/ui.css +2 -0
  49. data/lib/javascript/clean-css/test/data/129-assets/components/bootstrap/css/bootstrap.css +3 -0
  50. data/lib/javascript/clean-css/test/data/129-assets/components/bootstrap/images/glyphs.gif +0 -0
  51. data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/css/style.css +6 -0
  52. data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/images/next.gif +0 -0
  53. data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/images/prev.gif +0 -0
  54. data/lib/javascript/clean-css/test/data/960-min.css +125 -0
  55. data/lib/javascript/clean-css/test/data/960.css +602 -0
  56. data/lib/javascript/clean-css/test/data/big-min.css +2984 -0
  57. data/lib/javascript/clean-css/test/data/big.css +13794 -0
  58. data/lib/javascript/clean-css/test/data/blueprint-min.css +245 -0
  59. data/lib/javascript/clean-css/test/data/blueprint.css +556 -0
  60. data/lib/javascript/clean-css/test/data/charset-mixed-with-fonts-min.css +3 -0
  61. data/lib/javascript/clean-css/test/data/charset-mixed-with-fonts.css +14 -0
  62. data/lib/javascript/clean-css/test/data/font-awesome-ie7-min.css +392 -0
  63. data/lib/javascript/clean-css/test/data/font-awesome-ie7.css +1203 -0
  64. data/lib/javascript/clean-css/test/data/font-awesome-min.css +319 -0
  65. data/lib/javascript/clean-css/test/data/font-awesome.css +540 -0
  66. data/lib/javascript/clean-css/test/data/imports-min.css +5 -0
  67. data/lib/javascript/clean-css/test/data/imports.css +4 -0
  68. data/lib/javascript/clean-css/test/data/issue-117-snippet-min.css +3 -0
  69. data/lib/javascript/clean-css/test/data/issue-117-snippet.css +19 -0
  70. data/lib/javascript/clean-css/test/data/issue-159-snippet-min.css +7 -0
  71. data/lib/javascript/clean-css/test/data/issue-159-snippet.css +7 -0
  72. data/lib/javascript/clean-css/test/data/issue-192-min.css +1 -0
  73. data/lib/javascript/clean-css/test/data/issue-192.css +8 -0
  74. data/lib/javascript/clean-css/test/data/issue-198-min.css +3 -0
  75. data/lib/javascript/clean-css/test/data/issue-198.css +4 -0
  76. data/lib/javascript/clean-css/test/data/issue-232-min.css +2 -0
  77. data/lib/javascript/clean-css/test/data/issue-232.css +17 -0
  78. data/lib/javascript/clean-css/test/data/issue-241-min.css +2 -0
  79. data/lib/javascript/clean-css/test/data/issue-241.css +2 -0
  80. data/lib/javascript/clean-css/test/data/issue-304-min.css +1 -0
  81. data/lib/javascript/clean-css/test/data/issue-304.css +4 -0
  82. data/lib/javascript/clean-css/test/data/issue-305-min.css +1 -0
  83. data/lib/javascript/clean-css/test/data/issue-305.css +3 -0
  84. data/lib/javascript/clean-css/test/data/issue-308-min.css +1 -0
  85. data/lib/javascript/clean-css/test/data/issue-308.css +5 -0
  86. data/lib/javascript/clean-css/test/data/issue-312-min.css +1 -0
  87. data/lib/javascript/clean-css/test/data/issue-312.css +7 -0
  88. data/lib/javascript/clean-css/test/data/issue-337-min.css +1 -0
  89. data/lib/javascript/clean-css/test/data/issue-337.css +4 -0
  90. data/lib/javascript/clean-css/test/data/line-breaks-in-attributes-min.css +2 -0
  91. data/lib/javascript/clean-css/test/data/line-breaks-in-attributes.css +8 -0
  92. data/lib/javascript/clean-css/test/data/partials-absolute/base.css +3 -0
  93. data/lib/javascript/clean-css/test/data/partials-absolute/base2.css +1 -0
  94. data/lib/javascript/clean-css/test/data/partials-absolute/extra/sub.css +3 -0
  95. data/lib/javascript/clean-css/test/data/partials-relative/base.css +3 -0
  96. data/lib/javascript/clean-css/test/data/partials-relative/extra/included.css +1 -0
  97. data/lib/javascript/clean-css/test/data/partials/comment.css +2 -0
  98. data/lib/javascript/clean-css/test/data/partials/extra/down.gif +0 -0
  99. data/lib/javascript/clean-css/test/data/partials/extra/four.css +3 -0
  100. data/lib/javascript/clean-css/test/data/partials/extra/three.css +1 -0
  101. data/lib/javascript/clean-css/test/data/partials/five.css +1 -0
  102. data/lib/javascript/clean-css/test/data/partials/four.css +1 -0
  103. data/lib/javascript/clean-css/test/data/partials/one.css +1 -0
  104. data/lib/javascript/clean-css/test/data/partials/three.css +1 -0
  105. data/lib/javascript/clean-css/test/data/partials/two.css +5 -0
  106. data/lib/javascript/clean-css/test/data/reset-min.css +12 -0
  107. data/lib/javascript/clean-css/test/data/reset.css +64 -0
  108. data/lib/javascript/clean-css/test/data/sample1-min.css +4 -0
  109. data/lib/javascript/clean-css/test/data/sample1.css +12 -0
  110. data/lib/javascript/clean-css/test/data/unsupported/selectors-ie7.css +20 -0
  111. data/lib/javascript/clean-css/test/data/unsupported/selectors-ie8.css +17 -0
  112. data/lib/javascript/clean-css/test/module-test.js +185 -0
  113. data/lib/javascript/clean-css/test/protocol-imports-test.js +409 -0
  114. data/lib/javascript/clean-css/test/text/splitter-test.js +20 -0
  115. data/lib/javascript/clean-css/test/unit-test.js +2071 -0
  116. data/lib/ruby-clean-css.rb +6 -0
  117. data/lib/ruby-clean-css/compressor.rb +142 -0
  118. data/lib/ruby-clean-css/exports.rb +258 -0
  119. data/lib/ruby-clean-css/railtie.rb +27 -0
  120. data/lib/ruby-clean-css/sprockets.rb +19 -0
  121. data/lib/ruby-clean-css/version.rb +5 -0
  122. data/ruby-clean-css.gemspec +30 -0
  123. data/test/test_compressor.rb +84 -0
  124. metadata +203 -0
@@ -0,0 +1,6 @@
1
+ require 'therubyracer'
2
+ require 'commonjs'
3
+ require 'ruby-clean-css/version'
4
+ require 'ruby-clean-css/exports'
5
+ require 'ruby-clean-css/compressor'
6
+ require 'ruby-clean-css/railtie' if defined?(Rails)
@@ -0,0 +1,142 @@
1
+ class RubyCleanCSS::Compressor
2
+
3
+ LIB_PATH = File.expand_path(File.dirname(__FILE__)+'/../javascript')
4
+
5
+ attr_reader(:last_result)
6
+
7
+
8
+ def initialize(options = {})
9
+ @js_options = js_options_from_hash(options)
10
+ end
11
+
12
+
13
+ def compress(stream_or_string)
14
+ @last_result = result = { :min => nil }
15
+ begin
16
+ minifier.minify(stream_or_string.to_s, lambda { |this, errs, data|
17
+ result[:min] = data
18
+ })
19
+ rescue => e
20
+ raise(e)
21
+ ensure
22
+ result[:errors] = minifier.context.errors
23
+ result[:warnings] = minifier.context.warnings
24
+ GC.start # This prevents unexplained segmentation faults in the ref gem!
25
+ end
26
+ result[:min]
27
+ end
28
+
29
+
30
+ def minifier
31
+ @minifier ||= minifier_class.call(@js_options)
32
+ end
33
+
34
+
35
+ protected
36
+
37
+ def js_runtime
38
+ if @js_runtime
39
+ @js_runtime
40
+ else
41
+ @js_runtime = V8::Context.new
42
+ @js_runtime['process'] = RubyCleanCSS::Exports::Process.new
43
+ @js_runtime['console'] = RubyCleanCSS::Exports::Console.new
44
+ @js_runtime['Buffer'] = RubyCleanCSS::Exports::Buffer.new
45
+ @js_runtime
46
+ end
47
+ end
48
+
49
+
50
+ def js_env
51
+ if @js_env
52
+ @js_env
53
+ else
54
+ @js_env = CommonJS::Environment.new(js_runtime, :path => LIB_PATH)
55
+ @js_env.native('path', RubyCleanCSS::Exports::Path)
56
+ @js_env.native('util', RubyCleanCSS::Exports::Util)
57
+ @js_env.native('fs', RubyCleanCSS::Exports::FS)
58
+ @js_env.native('url', RubyCleanCSS::Exports::Url)
59
+ @js_env.native('http', RubyCleanCSS::Exports::Http.new)
60
+ @js_env.native('https', RubyCleanCSS::Exports::Http.new)
61
+ @js_env
62
+ end
63
+ end
64
+
65
+
66
+ def minifier_class
67
+ @minifier_class ||= js_env.require('clean-css/index')
68
+ end
69
+
70
+
71
+ # See README.md for a description of each option, and see
72
+ # https://github.com/GoalSmashers/clean-css#how-to-use-clean-css-programmatically
73
+ # for the JS translation.
74
+ #
75
+ def js_options_from_hash(options)
76
+ js_opts = {}
77
+
78
+ if options.has_key?(:keep_special_comments)
79
+ js_opts['keepSpecialComments'] = {
80
+ 'all' => '*',
81
+ 'first' => 1,
82
+ 'none' => 0,
83
+ '*' => '*',
84
+ '1' => 1,
85
+ '0' => 0
86
+ }[options[:keep_special_comments].to_s]
87
+ end
88
+
89
+ if options.has_key?(:keep_breaks)
90
+ js_opts['keepBreaks'] = options[:keep_breaks] ? true : false
91
+ end
92
+
93
+ if options.has_key?(:root)
94
+ js_opts['root'] = options[:root].to_s
95
+ end
96
+
97
+ if options.has_key?(:relative_to)
98
+ js_opts['relativeTo'] = options[:relative_to].to_s
99
+ end
100
+
101
+ if options.has_key?(:no_rebase)
102
+ js_opts['noRebase'] = options[:no_rebase] ? true : false
103
+ elsif !options[:rebase_urls].nil?
104
+ js_opts['noRebase'] = options[:rebase_urls] ? false : true
105
+ end
106
+
107
+ if options.has_key?(:no_advanced)
108
+ js_opts['noAdvanced'] = options[:no_advanced] ? true : false
109
+ elsif !options[:advanced].nil?
110
+ js_opts['noAdvanced'] = options[:advanced] ? false : true
111
+ end
112
+
113
+ if options.has_key?(:rounding_precision)
114
+ js_opts['roundingPrecision'] = options[:rounding_precision].to_i
115
+ end
116
+
117
+ if options.has_key?(:compatibility)
118
+ js_opts['compatibility'] = options[:compatibility].to_s
119
+ unless ['ie7', 'ie8'].include?(js_opts['compatibility'])
120
+ raise(
121
+ 'Ruby-Clean-CSS: unknown compatibility setting: '+
122
+ js_opts['compatibility']
123
+ )
124
+ end
125
+ end
126
+
127
+ if options.has_key?(:process_import)
128
+ raise('Ruby-Clean-CSS: processImport option is not yet supported')
129
+ end
130
+
131
+ if options.has_key?(:benchmark)
132
+ raise('Ruby-Clean-CSS: benchmark option is not yet supported')
133
+ end
134
+
135
+ if options.has_key?(:debug)
136
+ raise('Ruby-Clean-CSS: debug option is not yet supported')
137
+ end
138
+
139
+ js_opts
140
+ end
141
+
142
+ end
@@ -0,0 +1,258 @@
1
+ # Attribution: much of this stubbly code is drawn from
2
+ # https://github.com/cowboyd/less.rb/blob/master/lib/less/loader.rb
3
+ #
4
+ # Thanks!
5
+ #
6
+
7
+
8
+ require 'net/http'
9
+ require 'pathname'
10
+ require 'uri'
11
+
12
+ module RubyCleanCSS::Exports
13
+
14
+ class Process # :nodoc:
15
+
16
+ def nextTick
17
+ lambda { |global, fn| fn.call }
18
+ end
19
+
20
+
21
+ def cwd
22
+ lambda { Dir.pwd }
23
+ end
24
+
25
+
26
+ def exit(*args)
27
+ warn("JS process.exit(#{args.first}) called from: \n#{caller.join("\n")}")
28
+ end
29
+
30
+ end
31
+
32
+
33
+
34
+ class Console # :nodoc:
35
+
36
+ def log(*msgs)
37
+ STDOUT.puts(msgs.join(', '))
38
+ end
39
+
40
+
41
+ def warn(*msgs)
42
+ STDERR.puts(msgs.join(', '))
43
+ end
44
+
45
+ end
46
+
47
+
48
+
49
+ module Path # :nodoc:
50
+
51
+ def self.join(*components)
52
+ # node.js expands path on join
53
+ File.expand_path(File.join(*components))
54
+ end
55
+
56
+
57
+ def self.dirname(path)
58
+ File.dirname(path)
59
+ end
60
+
61
+
62
+ def self.resolve(path)
63
+ File.expand_path(path)
64
+ end
65
+
66
+
67
+ def self.relative(base, path)
68
+ Pathname.new(path).relative_path_from(Pathname.new(base)).to_s
69
+ end
70
+
71
+ end
72
+
73
+
74
+
75
+ module Util # :nodoc:
76
+
77
+ def self.error(*errors)
78
+ raise errors.join(' ')
79
+ end
80
+
81
+
82
+ def self.puts(*args)
83
+ args.each { |arg| STDOUT.puts(arg) }
84
+ end
85
+
86
+ end
87
+
88
+
89
+
90
+ module FS # :nodoc:
91
+
92
+ def self.statSync(path)
93
+ out = File.stat(path)
94
+ if out.respond_to?(:define_singleton_method)
95
+ out.define_singleton_method(:isFile) { lambda { File.file?(path) } }
96
+ else
97
+ out.instance_variable_set(:@isFile, File.file?(path))
98
+ def out.isFile; lambda { @isFile }; end
99
+ end
100
+ out
101
+ end
102
+
103
+
104
+ def self.existsSync(path)
105
+ File.exists?(path)
106
+ end
107
+
108
+
109
+ def self.readFile(path, encoding, callback)
110
+ callback.call(nil, File.read(path))
111
+ end
112
+
113
+
114
+ def self.readFileSync(path, encoding = nil)
115
+ IO.read(path)
116
+ end
117
+
118
+ end
119
+
120
+
121
+
122
+ class Buffer # :nodoc:
123
+
124
+ def isBuffer(data)
125
+ false
126
+ end
127
+
128
+ end
129
+
130
+
131
+
132
+ module Url # :nodoc:
133
+
134
+ def self.resolve(*args)
135
+ URI.join(*args)
136
+ end
137
+
138
+
139
+ def self.parse(url_string)
140
+ u = URI.parse(url_string)
141
+ result = {}
142
+ result['protocol'] = u.scheme+':' if u.scheme
143
+ result['hostname'] = u.host if u.host
144
+ result['pathname'] = u.path if u.path
145
+ result['port'] = u.port if u.port
146
+ result['query'] = u.query if u.query
147
+ result['search'] = '?'+u.query if u.query
148
+ result['hash'] = '#'+u.fragment if u.fragment
149
+ result
150
+ end
151
+
152
+ end
153
+
154
+
155
+
156
+ class Http # :nodoc:
157
+
158
+ attr_reader :get
159
+
160
+ def initialize
161
+ @get = lambda { |global, options, callback|
162
+ err = nil
163
+ uri_hash = {}
164
+ uri_hash[:host] = options['hostname'] || options['host']
165
+ path = options['path'] || options['pathname'] || ''
166
+ # We do this because node expects path and query to be combined:
167
+ path_components = path.split('?', 2)
168
+ if path_components.length > 1
169
+ uri_hash[:path] = path_components[0]
170
+ uri_hash[:query] = path_components[0]
171
+ else
172
+ uri_hash[:path] = path_components[0]
173
+ end
174
+ uri_hash[:port] = options['port'] ? options['port'] : Net::HTTP.http_default_port
175
+ # We check this way because of node's http.get:
176
+ uri_hash[:scheme] = uri_hash[:port] == Net::HTTP.https_default_port ? 'https' : 'http'
177
+ case uri_hash[:scheme]
178
+ when 'http'
179
+ uri = URI::HTTP.build(uri_hash)
180
+ when 'https'
181
+ uri = URI::HTTPS.build(uri_hash)
182
+ else
183
+ raise(Exception, 'import only supports http and https')
184
+ end
185
+ http = Net::HTTP.new(uri.host, uri.port)
186
+ if uri.scheme == 'https'
187
+ # Hurrah for insecurity
188
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
189
+ http.use_ssl = true
190
+ end
191
+ response = nil
192
+ http.start { |req| response = req.get(uri.to_s) }
193
+ begin
194
+ callback.call(
195
+ ServerResponse.new(response.read_body, response.code.to_i)
196
+ )
197
+ rescue => e
198
+ err = e
199
+ end
200
+ HttpGetResult.new(err);
201
+ }
202
+ end
203
+
204
+
205
+
206
+ class HttpGetResult
207
+
208
+ attr_accessor :err
209
+
210
+
211
+ def initialize(err)
212
+ @err = err
213
+ end
214
+
215
+
216
+ def on(event, callback)
217
+ if event == 'error' && @err
218
+ callback.call(@err)
219
+ end
220
+ self
221
+ end
222
+
223
+
224
+ def setTimeout(timer, callback)
225
+ # TODO?
226
+ end
227
+
228
+ end
229
+
230
+
231
+
232
+ class ServerResponse
233
+
234
+ attr_accessor :statusCode
235
+ attr_accessor :data # faked because ServerResponse actually implements WriteableStream
236
+
237
+
238
+ def initialize(data, status_code)
239
+ @data = data
240
+ @statusCode = status_code
241
+ end
242
+
243
+
244
+ def on(event, callback)
245
+ case event
246
+ when 'data'
247
+ callback.call(@data)
248
+ else
249
+ callback.call()
250
+ end
251
+ self
252
+ end
253
+
254
+ end
255
+
256
+ end
257
+
258
+ end
@@ -0,0 +1,27 @@
1
+ require 'action_controller/railtie'
2
+ require 'ruby-clean-css/sprockets'
3
+
4
+ class RubyCleanCSS::Railtie < ::Rails::Railtie
5
+
6
+ initializer(
7
+ 'ruby-clean-css.environment',
8
+ :after => 'sprockets.environment'
9
+ ) { |app|
10
+ RubyCleanCSS::Sprockets.register(app.assets)
11
+ }
12
+
13
+
14
+ initializer(
15
+ 'ruby-clean-css.setup',
16
+ :after => :setup_compression,
17
+ :group => :all
18
+ ) { |app|
19
+ if app.config.assets.enabled
20
+ curr = app.config.assets.css_compressor
21
+ unless curr.respond_to?(:compress)
22
+ app.config.assets.css_compressor = RubyCleanCSS::Sprockets::LABEL
23
+ end
24
+ end
25
+ }
26
+
27
+ end
@@ -0,0 +1,19 @@
1
+ module RubyCleanCSS::Sprockets
2
+
3
+ LABEL = :cleancss
4
+
5
+ def self.register(sprockets)
6
+ klass = RubyCleanCSS::Compressor
7
+ if sprockets.respond_to?(:register_compressor)
8
+ sprockets.register_compressor('text/css', LABEL, klass.new)
9
+ sprockets.css_compressor = LABEL
10
+ else
11
+ Sprockets::Compressors.register_css_compressor(
12
+ LABEL,
13
+ klass.to_s,
14
+ :default => true
15
+ )
16
+ end
17
+ end
18
+
19
+ end