Skip to content

Commit

Permalink
[+]: fixed html-encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
voku committed Oct 17, 2016
1 parent c927d17 commit 313909c
Show file tree
Hide file tree
Showing 5 changed files with 5,959 additions and 66 deletions.
137 changes: 81 additions & 56 deletions src/voku/helper/HtmlMin.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,59 +23,79 @@ class HtmlMin
* @var array
*/
private static $executableScriptsMimeTypes = array(
'text/javascript',
'text/ecmascript',
'text/jscript',
'application/javascript',
'application/x-javascript',
'application/ecmascript',
'text/javascript' => '',
'text/ecmascript' => '',
'text/jscript' => '',
'application/javascript' => '',
'application/x-javascript' => '',
'application/ecmascript' => '',
);

private static $selfClosingTags = array(
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr',
);


/**
* @var array
*/
private static $booleanAttributes = array(
'allowfullscreen',
'async',
'autofocus',
'autoplay',
'checked',
'compact',
'controls',
'declare',
'default',
'defaultchecked',
'defaultmuted',
'defaultselected',
'defer',
'disabled',
'enabled',
'formnovalidate',
'hidden',
'indeterminate',
'inert',
'ismap',
'itemscope',
'loop',
'multiple',
'muted',
'nohref',
'noresize',
'noshade',
'novalidate',
'nowrap',
'open',
'pauseonexit',
'readonly',
'required',
'reversed',
'scoped',
'seamless',
'selected',
'sortable',
'truespeed',
'typemustmatch',
'visible',
'allowfullscreen' => '',
'async' => '',
'autofocus' => '',
'autoplay' => '',
'checked' => '',
'compact' => '',
'controls' => '',
'declare' => '',
'default' => '',
'defaultchecked' => '',
'defaultmuted' => '',
'defaultselected' => '',
'defer' => '',
'disabled' => '',
'enabled' => '',
'formnovalidate' => '',
'hidden' => '',
'indeterminate' => '',
'inert' => '',
'ismap' => '',
'itemscope' => '',
'loop' => '',
'multiple' => '',
'muted' => '',
'nohref' => '',
'noresize' => '',
'noshade' => '',
'novalidate' => '',
'nowrap' => '',
'open' => '',
'pauseonexit' => '',
'readonly' => '',
'required' => '',
'reversed' => '',
'scoped' => '',
'seamless' => '',
'selected' => '',
'sortable' => '',
'truespeed' => '',
'typemustmatch' => '',
'visible' => '',
);
/**
* @var array
Expand Down Expand Up @@ -214,6 +234,12 @@ public function minify($html)
$html
);

static $cacheSelfClosingTags = null;
if ($cacheSelfClosingTags === null) {
$cacheSelfClosingTags = implode('|', self::$selfClosingTags);
}
$html = preg_replace('#<\b(' . $cacheSelfClosingTags . ')([^>]+)><\/\b\1>#', '<\\1\\2/>', $html);

// ------------------------------------
// check if compression worked
// ------------------------------------
Expand All @@ -230,20 +256,20 @@ public function minify($html)
* and remove some default attributes.
*
* @param SimpleHtmlDom $element
* @param array $attributs
*
* @return bool
*/
private function optimizeAttributes(SimpleHtmlDom $element, &$attributs)
private function optimizeAttributes(SimpleHtmlDom $element)
{
if (!$attributs) {
$attributs = $element->getAllAttributes();
if ($attributs === null) {
return false;
}

$attrs = array();
foreach ($attributs as $attrName => $attrValue) {
foreach ((array)$attributs as $attrName => $attrValue) {

if (in_array($attrName, self::$booleanAttributes, true)) {
if (isset(self::$booleanAttributes[$attrName])) {
$attrs[$attrName] = $this->booleanAttributesHelper;
$element->{$attrName} = null;
continue;
Expand Down Expand Up @@ -272,6 +298,7 @@ private function optimizeAttributes(SimpleHtmlDom $element, &$attributs)

ksort($attrs);
foreach ($attrs as $attrName => $attrValue) {
$attrValue = HtmlDomParser::replaceToPreserveHtmlEntities($attrValue);
$element->setAttribute($attrName, $attrValue, true);
}

Expand Down Expand Up @@ -326,7 +353,7 @@ private function optimizeAttributesFilters($tag, $attrName, $attrValue, $allAttr
}

// remove deprecated script-mime-types
if ($tag === 'script' && $attrName === 'type' && isset($allAttr['src']) && in_array($attrValue, self::$executableScriptsMimeTypes, true)) {
if ($tag === 'script' && $attrName === 'type' && isset($allAttr['src'], self::$executableScriptsMimeTypes[$attrValue])) {
return true;
}

Expand All @@ -353,9 +380,7 @@ private function optimizeAttributesFilters($tag, $attrName, $attrValue, $allAttr
private function optimizeAttributesInDom(HtmlDomParser $dom)
{
foreach ($dom->find('*') as $element) {
$attributs = $element->getAllAttributes();

$this->optimizeAttributes($element, $attributs);
$this->optimizeAttributes($element);
}

return $dom;
Expand Down
19 changes: 12 additions & 7 deletions tests/HtmlMinTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,24 @@ public function testMinifyCodeTag()
self::assertSame($expected, $htmlMin->minify($html));
}

public function testMinifyTheGuardian()
{
// init
$htmlMin = new HtmlMin();

$html = str_replace(array("\r\n", "\r", "\n"), "\n", UTF8::file_get_contents(__DIR__ . '/fixtures/theguardian.html'));
$expected = str_replace(array("\r\n", "\r", "\n",), "\n", UTF8::file_get_contents(__DIR__ . '/fixtures/theguardian_result.html'));

self::assertSame($expected, $htmlMin->minify($html));
}

public function testMinifyHlt()
{
// init
$htmlMin = new HtmlMin();

$html = str_replace(array("\r\n", "\r", "\n"), "\n", UTF8::file_get_contents(__DIR__ . '/fixtures/hlt.html'));
$expected = str_replace(
array(
"\r\n",
"\r",
"\n",
), "\n", UTF8::file_get_contents(__DIR__ . '/fixtures/hlt_result.html')
);
$expected = str_replace(array("\r\n", "\r", "\n",), "\n", UTF8::file_get_contents(__DIR__ . '/fixtures/hlt_result.html'));

self::assertSame($expected, $htmlMin->minify($html));
}
Expand Down
6 changes: 3 additions & 3 deletions tests/fixtures/hlt_result.html

Large diffs are not rendered by default.

4,153 changes: 4,153 additions & 0 deletions tests/fixtures/theguardian.html

Large diffs are not rendered by default.

1,710 changes: 1,710 additions & 0 deletions tests/fixtures/theguardian_result.html

Large diffs are not rendered by default.

0 comments on commit 313909c

Please sign in to comment.