PEEL Shopping
Open source ecommerce : PEEL Shopping
Minify_CSS_Compressor.php
Go to the documentation of this file.
1 <?php
22 
32  public static function process($css, $options = array())
33  {
34  $obj = new Minify_CSS_Compressor($options);
35  return $obj->_process($css);
36  }
37 
41  protected $_options = null;
42 
48  protected $_inHack = false;
49 
50 
56  private function __construct($options) {
57  $this->_options = $options;
58  }
59 
67  protected function _process($css)
68  {
69  if ($this->_options['do_compress']) {
70  $css = str_replace("\r\n", "\n", $css);
71 
72  // preserve empty comment after '>'
73  // http://www.webdevout.net/css-hacks#in_css-selectors
74  $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
75 
76  // preserve empty comment between property and value
77  // http://css-discuss.incutio.com/?page=BoxModelHack
78  $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
79  $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
80  }
81  // apply callback to all valid comments (and strip out surrounding ws
82  $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
83  ,array($this, '_commentCB'), $css);
84 
85  if ($this->_options['do_compress']) {
86  // remove ws around { } and last semicolon in declaration block
87  $css = preg_replace('/\\s*{\\s*/', '{', $css);
88  $css = preg_replace('/;?\\s*}\\s*/', '}', $css);
89 
90  // remove ws surrounding semicolons
91  $css = preg_replace('/\\s*;\\s*/', ';', $css);
92 
93  // remove ws around urls
94  $css = preg_replace('/
95  url\\( # url(
96  \\s*
97  ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis)
98  \\s*
99  \\) # )
100  /x', 'url($1)', $css);
101 
102  // remove ws between rules and colons
103  $css = preg_replace('/
104  \\s*
105  ([{;]) # 1 = beginning of block or rule separator
106  \\s*
107  ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter)
108  \\s*
109  :
110  \\s*
111  (\\b|[#\'"-]) # 3 = first character of a value
112  /x', '$1$2:$3', $css);
113  /*
114  // SUPPRIME CAR PLANTE PHP SUR WINDOWS !
115  // remove ws in selectors
116  $css = preg_replace_callback('/
117  (?: # non-capture
118  \\s*
119  [^~>+,\\s]+ # selector part
120  \\s*
121  [,>+~] # combinators
122  )+
123  \\s*
124  [^~>+,\\s]+ # selector part
125  { # open declaration block
126  /x'
127  ,array($this, '_selectorsCB'), $css);
128  */
129  // minimize hex colors
130  $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
131  , '$1#$2$3$4$5', $css);
132 
133  // remove spaces between font families
134  $css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
135  ,array($this, '_fontFamilyCB'), $css);
136 
137  $css = preg_replace('/@import\\s+url/', '@import url', $css);
138 
139  // replace any ws involving newlines with a single newline
140  $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
141 
142  // separate common descendent selectors w/ newlines (to limit line lengths)
143  $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
144 
145  // Use newline after 1st numeric value (to limit line lengths).
146  $css = preg_replace('/
147  ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
148  \\s+
149  /x'
150  ,"$1\n", $css);
151 
152  // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
153  $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
154  }
155  return trim($css);
156  }
157 
165  protected function _selectorsCB($m)
166  {
167  // remove ws around the combinators
168  return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
169  }
170 
178  protected function _commentCB($m)
179  {
180  $hasSurroundingWs = (trim($m[0]) !== $m[1]);
181  $m = $m[1];
182  // $m is the comment content w/o the surrounding tokens,
183  // but the return value will replace the entire comment.
184  if ($m === 'keep') {
185  return '/**/';
186  }
187  if ($m === '" "') {
188  // component of http://tantek.com/CSS/Examples/midpass.html
189  return '/*" "*/';
190  }
191  if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
192  // component of http://tantek.com/CSS/Examples/midpass.html
193  return '/*";}}/* */';
194  }
195  if ($this->_inHack) {
196  // inversion: feeding only to one browser
197  if (preg_match('@
198  ^/ # comment started like /*/
199  \\s*
200  (\\S[\\s\\S]+?) # has at least some non-ws content
201  \\s*
202  /\\* # ends like /*/ or /**/
203  @x', $m, $n)) {
204  // end hack mode after this comment, but preserve the hack and comment content
205  $this->_inHack = false;
206  return "/*/{$n[1]}/**/";
207  }
208  }
209  if (substr($m, -1) === '\\') { // comment ends like \*/
210  // begin hack mode and preserve hack
211  $this->_inHack = true;
212  return '/*\\*/';
213  }
214  if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
215  // begin hack mode and preserve hack
216  $this->_inHack = true;
217  return '/*/*/';
218  }
219  if ($this->_inHack) {
220  // a regular comment ends hack mode but should be preserved
221  $this->_inHack = false;
222  return '/**/';
223  }
224  // Issue 107: if there's any surrounding whitespace, it may be important, so
225  // replace the comment with a single space
226  return $hasSurroundingWs // remove all other comments
227  ? ' '
228  : '';
229  }
230 
238  protected function _fontFamilyCB($m)
239  {
240  // Issue 210: must not eliminate WS between words in unquoted families
241  $pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
242  $out = 'font-family:';
243  while (null !== ($piece = array_shift($pieces))) {
244  if ($piece[0] !== '"' && $piece[0] !== "'") {
245  $piece = preg_replace('/\\s+/', ' ', $piece);
246  $piece = preg_replace('/\\s?,\\s?/', ',', $piece);
247  }
248  $out .= $piece;
249  }
250  return $out . $m[2];
251  }
252 }
_fontFamilyCB($m)
Process a font-family listing and return a replacement.
_selectorsCB($m)
Replace what looks like a set of selectors.
static process($css, $options=array())
Minify a CSS string.
_process($css)
Minify a CSS string.
_commentCB($m)
Process a comment and return a replacement.

This documentation for Open ecommerce PEEL Shopping and PEEL.fr has been generated by Doxygen on Thu Oct 15 2015 14:30:03 - Peel ecommerce is a product of Agence web Advisto SAS. All rights reserved.