Tizen 2.0 Release
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / node_modules / grunt-css / node_modules / sqwish / src / index.js
1 /*!
2   * Sqwish - a CSS Compressor
3   * Copyright Dustin Diaz 2011
4   * https://github.com/ded/sqwish
5   * License MIT
6   */
7
8 var fs = require('fs');
9
10 function uniq(ar) {
11   var a = [], i, j;
12   label:
13   for (i = ar.length - 1; i >= 0; i--) {
14     for (j = a.length - 1; j >= 0; j--) {
15       if (a[j] == ar[i]) {
16         continue label;
17       }
18     }
19     a[a.length] = ar[i];
20   }
21   return a;
22 }
23
24 function sqwish(css, strict) {
25   // allow /*! bla */ style comments to retain copyrights etc.
26   var comments = css.match(/\/\*![\s\S]+?\*\//g);
27
28   css = css.trim() // give it a solid trimming to start
29
30     // comments
31     .replace(/\/\*[\s\S]+?\*\//g, '')
32
33     // line breaks and carriage returns
34     .replace(/[\n\r]/g, '')
35
36     // space between selectors, declarations, properties and values
37     .replace(/\s*([:;,{}])\s*/g, '$1')
38
39     // replace multiple spaces with single spaces
40     .replace(/\s+/g, ' ')
41
42     // space between last declaration and end of rule
43     // also remove trailing semi-colons on last declaration
44     .replace(/;}/g, '}')
45
46     // this is important
47     .replace(/\s+(!important)/g, '$1')
48
49     // convert longhand hex to shorthand hex
50     .replace(/#([a-fA-F0-9])\1([a-fA-F0-9])\2([a-fA-F0-9])\3/g, '#$1$2$3')
51
52     // replace longhand values with shorthand '5px 5px 5px 5px' => '5px'
53     .replace(/(\d+[a-z]{2}) \1 \1 \1/gi, '$1')
54
55     // replace double-specified longhand values with shorthand '5px 2px 5px 2px' => '5px 2px'
56     .replace(/(\d+[a-z]{2}) (\d+[a-z]{2}) \1 \2/gi, '$1 $2')
57
58     // replace 0px with 0
59     .replace(/([\s|:])[0]+px/g, '$10');
60
61   if (strict) {
62     css = strict_css(css);
63   }
64
65   // put back in copyrights
66   if (comments) {
67     comments = comments ? comments.join('\n') : '';
68     css = comments + '\n' + css;
69   }
70   return css;
71 }
72
73 function strict_css(css) {
74   // now some super fun funky shit where we remove duplicate declarations
75   // into combined rules
76
77   // store global dict of all rules
78   var ruleList = {},
79       rules = css.match(/([^{]+\{[^}]+\})+?/g);
80
81   // lets find the dups
82   rules.forEach(function (rule) {
83     // break rule into selector|declaration parts
84     var parts = rule.match(/([^{]+)\{([^}]+)/),
85         selector = parts[1],
86         declarations = parts[2];
87
88     // start new list if it wasn't created already
89     if (!ruleList[selector]) {
90       ruleList[selector] = [];
91     }
92
93     declarations = declarations.split(';');
94     // filter out duplicate properties
95     ruleList[selector] = ruleList[selector].filter(function (decl) {
96       var prop = decl.match(/[^:]+/)[0];
97       // pre-existing properties are not wanted anymore
98       return !declarations.some(function (dec) {
99         // must include '^' as to not confuse "color" with "border-color" etc.
100         return dec.match(new RegExp('^' + prop + ':'));
101       });
102     });
103
104     // latter takes presedence :)
105     ruleList[selector] = ruleList[selector].concat(declarations);
106     // still dups? just in case
107     ruleList[selector] = uniq(ruleList[selector]);
108   });
109
110   // reset css because we're gonna recreate the whole shabang.
111   css = '';
112   for (var selector in ruleList) {
113     var joinedRuleList = ruleList[selector].join(';');
114     css += selector + '{' + (joinedRuleList).replace(/;$/, '') + '}';
115   }
116   return css;
117 }
118
119 module.exports.exec = function (args) {
120   var out;
121   var read = args[0];
122   if (out = args.indexOf('-o') != -1) {
123     out = args[out + 1];
124   } else {
125     out = read.replace(/\.css$/, '.min.css');
126   }
127   console.log('compressing ' + read + ' to ' + out + '...');
128   var data = fs.readFileSync(read, 'utf8');
129   fs.writeFileSync(out, sqwish(data, (args.indexOf('--strict') != -1)), 'utf8');
130 };
131 module.exports.minify = function (css, strict) {
132   return sqwish(css, strict);
133 };