Version 3.3.4
This commit is contained in:
1 parent
78706903a2
commit
fb6b5baabc
2206 files changed
+409828
-382984
No files matched your search
@@ -72,8 +72,8 @@ For the best performance, edit groupsConfig.php to pre-specify groups of files
|
||||
to be combined under preset keys. E.g., here's an example configuration in
|
||||
groupsConfig.php:
|
||||
|
||||
return array(
|
||||
'js' => array('//js/Class.js', '//js/email.js')
|
||||
return array(
|
||||
'js' => array('//js/Class.js', '//js/email.js')
|
||||
);
|
||||
|
||||
This pre-selects the following files to be combined under the key "js":
|
||||
|
||||
@@ -26,8 +26,8 @@ if (isset($_GET['hello'])) {
|
||||
'content' => 'World!'
|
||||
,'method' => 'deflate'
|
||||
));
|
||||
$he->encode();
|
||||
$he->sendAll();
|
||||
$he->encode();
|
||||
$he->sendAll();
|
||||
|
||||
} else {
|
||||
// echo status "0" or "1"
|
||||
|
||||
@@ -135,7 +135,7 @@ $min_serveOptions['minApp']['groupsOnly'] = false;
|
||||
/**
|
||||
* Maximum # of files that can be specified in the "f" GET parameter
|
||||
*/
|
||||
$min_serveOptions['minApp']['maxFiles'] = 15;
|
||||
$min_serveOptions['minApp']['maxFiles'] = 25;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
* </code>
|
||||
*
|
||||
* For more control over headers, use getHeaders() and getData() and send your
|
||||
* own output.
|
||||
*
|
||||
* Note: If you don't need header mgmt, use PHP's native gzencode, gzdeflate,
|
||||
* and gzcompress functions for gzip, deflate, and compress-encoding
|
||||
* respectively.
|
||||
* own output.
|
||||
*
|
||||
* Note: If you don't need header mgmt, use PHP's native gzencode, gzdeflate,
|
||||
* and gzcompress functions for gzip, deflate, and compress-encoding
|
||||
* respectively.
|
||||
*
|
||||
* @package Minify
|
||||
* @subpackage HTTP
|
||||
@@ -88,7 +88,7 @@ class HTTP_Encoder {
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function __construct($spec)
|
||||
public function __construct($spec)
|
||||
{
|
||||
$this->_content = $spec['content'];
|
||||
$this->_headers['Content-Length'] = (string)strlen($this->_content);
|
||||
@@ -111,7 +111,7 @@ class HTTP_Encoder {
|
||||
*
|
||||
* return string
|
||||
*/
|
||||
public function getContent()
|
||||
public function getContent()
|
||||
{
|
||||
return $this->_content;
|
||||
}
|
||||
@@ -130,7 +130,7 @@ class HTTP_Encoder {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->_headers;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ class HTTP_Encoder {
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function sendHeaders()
|
||||
public function sendHeaders()
|
||||
{
|
||||
foreach ($this->_headers as $name => $val) {
|
||||
header($name . ': ' . $val);
|
||||
@@ -164,7 +164,7 @@ class HTTP_Encoder {
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function sendAll()
|
||||
public function sendAll()
|
||||
{
|
||||
$this->sendHeaders();
|
||||
echo $this->_content;
|
||||
@@ -181,16 +181,16 @@ class HTTP_Encoder {
|
||||
* be non 0. The methods are favored in order of gzip, deflate, then
|
||||
* compress. Deflate is always smallest and generally faster, but is
|
||||
* rarely sent by servers, so client support could be buggier.
|
||||
*
|
||||
*
|
||||
* @param bool $allowCompress allow the older compress encoding
|
||||
*
|
||||
* @param bool $allowDeflate allow the more recent deflate encoding
|
||||
* @param bool $allowDeflate allow the more recent deflate encoding
|
||||
*
|
||||
* @return array two values, 1st is the actual encoding method, 2nd is the
|
||||
* alias of that method to use in the Content-Encoding header (some browsers
|
||||
* call gzip "x-gzip" etc.)
|
||||
*/
|
||||
public static function getAcceptedEncoding($allowCompress = true, $allowDeflate = true)
|
||||
public static function getAcceptedEncoding($allowCompress = true, $allowDeflate = true)
|
||||
{
|
||||
// @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
|
||||
@@ -244,14 +244,14 @@ class HTTP_Encoder {
|
||||
* this fails, false is returned.
|
||||
*
|
||||
* The header "Vary: Accept-Encoding" is added. If encoding is successful,
|
||||
* the Content-Length header is updated, and Content-Encoding is also added.
|
||||
*
|
||||
* the Content-Length header is updated, and Content-Encoding is also added.
|
||||
*
|
||||
* @param int $compressionLevel given to zlib functions. If not given, the
|
||||
* class default will be used.
|
||||
*
|
||||
* @return bool success true if the content was actually compressed
|
||||
*/
|
||||
public function encode($compressionLevel = null)
|
||||
public function encode($compressionLevel = null)
|
||||
{
|
||||
$this->_headers['Vary'] = 'Accept-Encoding';
|
||||
if (null === $compressionLevel) {
|
||||
@@ -262,9 +262,9 @@ class HTTP_Encoder {
|
||||
|| !extension_loaded('zlib'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ($this->_encodeMethod[0] === 'deflate') {
|
||||
$encoded = gzdeflate($this->_content, $compressionLevel);
|
||||
}
|
||||
if ($this->_encodeMethod[0] === 'deflate') {
|
||||
$encoded = gzdeflate($this->_content, $compressionLevel);
|
||||
} elseif ($this->_encodeMethod[0] === 'gzip') {
|
||||
$encoded = gzencode($this->_content, $compressionLevel);
|
||||
} else {
|
||||
@@ -285,7 +285,7 @@ class HTTP_Encoder {
|
||||
* This is a convenience method for common use of the class
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
*
|
||||
* @param int $compressionLevel given to zlib functions. If not given, the
|
||||
* class default will be used.
|
||||
*
|
||||
@@ -296,12 +296,12 @@ class HTTP_Encoder {
|
||||
if (null === $compressionLevel) {
|
||||
$compressionLevel = self::$compressionLevel;
|
||||
}
|
||||
$he = new HTTP_Encoder(array('content' => $content));
|
||||
$ret = $he->encode($compressionLevel);
|
||||
$he = new HTTP_Encoder(array('content' => $content));
|
||||
$ret = $he->encode($compressionLevel);
|
||||
$he->sendAll();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected $_content = '';
|
||||
protected $_headers = array();
|
||||
protected $_encodeMethod = array('', '');
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -512,7 +512,7 @@ class Minify {
|
||||
{
|
||||
if (self::$_options['bubbleCssImports']) {
|
||||
// bubble CSS imports
|
||||
preg_match_all('/@import.*?;/', $css, $imports);
|
||||
preg_match_all('/@import.*?;/', $css, $imports);
|
||||
$css = implode('', $imports[0]) . preg_replace('/@import.*?;/', '', $css);
|
||||
} else if ('' !== self::$importWarning) {
|
||||
// remove comments so we don't mistake { in a comment as a block
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Minify_CSS
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
/**
|
||||
* Minify CSS
|
||||
*
|
||||
* This class uses Minify_CSS_Compressor and Minify_CSS_UriRewriter to
|
||||
* minify CSS and rewrite relative URIs.
|
||||
*
|
||||
* @package Minify
|
||||
* @author Stephen Clay <steve@mrclay.org>
|
||||
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
||||
*/
|
||||
class Minify_CSS {
|
||||
|
||||
/**
|
||||
* Minify a CSS string
|
||||
*
|
||||
* @param string $css
|
||||
*
|
||||
* @param array $options available options:
|
||||
*
|
||||
* 'preserveComments': (default true) multi-line comments that begin
|
||||
* with "/*!" will be preserved with newlines before and after to
|
||||
* enhance readability.
|
||||
*
|
||||
* 'prependRelativePath': (default null) if given, this string will be
|
||||
* prepended to all relative URIs in import/url declarations
|
||||
*
|
||||
* 'currentDir': (default null) if given, this is assumed to be the
|
||||
* directory of the current CSS file. Using this, minify will rewrite
|
||||
* all relative URIs in import/url declarations to correctly point to
|
||||
* the desired files. For this to work, the files *must* exist and be
|
||||
* visible by the PHP process.
|
||||
*
|
||||
<?php
|
||||
/**
|
||||
* Class Minify_CSS
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
/**
|
||||
* Minify CSS
|
||||
*
|
||||
* This class uses Minify_CSS_Compressor and Minify_CSS_UriRewriter to
|
||||
* minify CSS and rewrite relative URIs.
|
||||
*
|
||||
* @package Minify
|
||||
* @author Stephen Clay <steve@mrclay.org>
|
||||
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
||||
*/
|
||||
class Minify_CSS {
|
||||
|
||||
/**
|
||||
* Minify a CSS string
|
||||
*
|
||||
* @param string $css
|
||||
*
|
||||
* @param array $options available options:
|
||||
*
|
||||
* 'preserveComments': (default true) multi-line comments that begin
|
||||
* with "/*!" will be preserved with newlines before and after to
|
||||
* enhance readability.
|
||||
*
|
||||
* 'prependRelativePath': (default null) if given, this string will be
|
||||
* prepended to all relative URIs in import/url declarations
|
||||
*
|
||||
* 'currentDir': (default null) if given, this is assumed to be the
|
||||
* directory of the current CSS file. Using this, minify will rewrite
|
||||
* all relative URIs in import/url declarations to correctly point to
|
||||
* the desired files. For this to work, the files *must* exist and be
|
||||
* visible by the PHP process.
|
||||
*
|
||||
* 'symlinks': (default = array()) If the CSS file is stored in
|
||||
* a symlink-ed directory, provide an array of link paths to
|
||||
* target paths, where the link paths are within the document root. Because
|
||||
@@ -44,40 +44,40 @@ class Minify_CSS {
|
||||
* <code>
|
||||
* array('//symlink' => '/real/target/path') // unix
|
||||
* array('//static' => 'D:\\staticStorage') // Windows
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function minify($css, $options = array())
|
||||
{
|
||||
require_once 'Minify/CSS/Compressor.php';/*noLibHook*/
|
||||
if (isset($options['preserveComments'])
|
||||
&& !$options['preserveComments']) {
|
||||
$css = Minify_CSS_Compressor::process($css, $options);
|
||||
} else {
|
||||
require_once 'Minify/CommentPreserver.php';/*noLibHook*/
|
||||
$css = Minify_CommentPreserver::process(
|
||||
$css
|
||||
,array('Minify_CSS_Compressor', 'process')
|
||||
,array($options)
|
||||
);
|
||||
}
|
||||
if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
|
||||
return $css;
|
||||
}
|
||||
require_once 'Minify/CSS/UriRewriter.php';/*noLibHook*/
|
||||
if (isset($options['currentDir'])) {
|
||||
return Minify_CSS_UriRewriter::rewrite(
|
||||
$css
|
||||
,$options['currentDir']
|
||||
,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
|
||||
,isset($options['symlinks']) ? $options['symlinks'] : array()
|
||||
);
|
||||
} else {
|
||||
return Minify_CSS_UriRewriter::prepend(
|
||||
$css
|
||||
,$options['prependRelativePath']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function minify($css, $options = array())
|
||||
{
|
||||
require_once 'Minify/CSS/Compressor.php';/*noLibHook*/
|
||||
if (isset($options['preserveComments'])
|
||||
&& !$options['preserveComments']) {
|
||||
$css = Minify_CSS_Compressor::process($css, $options);
|
||||
} else {
|
||||
require_once 'Minify/CommentPreserver.php';/*noLibHook*/
|
||||
$css = Minify_CommentPreserver::process(
|
||||
$css
|
||||
,array('Minify_CSS_Compressor', 'process')
|
||||
,array($options)
|
||||
);
|
||||
}
|
||||
if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
|
||||
return $css;
|
||||
}
|
||||
require_once 'Minify/CSS/UriRewriter.php';/*noLibHook*/
|
||||
if (isset($options['currentDir'])) {
|
||||
return Minify_CSS_UriRewriter::rewrite(
|
||||
$css
|
||||
,$options['currentDir']
|
||||
,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
|
||||
,isset($options['symlinks']) ? $options['symlinks'] : array()
|
||||
);
|
||||
} else {
|
||||
return Minify_CSS_UriRewriter::prepend(
|
||||
$css
|
||||
,$options['prependRelativePath']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,250 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Minify_CSS_Compressor
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compress CSS
|
||||
*
|
||||
* This is a heavy regex-based removal of whitespace, unnecessary
|
||||
* comments and tokens, and some CSS value minimization, where practical.
|
||||
* Many steps have been taken to avoid breaking comment-based hacks,
|
||||
* including the ie5/mac filter (and its inversion), but expect tricky
|
||||
* hacks involving comment tokens in 'content' value strings to break
|
||||
* minimization badly. A test suite is available.
|
||||
*
|
||||
* @package Minify
|
||||
* @author Stephen Clay <steve@mrclay.org>
|
||||
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
||||
*/
|
||||
class Minify_CSS_Compressor {
|
||||
|
||||
/**
|
||||
* Minify a CSS string
|
||||
*
|
||||
* @param string $css
|
||||
*
|
||||
* @param array $options (currently ignored)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function process($css, $options = array())
|
||||
{
|
||||
$obj = new Minify_CSS_Compressor($options);
|
||||
return $obj->_process($css);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array options
|
||||
*/
|
||||
protected $_options = null;
|
||||
|
||||
/**
|
||||
* @var bool Are we "in" a hack?
|
||||
*
|
||||
* I.e. are some browsers targetted until the next comment?
|
||||
*/
|
||||
protected $_inHack = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options (currently ignored)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function __construct($options) {
|
||||
$this->_options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$m[1] = preg_replace('/
|
||||
\\s*
|
||||
(
|
||||
"[^"]+" # 1 = family in double qutoes
|
||||
|\'[^\']+\' # or 1 = family in single quotes
|
||||
|[\\w\\-]+ # or 1 = unquoted family
|
||||
)
|
||||
\\s*
|
||||
/x', '$1', $m[1]);
|
||||
return 'font-family:' . $m[1] . $m[2];
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Class Minify_CSS_Compressor
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compress CSS
|
||||
*
|
||||
* This is a heavy regex-based removal of whitespace, unnecessary
|
||||
* comments and tokens, and some CSS value minimization, where practical.
|
||||
* Many steps have been taken to avoid breaking comment-based hacks,
|
||||
* including the ie5/mac filter (and its inversion), but expect tricky
|
||||
* hacks involving comment tokens in 'content' value strings to break
|
||||
* minimization badly. A test suite is available.
|
||||
*
|
||||
* @package Minify
|
||||
* @author Stephen Clay <steve@mrclay.org>
|
||||
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
||||
*/
|
||||
class Minify_CSS_Compressor {
|
||||
|
||||
/**
|
||||
* Minify a CSS string
|
||||
*
|
||||
* @param string $css
|
||||
*
|
||||
* @param array $options (currently ignored)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function process($css, $options = array())
|
||||
{
|
||||
$obj = new Minify_CSS_Compressor($options);
|
||||
return $obj->_process($css);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array options
|
||||
*/
|
||||
protected $_options = null;
|
||||
|
||||
/**
|
||||
* @var bool Are we "in" a hack?
|
||||
*
|
||||
* I.e. are some browsers targetted until the next comment?
|
||||
*/
|
||||
protected $_inHack = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options (currently ignored)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private function __construct($options) {
|
||||
$this->_options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$m[1] = preg_replace('/
|
||||
\\s*
|
||||
(
|
||||
"[^"]+" # 1 = family in double qutoes
|
||||
|\'[^\']+\' # or 1 = family in single quotes
|
||||
|[\\w\\-]+ # or 1 = unquoted family
|
||||
)
|
||||
\\s*
|
||||
/x', '$1', $m[1]);
|
||||
return 'font-family:' . $m[1] . $m[2];
|
||||
}
|
||||
}
|
||||
@@ -118,9 +118,9 @@ class Minify_CSS_UriRewriter {
|
||||
*/
|
||||
private static $_docRoot = '';
|
||||
|
||||
/**
|
||||
* @var array directory replacements to map symlink targets back to their
|
||||
* source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
|
||||
/**
|
||||
* @var array directory replacements to map symlink targets back to their
|
||||
* source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
|
||||
*/
|
||||
private static $_symlinks = array();
|
||||
|
||||
@@ -219,16 +219,16 @@ class Minify_CSS_UriRewriter {
|
||||
self::$debugText .= "file-relative URI : {$uri}\n"
|
||||
. "path prepended : {$path}\n";
|
||||
|
||||
// "unresolve" a symlink back to doc root
|
||||
foreach ($symlinks as $link => $target) {
|
||||
if (0 === strpos($path, $target)) {
|
||||
// replace $target with $link
|
||||
// "unresolve" a symlink back to doc root
|
||||
foreach ($symlinks as $link => $target) {
|
||||
if (0 === strpos($path, $target)) {
|
||||
// replace $target with $link
|
||||
$path = $link . substr($path, strlen($target));
|
||||
|
||||
self::$debugText .= "symlink unresolved : {$path}\n";
|
||||
self::$debugText .= "symlink unresolved : {$path}\n";
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// strip doc root
|
||||
$path = substr($path, strlen($realDocRoot));
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,7 +11,7 @@ class Minify_Cache_File {
|
||||
if (! $path) {
|
||||
require_once 'Solar/Dir.php';/*noLibHook*/
|
||||
$path = rtrim(Solar_Dir::tmp(), DIRECTORY_SEPARATOR);
|
||||
}
|
||||
}
|
||||
$this->_locking = $fileLocking;
|
||||
$this->_path = $path;
|
||||
}
|
||||
@@ -27,20 +27,20 @@ class Minify_Cache_File {
|
||||
*/
|
||||
public function store($id, $data)
|
||||
{
|
||||
$flag = $this->_locking
|
||||
? LOCK_EX
|
||||
: null;
|
||||
if (is_file($this->_path . '/' . $id)) {
|
||||
@unlink($this->_path . '/' . $id);
|
||||
}
|
||||
if (! @file_put_contents($this->_path . '/' . $id, $data, $flag)) {
|
||||
return false;
|
||||
}
|
||||
// write control
|
||||
if ($data !== $this->fetch($id)) {
|
||||
@unlink($file);
|
||||
return false;
|
||||
$flag = $this->_locking
|
||||
? LOCK_EX
|
||||
: null;
|
||||
if (is_file($this->_path . '/' . $id)) {
|
||||
@unlink($this->_path . '/' . $id);
|
||||
}
|
||||
if (! @file_put_contents($this->_path . '/' . $id, $data, $flag)) {
|
||||
return false;
|
||||
}
|
||||
// write control
|
||||
if ($data !== $this->fetch($id)) {
|
||||
@unlink($file);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,15 +78,15 @@ class Minify_Cache_File {
|
||||
*/
|
||||
public function display($id)
|
||||
{
|
||||
if ($this->_locking) {
|
||||
$fp = fopen($this->_path . '/' . $id, 'rb');
|
||||
flock($fp, LOCK_SH);
|
||||
fpassthru($fp);
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
} else {
|
||||
readfile($this->_path . '/' . $id);
|
||||
}
|
||||
if ($this->_locking) {
|
||||
$fp = fopen($this->_path . '/' . $id, 'rb');
|
||||
flock($fp, LOCK_SH);
|
||||
fpassthru($fp);
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
} else {
|
||||
readfile($this->_path . '/' . $id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,15 +98,15 @@ class Minify_Cache_File {
|
||||
*/
|
||||
public function fetch($id)
|
||||
{
|
||||
if ($this->_locking) {
|
||||
$fp = fopen($this->_path . '/' . $id, 'rb');
|
||||
flock($fp, LOCK_SH);
|
||||
$ret = stream_get_contents($fp);
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
return $ret;
|
||||
} else {
|
||||
return file_get_contents($this->_path . '/' . $id);
|
||||
if ($this->_locking) {
|
||||
$fp = fopen($this->_path . '/' . $id, 'rb');
|
||||
flock($fp, LOCK_SH);
|
||||
$ret = stream_get_contents($fp);
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
return $ret;
|
||||
} else {
|
||||
return file_get_contents($this->_path . '/' . $id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,5 +121,5 @@ class Minify_Cache_File {
|
||||
}
|
||||
|
||||
private $_path = null;
|
||||
private $_locking = null;
|
||||
private $_locking = null;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -26,9 +26,9 @@ class Minify_Lines {
|
||||
*
|
||||
* 'id': (optional) string to identify file. E.g. file name/path
|
||||
*
|
||||
* 'currentDir': (default null) if given, this is assumed to be the
|
||||
* directory of the current CSS file. Using this, minify will rewrite
|
||||
* all relative URIs in import/url declarations to correctly point to
|
||||
* 'currentDir': (default null) if given, this is assumed to be the
|
||||
* directory of the current CSS file. Using this, minify will rewrite
|
||||
* all relative URIs in import/url declarations to correctly point to
|
||||
* the desired files, and prepend a comment with debugging information about
|
||||
* this process.
|
||||
*
|
||||
@@ -64,7 +64,7 @@ class Minify_Lines {
|
||||
$content = Minify_CSS_UriRewriter::rewrite(
|
||||
$content
|
||||
,$options['currentDir']
|
||||
,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
|
||||
,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
|
||||
,isset($options['symlinks']) ? $options['symlinks'] : array()
|
||||
);
|
||||
$content = "/* Minify_CSS_UriRewriter::\$debugText\n\n"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
+289
-289
@@ -1,289 +1,289 @@
|
||||
<?php
|
||||
/**
|
||||
* MyMin - JSMin like alternative parser for JavaScript
|
||||
*
|
||||
* This class is a jsmin alternative, based on same parser logic but modified
|
||||
* to mantain performances and to parse correctly JavaScript conditional comments too.
|
||||
*
|
||||
* SERVER SIDE
|
||||
* PHP 5 or greater is required.
|
||||
* This code is compatible with every error_reporting level (E_ALL | E_STRICT)
|
||||
* The best practice to use this code is caching results without run-time
|
||||
* evaluation (your server should be stressed too much with big files)
|
||||
*
|
||||
* Permission is hereby granted to use this version of the library under the
|
||||
* same terms as jsmin.php, which has the following license:
|
||||
*
|
||||
* --
|
||||
* Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* The Software shall be used for Good, not Evil.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
* --
|
||||
*
|
||||
* @class MyMin
|
||||
* @author Andrea Giammarchi <http://www.3site.eu>
|
||||
* @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
|
||||
* @copyright 2007 Ryan Grove <ryan@wonko.com> (PHP port)
|
||||
* @copyright 2007 Andrea Giammarchi (improvements + MyMinCompressor + MyMinCSS)
|
||||
* @license http://opensource.org/licenses/mit-license.php MIT License
|
||||
* @version 1.0.1 (2007-10-05) - updated 2008-02-17
|
||||
*/
|
||||
|
||||
// -- Class MyMin --------------------------------------------------------------
|
||||
class MyMin {
|
||||
|
||||
const /* char */ LF = "\n",
|
||||
SPACE = ' ',
|
||||
EOS = "\x00";
|
||||
|
||||
protected /* boolean */ $cc_on;
|
||||
|
||||
protected /* char */ $a,
|
||||
$ahead,
|
||||
$b;
|
||||
|
||||
protected /* int */ $index = 0,
|
||||
$length;
|
||||
|
||||
protected /* string */ $input,
|
||||
$output = "";
|
||||
|
||||
// -- Public Static Methods ----------------------------------------------------
|
||||
static public final function /* string */ parse(/* string */ $input, /* boolean */ $cc_on = true){
|
||||
return "".(new MyMin($input, $cc_on));
|
||||
}
|
||||
|
||||
// -- Public Instance Methods --------------------------------------------------
|
||||
public final function /* object */ __construct(/* string */ $input, /* boolean */ $cc_on = true){
|
||||
$this->input = preg_replace("/(\r\n|\n\r|\r|\n)+/", self::LF, trim($input));
|
||||
$this->length = strlen($this->input);
|
||||
$this->cc_on = $cc_on;
|
||||
$this->b = $this->ahead = self::SPACE;
|
||||
$this->a = self::LF;
|
||||
$this->action(3);
|
||||
while($this->a !== self::EOS){
|
||||
switch($this->a){
|
||||
case self::SPACE:
|
||||
$this->action($this->isAlNum($this->b) ? 1 : 2);
|
||||
break;
|
||||
case self::LF:
|
||||
switch($this->b){
|
||||
case '{':
|
||||
case '[':
|
||||
case '(':
|
||||
case '+':
|
||||
case '-':
|
||||
$this->action(1);
|
||||
break;
|
||||
case self::SPACE:
|
||||
$this->action(3);
|
||||
break;
|
||||
default:
|
||||
$this->action($this->isAlNum($this->b) ? 1 : 2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch($this->b){
|
||||
case self::SPACE:
|
||||
$this->action($this->isAlNum($this->a) ? 1 : 3);
|
||||
break;
|
||||
case self::LF:
|
||||
switch($this->a){
|
||||
case '}':
|
||||
case ']':
|
||||
case ')':
|
||||
case '+':
|
||||
case '-':
|
||||
case '"':
|
||||
case '\'':
|
||||
$this->action(1);
|
||||
break;
|
||||
default:
|
||||
$this->action($this->isAlNum($this->a) ? 1 : 3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->action(1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final function /* string */ __toString(/* void */){
|
||||
return str_replace("\n\n", "\n", ltrim($this->output));
|
||||
}
|
||||
|
||||
// -- Protected Instance Methods -----------------------------------------------
|
||||
protected function /* void */ action(/* int */ $i){
|
||||
switch($i){
|
||||
case 1:
|
||||
$this->output .= $this->a;
|
||||
case 2:
|
||||
$this->a = $this->b;
|
||||
if($this->a === '\'' || $this->a === '"'){
|
||||
while(true){
|
||||
$this->output .= $this->a;
|
||||
if(!$this->nextCharNoSlash($this->b, "Unterminated string literal."))
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
$this->b = $this->next();
|
||||
if($this->b === '/'){
|
||||
switch($this->a){
|
||||
case self::LF:
|
||||
case self::SPACE:
|
||||
if(!$this->spaceBeforeRegExp($this->output))
|
||||
break;
|
||||
|
||||
case '{':
|
||||
case ';':
|
||||
|
||||
case '(':
|
||||
case ',':
|
||||
case '=':
|
||||
case ':':
|
||||
case '[':
|
||||
case '!':
|
||||
case '&':
|
||||
case '|':
|
||||
case '?':
|
||||
$this->output .= $this->a.$this->b;
|
||||
while($this->nextCharNoSlash('/', "Unterminated regular expression literal."))
|
||||
$this->output .= $this->a;
|
||||
$this->b = $this->next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function /* void */ appendComment(/* int */ $pos, /* string */ $open, /* string */ $close) {
|
||||
$this->output .= $this->a.$open.(new MyMin(substr($this->input, $this->index, $pos - $this->index), $this->cc_on)).$close;
|
||||
$this->index = $pos;
|
||||
$this->a = self::LF;
|
||||
}
|
||||
|
||||
protected function /* void */ conditionalComment(/* char */ $find) {
|
||||
$single = $find === self::LF;
|
||||
$pos = strpos($this->input, $find, $this->index);
|
||||
if($pos === false){
|
||||
if($single)
|
||||
$pos = $this->length;
|
||||
else
|
||||
throw new MyMinException("Unterminated comment.");
|
||||
}
|
||||
$this->appendComment($pos, $single ? "//" : "/*", $find);
|
||||
}
|
||||
|
||||
protected function /* char */ get(/* void */) {
|
||||
$c = $this->ahead;
|
||||
$this->ahead = self::EOS;
|
||||
if($c === self::EOS && $this->index < $this->length)
|
||||
$c = $this->input{$this->index++};
|
||||
return ($c === self::EOS || $c === self::LF || $c >= self::SPACE) ? $c : self::SPACE;
|
||||
}
|
||||
|
||||
protected function /* boolean */ isAlNum(/* char */ $c) {
|
||||
return $c > 126 || $c === '\\' || preg_match('/^(\w|\$)$/', $c);
|
||||
}
|
||||
|
||||
protected function /* char */ next(/* void */) {
|
||||
$c = $this->get();
|
||||
$loop = true;
|
||||
if($c === '/'){
|
||||
switch($this->ahead = $this->get()){
|
||||
case '/':
|
||||
if($this->cc_on && $this->input{$this->index} === '@')
|
||||
$this->conditionalComment(self::LF);
|
||||
while($loop){
|
||||
$c = $this->get();
|
||||
if($c <= self::LF)
|
||||
$loop = false;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
$this->get();
|
||||
if($this->cc_on && $this->input{$this->index} === '@')
|
||||
$this->conditionalComment("*/");
|
||||
while($loop){
|
||||
switch($this->get()){
|
||||
case '*':
|
||||
if(($this->ahead = $this->get()) === '/'){
|
||||
$this->get();
|
||||
$c = self::SPACE;
|
||||
$loop = false;
|
||||
}
|
||||
break;
|
||||
case self::EOS:
|
||||
throw new MyMinException("Unterminated comment.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
protected function /* boolean */ nextCharNoSlash(/* char */ $c, /* string */ $message) {
|
||||
$loop = true;
|
||||
$this->a = $this->get();
|
||||
if($this->a === $c)
|
||||
$loop = false;
|
||||
else{
|
||||
if($this->a === '\\'){
|
||||
$this->output .= $this->a;
|
||||
$this->a = $this->get();
|
||||
}
|
||||
if($this->a <= self::LF)
|
||||
throw new MyMinException($message);
|
||||
}
|
||||
return $loop;
|
||||
}
|
||||
|
||||
protected function /* boolean */ spaceBeforeRegExp(/* string */ $output){
|
||||
for(
|
||||
$i = 0,
|
||||
$length = strlen($output),
|
||||
$reserved = array("case", "else", "in", "return", "typeof"),
|
||||
$result = false,
|
||||
$tmp = "";
|
||||
$i < 5 && !$result;
|
||||
$i++
|
||||
){
|
||||
if($length === strlen($reserved[$i]))
|
||||
$result = $reserved[$i] === $output;
|
||||
else if($length > strlen($reserved[$i])){
|
||||
$tmp = substr($output, $length - strlen($reserved[$i]) - 1);
|
||||
$result = substr($tmp, 1) === $reserved[$i] && !$this->isAlNum($tmp{0});
|
||||
}
|
||||
};
|
||||
return $length < 2 ? true : $result;
|
||||
}
|
||||
}
|
||||
|
||||
// -- MyMin Exceptions ---------------------------------------------------------
|
||||
class MyMinException extends Exception {}
|
||||
<?php
|
||||
/**
|
||||
* MyMin - JSMin like alternative parser for JavaScript
|
||||
*
|
||||
* This class is a jsmin alternative, based on same parser logic but modified
|
||||
* to mantain performances and to parse correctly JavaScript conditional comments too.
|
||||
*
|
||||
* SERVER SIDE
|
||||
* PHP 5 or greater is required.
|
||||
* This code is compatible with every error_reporting level (E_ALL | E_STRICT)
|
||||
* The best practice to use this code is caching results without run-time
|
||||
* evaluation (your server should be stressed too much with big files)
|
||||
*
|
||||
* Permission is hereby granted to use this version of the library under the
|
||||
* same terms as jsmin.php, which has the following license:
|
||||
*
|
||||
* --
|
||||
* Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* The Software shall be used for Good, not Evil.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
* --
|
||||
*
|
||||
* @class MyMin
|
||||
* @author Andrea Giammarchi <http://www.3site.eu>
|
||||
* @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
|
||||
* @copyright 2007 Ryan Grove <ryan@wonko.com> (PHP port)
|
||||
* @copyright 2007 Andrea Giammarchi (improvements + MyMinCompressor + MyMinCSS)
|
||||
* @license http://opensource.org/licenses/mit-license.php MIT License
|
||||
* @version 1.0.1 (2007-10-05) - updated 2008-02-17
|
||||
*/
|
||||
|
||||
// -- Class MyMin --------------------------------------------------------------
|
||||
class MyMin {
|
||||
|
||||
const /* char */ LF = "\n",
|
||||
SPACE = ' ',
|
||||
EOS = "\x00";
|
||||
|
||||
protected /* boolean */ $cc_on;
|
||||
|
||||
protected /* char */ $a,
|
||||
$ahead,
|
||||
$b;
|
||||
|
||||
protected /* int */ $index = 0,
|
||||
$length;
|
||||
|
||||
protected /* string */ $input,
|
||||
$output = "";
|
||||
|
||||
// -- Public Static Methods ----------------------------------------------------
|
||||
static public final function /* string */ parse(/* string */ $input, /* boolean */ $cc_on = true){
|
||||
return "".(new MyMin($input, $cc_on));
|
||||
}
|
||||
|
||||
// -- Public Instance Methods --------------------------------------------------
|
||||
public final function /* object */ __construct(/* string */ $input, /* boolean */ $cc_on = true){
|
||||
$this->input = preg_replace("/(\r\n|\n\r|\r|\n)+/", self::LF, trim($input));
|
||||
$this->length = strlen($this->input);
|
||||
$this->cc_on = $cc_on;
|
||||
$this->b = $this->ahead = self::SPACE;
|
||||
$this->a = self::LF;
|
||||
$this->action(3);
|
||||
while($this->a !== self::EOS){
|
||||
switch($this->a){
|
||||
case self::SPACE:
|
||||
$this->action($this->isAlNum($this->b) ? 1 : 2);
|
||||
break;
|
||||
case self::LF:
|
||||
switch($this->b){
|
||||
case '{':
|
||||
case '[':
|
||||
case '(':
|
||||
case '+':
|
||||
case '-':
|
||||
$this->action(1);
|
||||
break;
|
||||
case self::SPACE:
|
||||
$this->action(3);
|
||||
break;
|
||||
default:
|
||||
$this->action($this->isAlNum($this->b) ? 1 : 2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch($this->b){
|
||||
case self::SPACE:
|
||||
$this->action($this->isAlNum($this->a) ? 1 : 3);
|
||||
break;
|
||||
case self::LF:
|
||||
switch($this->a){
|
||||
case '}':
|
||||
case ']':
|
||||
case ')':
|
||||
case '+':
|
||||
case '-':
|
||||
case '"':
|
||||
case '\'':
|
||||
$this->action(1);
|
||||
break;
|
||||
default:
|
||||
$this->action($this->isAlNum($this->a) ? 1 : 3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->action(1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final function /* string */ __toString(/* void */){
|
||||
return str_replace("\n\n", "\n", ltrim($this->output));
|
||||
}
|
||||
|
||||
// -- Protected Instance Methods -----------------------------------------------
|
||||
protected function /* void */ action(/* int */ $i){
|
||||
switch($i){
|
||||
case 1:
|
||||
$this->output .= $this->a;
|
||||
case 2:
|
||||
$this->a = $this->b;
|
||||
if($this->a === '\'' || $this->a === '"'){
|
||||
while(true){
|
||||
$this->output .= $this->a;
|
||||
if(!$this->nextCharNoSlash($this->b, "Unterminated string literal."))
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
$this->b = $this->next();
|
||||
if($this->b === '/'){
|
||||
switch($this->a){
|
||||
case self::LF:
|
||||
case self::SPACE:
|
||||
if(!$this->spaceBeforeRegExp($this->output))
|
||||
break;
|
||||
|
||||
case '{':
|
||||
case ';':
|
||||
|
||||
case '(':
|
||||
case ',':
|
||||
case '=':
|
||||
case ':':
|
||||
case '[':
|
||||
case '!':
|
||||
case '&':
|
||||
case '|':
|
||||
case '?':
|
||||
$this->output .= $this->a.$this->b;
|
||||
while($this->nextCharNoSlash('/', "Unterminated regular expression literal."))
|
||||
$this->output .= $this->a;
|
||||
$this->b = $this->next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function /* void */ appendComment(/* int */ $pos, /* string */ $open, /* string */ $close) {
|
||||
$this->output .= $this->a.$open.(new MyMin(substr($this->input, $this->index, $pos - $this->index), $this->cc_on)).$close;
|
||||
$this->index = $pos;
|
||||
$this->a = self::LF;
|
||||
}
|
||||
|
||||
protected function /* void */ conditionalComment(/* char */ $find) {
|
||||
$single = $find === self::LF;
|
||||
$pos = strpos($this->input, $find, $this->index);
|
||||
if($pos === false){
|
||||
if($single)
|
||||
$pos = $this->length;
|
||||
else
|
||||
throw new MyMinException("Unterminated comment.");
|
||||
}
|
||||
$this->appendComment($pos, $single ? "//" : "/*", $find);
|
||||
}
|
||||
|
||||
protected function /* char */ get(/* void */) {
|
||||
$c = $this->ahead;
|
||||
$this->ahead = self::EOS;
|
||||
if($c === self::EOS && $this->index < $this->length)
|
||||
$c = $this->input{$this->index++};
|
||||
return ($c === self::EOS || $c === self::LF || $c >= self::SPACE) ? $c : self::SPACE;
|
||||
}
|
||||
|
||||
protected function /* boolean */ isAlNum(/* char */ $c) {
|
||||
return $c > 126 || $c === '\\' || preg_match('/^(\w|\$)$/', $c);
|
||||
}
|
||||
|
||||
protected function /* char */ next(/* void */) {
|
||||
$c = $this->get();
|
||||
$loop = true;
|
||||
if($c === '/'){
|
||||
switch($this->ahead = $this->get()){
|
||||
case '/':
|
||||
if($this->cc_on && $this->input{$this->index} === '@')
|
||||
$this->conditionalComment(self::LF);
|
||||
while($loop){
|
||||
$c = $this->get();
|
||||
if($c <= self::LF)
|
||||
$loop = false;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
$this->get();
|
||||
if($this->cc_on && $this->input{$this->index} === '@')
|
||||
$this->conditionalComment("*/");
|
||||
while($loop){
|
||||
switch($this->get()){
|
||||
case '*':
|
||||
if(($this->ahead = $this->get()) === '/'){
|
||||
$this->get();
|
||||
$c = self::SPACE;
|
||||
$loop = false;
|
||||
}
|
||||
break;
|
||||
case self::EOS:
|
||||
throw new MyMinException("Unterminated comment.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
protected function /* boolean */ nextCharNoSlash(/* char */ $c, /* string */ $message) {
|
||||
$loop = true;
|
||||
$this->a = $this->get();
|
||||
if($this->a === $c)
|
||||
$loop = false;
|
||||
else{
|
||||
if($this->a === '\\'){
|
||||
$this->output .= $this->a;
|
||||
$this->a = $this->get();
|
||||
}
|
||||
if($this->a <= self::LF)
|
||||
throw new MyMinException($message);
|
||||
}
|
||||
return $loop;
|
||||
}
|
||||
|
||||
protected function /* boolean */ spaceBeforeRegExp(/* string */ $output){
|
||||
for(
|
||||
$i = 0,
|
||||
$length = strlen($output),
|
||||
$reserved = array("case", "else", "in", "return", "typeof"),
|
||||
$result = false,
|
||||
$tmp = "";
|
||||
$i < 5 && !$result;
|
||||
$i++
|
||||
){
|
||||
if($length === strlen($reserved[$i]))
|
||||
$result = $reserved[$i] === $output;
|
||||
else if($length > strlen($reserved[$i])){
|
||||
$tmp = substr($output, $length - strlen($reserved[$i]) - 1);
|
||||
$result = substr($tmp, 1) === $reserved[$i] && !$this->isAlNum($tmp{0});
|
||||
}
|
||||
};
|
||||
return $length < 2 ? true : $result;
|
||||
}
|
||||
}
|
||||
|
||||
// -- MyMin Exceptions ---------------------------------------------------------
|
||||
class MyMinException extends Exception {}
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user