csspp
[ class tree: csspp ] [ index: csspp ] [ all elements ]

Source for file functions.inc.php

Documentation is available at functions.inc.php

  1. <?php
  2. /**
  3. * Various functions
  4. *
  5. * This file contains a few functions which are needed to optimise CSS Code. These
  6. * functions are not part of the main class since they are not directly related to the
  7. * parsing process.
  8. *
  9. * @package csspp
  10. * @author Florian Schmitz (floele at gmail dot com) 2005
  11. */
  12.  
  13.  
  14. /**
  15. * Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
  16. * @param string $color
  17. * @return string
  18. * @version 1.0
  19. */
  20. function cut_color($color)
  21. {
  22. if(strtolower(substr($color,0,4)) == 'rgb(')
  23. {
  24. $color_tmp = substr($color,4,strlen($color)-5);
  25. $color_tmp = explode(',',$color_tmp);
  26. for ( $i = 0; $i < count($color_tmp); $i++ )
  27. {
  28. $color_tmp[$i] = trim ($color_tmp[$i]);
  29. if(substr($color_tmp[$i],-1) == '%')
  30. {
  31. $color_tmp[$i] = round((255*$color_tmp[$i])/100);
  32. }
  33. if($color_tmp[$i]>255) $color_tmp[$i] = 255;
  34. }
  35. $color = '#';
  36. for ( $i=0; $i < 3; $i++ )
  37. {
  38. if($color_tmp[$i]<16) $color .= '0'.dechex($color_tmp[$i]);
  39. else $color .= dechex($color_tmp[$i]);
  40. }
  41. }
  42. if(strlen($color) == 7)
  43. {
  44. $color_temp = strtolower($color);
  45. if($color_temp{0} == '#' && $color_temp{1} == $color_temp{2} && $color_temp{3} == $color_temp{4} && $color_temp{5} == $color_temp{6})
  46. {
  47. $color = '#'.$color{1}.$color{3}.$color{5};
  48. }
  49. }
  50. switch(strtolower($color))
  51. {
  52. /* color name -> hex code */
  53. case 'black': return '#000';
  54. case 'fuchsia': return '#F0F';
  55. case 'white': return '#FFF';
  56. case 'yellow': return '#FF0';
  57. /* hex code -> color name */
  58. case '#800000': return 'maroon';
  59. case '#ffa500': return 'orange';
  60. case '#808000': return 'olive';
  61. case '#800080': return 'purple';
  62. case '#008000': return 'green';
  63. case '#000080': return 'navy';
  64. case '#008080': return 'teal';
  65. case '#c0c0c0': return 'silver';
  66. case '#808080': return 'gray';
  67. case '#f00': return 'red';
  68. }
  69. return $color;
  70. }
  71.  
  72. /**
  73. * Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
  74. * @param string $subvalue
  75. * @return string
  76. * @version 1.1
  77. */
  78. function compress_numbers(&$subvalue)
  79. {
  80. global $units;
  81. if(!(strlen($subvalue) > 0 && ( is_numeric($subvalue{0}) || $subvalue{0} == "+" || $subvalue{0} == "-" ) ))
  82. {
  83. return FALSE;
  84. }
  85. $temp = explode('/',$subvalue);
  86. for ($l = 0, $size_3 = count($temp); $l < $size_3; $l++)
  87. {
  88. if(strlen($temp[$l]) > 0 && floatval($temp[$l]) == 0 && ( is_numeric($subvalue{0}) || $subvalue{0} == "+" || $subvalue{0} == "-" ) )
  89. {
  90. $temp[$l] = 0;
  91. }
  92. elseif(strlen($temp[$l]) > 0 && ( is_numeric($subvalue{0}) || $subvalue{0} == "+" || $subvalue{0} == "-" ) )
  93. {
  94. $unit_found = FALSE;
  95. for( $m = 0, $size_4 = count($units); $m < $size_4; $m++ )
  96. {
  97. if(strpos(strtolower($temp[$l]),$units[$m]) !== FALSE)
  98. {
  99. $temp[$l] = floatval($temp[$l]).$units[$m];
  100. $unit_found = TRUE;
  101. break;
  102. }
  103. }
  104. if(!$unit_found) $temp[$l] = floatval($temp[$l]);
  105. }
  106. }
  107. $subvalue = (count($temp) > 1) ? $temp[0].'/'.$temp[1] : $temp[0];
  108. }
  109.  
  110. /**
  111. * Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
  112. * @param string $property
  113. * @param string $value
  114. * @return array
  115. * @version 1.0
  116. * @see merge_4value_shorthands()
  117. */
  118. function dissolve_4value_shorthands($property,$value)
  119. {
  120. global $shorthands;
  121. if(!is_array($shorthands[$property]))
  122. {
  123. $return[$property] = $value;
  124. return $return;
  125. }
  126. $important = '';
  127. if(csspp::is_important($value))
  128. {
  129. $value = csspp::gvw_important($value);
  130. $important = ' !important';
  131. }
  132. $values = explode(' ',$value);
  133.  
  134.  
  135. $return = array();
  136. if(count($values) == 4)
  137. {
  138. for($i=0;$i<4;$i++)
  139. {
  140. $return[$shorthands[$property][$i]] = $values[$i].$important;
  141. }
  142. }
  143. elseif(count($values) == 3)
  144. {
  145. $return[$shorthands[$property][0]] = $values[0].$important;
  146. $return[$shorthands[$property][1]] = $values[1].$important;
  147. $return[$shorthands[$property][3]] = $values[1].$important;
  148. $return[$shorthands[$property][2]] = $values[2].$important;
  149. }
  150. elseif(count($values) == 2)
  151. {
  152. for($i=0;$i<4;$i++)
  153. {
  154. $return[$shorthands[$property][$i]] = (($i % 2 != 0)) ? $values[1].$important : $values[0].$important;
  155. }
  156. }
  157. else
  158. {
  159. for($i=0;$i<4;$i++)
  160. {
  161. $return[$shorthands[$property][$i]] = $values[0].$important;
  162. }
  163. }
  164. return $return;
  165. }
  166.  
  167. /**
  168. * Explodes a string as explode() does, however, not if $sep is escaped or within a string
  169. * @param string $sep seperator
  170. * @param string $string
  171. * @return array
  172. * @version 1.0
  173. */
  174. function explode_ws($sep,$string)
  175. {
  176. $status = 'st';
  177. $to = '';
  178. $output = array();
  179. $num = 0;
  180. for($i = 0, $len = strlen($string);$i < $len; $i++)
  181. {
  182. switch($status)
  183. {
  184. case 'st':
  185. if($string{$i} == $sep && !csspp::escaped($string,$i))
  186. {
  187. ++$num;
  188. }
  189. elseif($string{$i} == '"' || $string{$i} == '\'' || $string{$i} == '(' && !csspp::escaped($string,$i))
  190. {
  191. $status = 'str';
  192. $to = ($string{$i} == '(') ? ')' : $string{$i};
  193. (isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
  194. }
  195. else
  196. {
  197. (isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
  198. }
  199. break;
  200. case 'str':
  201. if($string{$i} == $to && !csspp::escaped($string,$i))
  202. {
  203. $status = 'st';
  204. }
  205. (isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
  206. break;
  207. }
  208. }
  209. if(isset($output[0]))
  210. {
  211. return $output;
  212. }
  213. else
  214. {
  215. return array($output);
  216. }
  217. }
  218.  
  219. /**
  220. * Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
  221. * @param array $array
  222. * @return array
  223. * @version 1.0
  224. * @see dissolve_4value_shorthands()
  225. */
  226. function merge_4value_shorthands($array)
  227. {
  228. $return = $array;
  229. global $shorthands;
  230. foreach($shorthands as $key => $value)
  231. {
  232. if(csspp::has_subkey($value[0],$array) && csspp::has_subkey($value[1],$array)
  233. && csspp::has_subkey($value[2],$array) && csspp::has_subkey($value[3],$array))
  234. {
  235. $return[][$key] = '';
  236. end($return);
  237. $num = key($return);
  238. $important = '';
  239. for($i = 0; $i < 4; $i++)
  240. {
  241. $val = csspp::has_subkey($value[$i],$array,1);
  242. if(csspp::is_important($val))
  243. {
  244. $important = '!important';
  245. $return[$num][$key] .= csspp::gvw_important($return[$num][$key]).' ';
  246. }
  247. else
  248. {
  249. $return[$num][$key] .= $val.' ';
  250. }
  251. csspp::rm_subkey($value[$i],$return);
  252. }
  253. $return[$num][$key] = csspp::shorthand(trim($return[$num][$key].$important));
  254. }
  255. }
  256. return $return;
  257. }
  258.  
  259. /**
  260. * Dissolve background property, CSS3 will be compliant
  261. * @param string $str_value
  262. * @return array
  263. * @version 1.0
  264. * @see merge_bg()
  265. * @todo CSS 3 compliance
  266. */
  267. function dissolve_short_bg($str_value)
  268. {
  269. $repeat = array('repeat','repeat-x','repeat-y','no-repeat','space');
  270. $attachment = array('scroll','fixed','local');
  271. $clip = array('border','padding');
  272. $origin = array('border','padding','content');
  273. $pos = array('top','center','bottom','left','right');
  274. $important = '';
  275. $return = array('background-image' => NULL,'background-size' => NULL,'background-repeat' => NULL,'background-position' => NULL,'background-attachment'=>NULL,'background-clip' => NULL,'background-origin' => NULL,'background-color' => NULL);
  276. global $background_prop_default;
  277. if(csspp::is_important($str_value))
  278. {
  279. $important = ' !important';
  280. $str_value = csspp::gvw_important($str_value);
  281. }
  282. $str_value = explode_ws(',',$str_value);
  283. for($i = 0; $i < count($str_value); $i++)
  284. {
  285. $have['clip'] = FALSE; $have['pos'] = FALSE;
  286. $have['color'] = FALSE; $have['bg'] = FALSE;
  287. $str_value[$i] = explode_ws(' ',trim($str_value[$i]));
  288. for($j = 0; $j < count($str_value[$i]); $j++)
  289. {
  290. if($have['bg'] === FALSE && (substr($str_value[$i][$j],0,4) == 'url(' || $str_value[$i][$j] === 'none'))
  291. {
  292. $return['background-image'] .= $str_value[$i][$j].',';
  293. $have['bg'] = TRUE;
  294. }
  295. elseif(in_array($str_value[$i][$j],$repeat,TRUE))
  296. {
  297. $return['background-repeat'] .= $str_value[$i][$j].',';
  298. }
  299. elseif(in_array($str_value[$i][$j],$attachment,TRUE))
  300. {
  301. $return['background-attachment'] .= $str_value[$i][$j].',';
  302. }
  303. elseif(in_array($str_value[$i][$j],$clip,TRUE) && !$have['clip'])
  304. {
  305. $return['background-clip'] .= $str_value[$i][$j].',';
  306. $have['clip'] = TRUE;
  307. }
  308. elseif(in_array($str_value[$i][$j],$origin,TRUE))
  309. {
  310. $return['background-origin'] .= $str_value[$i][$j].',';
  311. }
  312. elseif($str_value[$i][$j]{0} == '(')
  313. {
  314. $return['background-size'] .= substr($str_value[$i][$j],1,-1).',';
  315. }
  316. elseif(in_array($str_value[$i][$j],$pos,TRUE) || is_numeric($str_value[$i][$j]{0}) || $str_value[$i][$j]{0} === NULL)
  317. {
  318. $return['background-position'] .= $str_value[$i][$j];
  319. if(!$have['pos']) $return['background-position'] .= ' '; else $return['background-position'].= ',';
  320. $have['pos'] = TRUE;
  321. }
  322. elseif(!$have['color'])
  323. {
  324. $return['background-color'] .= $str_value[$i][$j].',';
  325. $have['color'] = TRUE;
  326. }
  327. }
  328. }
  329. foreach($background_prop_default as $bg_prop => $default_value)
  330. {
  331. if($return[$bg_prop] !== NULL)
  332. {
  333. $return[$bg_prop] = substr($return[$bg_prop],0,-1).$important;
  334. }
  335. else $return[$bg_prop] = $default_value.$important;
  336. }
  337. return $return;
  338. }
  339.  
  340. /**
  341. * Merges all background properties
  342. * @param array $input_css
  343. * @return array
  344. * @version 1.0
  345. * @see dissolve_short_bg()
  346. * @todo CSS 3 compliance
  347. */
  348. function merge_bg($input_css)
  349. {
  350. global $background_prop_default;
  351. // Max number of background images. CSS3 not yet fully implemented
  352. $number_of_values = @max(count(explode_ws(',',csspp::has_subkey('background-image',$input_css,1))),count(explode_ws(',',csspp::has_subkey('background-color',$input_css,1))),1);
  353. // Array with background images to check if BG image exists
  354. $bg_img_array = explode_ws(',',csspp::gvw_important(csspp::has_subkey('background-image',$input_css,1)));
  355. $new_bg_value = '';
  356. $important = '';
  357. for($i = 0; $i < $number_of_values; $i++)
  358. {
  359. foreach($background_prop_default as $bg_property => $default_value)
  360. {
  361. $cur_value = csspp::has_subkey($bg_property,$input_css,1);
  362.  
  363. // Skip if property does not exist
  364. if(empty($cur_value))
  365. {
  366. continue;
  367. }
  368. // Skip some properties if there is no background image
  369. if((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none')
  370. && ($bg_property === 'background-size' || $bg_property === 'background-position'
  371. || $bg_property === 'background-attachment' || $bg_property === 'background-repeat'))
  372. {
  373. continue;
  374. }
  375. // Remove !important
  376. if(csspp::is_important($cur_value))
  377. {
  378. $important = ' !important';
  379. $cur_value = csspp::gvw_important($cur_value);
  380. }
  381. // Do not add default values
  382. if($cur_value === $default_value)
  383. {
  384. continue;
  385. }
  386. $temp = explode_ws(',',$cur_value);
  387.  
  388. if(isset($temp[$i]))
  389. {
  390. if($bg_property == 'background-size')
  391. {
  392. $new_bg_value .= '('.$temp[$i].') ';
  393. }
  394. else
  395. {
  396. $new_bg_value .= $temp[$i].' ';
  397. }
  398. }
  399. }
  400. $new_bg_value = trim($new_bg_value);
  401. if($i != $number_of_values-1) $new_bg_value .= ',';
  402. }
  403. // Delete all background-properties
  404. foreach($background_prop_default as $bg_property => $default_value)
  405. {
  406. csspp::rm_subkey($bg_property,$input_css);
  407. }
  408. // Add new background property
  409. if($new_bg_value !== '') $input_css[]['background'] = $new_bg_value.$important;
  410. return $input_css;
  411. }
  412. ?>

Documentation generated on Sat, 20 Aug 2005 17:04:30 +0200 by phpDocumentor 1.3.0RC3