namibia
df0489e1eeeeab5a9bd44e1d84fce49924fe1bac
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
<?php /** * Class Minify_CSS_Compressor * @package Minify */ /** * Compress CSS * * This is a heavy regex-based removal of whitespace, unnecessary * comments and tokens, and some CSS value minimization, where practical. * Many steps have been taken to avoid breaking comment-based hacks, * including the ie5/mac filter (and its inversion), but expect tricky * hacks involving comment tokens in 'content' value strings to break * minimization badly. A test suite is available. * * @package Minify * @author Stephen Clay <steve@mrclay.org> * @author http://code.google.com/u/1stvamp/ (Issue 64 patch) */ class Minify_CSS_Compressor { /** * Minify a CSS string * * @param string $css * * @param array $options (currently ignored) * * @return string */ public static function process($css, $options = array()) { $obj = new Minify_CSS_Compressor($options); return $obj->_process($css); } /** * @var array */ protected $_options = null; /** * Are we "in" a hack? I.e. are some browsers targetted until the next comment? * * @var bool */ protected $_inHack = false; /** * Constructor * * @param array $options (currently ignored) */ private function __construct($options) { $this->_options = $options; } /** * Minify a CSS string * * @param string $css * * @return string */ protected function _process($css) { $css = str_replace("\r\n", "\n", $css); // preserve empty comment after '>' // http://www.webdevout.net/css-hacks#in_css-selectors $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css); // preserve empty comment between property and value // http://css-discuss.incutio.com/?page=BoxModelHack $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css); $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css); // apply callback to all valid comments (and strip out surrounding ws $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@' ,array($this, '_commentCB'), $css); // remove ws around { } and last semicolon in declaration block $css = preg_replace('/\\s*{\\s*/', '{', $css); $css = preg_replace('/;?\\s*}\\s*/', '}', $css); // remove ws surrounding semicolons $css = preg_replace('/\\s*;\\s*/', ';', $css); // remove ws around urls $css = preg_replace('/ url\\( # url( \\s* ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis) \\s* \\) # ) /x', 'url($1)', $css); // remove ws between rules and colons $css = preg_replace('/ \\s* ([{;]) # 1 = beginning of block or rule separator \\s* ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter) \\s* : \\s* (\\b|[#\'"-]) # 3 = first character of a value /x', '$1$2:$3', $css); // remove ws in selectors $css = preg_replace_callback('/ (?: # non-capture \\s* [^~>+,\\s]+ # selector part \\s* [,>+~] # combinators )+ \\s* [^~>+,\\s]+ # selector part { # open declaration block /x' ,array($this, '_selectorsCB'), $css); // minimize hex colors $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i' , '$1#$2$3$4$5', $css); // remove spaces between font families $css = preg_replace_callback('/font-family:([^;}]+)([;}])/' ,array($this, '_fontFamilyCB'), $css); $css = preg_replace('/@import\\s+url/', '@import url', $css); // replace any ws involving newlines with a single newline $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css); // separate common descendent selectors w/ newlines (to limit line lengths) $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css); // Use newline after 1st numeric value (to limit line lengths). $css = preg_replace('/ ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value \\s+ /x' ,"$1\n", $css); // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/ $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css); return trim($css); } /** * Replace what looks like a set of selectors * * @param array $m regex matches * * @return string */ protected function _selectorsCB($m) { // remove ws around the combinators return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]); } /** * Process a comment and return a replacement * * @param array $m regex matches * * @return string */ protected function _commentCB($m) { $hasSurroundingWs = (trim($m[0]) !== $m[1]); $m = $m[1]; // $m is the comment content w/o the surrounding tokens, // but the return value will replace the entire comment. if ($m === 'keep') { return '/**/'; } if ($m === '" "') { // component of http://tantek.com/CSS/Examples/midpass.html return '/*" "*/'; } if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) { // component of http://tantek.com/CSS/Examples/midpass.html return '/*";}}/* */'; } if ($this->_inHack) { // inversion: feeding only to one browser if (preg_match('@ ^/ # comment started like /*/ \\s* (\\S[\\s\\S]+?) # has at least some non-ws content \\s* /\\* # ends like /*/ or /**/ @x', $m, $n)) { // end hack mode after this comment, but preserve the hack and comment content $this->_inHack = false; return "/*/{$n[1]}/**/"; } } if (substr($m, -1) === '\\') { // comment ends like \*/ // begin hack mode and preserve hack $this->_inHack = true; return '/*\\*/'; } if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */ // begin hack mode and preserve hack $this->_inHack = true; return '/*/*/'; } if ($this->_inHack) { // a regular comment ends hack mode but should be preserved $this->_inHack = false; return '/**/'; } // Issue 107: if there's any surrounding whitespace, it may be important, so // replace the comment with a single space return $hasSurroundingWs // remove all other comments ? ' ' : ''; } /** * Process a font-family listing and return a replacement * * @param array $m regex matches * * @return string */ protected function _fontFamilyCB($m) { // Issue 210: must not eliminate WS between words in unquoted families $pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $out = 'font-family:'; while (null !== ($piece = array_shift($pieces))) { if ($piece[0] !== '"' && $piece[0] !== "'") { $piece = preg_replace('/\\s+/', ' ', $piece); $piece = preg_replace('/\\s?,\\s?/', ',', $piece); } $out .= $piece; } return $out . $m[2]; } } |
Commits for namibiapublic/min/lib/Minify/CSS/Compressor.php
Revision | Author | Commited | Message |
---|---|---|---|
df0489 ... | Mark | Fri 14 Oct, 2016 10:01:00 +0000 | initial commit |