PageRenderTime 69ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/build/tools/css-compressor/lib/Trim.php

https://github.com/joacim-boive/mobile-html5-boilerplate
PHP | 213 lines | 193 code | 1 blank | 19 comment | 2 complexity | ef995bba67300fd8e9bb53fced6f9ee8 MD5 | raw file
Possible License(s): MIT, Apache-2.0
  1. <?php
  2. /**
  3. * CSS Compressor [VERSION]
  4. * [DATE]
  5. * Corey Hart @ http://www.codenothing.com
  6. */
  7. Class CSSCompression_Trim
  8. {
  9. /**
  10. * Trim Patterns
  11. *
  12. * @class Control: Compression Controller
  13. * @param (array) options: Reference to options
  14. * @param (regex) rcmark: Marking point when traversing through sheet for comments
  15. * @param (regex) rendcomment: Finds the ending comment point
  16. * @param (regex) rendquote: Finds the ending quote point
  17. * @param (regex) rendsinglequote: Finds the ending single quote point
  18. * @param (array) rescape: Array of patterns of groupings that should be escaped
  19. * @param (array) trimmings: Stylesheet trimming patterns/replacements
  20. * @param (array) escaped: Array of characters that need to be escaped
  21. */
  22. private $Control;
  23. private $options = array();
  24. private $rcmark = "/((?<!\\\)\/\*|(?<!\\\)\"|(?<!\\\)')/";
  25. private $rendcomment = "/\*\//";
  26. private $rendquote = "/(?<!\\\)\"/";
  27. private $rendsinglequote = "/(?<!\\\)'/";
  28. private $rescape = array(
  29. "/(url\()([^'\"].*?)(\))/is",
  30. "/((?<!\\\)\")(.*?)((?<!\\\)\")/s",
  31. "/((?<!\\\)')(.*?)((?<!\\\)')/s",
  32. );
  33. private $trimmings = array(
  34. 'patterns' => array(
  35. "/(?<!\\\)(\s+)?(?<!\\\)([!,{};>\~\+\/])(?<!\\\)(\s+)?/s", // Remove un-needed spaces around special characters
  36. "/url\((?<!\\\)\"(.*?)(?<!\\\)\"\)/is", // Remove quotes from urls
  37. "/url\((?<!\\\)'(.*?)(?<!\\\)'\)/is", // Remove single quotes from urls
  38. "/url\((.*?)\)/is", // Lowercase url wrapper
  39. "/(?<!\\\);{2,}/", // Remove unecessary semi-colons
  40. "/(?<!\\\)\s+/s", // Compress all spaces into single space
  41. ),
  42. 'replacements' => array(
  43. '$2',
  44. 'url($1)',
  45. 'url($1)',
  46. 'url($1)',
  47. ';',
  48. ' ',
  49. )
  50. );
  51. private $escaped = array(
  52. 'search' => array(
  53. ":",
  54. ";",
  55. "}",
  56. "{",
  57. "@",
  58. "!",
  59. ",",
  60. ">",
  61. "+",
  62. "~",
  63. "/",
  64. "*",
  65. ".",
  66. "=",
  67. "#",
  68. "\r",
  69. "\n",
  70. "\t",
  71. " ",
  72. ),
  73. 'replace' => array(
  74. "\\:",
  75. "\\;",
  76. "\\}",
  77. "\\{",
  78. "\\@",
  79. "\\!",
  80. "\\,",
  81. "\\>",
  82. "\\+",
  83. "\\~",
  84. "\\/",
  85. "\\*",
  86. "\\.",
  87. "\\=",
  88. "\\#",
  89. "\\r",
  90. "\\n",
  91. "\\t",
  92. "\\ ",
  93. ),
  94. );
  95. /**
  96. * Stash a reference to the controller on each instantiation
  97. *
  98. * @param (class) control: CSSCompression Controller
  99. */
  100. public function __construct( CSSCompression_Control $control ) {
  101. $this->Control = $control;
  102. $this->options = &$control->Option->options;
  103. }
  104. /**
  105. * Central trim handler
  106. *
  107. * @param (string) css: Stylesheet to trim
  108. */
  109. public function trim( $css ) {
  110. $css = $this->comments( $css );
  111. $css = $this->escape( $css );
  112. $css = $this->strip( $css );
  113. return $css;
  114. }
  115. /**
  116. * Does a quick run through the script to remove all comments from the sheet,
  117. *
  118. * @param (string) css: Stylesheet to trim
  119. */
  120. private function comments( $css ) {
  121. $pos = 0;
  122. while ( preg_match( $this->rcmark, $css, $match, PREG_OFFSET_CAPTURE, $pos ) ) {
  123. switch ( $match[ 1 ][ 0 ] ) {
  124. // Start of comment block
  125. case "/*":
  126. if ( preg_match( $this->rendcomment, $css, $m, PREG_OFFSET_CAPTURE, $match[ 1 ][ 1 ] + 1 ) ) {
  127. $end = $m[ 0 ][ 1 ] - $match[ 1 ][ 1 ] + strlen( $m[ 0 ][ 0 ] );
  128. $css = substr_replace( $css, '', $match[ 1 ][ 1 ], $end );
  129. $pos = $match[ 0 ][ 1 ];
  130. }
  131. else {
  132. $css = substr( $css, 0, $match[ 1 ][ 1 ] );
  133. break 2;
  134. }
  135. break;
  136. // Start of string
  137. case "\"":
  138. if ( preg_match( $this->rendquote, $css, $m, PREG_OFFSET_CAPTURE, $match[ 1 ][ 1 ] + 1 ) ) {
  139. $pos = $m[ 0 ][ 1 ] + strlen( $m[ 0 ][ 0 ] );
  140. }
  141. else {
  142. break 2;
  143. }
  144. break;
  145. // Start of string
  146. case "'":
  147. if ( preg_match( $this->rendsinglequote, $css, $m, PREG_OFFSET_CAPTURE, $match[ 1 ][ 1 ] + 1 ) ) {
  148. $pos = $m[ 0 ][ 1 ] + strlen( $m[ 0 ][ 0 ] );
  149. }
  150. else {
  151. break 2;
  152. }
  153. break;
  154. // Should have never gotten here
  155. default:
  156. break 2;
  157. }
  158. }
  159. return $css;
  160. }
  161. /**
  162. * Escape out possible splitter characters within urls
  163. *
  164. * @param (string) css: Full stylesheet
  165. */
  166. private function escape( $css ) {
  167. foreach ( $this->rescape as $regex ) {
  168. $start = 0;
  169. while ( preg_match( $regex, $css, $match, PREG_OFFSET_CAPTURE, $start ) ) {
  170. $value = $match[ 1 ][ 0 ]
  171. . str_replace( $this->escaped['search'], $this->escaped['replace'], $match[ 2 ][ 0 ] )
  172. . $match[ 3 ][ 0 ];
  173. $css = substr_replace( $css, $value, $match[ 0 ][ 1 ], strlen( $match[ 0 ][ 0 ] ) );
  174. $start = $match[ 0 ][ 1 ] + strlen( $value ) + 1;
  175. }
  176. }
  177. return $css;
  178. }
  179. /**
  180. * Runs initial formatting to setup for compression
  181. *
  182. * @param (string) css: CSS Contents
  183. */
  184. private function strip( $css ) {
  185. // Run replacements
  186. return trim( preg_replace( $this->trimmings['patterns'], $this->trimmings['replacements'], $css ) );
  187. }
  188. /**
  189. * Access to private methods for testing
  190. *
  191. * @param (string) method: Method to be called
  192. * @param (array) args: Array of paramters to be passed in
  193. */
  194. public function access( $method, $args ) {
  195. if ( method_exists( $this, $method ) ) {
  196. return call_user_func_array( array( $this, $method ), $args );
  197. }
  198. else {
  199. throw new CSSCompression_Exception( "Unknown method in Trim Class - " . $method );
  200. }
  201. }
  202. };
  203. ?>