ruby-clean-css 0.0.2

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.
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