Last active
May 4, 2022 16:33
-
-
Save strsar/ba6f17a40700c2b4ca2a27e247c302dd to your computer and use it in GitHub Desktop.
[WP] HTML minify class WP_HTML_Compression
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php defined('ABSPATH') or header('Location: /'); | |
| /** | |
| * HTML document compression | |
| * | |
| * Clean and minify all markup | |
| * Wrap `<!--no compression-->` to skip over content | |
| */ | |
| class WP_HTML_Compression { | |
| protected $compress_css = true; // Compress all inline styles | |
| protected $compress_js = true; // May cause issues if inline js contains single line `//` comments | |
| protected $remove_comments = true; // Remove all html comments | |
| protected $strip_whitespace = true; // May cause spacing issues within content | |
| protected $remove_cdata = true; // Remove CDATA within script tags | |
| protected $info_comment = false; // Add custom comment to bottom of document | |
| protected $ignore_flag = '<!--no compression-->'; // Comment used as a flag to skip minifying a section of markup | |
| protected $html; | |
| /** | |
| * Construct | |
| */ | |
| public function __construct($html){ | |
| if(!empty($html)){ | |
| $this->parse_html($html); | |
| } | |
| } | |
| /** | |
| * Markup to string | |
| */ | |
| public function __toString(){ | |
| if(is_null($this->html)) { | |
| return 'NULL'; | |
| } | |
| return $this->html; | |
| } | |
| /** | |
| * Add comment | |
| */ | |
| protected function bottom_comment($raw, $compressed){ | |
| return ''; | |
| } | |
| /** | |
| * Minify markup | |
| */ | |
| protected function minify_html($html){ | |
| $html = preg_replace('/\>\s+\</m', '><', $html); | |
| $pattern = '/<(?<script>script).*?<\/script\s*>|<(?<style>style).*?<\/style\s*>|<!(?<comment>--).*?-->|<(?<tag>[\/\w.:-]*)(?:".*?"|\'.*?\'|[^\'">]+)*>|(?<text>((<[^!\/\w.:-])?[^<]*)+)|/si'; | |
| preg_match_all($pattern, $html, $matches, PREG_SET_ORDER); | |
| $overriding = false; | |
| $raw_tag = false; | |
| $html = ''; | |
| foreach($matches as $token){ | |
| $strip = $this->strip_whitespace; | |
| $tag = (isset($token['tag'])) ? strtolower($token['tag']) : null; | |
| $content = $token[0]; | |
| if(is_null($tag)){ | |
| if(!empty($token['script']) ){ | |
| if(!$overriding){ | |
| $strip = $this->compress_js; | |
| $content = str_replace(array(' type="text/javascript"', " type='text/javascript'"), array('', ''), $content); | |
| if($this->remove_comments){ | |
| $content = preg_replace('#^\s*// .+$#m', '', $content); // Removes inline JS comments | |
| } | |
| if($this->remove_cdata) { | |
| $content = str_replace(array('//<![CDATA[', '//]]>'), array('', ''), $content); | |
| } | |
| } | |
| }elseif(!empty($token['style'])){ | |
| $strip = $this->compress_css; | |
| $content = str_replace(array(' type="text/css"', " type='text/css'"), array('', ''), $content); | |
| }elseif($content == $this->ignore_flag){ | |
| $overriding = !$overriding; | |
| continue; | |
| }elseif($this->remove_comments){ | |
| if(!$overriding && $raw_tag != 'textarea'){ | |
| $content = preg_replace('#\s*<!--(?!\[if\s).*?-->\s*|(?<!\>)\n+(?=\<[^!])#s', '', $content); // Remove any HTML comments, except IE conditionals | |
| } | |
| } | |
| }else{ | |
| if($tag == 'pre' || $tag == 'textarea'){ | |
| $raw_tag = $tag; | |
| }elseif($tag == '/pre' || $tag == '/textarea'){ | |
| $raw_tag = false; | |
| }else{ | |
| if($raw_tag || $overriding){ | |
| $strip = false; | |
| }else{ | |
| $strip = true; | |
| $content = preg_replace('#\s*(\w++(?<!\baction|\balt|\bcontent|\bsrc|\bvalue)="")#s', '$1', $content); // Remove any empty attributes no certain tags | |
| $content = str_replace(' />', '>', $content); // Fix self closing tags | |
| } | |
| } | |
| } | |
| if($strip){ | |
| if(!$overriding){ | |
| $content = $this->remove_white_space($content); | |
| } | |
| } | |
| $html .= $content; | |
| } | |
| return $html; | |
| } | |
| /** | |
| * Parse markup | |
| */ | |
| public function parse_html($html){ | |
| $this->html = $this->minify_html($html); | |
| if($this->info_comment){ | |
| $this->html .= "\n" . $this->bottom_comment($html, $this->html); | |
| } | |
| } | |
| /** | |
| * Remove white space | |
| */ | |
| protected function remove_white_space($str){ | |
| $str = preg_replace('/\s+/', ' ', $str); | |
| return $str; | |
| } | |
| } | |
| // Start compression | |
| function wp_html_compression_start(){ | |
| ob_start('wp_html_compression_finish'); | |
| } | |
| // Finish compression | |
| function wp_html_compression_finish($html){ | |
| return new WP_HTML_Compression($html); | |
| } | |
| // Run class | |
| if(!is_admin() && !is_user_logged_in() && !is_feed()){ | |
| add_action('get_header', 'wp_html_compression_start'); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment