Skip to content

Instantly share code, notes, and snippets.

@clemgrim
Last active October 14, 2015 09:01
Show Gist options
  • Save clemgrim/54dd4e8f52e60ed50b8b to your computer and use it in GitHub Desktop.
Save clemgrim/54dd4e8f52e60ed50b8b to your computer and use it in GitHub Desktop.
<?php
/**
* Based on https://gist.github.com/tovic/d7b310dea3b33e4732c0
*/
class Minify
{
public function minifyHtml($html, $processJs = true, $processCss = true)
{
$html = trim($html);
if ($html === "") {
return $html;
}
// process js
if ($processJs) {
$html = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/is', function ($match) {
if ($match[1]) {
return '<script>'.$this->minifyJs($match[1]).'</script>';
}
return $match[0];
}, $html);
}
// process css
if ($processCss) {
$html = preg_replace_callback('/<style\b[^>]*>(.*?)<\/style>/is', function ($match) {
if ($match[1]) {
return '<style>'.$this->minifyCss($match[1]).'</style>';
}
return $match[0];
}, $html);
}
// remove extra white-spaces
$html = preg_replace('/\s{2,}/', ' ', $html);
return preg_replace(
array(
// Remove HTML comments except IE comments
'#\s*(<\!--(?=\[if).*?-->)\s*|\s*<\!--.*?-->\s*#s',
// Do not remove white-space after image and
// input tag that is followed by a tag open
'#(<(?:img|input)(?:\/?>|\s[^<>]*?\/?>))\s+(?=\<[^\/])#s',
// Remove two or more white-spaces between tags
'#(<\!--.*?-->)|(>)\s{2,}|\s{2,}(<)|(>)\s{2,}(<)#s',
// Proofing ...
// o: tag open, c: tag close, t: text
// If `<tag> </tag>` remove white-space
// If `</tag> <tag>` keep white-space
// If `<tag> <tag>` remove white-space
// If `</tag> </tag>` remove white-space
// If `<tag> ...</tag>` remove white-spaces
// If `</tag> ...<tag>` remove white-spaces
// If `<tag> ...<tag>` remove white-spaces
// If `</tag> ...</tag>` remove white-spaces
// If `abc <tag>` keep white-space
// If `<tag> abc` remove white-space
// If `abc </tag>` remove white-space
// If `</tag> abc` keep white-space
// TODO: If `abc ...<tag>` keep one white-space
// If `<tag> ...abc` remove white-spaces
// If `abc ...</tag>` remove white-spaces
// TODO: If `</tag> ...abc` keep one white-space
'#(<\!--.*?-->)|(<(?:img|input)(?:\/?>|\s[^<>]*?\/?>))\s+(?!\<\/)#s', // o+t | o+o
'#(<\!--.*?-->)|(<[^\/\s<>]+(?:>|\s[^<>]*?>))\s+(?=\<[^\/])#s', // o+o
'#(<\!--.*?-->)|(<\/[^\/\s<>]+?>)\s+(?=\<\/)#s', // c+c
'#(<\!--.*?-->)|(<([^\/\s<>]+)(?:>|\s[^<>]*?>))\s+(<\/\3>)#s', // o+c
'#(<\!--.*?-->)|(<[^\/\s<>]+(?:>|\s[^<>]*?>))\s+(?!\<)#s', // o+t
'#(<\!--.*?-->)|(?!\>)\s+(<\/[^\/\s<>]+?>)#s', // t+c
'#(<\!--.*?-->)|(?!\>)\s+(?=\<[^\/])#s', // t+o
'#(<\!--.*?-->)|(<\/[^\/\s<>]+?>)\s+(?!\<)#s', // c+t
'#(<\!--.*?-->)|(\/>)\s+(?!\<)#', // o+t
// Replace `&nbsp;&nbsp;&nbsp;` with `&nbsp; &nbsp;`
'#(?<=&nbsp;)(&nbsp;){2}#',
// Proofing ...
'#(?<=\>)&nbsp;(?!\s|&nbsp;|<\/)#',
'#(?<=--\>)(?:\s|&nbsp;)+(?=\<)#'
),
array(
'$1',
'$1&nbsp;',
'$1$2$3$4$5',
'$1$2&nbsp;', // o+t | o+o
'$1$2', // o+o
'$1$2', //c+c
'$1$2$4', // o+c
'$1$2', // o+t
'$1$2', // t+c
'$1$2 ', // t+o
'$1$2 ', // c+t
'$1$2 ', // o+t
' $1',
' ',
""
),
$html
);
}
public function minifyCss($css)
{
return CssMin::minify($css);
}
public function minifyJs ($js)
{
$packer = new JavaScriptPacker($js, 'None');
return $packer->pack();
}
}
<p>
<i class="fa fa-user"></i> Utilisateur
</p>
<p><strong>Ceci</strong> ne devrait pas être collé <i>et celui-ci non plus</i> héhé</p>
<p>
Texte
Sur
Beaucoup
De
Lignes
</p>
<small>empty</small>
<div class="empty" data-test
data-src="http//fake.com"
data-width="500"
style="display:block";
> </div>
<div class="empty too">
</div>
<p> <strong>Remove before and after</strong> </p>
<p style="
font-size: 22px;
color : red; font-family: Georgia ;
">Hello</p>
<style>
/** gros commentaire */
p, html /*lol*/, test {
font-size: 16px;
}
.empty {
background-color: rgba(0, 0, 0, .7);
display: inline-block;
width: calc(100% - 80px);
margin-left: auto;
margin-right: auto;
}
</style>
<script>
// ceci est un commentaire
console.log('Qui ne devrait pas empêcher cela de s\'afficher', "'héhé\"");
var a = 5 + 2;
console.log(++a);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment