PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Utility/HtmlCompressor.php

https://bitbucket.org/slovacus/zrt
PHP | 216 lines | 101 code | 30 blank | 85 comment | 8 complexity | 1f03131cd7ae432cbc6bfdca7eef3911 MD5 | raw file
  1. <?php
  2. /**
  3. * TomatoCMS
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the GNU GENERAL PUBLIC LICENSE Version 2
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://www.gnu.org/licenses/gpl-2.0.txt
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@tomatocms.com so we can send you a copy immediately.
  14. *
  15. * @copyright Copyright (c) 2009-2010 TIG Corporation (http://www.tig.vn)
  16. * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU GENERAL PUBLIC LICENSE Version 2
  17. * @version $Id: HtmlCompressor.php 3986 2010-07-25 16:32:46Z huuphuoc $
  18. * @since 2.0.0
  19. */
  20. /**
  21. * Inspired from the set of functions created by Oliver Lillie
  22. * @see http://php100.wordpress.com/2006/10/30/html-compact/#comment-12700
  23. */
  24. class Zrt_Utility_HtmlCompressor
  25. {
  26. public static function compress( $html )
  27. {
  28. $html = self::_removeHtmlComments( $html );
  29. $ret = self::_compressHorizontally( $html );
  30. $ret = self::_compressVertically( $ret[0] , $ret[1] );
  31. $html = self::_removeSpacesInScriptAndStyleTags( $ret[0] );
  32. return $html;
  33. }
  34. private static function _removeHtmlComments( $html )
  35. {
  36. /**
  37. * Check that the opening browser is Internet Explorer
  38. */
  39. $msie = "/msie\s(.*).*(win)/i";
  40. $keepCond = (isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( $msie ,
  41. $_SERVER['HTTP_USER_AGENT'] ));
  42. if ( $keepCond )
  43. {
  44. $html = str_replace( array( '<!–[if' , '' ) ,
  45. array( '–**@@IECOND-OPEN@@**–' , '–**@@IECOND-CLOSE@@**–' ) ,
  46. $html );
  47. }
  48. /**
  49. * Remove comments
  50. */
  51. $html = preg_replace( '//' , '' , $html );
  52. /**
  53. * Re sub-in the conditionals if required.
  54. */
  55. if ( $keepCond )
  56. {
  57. $html = str_replace( array( '–**@@IECOND-OPEN@@**–' , '–**@@IECOND-CLOSE@@**–' ) ,
  58. array( '<!–[if' , '' ) , $html );
  59. }
  60. return $html;
  61. }
  62. /**
  63. * Compresses white space horizontally (ie spaces, tabs etc) whilst preserving
  64. * textarea and pre content.
  65. * Idea and partial code borrowed from smarty.
  66. * http://smarty.net/contribs/plugins/view.php/outputfilter.trimwhitespace.php
  67. *
  68. * @return array
  69. */
  70. private static function _compressHorizontally( $html ,
  71. $preservedBlocks = false )
  72. {
  73. $flag = true;
  74. if ( !$preservedBlocks )
  75. {
  76. $flag = false;
  77. /**
  78. * Get the textarea matches
  79. */
  80. preg_match_all( '!]*>.*?!is' , $html , $preservedAreaMatch );
  81. $preservedBlocks = $preservedAreaMatch[0];
  82. /**
  83. * Replace the textareas inerds with markers
  84. */
  85. $html = preg_replace( '!]*>.*?!is' , '@@@HTMLCOMPRESSION@@@' , $html );
  86. }
  87. /**
  88. * Remove the white space
  89. */
  90. $html = preg_replace( '/((?)\n)[\s]+/m' , '\1' , $html );
  91. /**
  92. * Reinsert the textareas inners
  93. */
  94. if ( $flag )
  95. {
  96. foreach ( $preservedBlocks as $currBlock )
  97. {
  98. $html = preg_replace( '!@@@HTMLCOMPRESSION@@@!' , $currBlock ,
  99. $html , 1 );
  100. }
  101. }
  102. return array( $html , $preservedBlocks );
  103. }
  104. /**
  105. * Compresses white space vertically (ie line breaks) whilst preserving
  106. * textarea and pre content.
  107. *
  108. * @param mixed $preservedBlocks false if no textarea blocks have already been taken out, otherwise an array.
  109. * @return array
  110. */
  111. private static function _compressVertically( $html ,
  112. $preservedBlocks = false )
  113. {
  114. $flag = true;
  115. if ( !$preservedBlocks )
  116. {
  117. $flag = false;
  118. /**
  119. * Get the textarea matches
  120. */
  121. preg_match_all( '!]*>.*?!is' , $html , $preservedAreaMatch );
  122. $preservedBlocks = $preservedAreaMatch[0];
  123. /**
  124. * Replace the textareas inerds with markers
  125. */
  126. $html = preg_replace( '!]*>.*?!is' , '@@@HTMLCOMPRESSION@@@' , $html );
  127. }
  128. $html = str_replace( "\n" , '' , $html );
  129. /**
  130. * Reinsert the textareas inerds
  131. */
  132. if ( $flag )
  133. {
  134. foreach ( $preservedBlocks as $currBlock )
  135. {
  136. $html = preg_replace( '!@@@HTMLCOMPRESSION@@@!' , $currBlock ,
  137. $html , 1 );
  138. }
  139. }
  140. return array( $html , $preservedBlocks );
  141. }
  142. private static function _removeSpacesInScriptAndStyleTags( $html )
  143. {
  144. preg_match_all( '!(]*>(?:\\s*\\s*)?)!is' , $html , $scripts );
  145. /**
  146. * Collect and compress the parts
  147. */
  148. $compressed = array( );
  149. $parts = array( );
  150. for ( $i = 0; $i < count( $scripts[0] ); $i++ )
  151. {
  152. array_push( $parts , $scripts[0][$i] );
  153. array_push( $compressed ,
  154. self::_removeSpacesInJsAndCss( $scripts[0][$i] ) );
  155. }
  156. /**
  157. * Do the replacements and return
  158. */
  159. $html = str_replace( $parts , $compressed , $html );
  160. return $html;
  161. }
  162. private static function _removeSpacesInJsAndCss( $code )
  163. {
  164. /**
  165. * Remove multiline comment
  166. */
  167. $mulLineComment = '/\/\*(?!-)[\x00-\xff]*?\*\//';
  168. $code = preg_replace( $mulLineComment , '' , $code );
  169. /**
  170. * Remove single line comment
  171. */
  172. $singLineComment = '/[^:]\/\/.*/';
  173. $code = preg_replace( $singLineComment , '' , $code );
  174. /**
  175. * Remove extra spaces
  176. */
  177. $extraSpace = '/\s+/';
  178. $code = preg_replace( $extraSpace , ' ' , $code );
  179. /**
  180. * Remove spaces that can be removed
  181. */
  182. $removableSpace = '/\s?([\{\};\=\(\)\\\/\+\*-])\s?/';
  183. $code = preg_replace( '/\s?([\{\};\=\(\)\/\+\*-])\s?/' , '\\1' , $code );
  184. return $code;
  185. }
  186. }