cssminify2 2.0.0

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 (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGES.md +17 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.md +23 -0
  7. data/README.md +71 -0
  8. data/cssminify2.gemspec +31 -0
  9. data/lib/cssminify2.rb +34 -0
  10. data/lib/cssminify2/cssmin.rb +394 -0
  11. data/lib/cssminify2/version.rb +5 -0
  12. data/spec/cssminify_spec.rb +321 -0
  13. data/spec/sample.css +141 -0
  14. data/spec/spec_helper.rb +4 -0
  15. data/spec/tests/background-position.css +2 -0
  16. data/spec/tests/background-position.css.min +1 -0
  17. data/spec/tests/border-none.css +5 -0
  18. data/spec/tests/border-none.css.min +1 -0
  19. data/spec/tests/box-model-hack.css +9 -0
  20. data/spec/tests/box-model-hack.css.min +1 -0
  21. data/spec/tests/bug2527974.css +10 -0
  22. data/spec/tests/bug2527974.css.min +1 -0
  23. data/spec/tests/bug2527991.css +19 -0
  24. data/spec/tests/bug2527991.css.min +1 -0
  25. data/spec/tests/bug2527998.css +4 -0
  26. data/spec/tests/bug2527998.css.min +1 -0
  27. data/spec/tests/bug2528034.css +5 -0
  28. data/spec/tests/bug2528034.css.min +1 -0
  29. data/spec/tests/bug2528093.css +3 -0
  30. data/spec/tests/bug2528093.css.min +1 -0
  31. data/spec/tests/charset-media.css +9 -0
  32. data/spec/tests/charset-media.css.min +1 -0
  33. data/spec/tests/color-simple.css +8 -0
  34. data/spec/tests/color-simple.css.min +1 -0
  35. data/spec/tests/color.css +46 -0
  36. data/spec/tests/color.css.min +1 -0
  37. data/spec/tests/comment.css +3 -0
  38. data/spec/tests/comment.css.min +1 -0
  39. data/spec/tests/concat-charset.css +15 -0
  40. data/spec/tests/concat-charset.css.min +1 -0
  41. data/spec/tests/dataurl-base64-doublequotes.css +23 -0
  42. data/spec/tests/dataurl-base64-doublequotes.css.min +1 -0
  43. data/spec/tests/dataurl-base64-eof.css +10 -0
  44. data/spec/tests/dataurl-base64-eof.css.min +1 -0
  45. data/spec/tests/dataurl-base64-linebreakindata.css +34 -0
  46. data/spec/tests/dataurl-base64-linebreakindata.css.min +1 -0
  47. data/spec/tests/dataurl-base64-noquotes.css +26 -0
  48. data/spec/tests/dataurl-base64-noquotes.css.min +1 -0
  49. data/spec/tests/dataurl-base64-singlequotes.css +23 -0
  50. data/spec/tests/dataurl-base64-singlequotes.css.min +1 -0
  51. data/spec/tests/dataurl-base64-twourls.css +27 -0
  52. data/spec/tests/dataurl-base64-twourls.css.min +1 -0
  53. data/spec/tests/dataurl-dbquote-font.css +30 -0
  54. data/spec/tests/dataurl-dbquote-font.css.min +5 -0
  55. data/spec/tests/dataurl-nonbase64-doublequotes.css +13 -0
  56. data/spec/tests/dataurl-nonbase64-doublequotes.css.min +1 -0
  57. data/spec/tests/dataurl-nonbase64-noquotes.css +11 -0
  58. data/spec/tests/dataurl-nonbase64-noquotes.css.min +1 -0
  59. data/spec/tests/dataurl-nonbase64-singlequotes.css +15 -0
  60. data/spec/tests/dataurl-nonbase64-singlequotes.css.min +2 -0
  61. data/spec/tests/dataurl-noquote-multiline-font.css +31 -0
  62. data/spec/tests/dataurl-noquote-multiline-font.css.min +3 -0
  63. data/spec/tests/dataurl-realdata-doublequotes.css +90 -0
  64. data/spec/tests/dataurl-realdata-doublequotes.css.min +1 -0
  65. data/spec/tests/dataurl-realdata-noquotes.css +90 -0
  66. data/spec/tests/dataurl-realdata-noquotes.css.min +1 -0
  67. data/spec/tests/dataurl-realdata-singlequotes.css +90 -0
  68. data/spec/tests/dataurl-realdata-singlequotes.css.min +1 -0
  69. data/spec/tests/dataurl-realdata-yuiapp.css +106 -0
  70. data/spec/tests/dataurl-realdata-yuiapp.css.min +1 -0
  71. data/spec/tests/dataurl-singlequote-font.css +30 -0
  72. data/spec/tests/dataurl-singlequote-font.css.min +3 -0
  73. data/spec/tests/decimals.css +3 -0
  74. data/spec/tests/decimals.css.min +1 -0
  75. data/spec/tests/dollar-header.css +7 -0
  76. data/spec/tests/dollar-header.css.min +3 -0
  77. data/spec/tests/font-face.css +6 -0
  78. data/spec/tests/font-face.css.min +1 -0
  79. data/spec/tests/ie5mac.css +5 -0
  80. data/spec/tests/ie5mac.css.min +1 -0
  81. data/spec/tests/issue221.css +7 -0
  82. data/spec/tests/issue221.css.min +1 -0
  83. data/spec/tests/issue222.css +3 -0
  84. data/spec/tests/issue222.css.min +1 -0
  85. data/spec/tests/keyframe.css +4 -0
  86. data/spec/tests/keyframe.css.min +1 -0
  87. data/spec/tests/media-empty-class.css +16 -0
  88. data/spec/tests/media-empty-class.css.min +1 -0
  89. data/spec/tests/media-multi.css +3 -0
  90. data/spec/tests/media-multi.css.min +1 -0
  91. data/spec/tests/media-test.css +3 -0
  92. data/spec/tests/media-test.css.min +1 -0
  93. data/spec/tests/opacity-filter.css +14 -0
  94. data/spec/tests/opacity-filter.css.min +1 -0
  95. data/spec/tests/preserve-case.css +15 -0
  96. data/spec/tests/preserve-case.css.min +1 -0
  97. data/spec/tests/preserve-new-line.css +6 -0
  98. data/spec/tests/preserve-new-line.css.min +3 -0
  99. data/spec/tests/preserve-strings.css +7 -0
  100. data/spec/tests/preserve-strings.css.min +1 -0
  101. data/spec/tests/pseudo-first.css +16 -0
  102. data/spec/tests/pseudo-first.css.min +1 -0
  103. data/spec/tests/pseudo.css +4 -0
  104. data/spec/tests/pseudo.css.min +1 -0
  105. data/spec/tests/special-comments.css +13 -0
  106. data/spec/tests/special-comments.css.min +9 -0
  107. data/spec/tests/star-underscore-hacks.css +5 -0
  108. data/spec/tests/star-underscore-hacks.css.min +1 -0
  109. data/spec/tests/string-in-comment.css +8 -0
  110. data/spec/tests/string-in-comment.css.min +1 -0
  111. data/spec/tests/webkit-transform.css +2 -0
  112. data/spec/tests/webkit-transform.css.min +1 -0
  113. data/spec/tests/zeros.css +12 -0
  114. data/spec/tests/zeros.css.min +1 -0
  115. metadata +278 -0
@@ -0,0 +1,5 @@
1
+ # coding: utf-8
2
+
3
+ class CSSminify2
4
+ VERSION = "2.0.0"
5
+ end
@@ -0,0 +1,321 @@
1
+ # coding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+
6
+ describe "CSSminify2" do
7
+
8
+ context "application" do
9
+
10
+ it "minifies CSS" do
11
+ source = File.open(File.expand_path("../sample.css", __FILE__), "r:UTF-8").read
12
+ minified = CSSminify2.compress(source)
13
+ minified.length.should < source.length
14
+ lambda {
15
+ CSSminify2.compress(minified)
16
+ }.should_not raise_error
17
+ end
18
+
19
+ it "honors the specified maximum line length" do
20
+ source = <<-EOS
21
+ .classname1 {
22
+ border: none;
23
+ background: none;
24
+ outline: none;
25
+ }
26
+ .classname2 {
27
+ border: none;
28
+ background: none;
29
+ outline: none;
30
+ }
31
+ EOS
32
+ minified = CSSminify2.compress(source, 30)
33
+ minified.split("\n").length.should eq(2)
34
+ minified.should eq(".classname1{border:0;background:0;outline:0}\n.classname2{border:0;background:0;outline:0}")
35
+ end
36
+
37
+ it "handles strings as input format" do
38
+ lambda {
39
+ CSSminify2.compress(File.open(File.expand_path("../sample.css", __FILE__), "r:UTF-8").read).should_not be_empty
40
+ }.should_not raise_error
41
+ end
42
+
43
+ it "handles files as input format" do
44
+ lambda {
45
+ CSSminify2.compress(File.open(File.expand_path("../sample.css", __FILE__), "r:UTF-8")).should_not be_empty
46
+ }.should_not raise_error
47
+ end
48
+
49
+ it "works as both class and class instance" do
50
+ lambda {
51
+ CSSminify2.compress(File.open(File.expand_path("../sample.css", __FILE__), "r:UTF-8").read).should_not be_empty
52
+ CSSminify2.new.compress(File.open(File.expand_path("../sample.css", __FILE__), "r:UTF-8").read).should_not be_empty
53
+ }.should_not raise_error
54
+ end
55
+
56
+ end
57
+
58
+
59
+ context "compression" do
60
+
61
+ it "removes comments and white space" do
62
+ source = <<-EOS
63
+ /*****
64
+ Multi-line comment
65
+ before a new class name
66
+ *****/
67
+ .classname {
68
+ /* comment in declaration block */
69
+ font-weight: normal;
70
+ }
71
+ EOS
72
+ CSSminify2.compress(source).should eq('.classname{font-weight:normal}')
73
+ end
74
+
75
+ it "preserves special comments" do
76
+ source = <<-EOS
77
+ /*!
78
+ (c) Very Important Comment
79
+ */
80
+ .classname {
81
+ /* comment in declaration block */
82
+ font-weight: normal;
83
+ }
84
+ EOS
85
+ result = <<-EOS
86
+ /*!
87
+ (c) Very Important Comment
88
+ */.classname{font-weight:normal}
89
+ EOS
90
+ (CSSminify2.compress(source) + "\n").should eq(result)
91
+ end
92
+
93
+ it "removes last semi-colon in a block" do
94
+ source = <<-EOS
95
+ .classname {
96
+ border-top: 1px;
97
+ border-bottom: 2px;
98
+ }
99
+ EOS
100
+ CSSminify2.compress(source).should eq('.classname{border-top:1px;border-bottom:2px}')
101
+ end
102
+
103
+ it "removes extra semi-colons" do
104
+ source = <<-EOS
105
+ .classname {
106
+ border-top: 1px; ;
107
+ border-bottom: 2px;;;
108
+ }
109
+ EOS
110
+ CSSminify2.compress(source).should eq('.classname{border-top:1px;border-bottom:2px}')
111
+ end
112
+
113
+ it "removes empty declarations" do
114
+ source = <<-EOS
115
+ .empty { ;}
116
+ .nonempty {border: 0;}
117
+ EOS
118
+ CSSminify2.compress(source).should eq('.nonempty{border:0}')
119
+ end
120
+
121
+ it "simplifies zero values" do
122
+ source = <<-EOS
123
+ a {
124
+ margin: 0px 0pt 0em 0%;
125
+ background-position: 0 0ex;
126
+ padding: 0in 0cm 0mm 0pc
127
+ }
128
+ EOS
129
+ CSSminify2.compress(source).should eq('a{margin:0;background-position:0 0;padding:0}')
130
+ end
131
+
132
+ it "simplifies zero values preserving unit when necessary" do
133
+ source = <<-EOS
134
+ @-webkit-keyframes anim {
135
+ 0% {
136
+ left: 0;
137
+ }
138
+ 100% {
139
+ left: -100%;
140
+ }
141
+ }
142
+ @-moz-keyframes anim {
143
+ 0% {
144
+ left: 0;
145
+ }
146
+ 100% {
147
+ left: -100%;
148
+ }
149
+ }
150
+ @-ms-keyframes anim {
151
+ 0% {
152
+ left: 0;
153
+ }
154
+ 100% {
155
+ left: -100%;
156
+ }
157
+ }
158
+ @-o-keyframes anim {
159
+ 0% {
160
+ left: 0;
161
+ }
162
+ 100% {
163
+ left: -100%;
164
+ }
165
+ }
166
+ @keyframes anim {
167
+ 0% {
168
+ left: 0;
169
+ }
170
+ 100% {
171
+ left: -100%;
172
+ }
173
+ }
174
+ EOS
175
+ CSSminify2.compress(source).should eq('@-webkit-keyframes anim{0%{left:0}100%{left:-100%}}@-moz-keyframes anim{0%{left:0}100%{left:-100%}}@-ms-keyframes anim{0%{left:0}100%{left:-100%}}@-o-keyframes anim{0%{left:0}100%{left:-100%}}@keyframes anim{0%{left:0}100%{left:-100%}}')
176
+ end
177
+
178
+ it "removes leading zeros from floats" do
179
+ source = <<-EOS
180
+ .classname {
181
+ margin: 0.6px 0.333pt 1.2em 8.8cm;
182
+ }
183
+ EOS
184
+ CSSminify2.compress(source).should eq('.classname{margin:.6px .333pt 1.2em 8.8cm}')
185
+ end
186
+
187
+ it "removes leading zeros from groups" do
188
+ source = <<-EOS
189
+ a {
190
+ margin: 0px 0pt 0em 0%;
191
+ _padding-top: 0ex;
192
+ background-position: 0 0;
193
+ padding: 0in 0cm 0mm 0pc;
194
+ transition: opacity .0s;
195
+ transition-delay: 0.0ms;
196
+ transform: rotate3d(0grad, 0rad, 0deg);
197
+ pitch: 0khz;
198
+ pitch:
199
+ 0hz /* intentionally on next line */;
200
+ }
201
+ EOS
202
+ CSSminify2.compress(source).should eq('a{margin:0;_padding-top:0;background-position:0 0;padding:0;transition:opacity 0;transition-delay:0;transform:rotate3d(0,0,0);pitch:0;pitch:0}')
203
+ end
204
+
205
+ it "simplifies color values but preserves filter properties, RGBa values and ID strings" do
206
+ source = <<-EOS
207
+ .color-me {
208
+ color: rgb(123, 123, 123);
209
+ border-color: #ffeedd;
210
+ background: none repeat scroll 0 0 rgb(255, 0,0);
211
+ }
212
+ EOS
213
+ CSSminify2.compress(source).should eq('.color-me{color:#7b7b7b;border-color:#fed;background:none repeat scroll 0 0 #f00}')
214
+
215
+ source = <<-EOS
216
+ #AABBCC {
217
+ color: rgba(1, 2, 3, 4);
218
+ filter: chroma(color="#FFFFFF");
219
+ }
220
+ EOS
221
+ CSSminify2.compress(source).should eq('#AABBCC{color:rgba(1,2,3,4);filter:chroma(color="#FFFFFF")}')
222
+ end
223
+
224
+ it "only keeps the first charset declaration" do
225
+ source = <<-EOS
226
+ @charset "utf-8";
227
+ #foo {
228
+ border-width: 1px;
229
+ }
230
+
231
+ /* second css, merged */
232
+ @charset "another one";
233
+ #bar {
234
+ border-width: 10px;
235
+ }
236
+ EOS
237
+ CSSminify2.compress(source).should eq('@charset "utf-8";#foo{border-width:1px}#bar{border-width:10px}')
238
+ end
239
+
240
+ it "simplifies the IE opacity filter syntax" do
241
+ source = <<-EOS
242
+ .classname {
243
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; /* IE 8 */
244
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); /* IE < 8 */
245
+ }
246
+ EOS
247
+ CSSminify2.compress(source).should eq('.classname{-ms-filter:"alpha(opacity=80)";filter:alpha(opacity=80)}')
248
+ end
249
+
250
+ it "replaces 'none' values with 0 where allowed" do
251
+ source = <<-EOS
252
+ .classname {
253
+ border: none;
254
+ background: none;
255
+ outline: none;
256
+ }
257
+ EOS
258
+ CSSminify2.compress(source).should eq('.classname{border:0;background:0;outline:0}')
259
+ end
260
+
261
+ it "tolerates underscore/star hacks" do
262
+ source = <<-EOS
263
+ #element {
264
+ width: 1px;
265
+ *width: 2px;
266
+ _width: 3px;
267
+ }
268
+ EOS
269
+ CSSminify2.compress(source).should eq('#element{width:1px;*width:2px;_width:3px}')
270
+ end
271
+
272
+ it "tolerates child selector hacks" do
273
+ source = <<-EOS
274
+ html >/**/ body p {
275
+ color: blue;
276
+ }
277
+ EOS
278
+ CSSminify2.compress(source).should eq('html>/**/body p{color:blue}')
279
+ end
280
+
281
+ it "tolerates IE5/Mac hacks" do
282
+ source = <<-EOS
283
+ /* Ignore the next rule in IE mac \\*/
284
+ .selector {
285
+ color: khaki;
286
+ }
287
+ /* Stop ignoring in IE mac */
288
+ EOS
289
+ CSSminify2.compress(source).should eq('/*\*/.selector{color:khaki}/**/')
290
+ end
291
+
292
+ it "tolerates box model hacks" do
293
+ source = <<-EOS
294
+ #elem {
295
+ width: 100px; /* IE */
296
+ voice-family: "\\"}\\"";
297
+ voice-family:inherit;
298
+ width: 200px; /* others */
299
+ }
300
+ html>body #elem {
301
+ width: 200px; /* others */
302
+ }
303
+ EOS
304
+ CSSminify2.compress(source).should eq('#elem{width:100px;voice-family:"\"}\"";voice-family:inherit;width:200px}html>body #elem{width:200px}')
305
+ end
306
+
307
+ it "should pass all the original tests included in the YUI compressor package" do
308
+ puts "Now running original YUI compressor test files:"
309
+
310
+ files = Dir.glob(File.join(File.dirname(__FILE__), 'tests', '*.css'))
311
+
312
+ for file in files do
313
+ print " -- testing #{file} ..."
314
+ CSSminify2.compress(File.read(file)).chomp.strip.should eq(File.read(file + '.min').chomp.strip)
315
+ print "successful\n"
316
+ end
317
+ end
318
+
319
+ end
320
+
321
+ end
data/spec/sample.css ADDED
@@ -0,0 +1,141 @@
1
+ /* Source http://developer.yahoo.com/yui/compressor/css.html */
2
+
3
+ /*****
4
+ Multi-line comment
5
+ before a new class name
6
+ *****/
7
+ .classname {
8
+ /* comment in declaration block */
9
+ font-weight: normal;
10
+ }
11
+
12
+ /*!
13
+ (c) Very Important Comment
14
+ */
15
+ .classname {
16
+ /* comment in declaration block */
17
+ font-weight: normal;
18
+ }
19
+
20
+ .classname {
21
+ border-top: 1px;
22
+ border-bottom: 2px;
23
+ }
24
+
25
+ .classname {
26
+ border-top: 1px; ;
27
+ border-bottom: 2px;;;
28
+ }
29
+
30
+ .empty { ;}
31
+ .nonempty {border: 0;}
32
+
33
+ a {
34
+ margin: 0px 0pt 0em 0%;
35
+ background-position: 0 0ex;
36
+ padding: 0in 0cm 0mm 0pc
37
+ }
38
+
39
+ @-webkit-keyframes marquee {
40
+ 0% {
41
+ left: 0;
42
+ }
43
+ 100% {
44
+ left: -100%;
45
+ }
46
+ }
47
+ @-moz-keyframes marquee {
48
+ 0% {
49
+ left: 0;
50
+ }
51
+ 100% {
52
+ left: -100%;
53
+ }
54
+ }
55
+ @-ms-keyframes marquee {
56
+ 0% {
57
+ left: 0;
58
+ }
59
+ 100% {
60
+ left: -100%;
61
+ }
62
+ }
63
+ @-o-keyframes marquee {
64
+ 0% {
65
+ left: 0;
66
+ }
67
+ 100% {
68
+ left: -100%;
69
+ }
70
+ }
71
+ @keyframes marquee {
72
+ 0% {
73
+ left: 0;
74
+ }
75
+ 100% {
76
+ left: -100%;
77
+ }
78
+ }
79
+
80
+ .classname {
81
+ margin: 0.6px 0.333pt 1.2em 8.8cm;
82
+ }
83
+
84
+ .color-me {
85
+ color: rgb(123, 123, 123);
86
+ border-color: #ffeedd;
87
+ background: none repeat scroll 0 0 rgb(255, 0,0);
88
+ }
89
+
90
+ .cantouch {
91
+ color: rgba(1, 2, 3, 4);
92
+ filter: chroma(color="#FFFFFF");
93
+ }
94
+
95
+ @charset "utf-8";
96
+ #foo {
97
+ border-width: 1px;
98
+ }
99
+
100
+ /* second css, merged */
101
+ @charset "another one";
102
+ #bar {
103
+ border-width: 10px;
104
+ }
105
+
106
+ .classname {
107
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; /* IE 8 */
108
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); /* IE < 8 */
109
+ }
110
+
111
+ .classname {
112
+ border: none;
113
+ background: none;
114
+ outline: none;
115
+ }
116
+
117
+ #element {
118
+ width: 1px;
119
+ *width: 2px;
120
+ _width: 3px;
121
+ }
122
+
123
+ html >/**/ body p {
124
+ color: blue;
125
+ }
126
+
127
+ /* Ignore the next rule in IE mac \*/
128
+ .selector {
129
+ color: khaki;
130
+ }
131
+ /* Stop ignoring in IE mac */
132
+
133
+ #elem {
134
+ width: 100px; /* IE */
135
+ voice-family: "\"}\"";
136
+ voice-family:inherit;
137
+ width: 200px; /* others */
138
+ }
139
+ html>body #elem {
140
+ width: 200px; /* others */
141
+ }