Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/minify/lib/Minify/CSS/Compressor.php
Go to the documentation of this file.
00001 <?php
00021 class Minify_CSS_Compressor {
00022 
00032     public static function process($css, $options = array())
00033     {
00034         $obj = new Minify_CSS_Compressor($options);
00035         return $obj->_process($css);
00036     }
00037     
00041     protected $_options = null;
00042     
00048     protected $_inHack = false;
00049     
00050     
00058     private function __construct($options) {
00059         $this->_options = $options;
00060     }
00061     
00069     protected function _process($css)
00070     {
00071         $css = str_replace("\r\n", "\n", $css);
00072         
00073         // preserve empty comment after '>'
00074         // http://www.webdevout.net/css-hacks#in_css-selectors
00075         $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
00076         
00077         // preserve empty comment between property and value
00078         // http://css-discuss.incutio.com/?page=BoxModelHack
00079         $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
00080         $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
00081         
00082         // apply callback to all valid comments (and strip out surrounding ws
00083         $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
00084             ,array($this, '_commentCB'), $css);
00085 
00086         // remove ws around { } and last semicolon in declaration block
00087         $css = preg_replace('/\\s*{\\s*/', '{', $css);
00088         $css = preg_replace('/;?\\s*}\\s*/', '}', $css);
00089         
00090         // remove ws surrounding semicolons
00091         $css = preg_replace('/\\s*;\\s*/', ';', $css);
00092         
00093         // remove ws around urls
00094         $css = preg_replace('/
00095                 url\\(      # url(
00096                 \\s*
00097                 ([^\\)]+?)  # 1 = the URL (really just a bunch of non right parenthesis)
00098                 \\s*
00099                 \\)         # )
00100             /x', 'url($1)', $css);
00101         
00102         // remove ws between rules and colons
00103         $css = preg_replace('/
00104                 \\s*
00105                 ([{;])              # 1 = beginning of block or rule separator 
00106                 \\s*
00107                 ([\\*_]?[\\w\\-]+)  # 2 = property (and maybe IE filter)
00108                 \\s*
00109                 :
00110                 \\s*
00111                 (\\b|[#\'"])        # 3 = first character of a value
00112             /x', '$1$2:$3', $css);
00113         
00114         // remove ws in selectors
00115         $css = preg_replace_callback('/
00116                 (?:              # non-capture
00117                     \\s*
00118                     [^~>+,\\s]+  # selector part
00119                     \\s*
00120                     [,>+~]       # combinators
00121                 )+
00122                 \\s*
00123                 [^~>+,\\s]+      # selector part
00124                 {                # open declaration block
00125             /x'
00126             ,array($this, '_selectorsCB'), $css);
00127         
00128         // minimize hex colors
00129         $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
00130             , '$1#$2$3$4$5', $css);
00131         
00132         // remove spaces between font families
00133         $css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
00134             ,array($this, '_fontFamilyCB'), $css);
00135         
00136         $css = preg_replace('/@import\\s+url/', '@import url', $css);
00137         
00138         // replace any ws involving newlines with a single newline
00139         $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
00140         
00141         // separate common descendent selectors w/ newlines (to limit line lengths)
00142         $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
00143         
00144         // Use newline after 1st numeric value (to limit line lengths).
00145         $css = preg_replace('/
00146             ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
00147             \\s+
00148             /x'
00149             ,"$1\n", $css);
00150         
00151         // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
00152         $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
00153             
00154         return trim($css);
00155     }
00156     
00164     protected function _selectorsCB($m)
00165     {
00166         // remove ws around the combinators
00167         return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
00168     }
00169     
00177     protected function _commentCB($m)
00178     {
00179         $hasSurroundingWs = (trim($m[0]) !== $m[1]);
00180         $m = $m[1]; 
00181         // $m is the comment content w/o the surrounding tokens, 
00182         // but the return value will replace the entire comment.
00183         if ($m === 'keep') {
00184             return '/**/';
00185         }
00186         if ($m === '" "') {
00187             // component of http://tantek.com/CSS/Examples/midpass.html
00188             return '/*" "*/';
00189         }
00190         if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
00191             // component of http://tantek.com/CSS/Examples/midpass.html
00192             return '/*";}}/* */';
00193         }
00194         if ($this->_inHack) {
00195             // inversion: feeding only to one browser
00196             if (preg_match('@
00197                     ^/               # comment started like /*/
00198                     \\s*
00199                     (\\S[\\s\\S]+?)  # has at least some non-ws content
00200                     \\s*
00201                     /\\*             # ends like /*/ or /**/
00202                 @x', $m, $n)) {
00203                 // end hack mode after this comment, but preserve the hack and comment content
00204                 $this->_inHack = false;
00205                 return "/*/{$n[1]}/**/";
00206             }
00207         }
00208         if (substr($m, -1) === '\\') { // comment ends like \*/
00209             // begin hack mode and preserve hack
00210             $this->_inHack = true;
00211             return '/*\\*/';
00212         }
00213         if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
00214             // begin hack mode and preserve hack
00215             $this->_inHack = true;
00216             return '/*/*/';
00217         }
00218         if ($this->_inHack) {
00219             // a regular comment ends hack mode but should be preserved
00220             $this->_inHack = false;
00221             return '/**/';
00222         }
00223         // Issue 107: if there's any surrounding whitespace, it may be important, so 
00224         // replace the comment with a single space
00225         return $hasSurroundingWs // remove all other comments
00226             ? ' '
00227             : '';
00228     }
00229     
00237     protected function _fontFamilyCB($m)
00238     {
00239         // Issue 210: must not eliminate WS between words in unquoted families
00240         $pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
00241         $out = 'font-family:';
00242         while (null !== ($piece = array_shift($pieces))) {
00243             if ($piece[0] !== '"' && $piece[0] !== "'") {
00244                 $piece = preg_replace('/\\s+/', ' ', $piece);
00245                 $piece = preg_replace('/\\s?,\\s?/', ',', $piece);
00246             }
00247             $out .= $piece;
00248         }
00249         return $out . $m[2];
00250     }
00251 }
 All Data Structures Namespaces Files Functions Variables Enumerations