* qui servent parfois aux plugins, et parfois même après
* le passage du compacteur HTML
*
* C'était le cas du bouton statistiques du formulaire admin par exemple
*
* On permet de conserver également tout commentaire commençant par
*
* @package SPIP\Compresseur\Minifieur
**/
class Minify_HTML_SPIP extends Minify_HTML {
/**
* {@inheritdoc}
*
*
* @param string $html
* HTML à minifier
* @param array $options
* Tableau d'option avec les index possibles
* - '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
* HTML minifié
**/
public static function minify($html, $options = array()) {
$min = new Minify_HTML_SPIP($html, $options);
return $min->process();
}
/**
* Minification des commentaires
*
* Le cas doit être conservé dans les commentaires,
* tout comme
*
* @param array $m Matches du preg_match d'un commentaire HTML
* @return string Contenu minifié
*/
protected function _commentCB($m)
{
if ($m[1] === 'extra') return $m[0];
if ($m[1] AND $m[1][0] === 'k' AND substr($m[1],0,7) === 'keepme:') return $m[0];
return parent::_commentCB($m);
}
}
/**
* Compress HTML
*
* 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.
*
* A test suite is available.
* http://code.google.com/p/minify/source/browse/trunk/min/lib/Minify/HTML.php
*
* @package Minify
* @author Stephen Clay
*/
class Minify_HTML {
/**
* "Minify" an HTML page
*
* @param string $html
*
* @param array $options
*
* '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 Minify_HTML($html, $options);
return $min->process();
}
/**
* Create a minifier object
*
* @param string $html
*
* @param array $options
*
* '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 null
*/
public function __construct($html, $options = array())
{
$this->_html = str_replace("\r\n", "\n", trim($html));
if (isset($options['xhtml'])) {
$this->_isXhtml = (bool)$options['xhtml'];
}
if (isset($options['cssMinifier'])) {
$this->_cssMinifier = $options['cssMinifier'];
}
if (isset($options['jsMinifier'])) {
$this->_jsMinifier = $options['jsMinifier'];
}
}
/**
* Minify the markeup given in the constructor
*
* @return string
*/
public function process()
{
if ($this->_isXhtml === null) {
$this->_isXhtml = (false !== strpos($this->_html, '_html);
// fill placeholders
$this->_html = str_replace(
array_keys($this->_placeholders)
,array_values($this->_placeholders)
,$this->_html
);
return $this->_html;
}
protected function _commentCB($m)
{
return (0 === strpos($m[1], '[') || false !== strpos($m[1], '_replacementHash . count($this->_placeholders) . '%';
$this->_placeholders[$placeholder] = $content;
return $placeholder;
}
protected $_isXhtml = null;
protected $_replacementHash = null;
protected $_placeholders = array();
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]);
}
protected function _removeTextareaCB($m)
{
return $this->_reservePlace($m[1]);
}
protected function _removeStyleCB($m)
{
$openStyle = $m[1];
$css = $m[2];
// remove HTML comments
$css = preg_replace('/(?:^\\s*\\s*$)/', '', $css);
// remove CDATA section markers
$css = $this->_removeCdata($css);
// minify
$minifier = $this->_cssMinifier
? $this->_cssMinifier
: 'trim';
$css = call_user_func($minifier, $css);
return $this->_reservePlace($this->_needsCdata($css)
? "{$openStyle}/**/"
: "{$openStyle}{$css}"
);
}
protected function _removeScriptCB($m)
{
$openScript = $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*$)/', '', $js);
// remove CDATA section markers
$js = $this->_removeCdata($js);
// minify
$minifier = $this->_jsMinifier
? $this->_jsMinifier
: 'trim';
$js = call_user_func($minifier, $js);
return $this->_reservePlace($this->_needsCdata($js)
? "{$ws1}{$openScript}/**/{$ws2}"
: "{$ws1}{$openScript}{$js}{$ws2}"
);
}
protected function _removeCdata($str)
{
return (false !== strpos($str, ''), '', $str)
: $str;
}
protected function _needsCdata($str)
{
return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
}
}