mirror of
https://github.com/monstra-cms/monstra.git
synced 2025-08-04 20:27:40 +02:00
New Minify Classes!
This commit is contained in:
@@ -88,7 +88,9 @@ ClassLoader::mapClasses(array(
|
|||||||
'Html' => __DIR__.'/Html/Html.php',
|
'Html' => __DIR__.'/Html/Html.php',
|
||||||
'Image' => __DIR__.'/Image/Image.php',
|
'Image' => __DIR__.'/Image/Image.php',
|
||||||
'Inflector' => __DIR__.'/Inflector/Inflector.php',
|
'Inflector' => __DIR__.'/Inflector/Inflector.php',
|
||||||
'Minify' => __DIR__.'/Minify/Minify.php',
|
'MinifyCSS' => __DIR__.'/Minify/MinifyCSS.php',
|
||||||
|
'MinifyHTML' => __DIR__.'/Minify/MinifyHTML.php',
|
||||||
|
'MinifyJS' => __DIR__.'/Minify/MinifyJS.php',
|
||||||
'Notification' => __DIR__.'/Notification/Notification.php',
|
'Notification' => __DIR__.'/Notification/Notification.php',
|
||||||
'Number' => __DIR__.'/Number/Number.php',
|
'Number' => __DIR__.'/Number/Number.php',
|
||||||
'Registry' => __DIR__.'/Registry/Registry.php',
|
'Registry' => __DIR__.'/Registry/Registry.php',
|
||||||
|
@@ -1,93 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gelato Library
|
|
||||||
*
|
|
||||||
* This source file is part of the Gelato Library. More information,
|
|
||||||
* documentation and tutorials can be found at http://gelato.monstra.org
|
|
||||||
*
|
|
||||||
* @package Gelato
|
|
||||||
*
|
|
||||||
* @author Romanenko Sergey / Awilum <awilum@msn.com>
|
|
||||||
* @copyright 2012-2013 Romanenko Sergey / Awilum <awilum@msn.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Minify
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Protected constructor since this is a static class.
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected function __construct()
|
|
||||||
{
|
|
||||||
// Nothing here
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minify html
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* echo Minify::html($buffer);
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param string $buffer html
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function html($buffer)
|
|
||||||
{
|
|
||||||
return preg_replace('/^\\s+|\\s+$/m', '', $buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minify css
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* echo Minify::css($buffer);
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param string $buffer css
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function css($buffer)
|
|
||||||
{
|
|
||||||
// Remove comments
|
|
||||||
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
|
|
||||||
|
|
||||||
// Remove tabs, spaces, newlines, etc.
|
|
||||||
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);
|
|
||||||
|
|
||||||
// Preserve empty comment after '>' http://www.webdevout.net/css-hacks#in_css-selectors
|
|
||||||
$buffer = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $buffer);
|
|
||||||
|
|
||||||
// Preserve empty comment between property and value
|
|
||||||
// http://css-discuss.incutio.com/?page=BoxModelHack
|
|
||||||
$buffer = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $buffer);
|
|
||||||
$buffer = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $buffer);
|
|
||||||
|
|
||||||
// Remove ws around { } and last semicolon in declaration block
|
|
||||||
$buffer = preg_replace('/\\s*{\\s*/', '{', $buffer);
|
|
||||||
$buffer = preg_replace('/;?\\s*}\\s*/', '}', $buffer);
|
|
||||||
|
|
||||||
// Remove ws surrounding semicolons
|
|
||||||
$buffer = preg_replace('/\\s*;\\s*/', ';', $buffer);
|
|
||||||
|
|
||||||
// Remove ws around urls
|
|
||||||
$buffer = preg_replace('/url\\(\\s*([^\\)]+?)\\s*\\)/x', 'url($1)', $buffer);
|
|
||||||
|
|
||||||
// Remove ws between rules and colons
|
|
||||||
$buffer = preg_replace('/\\s*([{;])\\s*([\\*_]?[\\w\\-]+)\\s*:\\s*(\\b|[#\'"])/x', '$1$2:$3', $buffer);
|
|
||||||
|
|
||||||
// Minimize hex colors
|
|
||||||
$buffer = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i', '$1#$2$3$4$5', $buffer);
|
|
||||||
|
|
||||||
// Replace any ws involving newlines with a single newline
|
|
||||||
$buffer = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $buffer);
|
|
||||||
|
|
||||||
return $buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
255
libraries/Gelato/Minify/MinifyCSS.php
Normal file
255
libraries/Gelato/Minify/MinifyCSS.php
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gelato Library
|
||||||
|
*
|
||||||
|
* This source file is part of the Gelato Library. More information,
|
||||||
|
* documentation and tutorials can be found at http://gelato.monstra.org
|
||||||
|
*
|
||||||
|
* @package Gelato
|
||||||
|
*
|
||||||
|
* @author Romanenko Sergey / Awilum <awilum@msn.com>
|
||||||
|
* @author Stephen Clay <steve@mrclay.org>
|
||||||
|
* @copyright 2012-2013 Romanenko Sergey / Awilum <awilum@msn.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MinifyCSS
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $_options = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we "in" a hack? I.e. are some browsers targetted until the next comment?
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $_inHack = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param array $options (currently ignored)
|
||||||
|
*/
|
||||||
|
private function __construct($options)
|
||||||
|
{
|
||||||
|
$this->_options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minify a CSS string
|
||||||
|
*
|
||||||
|
* @param string $css
|
||||||
|
*
|
||||||
|
* @param array $options (currently ignored)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function process($css, $options = array())
|
||||||
|
{
|
||||||
|
$obj = new MinifyCSS($options);
|
||||||
|
|
||||||
|
return $obj->_process($css);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minify a CSS string
|
||||||
|
*
|
||||||
|
* @param string $css
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _process($css)
|
||||||
|
{
|
||||||
|
$css = str_replace("\r\n", "\n", $css);
|
||||||
|
|
||||||
|
// preserve empty comment after '>'
|
||||||
|
// http://www.webdevout.net/css-hacks#in_css-selectors
|
||||||
|
$css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
|
||||||
|
|
||||||
|
// preserve empty comment between property and value
|
||||||
|
// http://css-discuss.incutio.com/?page=BoxModelHack
|
||||||
|
$css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
|
||||||
|
$css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
|
||||||
|
|
||||||
|
// apply callback to all valid comments (and strip out surrounding ws
|
||||||
|
$css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
|
||||||
|
,array($this, '_commentCB'), $css);
|
||||||
|
|
||||||
|
// remove ws around { } and last semicolon in declaration block
|
||||||
|
$css = preg_replace('/\\s*{\\s*/', '{', $css);
|
||||||
|
$css = preg_replace('/;?\\s*}\\s*/', '}', $css);
|
||||||
|
|
||||||
|
// remove ws surrounding semicolons
|
||||||
|
$css = preg_replace('/\\s*;\\s*/', ';', $css);
|
||||||
|
|
||||||
|
// remove ws around urls
|
||||||
|
$css = preg_replace('/
|
||||||
|
url\\( # url(
|
||||||
|
\\s*
|
||||||
|
([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis)
|
||||||
|
\\s*
|
||||||
|
\\) # )
|
||||||
|
/x', 'url($1)', $css);
|
||||||
|
|
||||||
|
// remove ws between rules and colons
|
||||||
|
$css = preg_replace('/
|
||||||
|
\\s*
|
||||||
|
([{;]) # 1 = beginning of block or rule separator
|
||||||
|
\\s*
|
||||||
|
([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter)
|
||||||
|
\\s*
|
||||||
|
:
|
||||||
|
\\s*
|
||||||
|
(\\b|[#\'"-]) # 3 = first character of a value
|
||||||
|
/x', '$1$2:$3', $css);
|
||||||
|
|
||||||
|
// remove ws in selectors
|
||||||
|
$css = preg_replace_callback('/
|
||||||
|
(?: # non-capture
|
||||||
|
\\s*
|
||||||
|
[^~>+,\\s]+ # selector part
|
||||||
|
\\s*
|
||||||
|
[,>+~] # combinators
|
||||||
|
)+
|
||||||
|
\\s*
|
||||||
|
[^~>+,\\s]+ # selector part
|
||||||
|
{ # open declaration block
|
||||||
|
/x'
|
||||||
|
,array($this, '_selectorsCB'), $css);
|
||||||
|
|
||||||
|
// minimize hex colors
|
||||||
|
$css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
|
||||||
|
, '$1#$2$3$4$5', $css);
|
||||||
|
|
||||||
|
// remove spaces between font families
|
||||||
|
$css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
|
||||||
|
,array($this, '_fontFamilyCB'), $css);
|
||||||
|
|
||||||
|
$css = preg_replace('/@import\\s+url/', '@import url', $css);
|
||||||
|
|
||||||
|
// replace any ws involving newlines with a single newline
|
||||||
|
$css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
|
||||||
|
|
||||||
|
// separate common descendent selectors w/ newlines (to limit line lengths)
|
||||||
|
$css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
|
||||||
|
|
||||||
|
// Use newline after 1st numeric value (to limit line lengths).
|
||||||
|
$css = preg_replace('/
|
||||||
|
((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
|
||||||
|
\\s+
|
||||||
|
/x'
|
||||||
|
,"$1\n", $css);
|
||||||
|
|
||||||
|
// prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
|
||||||
|
$css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
|
||||||
|
|
||||||
|
return trim($css);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace what looks like a set of selectors
|
||||||
|
*
|
||||||
|
* @param array $m regex matches
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _selectorsCB($m)
|
||||||
|
{
|
||||||
|
// remove ws around the combinators
|
||||||
|
return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a comment and return a replacement
|
||||||
|
*
|
||||||
|
* @param array $m regex matches
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _commentCB($m)
|
||||||
|
{
|
||||||
|
$hasSurroundingWs = (trim($m[0]) !== $m[1]);
|
||||||
|
$m = $m[1];
|
||||||
|
// $m is the comment content w/o the surrounding tokens,
|
||||||
|
// but the return value will replace the entire comment.
|
||||||
|
if ($m === 'keep') {
|
||||||
|
return '/**/';
|
||||||
|
}
|
||||||
|
if ($m === '" "') {
|
||||||
|
// component of http://tantek.com/CSS/Examples/midpass.html
|
||||||
|
return '/*" "*/';
|
||||||
|
}
|
||||||
|
if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
|
||||||
|
// component of http://tantek.com/CSS/Examples/midpass.html
|
||||||
|
return '/*";}}/* */';
|
||||||
|
}
|
||||||
|
if ($this->_inHack) {
|
||||||
|
// inversion: feeding only to one browser
|
||||||
|
if (preg_match('@
|
||||||
|
^/ # comment started like /*/
|
||||||
|
\\s*
|
||||||
|
(\\S[\\s\\S]+?) # has at least some non-ws content
|
||||||
|
\\s*
|
||||||
|
/\\* # ends like /*/ or /**/
|
||||||
|
@x', $m, $n)) {
|
||||||
|
// end hack mode after this comment, but preserve the hack and comment content
|
||||||
|
$this->_inHack = false;
|
||||||
|
|
||||||
|
return "/*/{$n[1]}/**/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (substr($m, -1) === '\\') { // comment ends like \*/
|
||||||
|
// begin hack mode and preserve hack
|
||||||
|
$this->_inHack = true;
|
||||||
|
|
||||||
|
return '/*\\*/';
|
||||||
|
}
|
||||||
|
if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
|
||||||
|
// begin hack mode and preserve hack
|
||||||
|
$this->_inHack = true;
|
||||||
|
|
||||||
|
return '/*/*/';
|
||||||
|
}
|
||||||
|
if ($this->_inHack) {
|
||||||
|
// a regular comment ends hack mode but should be preserved
|
||||||
|
$this->_inHack = false;
|
||||||
|
|
||||||
|
return '/**/';
|
||||||
|
}
|
||||||
|
// Issue 107: if there's any surrounding whitespace, it may be important, so
|
||||||
|
// replace the comment with a single space
|
||||||
|
return $hasSurroundingWs // remove all other comments
|
||||||
|
? ' '
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a font-family listing and return a replacement
|
||||||
|
*
|
||||||
|
* @param array $m regex matches
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _fontFamilyCB($m)
|
||||||
|
{
|
||||||
|
// Issue 210: must not eliminate WS between words in unquoted families
|
||||||
|
$pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||||
|
$out = 'font-family:';
|
||||||
|
while (null !== ($piece = array_shift($pieces))) {
|
||||||
|
if ($piece[0] !== '"' && $piece[0] !== "'") {
|
||||||
|
$piece = preg_replace('/\\s+/', ' ', $piece);
|
||||||
|
$piece = preg_replace('/\\s?,\\s?/', ',', $piece);
|
||||||
|
}
|
||||||
|
$out .= $piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out . $m[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
libraries/Gelato/Minify/MinifyHTML.php
Normal file
47
libraries/Gelato/Minify/MinifyHTML.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gelato Library
|
||||||
|
*
|
||||||
|
* This source file is part of the Gelato Library. More information,
|
||||||
|
* documentation and tutorials can be found at http://gelato.monstra.org
|
||||||
|
*
|
||||||
|
* @package Gelato
|
||||||
|
*
|
||||||
|
* @author Romanenko Sergey / Awilum <awilum@msn.com>
|
||||||
|
* @copyright 2012-2013 Romanenko Sergey / Awilum <awilum@msn.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MinifyHTML
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Minify html
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* echo MinifyHTML::process($html);
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @param string $buffer html
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function process($html)
|
||||||
|
{
|
||||||
|
// Remove HTML comments (not containing IE conditional comments).
|
||||||
|
$html = preg_replace_callback('/<!--([\\s\\S]*?)-->/', 'self::_comments', $html);
|
||||||
|
|
||||||
|
// Trim each line.
|
||||||
|
$html = preg_replace('/^\\s+|\\s+$/m', '', $html);
|
||||||
|
|
||||||
|
// Return HTML
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function _comments($m)
|
||||||
|
{
|
||||||
|
return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<![')) ? $m[0] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
50
libraries/Gelato/Minify/MinifyJS.php
Normal file
50
libraries/Gelato/Minify/MinifyJS.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gelato Library
|
||||||
|
*
|
||||||
|
* This source file is part of the Gelato Library. More information,
|
||||||
|
* documentation and tutorials can be found at http://gelato.monstra.org
|
||||||
|
*
|
||||||
|
* @package Gelato
|
||||||
|
*
|
||||||
|
* @author Romanenko Sergey / Awilum <awilum@msn.com>
|
||||||
|
* @copyright 2012-2013 Romanenko Sergey / Awilum <awilum@msn.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MinifyJS
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Minify js
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* echo MinifyJS::process($js);
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @param string $buffer html
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function process($js)
|
||||||
|
{
|
||||||
|
// newlines > linefeed
|
||||||
|
$js = str_replace(array("\r\n", "\r", "\n"), "\n", $js);
|
||||||
|
|
||||||
|
// empty lines > collapse
|
||||||
|
$js = preg_replace('/^[ \t]*|[ \t]*$/m', '', $js);
|
||||||
|
$js = preg_replace('/\n+/m', "\n", $js);
|
||||||
|
$js = trim($js);
|
||||||
|
|
||||||
|
// redundant whitespace > remove
|
||||||
|
$js = preg_replace('/(?<=[{}\[\]\(\)=><&\|;:,\?!\+-])[ \t]*|[ \t]*(?=[{}\[\]\(\)=><&\|;:,\?!\+-])/i', '', $js);
|
||||||
|
$js = preg_replace('/[ \t]+/', ' ', $js);
|
||||||
|
|
||||||
|
// redundant semicolons (followed by another semicolon or closing curly bracket) > remove
|
||||||
|
$js = preg_replace('/;\s*(?=[;}])/s', '', $js);
|
||||||
|
|
||||||
|
// Return JS
|
||||||
|
return $js;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user