This repository was archived by the owner on Jul 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated Minify_HTML to the latest version
- Loading branch information
Showing
2 changed files
with
58 additions
and
43 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,26 @@ | ||
<?php | ||
/** | ||
* Class Minify_HTML | ||
* @package Minify | ||
*/ | ||
|
||
/** | ||
* Compress HTML | ||
* | ||
* This is a heavy regex-based removal of whitespace, unnecessary comments and | ||
* This is a heavy regex-based removal of whitespace, unnecessary comments and | ||
* tokens. IE conditional comments are preserved. There are also options to have | ||
* STYLE and SCRIPT blocks compressed by callback functions. | ||
* | ||
* STYLE and SCRIPT blocks compressed by callback functions. | ||
* | ||
* A test suite is available. | ||
* | ||
* | ||
* @package Minify | ||
* @author Stephen Clay <[email protected]> | ||
*/ | ||
class HTMLMin { | ||
class Minify_HTML { | ||
/** | ||
* @var boolean | ||
*/ | ||
protected $_jsCleanComments = true; | ||
|
||
/** | ||
* "Minify" an HTML page | ||
|
@@ -22,21 +31,21 @@ class HTMLMin { | |
* | ||
* 'cssMinifier' : (optional) callback function to process content of STYLE | ||
* elements. | ||
* | ||
* | ||
* 'jsMinifier' : (optional) callback function to process content of SCRIPT | ||
* elements. Note: the type attribute is ignored. | ||
* | ||
* | ||
* 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If | ||
* unset, minify will sniff for an XHTML doctype. | ||
* | ||
* | ||
* @return string | ||
*/ | ||
public static function minify($html, $options = array()) { | ||
$min = new HTMLMin($html, $options); | ||
$min = new self($html, $options); | ||
return $min->process(); | ||
} | ||
|
||
|
||
/** | ||
* Create a minifier object | ||
* | ||
|
@@ -46,14 +55,14 @@ public static function minify($html, $options = array()) { | |
* | ||
* 'cssMinifier' : (optional) callback function to process content of STYLE | ||
* elements. | ||
* | ||
* | ||
* 'jsMinifier' : (optional) callback function to process content of SCRIPT | ||
* elements. Note: the type attribute is ignored. | ||
* | ||
* | ||
* 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block | ||
* | ||
* 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If | ||
* unset, minify will sniff for an XHTML doctype. | ||
* | ||
* @return null | ||
*/ | ||
public function __construct($html, $options = array()) | ||
{ | ||
|
@@ -67,9 +76,12 @@ public function __construct($html, $options = array()) | |
if (isset($options['jsMinifier'])) { | ||
$this->_jsMinifier = $options['jsMinifier']; | ||
} | ||
if (isset($options['jsCleanComments'])) { | ||
$this->_jsCleanComments = (bool)$options['jsCleanComments']; | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Minify the markeup given in the constructor | ||
* | ||
|
@@ -86,13 +98,13 @@ public function process() | |
|
||
// replace SCRIPTs (and minify) with placeholders | ||
$this->_html = preg_replace_callback( | ||
'/(\\s*)(<script\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i' | ||
'/(\\s*)<script(\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i' | ||
,array($this, '_removeScriptCB') | ||
,$this->_html); | ||
|
||
// replace STYLEs (and minify) with placeholders | ||
$this->_html = preg_replace_callback( | ||
'/\\s*(<style\\b[^>]*?>)([\\s\\S]*?)<\\/style>\\s*/i' | ||
'/\\s*<style(\\b[^>]*>)([\\s\\S]*?)<\\/style>\\s*/i' | ||
,array($this, '_removeStyleCB') | ||
,$this->_html); | ||
|
||
|
@@ -103,13 +115,13 @@ public function process() | |
,$this->_html); | ||
|
||
// replace PREs with placeholders | ||
$this->_html = preg_replace_callback('/\\s*(<pre\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i' | ||
$this->_html = preg_replace_callback('/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i' | ||
,array($this, '_removePreCB') | ||
,$this->_html); | ||
|
||
// replace TEXTAREAs with placeholders | ||
$this->_html = preg_replace_callback( | ||
'/\\s*(<textarea\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i' | ||
'/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i' | ||
,array($this, '_removeTextareaCB') | ||
,$this->_html); | ||
|
||
|
@@ -119,15 +131,15 @@ public function process() | |
|
||
// remove ws around block/undisplayed elements | ||
$this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body' | ||
.'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' | ||
.'|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' | ||
.'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta' | ||
.'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)' | ||
.'|ul)\\b[^>]*>)/i', '$1', $this->_html); | ||
|
||
// remove ws outside of all elements | ||
$this->_html = preg_replace_callback( | ||
'/>([^<]+)</' | ||
,array($this, '_outsideTagCB') | ||
$this->_html = preg_replace( | ||
'/>(\\s(?:\\s*))?([^<]+)(\\s(?:\s*))?</' | ||
,'>$1$2$3<' | ||
,$this->_html); | ||
|
||
// use newlines before 1st attribute in open tags (to limit line lengths) | ||
|
@@ -139,6 +151,12 @@ public function process() | |
,array_values($this->_placeholders) | ||
,$this->_html | ||
); | ||
// issue 229: multi-pass to catch scripts that didn't get replaced in textareas | ||
$this->_html = str_replace( | ||
array_keys($this->_placeholders) | ||
,array_values($this->_placeholders) | ||
,$this->_html | ||
); | ||
return $this->_html; | ||
} | ||
|
||
|
@@ -162,24 +180,19 @@ protected function _reservePlace($content) | |
protected $_cssMinifier = null; | ||
protected $_jsMinifier = null; | ||
|
||
protected function _outsideTagCB($m) | ||
{ | ||
return '>' . preg_replace('/^\\s+|\\s+$/', ' ', $m[1]) . '<'; | ||
} | ||
|
||
protected function _removePreCB($m) | ||
{ | ||
return $this->_reservePlace($m[1]); | ||
return $this->_reservePlace("<pre{$m[1]}"); | ||
} | ||
|
||
protected function _removeTextareaCB($m) | ||
{ | ||
return $this->_reservePlace($m[1]); | ||
return $this->_reservePlace("<textarea{$m[1]}"); | ||
} | ||
|
||
protected function _removeStyleCB($m) | ||
{ | ||
$openStyle = $m[1]; | ||
$openStyle = "<style{$m[1]}"; | ||
$css = $m[2]; | ||
// remove HTML comments | ||
$css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css); | ||
|
@@ -201,23 +214,25 @@ protected function _removeStyleCB($m) | |
|
||
protected function _removeScriptCB($m) | ||
{ | ||
$openScript = $m[2]; | ||
$openScript = "<script{$m[2]}"; | ||
$js = $m[3]; | ||
|
||
// whitespace surrounding? preserve at least one space | ||
$ws1 = ($m[1] === '') ? '' : ' '; | ||
$ws2 = ($m[4] === '') ? '' : ' '; | ||
|
||
// remove HTML comments (and ending "//" if present) | ||
$js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js); | ||
|
||
if ($this->_jsCleanComments) { | ||
$js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js); | ||
} | ||
|
||
// remove CDATA section markers | ||
$js = $this->_removeCdata($js); | ||
|
||
// minify | ||
$minifier = $this->_jsMinifier | ||
? $this->_jsMinifier | ||
: 'trim'; | ||
: 'trim'; | ||
$js = call_user_func($minifier, $js); | ||
|
||
return $this->_reservePlace($this->_needsCdata($js) | ||
|
@@ -237,4 +252,4 @@ protected function _needsCdata($str) | |
{ | ||
return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str)); | ||
} | ||
} | ||
} |