You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

outputfilter.trimwhitespace.php 3.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. /**
  3. * Smarty plugin
  4. *
  5. * @package Smarty
  6. * @subpackage PluginsFilter
  7. */
  8. /**
  9. * Smarty trimwhitespace outputfilter plugin
  10. * Trim unnecessary whitespace from HTML markup.
  11. *
  12. * @author Rodney Rehm
  13. *
  14. * @param string $source input string
  15. *
  16. * @return string filtered output
  17. * @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
  18. */
  19. function smarty_outputfilter_trimwhitespace($source)
  20. {
  21. $store = array();
  22. $_store = 0;
  23. $_offset = 0;
  24. // Unify Line-Breaks to \n
  25. $source = preg_replace('/\015\012|\015|\012/', "\n", $source);
  26. // capture Internet Explorer and KnockoutJS Conditional Comments
  27. if (preg_match_all('#<!--((\[[^\]]+\]>.*?<!\[[^\]]+\])|(\s*/?ko\s+.+))-->#is', $source, $matches,
  28. PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
  29. foreach ($matches as $match) {
  30. $store[] = $match[ 0 ][ 0 ];
  31. $_length = strlen($match[ 0 ][ 0 ]);
  32. $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
  33. $source = substr_replace($source, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
  34. $_offset += $_length - strlen($replace);
  35. $_store ++;
  36. }
  37. }
  38. // Strip all HTML-Comments
  39. // yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
  40. $source = preg_replace('#<!--.*?-->#ms', '', $source);
  41. // capture html elements not to be messed with
  42. $_offset = 0;
  43. if (preg_match_all('#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
  44. $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
  45. foreach ($matches as $match) {
  46. $store[] = $match[ 0 ][ 0 ];
  47. $_length = strlen($match[ 0 ][ 0 ]);
  48. $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
  49. $source = substr_replace($source, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
  50. $_offset += $_length - strlen($replace);
  51. $_store ++;
  52. }
  53. }
  54. $expressions = array(// replace multiple spaces between tags by a single space
  55. // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
  56. '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
  57. // remove spaces between attributes (but not in attribute values!)
  58. '#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
  59. // note: for some very weird reason trim() seems to remove spaces inside attributes.
  60. // maybe a \0 byte or something is interfering?
  61. '#^\s+<#Ss' => '<', '#>\s+$#Ss' => '>',);
  62. $source = preg_replace(array_keys($expressions), array_values($expressions), $source);
  63. // note: for some very weird reason trim() seems to remove spaces inside attributes.
  64. // maybe a \0 byte or something is interfering?
  65. // $source = trim( $source );
  66. $_offset = 0;
  67. if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
  68. foreach ($matches as $match) {
  69. $_length = strlen($match[ 0 ][ 0 ]);
  70. $replace = $store[ $match[ 1 ][ 0 ] ];
  71. $source = substr_replace($source, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
  72. $_offset += strlen($replace) - $_length;
  73. $_store ++;
  74. }
  75. }
  76. return $source;
  77. }