1 //<script type="text/javascript">
4 * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
5 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
6 * Code licensed under the BSD License:
7 * http://developer.yahoo.net/yui/license.txt
9 * This code is a port of Isaac Schlueter's cssmin utility.
11 * Usage: seed buildSDK/cssmini.js
12 * Usage: gjs -I buildSDK buildSDK/cssmini.js
17 GLib = imports.gi.GLib;
19 // let's see if this works..
20 // should be run from top level..
21 var pa = GLib.get_current_dir();
25 //println(pack(File.read(pa+'/css/basic-dialog.css')));
27 var lines = String(GLib.file_get_contents(pa + '/css/roojs-debug.css')[1]).split(/\n/);
28 //@import url("reset-min.css");
30 lines.forEach(function(l) {
31 if (!l.match(/^@import/)) {
34 l = l.replace(/^[^"]+"([^"]+)".*/, '$1');
36 //out += pack(File.read(pa+'/css/' + l)).replace(/\}/g, "}\n")+"\n";
37 var data = String(GLib.file_get_contents(pa+'/css/' + l)[1]);
39 out += pack(data) + "\n";
41 var f = Gio.file_new_for_path(String(pa+'/css/roojs.css'));
42 var data_out = new Gio.DataOutputStream({base_stream:f.replace(null, false, Gio.FileCreateFlags.NONE, null)});
43 data_out.put_string(out, null);
47 print("written css/roojs.css");
62 function removeComments(str)
68 while ((si = str.indexOf("/*")) > -1) {
69 ei = str.indexOf("*/");
73 if (str.charAt(ei-1) == '\\') { // eg. /* \*/
76 // Looks like a comment to hide rules from IE Mac.
77 // Leave this comment, and the following one, alone...
80 r += str.substring(0, ei) ;
81 str = str.substring(ei);
87 r += str.substring(0, ei) ;
88 str = str.substring(ei+2);
92 r += str.substring(0, si) ;
93 str = str.substring(ei+2);
97 r += str.substring(0, 2);
98 str = str.substring(2);
106 istr = removeComments(istr);
107 //println("after comments remove: " + istr);
109 // Normalize all whitespace strings to single spaces. Easier to work with that way.
110 istr = istr.replace(/\s+/g, ' ');
112 // Make a pseudo class for the Box Model Hack ????
113 //css = css.replaceAll("\"\\\\\"}\\\\\"\"", "___PSEUDOCLASSBMH___");
114 istr = istr.replace(/"\\"\}\\"/g, "___PSEUDOCLASSBMH___");
116 // Remove the spaces before the things that should not have spaces before them.
117 // But, be careful not to turn "p :link {...}" into "p:link{...}"
118 // Swap out any pseudo-class colons with the token, and then swap back.
120 istr = istr.replace(/(^|\})(([^\{:])+:)+([^\{]*\{)/g, function(m) {
121 return m.replace(/:/g, "___PSEUDOCLASSCOLON___");
125 istr = istr.replace(/\s+([!{};:>+\(\)\],])/g, "$1");
126 istr = istr.replace(/___PSEUDOCLASSCOLON___/g, ":");
128 // Remove the spaces after the things that should not have spaces after them.
129 istr = istr.replace(/([!{}:;>+\(\[,])\s+/g, "$1");
131 // Add the semicolon where it's missing.
132 istr = istr.replace(/([^;\}])\}/g, "$1;}");
134 // Replace 0(px,em,%) with 0.
135 istr = istr.replace(/([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)/g, "$1$2");
137 // Replace 0 0 0 0; with 0. (by this time, we have reduced spaces etc..
138 istr = istr.replace(/:0 0 0 0;/g, ":0;");
139 istr = istr.replace(/:0 0 0;/g, ":0;");
140 istr = istr.replace(/:0 0;/g, ":0;");
141 // Replace background-position:0; with background-position:0 0;
142 istr = istr.replace(/background-position:0;/g, "background-position:0 0;");
144 // Replace 0.6 to .6, but only when preceded by : or a white-space
145 istr = istr.replace(/(:|\s)0+\.(\d+)/g, "$1.$2");
147 // Shorten colors from rgb(51,102,153) to #336699
148 // This makes it more likely that it'll get further compressed in the next step.
150 istr = istr.replace(/rgb\s*\(\s*([0-9,\s]+)\s*\)/g, function(m, c)
152 var rgb = c.split(',');
154 for (var i = 0; i < rgb.length; i++) {
155 var val = parseInt(rgb[i]);
159 hx+=val.toString(16);
167 // Shorten colors from #AABBCC to #ABC. Note that we want to make sure
168 // the color is not preceded by either ", " or =. Indeed, the property
169 // filter: chroma(color="#FFFFFF");
171 // filter: chroma(color="#FFF");
172 // which makes the filter break in IE.
174 istr = istr.replace(/([^"'=\s])(\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/g,
175 function(m, g1,g2,g3,g4,g5,g6,g7,g8) {
179 if (g3.toLowerCase() == g4.toLowerCase() &&
180 g5.toLowerCase() == g6.toLowerCase() &&
181 g7.toLowerCase() == g8.toLowerCase()) {
183 return g1+g2+'#' + g3+g5+g7;
191 // Remove empty rules.
192 istr = istr.replace(/[^\}]+\{;\}/g, "");
194 if (linebreakpos >= 0) {
195 // Some source control tools don't like it when files containing lines longer
196 // than, say 8000 characters, are checked in. The linebreak option is used in
197 // that case to split long lines after a specific column.
199 int linestartpos = 0;
200 sb = new StringBuffer(css);
201 while (i < sb.length()) {
202 char c = sb.charAt(i++);
203 if (c == '}' && i - linestartpos > linebreakpos) {
212 // Replace the pseudo class for the Box Model Hack
213 istr = istr.replace(/___PSEUDOCLASSBMH___/g, "\"\\\\\"}\\\\\"\"");
215 // Trim the final string (for any leading or trailing white spaces)
216 istr = istr.replace(/^\s+/g, '');
217 istr = istr.replace(/\s+$/g, '');
220 // Write the output...