1
0
mirror of https://github.com/mrclay/minify.git synced 2025-08-13 09:34:54 +02:00

+ Minify/CommentPreserver.php w/ unit tests

CSS/UriRewriter.php : unit tests
Minify/ImportProcessor.php : unit tests (need JS tests)
Minify/CSS.php : refactoring using CommentPreserver.php
Minify/Javascript.php : refactoring using CommentPreserver.php
Minify/Lines.php : simplification
This commit is contained in:
Steve Clay
2008-09-01 21:19:59 +00:00
parent eebe132aed
commit a45e4a3d8d
13 changed files with 431 additions and 325 deletions

View File

@@ -47,44 +47,16 @@ class Minify_CSS {
&& !$options['preserveComments']) { && !$options['preserveComments']) {
return self::_minify($css, $options); return self::_minify($css, $options);
} }
$ret = ''; require_once 'Minify/CommentPreserver.php';
while (1) { // recursive calls don't preserve comments
list($beforeComment, $comment, $afterComment) $options['preserveComments'] = false;
= self::_nextYuiComment($css); return Minify_CommentPreserver::process(
$ret .= self::_minify($beforeComment, $options); $css
if (false === $comment) { ,array('Minify_CSS', 'minify')
break; ,array($options)
} );
$ret .= $comment;
$css = $afterComment;
}
return $ret;
} }
/**
* Extract comments that YUI Compressor preserves.
*
* @param string $in input
*
* @return array 3 elements are returned. If a YUI comment is found, the
* 2nd element is the comment and the 1st and 2nd are the surrounding
* strings. If no comment is found, the entire string is returned as the
* 1st element and the other two are false.
*/
private static function _nextYuiComment($in)
{
return (
(false !== ($start = strpos($in, '/*!')))
&& (false !== ($end = strpos($in, '*/', $start + 3)))
)
? array(
substr($in, 0, $start)
,"\n/*" . substr($in, $start + 3, $end - $start - 1) . "\n"
,substr($in, -(strlen($in) - $end - 2))
)
: array($in, false, false);
}
/** /**
* Minify a CSS string * Minify a CSS string
* *
@@ -113,9 +85,6 @@ class Minify_CSS {
$css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@' $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
,array('Minify_CSS', '_commentCB'), $css); ,array('Minify_CSS', '_commentCB'), $css);
// leave needed comments
$css = str_replace('/*keep*/', '/**/', $css);
// remove ws around { } and last semicolon in declaration block // remove ws around { } and last semicolon in declaration block
$css = preg_replace('/\\s*{\\s*/', '{', $css); $css = preg_replace('/\\s*{\\s*/', '{', $css);
$css = preg_replace('/;?\\s*}\\s*/', '}', $css); $css = preg_replace('/;?\\s*}\\s*/', '}', $css);
@@ -242,7 +211,7 @@ class Minify_CSS {
// $m is the comment content w/o the surrounding tokens, // $m is the comment content w/o the surrounding tokens,
// but the return value will replace the entire comment. // but the return value will replace the entire comment.
if ($m === 'keep') { if ($m === 'keep') {
return '/*keep*/'; return '/**/';
} }
if ($m === '" "') { if ($m === '" "') {
// component of http://tantek.com/CSS/Examples/midpass.html // component of http://tantek.com/CSS/Examples/midpass.html
@@ -263,7 +232,7 @@ class Minify_CSS {
@x', $m, $n)) { @x', $m, $n)) {
// end hack mode after this comment, but preserve the hack and comment content // end hack mode after this comment, but preserve the hack and comment content
self::$_inHack = false; self::$_inHack = false;
return "/*/{$n[1]}/*keep*/"; return "/*/{$n[1]}/**/";
} }
} }
if (substr($m, -1) === '\\') { // comment ends like \*/ if (substr($m, -1) === '\\') { // comment ends like \*/
@@ -279,7 +248,7 @@ class Minify_CSS {
if (self::$_inHack) { if (self::$_inHack) {
// a regular comment ends hack mode but should be preserved // a regular comment ends hack mode but should be preserved
self::$_inHack = false; self::$_inHack = false;
return '/*keep*/'; return '/**/';
} }
return ''; // remove all other comments return ''; // remove all other comments
} }

View File

@@ -7,7 +7,7 @@
/** /**
* Rewrite file-relative URIs as root-relative in CSS files * Rewrite file-relative URIs as root-relative in CSS files
* *
* @todo: unit tests, use in Minify_CSS and Minify_ImportProcessor * @todo: prepend() method
* *
* @package Minify * @package Minify
* @author Stephen Clay <steve@mrclay.org> * @author Stephen Clay <steve@mrclay.org>
@@ -55,14 +55,14 @@ class Minify_CSS_UriRewriter {
/** /**
* @var string directory of this stylesheet * @var string directory of this stylesheet
*/ */
protected static $_currentDir = ''; private static $_currentDir = '';
/** /**
* @var string DOC_ROOT * @var string DOC_ROOT
*/ */
protected static $_docRoot = ''; private static $_docRoot = '';
protected static function _uriCB($m) private static function _uriCB($m)
{ {
$isImport = ($m[0][0] === '@'); $isImport = ($m[0][0] === '@');
if ($isImport) { if ($isImport) {
@@ -90,7 +90,12 @@ class Minify_CSS_UriRewriter {
$path = substr($path, strlen(self::$_docRoot)); $path = substr($path, strlen(self::$_docRoot));
// fix to root-relative URI // fix to root-relative URI
$uri = strtr($path, DIRECTORY_SEPARATOR, '/'); $uri = strtr($path, DIRECTORY_SEPARATOR, '/');
// eat .
$uri = str_replace('/./', '/', $uri); $uri = str_replace('/./', '/', $uri);
// eat ..
while (preg_match('@/[^/\\.]+/\\.\\./@', $uri, $m)) {
$uri = str_replace($m[0], '/', $uri);
}
} }
} }
if ($isImport) { if ($isImport) {

View File

@@ -0,0 +1,90 @@
<?php
/**
* Class Minify_CommentPreserver
* @package Minify
*/
/**
* Process a string in pieces preserving C-style comments that begin with "/*!"
*
* @package Minify
* @author Stephen Clay <steve@mrclay.org>
*/
class Minify_CommentPreserver {
/**
* String to be prepended to each preserved comment
*
* @var string
*/
public static $prepend = "\n";
/**
* String to be appended to each preserved comment
*
* @var string
*/
public static $append = "\n";
/**
* Process a string outside of C-style comments that begin with "/*!"
*
* On each non-empty string outside these comments, the given processor
* function will be called. The first "!" will be removed from the
* preserved comments, and the comments will be surrounded by
* Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append.
*
* @param string $content
* @param callback $processor function
* @param array $args array of extra arguments to pass to the processor
* function (default = array())
* @return string
*/
public static function process($content, $processor, $args = array())
{
$ret = '';
while (true) {
list($beforeComment, $comment, $afterComment) = self::_nextComment($content);
if ('' !== $beforeComment) {
$callArgs = $args;
array_unshift($callArgs, $beforeComment);
$ret .= call_user_func_array($processor, $callArgs);
}
if (false === $comment) {
break;
}
$ret .= $comment;
$content = $afterComment;
}
return $ret;
}
/**
* Extract comments that YUI Compressor preserves.
*
* @param string $in input
*
* @return array 3 elements are returned. If a YUI comment is found, the
* 2nd element is the comment and the 1st and 2nd are the surrounding
* strings. If no comment is found, the entire string is returned as the
* 1st element and the other two are false.
*/
private static function _nextComment($in)
{
if (
false === ($start = strpos($in, '/*!'))
|| false === ($end = strpos($in, '*/', $start + 3))
) {
return array($in, false, false);
}
$ret = array(
substr($in, 0, $start)
,self::$prepend . '/*' . substr($in, $start + 3, $end - $start - 1) . self::$append
);
$endChars = (strlen($in) - $end - 2);
$ret[] = (0 === $endChars)
? ''
: substr($in, -$endChars);
return $ret;
}
}

View File

@@ -6,7 +6,11 @@
/** /**
* Linearize a CSS/JS file by including content specified by CSS import * Linearize a CSS/JS file by including content specified by CSS import
* declarations. In CSS files, relative URIs are fixed. * declarations. In CSS files, relative URIs are fixed.
*
* @imports will be processed regardless of where they appear in the source
* files; i.e. @imports commented out or in string content will still be
* processed!
* *
* @package Minify * @package Minify
* @author Stephen Clay <steve@mrclay.org> * @author Stephen Clay <steve@mrclay.org>

View File

@@ -33,42 +33,14 @@ class Minify_Javascript {
&& !$options['preserveComments']) { && !$options['preserveComments']) {
return trim(JSMin::minify($js)); return trim(JSMin::minify($js));
} }
$ret = ''; require_once 'Minify/CommentPreserver.php';
while (1) { // recursive calls don't preserve comments
list($beforeComment, $comment, $afterComment) $options['preserveComments'] = false;
= self::_nextYuiComment($js); return Minify_CommentPreserver::process(
$ret .= trim(JSMin::minify($beforeComment)); $js
if (false === $comment) { ,array('Minify_Javascript', 'minify')
break; ,array($options)
} );
$ret .= $comment;
$js = $afterComment;
}
return $ret;
}
/**
* Extract comments that YUI Compressor preserves.
*
* @param string $in input
*
* @return array 3 elements are returned. If a YUI comment is found, the
* 2nd element is the comment and the 1st and 2nd are the surrounding
* strings. If no comment is found, the entire string is returned as the
* 1st element and the other two are false.
*/
private static function _nextYuiComment($in)
{
return (
(false !== ($start = strpos($in, '/*!')))
&& (false !== ($end = strpos($in, '*/', $start + 3)))
)
? array(
substr($in, 0, $start)
,"\n/*" . substr($in, $start + 3, $end - $start - 1) . "\n"
,substr($in, -(strlen($in) - $end - 2))
)
: array($in, false, false);
} }
} }

View File

@@ -32,10 +32,8 @@ class Minify_Lines {
$id = (isset($options['id']) && $options['id']) $id = (isset($options['id']) && $options['id'])
? $options['id'] ? $options['id']
: ''; : '';
if (! $eol = self::_getEol($content)) { $content = str_replace("\r\n", "\n", $content);
return $content; $lines = explode("\n", $content);
}
$lines = explode($eol, $content);
$numLines = count($lines); $numLines = count($lines);
// determine left padding // determine left padding
$padTo = strlen($numLines); $padTo = strlen($numLines);
@@ -50,28 +48,7 @@ class Minify_Lines {
$newLines[] = self::_addNote($line, $i, $inComment, $padTo); $newLines[] = self::_addNote($line, $i, $inComment, $padTo);
$inComment = self::_eolInComment($line, $inComment); $inComment = self::_eolInComment($line, $inComment);
} }
return implode($eol, $newLines) . $eol; return implode("\n", $newLines) . "\n";
}
/**
* Determine EOL character sequence
*
* @param string $str file content
*
* @return string EOL char(s) or '' if no EOL could be found
*/
private static function _getEol($str)
{
$r = strpos($str, "\r");
$n = strpos($str, "\n");
if (false === $r && false === $n) {
return '';
}
return ($r !== false)
? ($n == ($r + 1)
? "\r\n"
: "\r")
: "\n";
} }
/** /**

View File

@@ -0,0 +1,10 @@
@import "/_test_files/css_uriRewriter/foo.css";
@import '/_test_files/css_uriRewriter/bar/foo.css' print;
@import '/css/foo.css'; /* abs, should not alter */
@import 'http://foo.com/css/foo.css'; /* abs, should not alter */
@import url(/_test_files/foo.css) tv, projection;
@import url("/css/foo.css"); /* abs, should not alter */
@import url(/css2/foo.css); /* abs, should not alter */
foo {background:url('/_test_files/css_uriRewriter/bar/foo.png')}
foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */
foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */

View File

@@ -0,0 +1,10 @@
@import "foo.css";
@import 'bar/foo.css' print;
@import '/css/foo.css'; /* abs, should not alter */
@import 'http://foo.com/css/foo.css'; /* abs, should not alter */
@import url(../foo.css) tv, projection;
@import url("/css/foo.css"); /* abs, should not alter */
@import url(/css2/foo.css); /* abs, should not alter */
foo {background:url('bar/foo.png')}
foo {background:url('http://foo.com/css/foo.css');} /* abs, should not alter */
foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */

View File

@@ -1,7 +1,7 @@
@media screen { @media screen {
/* some CSS to try to exercise things in general */ /* some CSS to try to exercise things in general */
@import url(/_3rd_party/minify/min_extras/unit_tests/_test_files/css/more.css);
body, td, th { body, td, th {
font-family: Verdana , "Bitstream Vera Sans" , sans-serif ; font-family: Verdana , "Bitstream Vera Sans" , sans-serif ;
@@ -30,19 +30,19 @@ h1 + p {
@media screen and (max-width: 2000px) { @media screen and (max-width: 2000px) {
#media-queries-2 { background-color: #0f0; } #media-queries-2 { background-color: #0f0; }
} }
@import url(http://example.com/hello.css);
adjacent foo { background: red url(/red.gif); } adjacent foo { background: red url(/red.gif); }
adjacent bar { background: url('%TEST_FILES_URI%/cssLinearizer/../green.gif') } adjacent bar { background: url('/_3rd_party/minify/min_extras/unit_tests/_test_files/importProcessor/../green.gif') }
} }
@media tv,projection { @media tv,projection {
/* */ /* @import url('/_3rd_party/minify/min_extras/unit_tests/_test_files/importProcessor/1/bad.css') bad; */
adjacent2 foo { background: red url(/red.gif); } adjacent2 foo { background: red url(/red.gif); }
adjacent2 bar { background: url('%TEST_FILES_URI%/cssLinearizer/1/../green.gif') } adjacent2 bar { background: url('/_3rd_party/minify/min_extras/unit_tests/_test_files/importProcessor/1/../green.gif') }
@import '../input.css';
tv foo { background: red url(/red.gif); } tv foo { background: red url(/red.gif); }
tv bar { background: url('%TEST_FILES_URI%/cssLinearizer/1/../green.gif') } tv bar { background: url('/_3rd_party/minify/min_extras/unit_tests/_test_files/importProcessor/1/../green.gif') }
} }
input foo { background: red url(/red.gif); } input foo { background: red url(/red.gif); }
input bar { background: url('%TEST_FILES_URI%/cssLinearizer/../green.gif') } input bar { background: url('/_3rd_party/minify/min_extras/unit_tests/_test_files/importProcessor/../green.gif') }

View File

@@ -1,210 +1,210 @@
/* email.js */ /* email.js */
/* 1 */ // http://mrclay.org/ /* 1 */ // http://mrclay.org/
/* 2 */ (function(){ /* 2 */ (function(){
/* 3 */ var /* 3 */ var
/* 4 */ reMailto = /^mailto:my_name_is_(\S+)_and_the_domain_is_(\S+)$/, /* 4 */ reMailto = /^mailto:my_name_is_(\S+)_and_the_domain_is_(\S+)$/,
/* 5 */ reRemoveTitleIf = /^my name is/, /* 5 */ reRemoveTitleIf = /^my name is/,
/* 6 */ oo = window.onload, /* 6 */ oo = window.onload,
/* 7 */ fixHrefs = function() { /* 7 */ fixHrefs = function() {
/* 8 */ var i = 0, l, m; /* 8 */ var i = 0, l, m;
/* 9 */ while (l = document.links[i++]) { /* 9 */ while (l = document.links[i++]) {
/* 10 */ // require phrase in href property /* 10 */ // require phrase in href property
/* 11 */ if (m = l.href.match(reMailto)) { /* 11 */ if (m = l.href.match(reMailto)) {
/* 12 */ l.href = 'mailto:' + m[1] + '@' + m[2]; /* 12 */ l.href = 'mailto:' + m[1] + '@' + m[2];
/* 13 */ if (reRemoveTitleIf.test(l.title)) { /* 13 */ if (reRemoveTitleIf.test(l.title)) {
/* 14 */ l.title = ''; /* 14 */ l.title = '';
/* 15 */ } /* 15 */ }
/* 16 */ } /* 16 */ }
/* 17 */ } /* 17 */ }
/* 18 */ }; /* 18 */ };
/* 19 */ // end var /* 19 */ // end var
/* 20 */ window.onload = function() { /* 20 */ window.onload = function() {
/* 21 */ oo && oo(); /* 21 */ oo && oo();
/* 22 */ fixHrefs(); /* 22 */ fixHrefs();
/* 23 */ }; /* 23 */ };
/* 24 */ })(); /* 24 */ })();
; ;
/* QueryString.js */ /* QueryString.js */
/* 1 */ var MrClay = window.MrClay || {}; /* 1 */ var MrClay = window.MrClay || {};
/* 2 */ /* 2 */
/* 3 */ /** /* 3 */ /**
/* 4 *| * Simplified access to/manipulation of the query string /* 4 *| * Simplified access to/manipulation of the query string
/* 5 *| * /* 5 *| *
/* 6 *| * Based on: http://adamv.com/dev/javascript/files/querystring.js /* 6 *| * Based on: http://adamv.com/dev/javascript/files/querystring.js
/* 7 *| * Design pattern: http://www.litotes.demon.co.uk/js_info/private_static.html#wConst /* 7 *| * Design pattern: http://www.litotes.demon.co.uk/js_info/private_static.html#wConst
/* 8 *| */ /* 8 *| */
/* 9 */ MrClay.QueryString = function(){ /* 9 */ MrClay.QueryString = function(){
/* 10 */ /** /* 10 */ /**
/* 11 *| * @static /* 11 *| * @static
/* 12 *| * @private /* 12 *| * @private
/* 13 *| */ /* 13 *| */
/* 14 */ var parse = function(str) { /* 14 */ var parse = function(str) {
/* 15 */ var assignments = str.split('&') /* 15 */ var assignments = str.split('&')
/* 16 */ ,obj = {} /* 16 */ ,obj = {}
/* 17 */ ,propValue; /* 17 */ ,propValue;
/* 18 */ for (var i = 0, l = assignments.length; i < l; ++i) { /* 18 */ for (var i = 0, l = assignments.length; i < l; ++i) {
/* 19 */ propValue = assignments[i].split('='); /* 19 */ propValue = assignments[i].split('=');
/* 20 */ if (propValue.length > 2 /* 20 */ if (propValue.length > 2
/* 21 */ || -1 != propValue[0].indexOf('+') /* 21 */ || -1 != propValue[0].indexOf('+')
/* 22 */ || propValue[0] == '' /* 22 */ || propValue[0] == ''
/* 23 */ ) { /* 23 */ ) {
/* 24 */ continue; /* 24 */ continue;
/* 25 */ } /* 25 */ }
/* 26 */ if (propValue.length == 1) { /* 26 */ if (propValue.length == 1) {
/* 27 */ propValue[1] = propValue[0]; /* 27 */ propValue[1] = propValue[0];
/* 28 */ } /* 28 */ }
/* 29 */ obj[unescape(propValue[0])] = unescape(propValue[1].replace(/\+/g, ' ')); /* 29 */ obj[unescape(propValue[0])] = unescape(propValue[1].replace(/\+/g, ' '));
/* 30 */ } /* 30 */ }
/* 31 */ return obj; /* 31 */ return obj;
/* 32 */ }; /* 32 */ };
/* 33 */ /* 33 */
/* 34 */ /** /* 34 */ /**
/* 35 *| * Constructor (MrClay.QueryString becomes this) /* 35 *| * Constructor (MrClay.QueryString becomes this)
/* 36 *| * /* 36 *| *
/* 37 *| * @param mixed A window object, a query string, or empty (default current window) /* 37 *| * @param mixed A window object, a query string, or empty (default current window)
/* 38 *| */ /* 38 *| */
/* 39 */ function construct_(spec) { /* 39 */ function construct_(spec) {
/* 40 */ spec = spec || window; /* 40 */ spec = spec || window;
/* 41 */ if (typeof spec == 'object') { /* 41 */ if (typeof spec == 'object') {
/* 42 */ // get querystring from window /* 42 */ // get querystring from window
/* 43 */ this.window = spec; /* 43 */ this.window = spec;
/* 44 */ spec = spec.location.search.substr(1); /* 44 */ spec = spec.location.search.substr(1);
/* 45 */ } else { /* 45 */ } else {
/* 46 */ this.window = window; /* 46 */ this.window = window;
/* 47 */ } /* 47 */ }
/* 48 */ this.vars = parse(spec); /* 48 */ this.vars = parse(spec);
/* 49 */ } /* 49 */ }
/* 50 */ /* 50 */
/* QueryString.js */ /* QueryString.js */
/* 51 */ /** /* 51 */ /**
/* 52 *| * Reload the window /* 52 *| * Reload the window
/* 53 *| * /* 53 *| *
/* 54 *| * @static /* 54 *| * @static
/* 55 *| * @public /* 55 *| * @public
/* 56 *| * @param object vars Specify querystring vars only if you wish to replace them /* 56 *| * @param object vars Specify querystring vars only if you wish to replace them
/* 57 *| * @param object window_ window to be reloaded (current window by default) /* 57 *| * @param object window_ window to be reloaded (current window by default)
/* 58 *| */ /* 58 *| */
/* 59 */ construct_.reload = function(vars, window_) { /* 59 */ construct_.reload = function(vars, window_) {
/* 60 */ window_ = window_ || window; /* 60 */ window_ = window_ || window;
/* 61 */ vars = vars || (new MrClay.QueryString(window_)).vars; /* 61 */ vars = vars || (new MrClay.QueryString(window_)).vars;
/* 62 */ var l = window_.location /* 62 */ var l = window_.location
/* 63 */ ,currUrl = l.href /* 63 */ ,currUrl = l.href
/* 64 */ ,s = MrClay.QueryString.toString(vars) /* 64 */ ,s = MrClay.QueryString.toString(vars)
/* 65 */ ,newUrl = l.protocol + '//' + l.hostname + l.pathname /* 65 */ ,newUrl = l.protocol + '//' + l.hostname + l.pathname
/* 66 */ + (s ? '?' + s : '') + l.hash; /* 66 */ + (s ? '?' + s : '') + l.hash;
/* 67 */ if (currUrl == newUrl) { /* 67 */ if (currUrl == newUrl) {
/* 68 */ l.reload(); /* 68 */ l.reload();
/* 69 */ } else { /* 69 */ } else {
/* 70 */ l.assign(newUrl); /* 70 */ l.assign(newUrl);
/* 71 */ } /* 71 */ }
/* 72 */ }; /* 72 */ };
/* 73 */ /* 73 */
/* 74 */ /** /* 74 */ /**
/* 75 *| * Get the value of a querystring var /* 75 *| * Get the value of a querystring var
/* 76 *| * /* 76 *| *
/* 77 *| * @static /* 77 *| * @static
/* 78 *| * @public /* 78 *| * @public
/* 79 *| * @param string key /* 79 *| * @param string key
/* 80 *| * @param mixed default_ value to return if key not found /* 80 *| * @param mixed default_ value to return if key not found
/* 81 *| * @param object window_ window to check (current window by default) /* 81 *| * @param object window_ window to check (current window by default)
/* 82 *| * @return mixed /* 82 *| * @return mixed
/* 83 *| */ /* 83 *| */
/* 84 */ construct_.get = function(key, default_, window_) { /* 84 */ construct_.get = function(key, default_, window_) {
/* 85 */ window_ = window_ || window; /* 85 */ window_ = window_ || window;
/* 86 */ return (new MrClay.QueryString(window_)).get(key, default_); /* 86 */ return (new MrClay.QueryString(window_)).get(key, default_);
/* 87 */ }; /* 87 */ };
/* 88 */ /* 88 */
/* 89 */ /** /* 89 */ /**
/* 90 *| * Reload the page setting one or multiple querystring vars /* 90 *| * Reload the page setting one or multiple querystring vars
/* 91 *| * /* 91 *| *
/* 92 *| * @static /* 92 *| * @static
/* 93 *| * @public /* 93 *| * @public
/* 94 *| * @param mixed key object of query vars/values, or a string key for a single /* 94 *| * @param mixed key object of query vars/values, or a string key for a single
/* 95 *| * assignment /* 95 *| * assignment
/* 96 *| * @param mixed null for multiple settings, the value to assign for single /* 96 *| * @param mixed null for multiple settings, the value to assign for single
/* 97 *| * @param object window_ window to reload (current window by default) /* 97 *| * @param object window_ window to reload (current window by default)
/* 98 *| */ /* 98 *| */
/* 99 */ construct_.set = function(key, value, window_) { /* 99 */ construct_.set = function(key, value, window_) {
/* 100 */ window_ = window_ || window; /* 100 */ window_ = window_ || window;
/* QueryString.js */ /* QueryString.js */
/* 101 */ (new MrClay.QueryString(window_)).set(key, value).reload(); /* 101 */ (new MrClay.QueryString(window_)).set(key, value).reload();
/* 102 */ }; /* 102 */ };
/* 103 */ /* 103 */
/* 104 */ /** /* 104 */ /**
/* 105 *| * Convert an object of query vars/values to a querystring /* 105 *| * Convert an object of query vars/values to a querystring
/* 106 *| * /* 106 *| *
/* 107 *| * @static /* 107 *| * @static
/* 108 *| * @public /* 108 *| * @public
/* 109 *| * @param object query vars/values /* 109 *| * @param object query vars/values
/* 110 *| * @return string /* 110 *| * @return string
/* 111 *| */ /* 111 *| */
/* 112 */ construct_.toString = function(vars) { /* 112 */ construct_.toString = function(vars) {
/* 113 */ var pieces = []; /* 113 */ var pieces = [];
/* 114 */ for (var prop in vars) { /* 114 */ for (var prop in vars) {
/* 115 */ pieces.push(escape(prop) + '=' + escape(vars[prop])); /* 115 */ pieces.push(escape(prop) + '=' + escape(vars[prop]));
/* 116 */ } /* 116 */ }
/* 117 */ return pieces.join('&'); /* 117 */ return pieces.join('&');
/* 118 */ }; /* 118 */ };
/* 119 */ /* 119 */
/* 120 */ /** /* 120 */ /**
/* 121 *| * @public /* 121 *| * @public
/* 122 *| */ /* 122 *| */
/* 123 */ construct_.prototype.reload = function() { /* 123 */ construct_.prototype.reload = function() {
/* 124 */ MrClay.QueryString.reload(this.vars, this.window); /* 124 */ MrClay.QueryString.reload(this.vars, this.window);
/* 125 */ return this; /* 125 */ return this;
/* 126 */ }; /* 126 */ };
/* 127 */ /* 127 */
/* 128 */ /** /* 128 */ /**
/* 129 *| * @public /* 129 *| * @public
/* 130 *| */ /* 130 *| */
/* 131 */ construct_.prototype.get = function(key, default_) { /* 131 */ construct_.prototype.get = function(key, default_) {
/* 132 */ if (typeof default_ == 'undefined') { /* 132 */ if (typeof default_ == 'undefined') {
/* 133 */ default_ = null; /* 133 */ default_ = null;
/* 134 */ } /* 134 */ }
/* 135 */ return (this.vars[key] == null) /* 135 */ return (this.vars[key] == null)
/* 136 */ ? default_ /* 136 */ ? default_
/* 137 */ : this.vars[key]; /* 137 */ : this.vars[key];
/* 138 */ }; /* 138 */ };
/* 139 */ /* 139 */
/* 140 */ /** /* 140 */ /**
/* 141 *| * @public /* 141 *| * @public
/* 142 *| */ /* 142 *| */
/* 143 */ construct_.prototype.set = function(key, value) { /* 143 */ construct_.prototype.set = function(key, value) {
/* 144 */ var obj = {}; /* 144 */ var obj = {};
/* 145 */ if (typeof key == 'string') { /* 145 */ if (typeof key == 'string') {
/* 146 */ obj[key] = value; /* 146 */ obj[key] = value;
/* 147 */ } else { /* 147 */ } else {
/* 148 */ obj = key; /* 148 */ obj = key;
/* 149 */ } /* 149 */ }
/* 150 */ for (var prop in obj) { /* 150 */ for (var prop in obj) {
/* QueryString.js */ /* QueryString.js */
/* 151 */ if (obj[prop] == null) { /* 151 */ if (obj[prop] == null) {
/* 152 */ delete this.vars[prop]; /* 152 */ delete this.vars[prop];
/* 153 */ } else { /* 153 */ } else {
/* 154 */ this.vars[prop] = obj[prop]; /* 154 */ this.vars[prop] = obj[prop];
/* 155 */ } /* 155 */ }
/* 156 */ } /* 156 */ }
/* 157 */ return this; /* 157 */ return this;
/* 158 */ }; /* 158 */ };
/* 159 */ /* 159 */
/* 160 */ /** /* 160 */ /**
/* 161 *| * @public /* 161 *| * @public
/* 162 *| */ /* 162 *| */
/* 163 */ construct_.prototype.toString = function() { /* 163 */ construct_.prototype.toString = function() {
/* 164 */ return QueryString.toString(this.vars); /* 164 */ return QueryString.toString(this.vars);
/* 165 */ }; /* 165 */ };
/* 166 */ /* 166 */
/* 167 */ return construct_; /* 167 */ return construct_;
/* 168 */ }(); // define and execute /* 168 */ }(); // define and execute
; ;
/* before.js */ /* before.js */

View File

@@ -0,0 +1,30 @@
<?php
require_once '_inc.php';
require_once 'Minify/CSS/UriRewriter.php';
function test_Minify_CSS_UriRewriter()
{
global $thisDir;
$in = file_get_contents($thisDir . '/_test_files/css_uriRewriter/in.css');
$expected = file_get_contents($thisDir . '/_test_files/css_uriRewriter/exp.css');
$actual = Minify_CSS_UriRewriter::rewrite(
$in
,$thisDir . '/_test_files/css_uriRewriter'
,$thisDir
);
$passed = assertTrue($expected === $actual, 'Minify_CSS_UriRewriter');
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
echo "\n---Input:\n\n{$in}\n";
echo "\n---Output: " .strlen($actual). " bytes\n\n{$actual}\n\n";
if (!$passed) {
echo "---Expected: " .strlen($expected). " bytes\n\n{$expected}\n\n\n";
}
}
}
test_Minify_CSS_UriRewriter();

View File

@@ -0,0 +1,37 @@
<?php
require_once '_inc.php';
require_once 'Minify/CommentPreserver.php';
function test_Minify_CommentPreserver()
{
global $thisDir;
$inOut = array(
'/*!*/' => "\n/**/\n"
,'/*!*/a' => "\n/**/\n1A"
,'a/*!*//*!*/b' => "2A\n/**/\n\n/**/\n3B"
,'a/*!*/b/*!*/' => "4A\n/**/\n5B\n/**/\n"
);
foreach ($inOut as $in => $expected) {
$actual = Minify_CommentPreserver::process($in, '_test_MCP_processor');
$passed = assertTrue($expected === $actual, 'Minify_CommentPreserver');
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
echo "\n---Output: " .strlen($actual). " bytes\n\n{$actual}\n\n";
if (!$passed) {
echo "---Expected: " .strlen($expected). " bytes\n\n{$expected}\n\n\n";
}
}
}
}
function _test_MCP_processor($content, $options = array())
{
static $callCount = 0;
++$callCount;
return $callCount . strtoupper($content);
}
test_Minify_CommentPreserver();

View File

@@ -5,6 +5,8 @@ require 'test_Minify_Build.php';
require 'test_Minify_Cache_File.php'; require 'test_Minify_Cache_File.php';
require 'test_Minify_Cache_Memcache.php'; require 'test_Minify_Cache_Memcache.php';
require 'test_Minify_CSS.php'; require 'test_Minify_CSS.php';
require 'test_Minify_CSS_UriRewriter.php';
require 'test_Minify_CommentPreserver.php';
require 'test_Minify_HTML.php'; require 'test_Minify_HTML.php';
require 'test_Minify_ImportProcessor.php'; require 'test_Minify_ImportProcessor.php';
require 'test_Minify_Javascript.php'; require 'test_Minify_Javascript.php';