mirror of
https://github.com/mrclay/minify.git
synced 2025-08-11 16:44:44 +02:00
Work on: Issue 120, Issue 170, Issue 152, Issue 125, Issue 134, Issue 143
Broke some tests
This commit is contained in:
10
README.txt
10
README.txt
@@ -16,12 +16,14 @@ See UPGRADING.txt for instructions.
|
||||
INSTALLATION AND USAGE:
|
||||
|
||||
1. Place the /min/ directory as a child of your DOCUMENT_ROOT
|
||||
directory: i.e. you will have: /home/user/www/public_html/min
|
||||
directory: i.e. you will have: /home/user/www/min
|
||||
|
||||
2. Open http://yourdomain/min/ in a web browser. This will forward
|
||||
you to the Minify URI Builder application, which will help you
|
||||
quickly start using Minify to serve content on your site.
|
||||
|
||||
See the User Guide: http://code.google.com/p/minify/wiki/UserGuide
|
||||
|
||||
|
||||
UNIT TESTING:
|
||||
|
||||
@@ -36,12 +38,6 @@ components with more verbose output.)
|
||||
3. Remove /min_unit_tests/ from your DOCUMENT_ROOT when you are done.
|
||||
|
||||
|
||||
EXTRAS:
|
||||
|
||||
The min_extras folder contains files for benchmarking using Apache ab on Windows
|
||||
and a couple single-use tools. DO NOT place this on your production server.
|
||||
|
||||
|
||||
FILE ENCODINGS
|
||||
|
||||
Minify *should* work fine with files encoded in UTF-8 or other 8-bit
|
||||
|
@@ -1,4 +1,13 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteRule ^([a-z]=.*) index.php?$1 [L,NE]
|
||||
|
||||
# You may need RewriteBase on some servers
|
||||
#RewriteBase /min
|
||||
|
||||
# rewrite URLs like "/min/f=..." to "/min/?f=..."
|
||||
RewriteRule ^([bfg]=.*) index.php?$1 [L,NE]
|
||||
</IfModule>
|
||||
<IfModule mod_env.c>
|
||||
# In case AddOutputFilterByType has been added
|
||||
SetEnv no-gzip
|
||||
</IfModule>
|
@@ -66,9 +66,9 @@ to the /js and /themes/default directories, use:
|
||||
$min_serveOptions['minApp']['allowDirs'] = array('//js', '//themes/default');
|
||||
|
||||
|
||||
GROUPS: FASTER PERFORMANCE AND BETTER URLS
|
||||
GROUPS: NICER URLS
|
||||
|
||||
For the best performance, edit groupsConfig.php to pre-specify groups of files
|
||||
For nicer URLs, 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:
|
||||
|
||||
|
@@ -202,7 +202,7 @@ var MUB = {
|
||||
$('#sources').html('');
|
||||
$('#add button').click(MUB.addButtonClick);
|
||||
// make easier to copy text out of
|
||||
$('#uriHtml, #groupConfig').click(function () {
|
||||
$('#uriHtml, #groupConfig, #symlinkOpt').click(function () {
|
||||
this.select();
|
||||
}).focus(function () {
|
||||
this.select();
|
||||
@@ -223,10 +223,9 @@ var MUB = {
|
||||
return false;
|
||||
}).attr({title:'Add file +'});
|
||||
} else {
|
||||
// copy bookmarklet code into href
|
||||
var bmUri = location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1);
|
||||
// setup bookmarklet 1
|
||||
$.ajax({
|
||||
url : '../?f=' + bmUri
|
||||
url : '../?f=' + location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1)
|
||||
,success : function (code) {
|
||||
$('#bm')[0].href = code
|
||||
.replace('%BUILDER_URL%', location.href)
|
||||
@@ -237,6 +236,14 @@ var MUB = {
|
||||
$.browser.msie && $('#getBm p:last').append(' Sorry, not supported in MSIE!');
|
||||
MUB.addButtonClick();
|
||||
}
|
||||
// setup bookmarklet 2
|
||||
$.ajax({
|
||||
url : '../?f=' + location.pathname.replace(/\/[^\/]*$/, '/bm2.js').substr(1)
|
||||
,success : function (code) {
|
||||
$('#bm2')[0].href = code.replace(/\n/g, ' ');
|
||||
}
|
||||
,dataType : 'text'
|
||||
});
|
||||
MUB.checkRewrite();
|
||||
}
|
||||
};
|
||||
|
14
min/builder/bm2.js
Normal file
14
min/builder/bm2.js
Normal file
@@ -0,0 +1,14 @@
|
||||
javascript:(function(){
|
||||
var d = document
|
||||
,c = d.cookie
|
||||
,m = c.match(/\bminDebug=([^; ]+)/)
|
||||
,v = m ? decodeURIComponent(m[1]) : ''
|
||||
,p = prompt('Debug Minify URIs on "' + location.hostname + '" \ncontaining: (empty to disable)', v)
|
||||
;
|
||||
if (p === null) return;
|
||||
p = p.replace(/\s+/g, '');
|
||||
v = (p === '')
|
||||
? 'minDebug=; expires=Fri, 27 Jul 2001 02:47:11 UTC; path=/'
|
||||
: 'minDebug=' + encodeURIComponent(p) + '; path=/';
|
||||
d.cookie = v;
|
||||
})();
|
@@ -8,6 +8,20 @@ if (phpversion() < 5) {
|
||||
$encodeOutput = (function_exists('gzdeflate')
|
||||
&& !ini_get('zlib.output_compression'));
|
||||
|
||||
// recommend $min_symlinks setting for Apache UserDir
|
||||
$symlinkOption = '';
|
||||
if (0 === strpos($_SERVER["SERVER_SOFTWARE"], 'Apache/')
|
||||
&& preg_match('@^/\\~(\\w+)/@', $_SERVER['REQUEST_URI'], $m)
|
||||
) {
|
||||
$userDir = DIRECTORY_SEPARATOR . $m[1] . DIRECTORY_SEPARATOR;
|
||||
if (false !== strpos(__FILE__, $userDir)) {
|
||||
$sm = array();
|
||||
$sm["//~{$m[1]}"] = dirname(dirname(__FILE__));
|
||||
$array = str_replace('array (', 'array(', var_export($sm, 1));
|
||||
$symlinkOption = "\$min_symlinks = $array;";
|
||||
}
|
||||
}
|
||||
|
||||
require dirname(__FILE__) . '/../config.php';
|
||||
|
||||
if (! $min_enableBuilder) {
|
||||
@@ -18,8 +32,8 @@ if (! $min_enableBuilder) {
|
||||
ob_start();
|
||||
?>
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
|
||||
<title>Minify URI Builder</title>
|
||||
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
|
||||
<style type="text/css">
|
||||
body {margin:1em 60px;}
|
||||
h1, h2, h3 {margin-left:-25px; position:relative;}
|
||||
@@ -39,14 +53,24 @@ b {color:#c00}
|
||||
.topWarning a {color:#fff;}
|
||||
</style>
|
||||
<body>
|
||||
<?php if ($symlinkOption): ?>
|
||||
<div class=topNote><strong>Note:</strong> It looks like you're running Minify in a user
|
||||
directory. You may need the following option in /min/config.php to have URIs
|
||||
correctly rewritten in CSS output:
|
||||
<br><textarea id=symlinkOpt rows=3 cols=80 readonly><?php echo htmlspecialchars($symlinkOption); ?></textarea>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class=topWarning id=jsDidntLoad><strong>Uh Oh.</strong> Minify was unable to
|
||||
serve the Javascript for this app. <a href="http://code.google.com/p/minify/wiki/Debugging">Enable
|
||||
FirePHP debugging</a> and request the <a id=builderScriptSrc href=#>Minify URL</a> directly.
|
||||
serve the Javascript for this app. To troubleshoot this,
|
||||
<a href="http://code.google.com/p/minify/wiki/Debugging">enable FirePHP debugging</a>
|
||||
and request the <a id=builderScriptSrc href=#>Minify URL</a> directly. Hopefully the
|
||||
FirePHP console will report the cause of the error.
|
||||
</p>
|
||||
|
||||
<?php if (! isset($min_cachePath)): ?>
|
||||
<p class=topNote><strong>Note:</strong> Please set <code>$min_cachePath</code>
|
||||
in /min/config.php to improve performance.</p>
|
||||
<p class=topNote><strong>Note:</strong> You can set <code>$min_cachePath</code>
|
||||
in /min/config.php to slightly improve performance.</p>
|
||||
<?php endIf; ?>
|
||||
|
||||
<p id=minRewriteFailed class="hide"><strong>Note:</strong> Your webserver does not seem to
|
||||
@@ -111,14 +135,21 @@ in your list, and move any others to the top of the first file in your list
|
||||
<p>If you desire, you can use Minify URIs in imports and they will not be touched
|
||||
by Minify. E.g. <code>@import "<span class=minRoot>/min/?</span>g=css2";</code></p>
|
||||
|
||||
<h3>Debug Mode</h3>
|
||||
<p>When /min/config.php has <code>$min_allowDebugFlag = <strong>true</strong>;</code>
|
||||
you can get debug output by appending <code>&debug</code> to a Minify URL, or
|
||||
by sending the cookie <code>minDebug=<match></code>, where <code>minDebug=<match></code>
|
||||
should match the Minify URIs you'd like to debug. This bookmarklet will allow you to
|
||||
set this cookie.</p>
|
||||
<p><a id=bm2>Minify Debug</a> <small>(right-click, add to bookmarks)</small></p>
|
||||
|
||||
</div><!-- #app -->
|
||||
|
||||
<hr>
|
||||
<p>Need help? Search or post to the <a class=ext
|
||||
href="http://groups.google.com/group/minify">Minify discussion list</a>.</p>
|
||||
<p><small>This app is minified :) <a class=ext
|
||||
href="http://code.google.com/p/minify/source/browse/trunk/min/builder/index.php">view
|
||||
source</a></small></p>
|
||||
<p>Need help? Check the <a href="http://code.google.com/p/minify/w/list?can=3">wiki</a>,
|
||||
or post to the <a class=ext href="http://groups.google.com/group/minify">discussion
|
||||
list</a>.</p>
|
||||
<p><small>This app is minified :)</small></p>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
|
||||
@@ -163,9 +194,22 @@ $(function () {
|
||||
</script>
|
||||
</body>
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
|
||||
$serveOpts = array(
|
||||
'content' => ob_get_contents()
|
||||
// setup Minify
|
||||
set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path());
|
||||
require 'Minify.php';
|
||||
if (0 === stripos(PHP_OS, 'win')) {
|
||||
Minify::setDocRoot(); // we may be on IIS
|
||||
}
|
||||
Minify::setCache(
|
||||
isset($min_cachePath) ? $min_cachePath : ''
|
||||
,$min_cacheFileLocking
|
||||
);
|
||||
Minify::$uploaderHoursBehind = $min_uploaderHoursBehind;
|
||||
|
||||
Minify::serve('Page', array(
|
||||
'content' => $content
|
||||
,'id' => __FILE__
|
||||
,'lastModifiedTime' => max(
|
||||
// regenerate cache if either of these change
|
||||
@@ -174,17 +218,4 @@ $serveOpts = array(
|
||||
)
|
||||
,'minifyAll' => true
|
||||
,'encodeOutput' => $encodeOutput
|
||||
);
|
||||
ob_end_clean();
|
||||
|
||||
set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
require 'Minify.php';
|
||||
|
||||
if (0 === stripos(PHP_OS, 'win')) {
|
||||
Minify::setDocRoot(); // we may be on IIS
|
||||
}
|
||||
Minify::setCache(isset($min_cachePath) ? $min_cachePath : null);
|
||||
Minify::$uploaderHoursBehind = $min_uploaderHoursBehind;
|
||||
|
||||
Minify::serve('Page', $serveOpts);
|
||||
));
|
||||
|
@@ -7,16 +7,6 @@
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* In 'debug' mode, Minify can combine files with no minification and
|
||||
* add comments to indicate line #s of the original files.
|
||||
*
|
||||
* To allow debugging, set this option to true and add "&debug=1" to
|
||||
* a URI. E.g. /min/?f=script1.js,script2.js&debug=1
|
||||
*/
|
||||
$min_allowDebugFlag = false;
|
||||
|
||||
|
||||
/**
|
||||
* Set to true to log messages to FirePHP (Firefox Firebug addon).
|
||||
* Set to false for no error logging (Minify may be slightly faster).
|
||||
@@ -30,6 +20,21 @@ $min_allowDebugFlag = false;
|
||||
$min_errorLogger = false;
|
||||
|
||||
|
||||
/**
|
||||
* To allow debugging, you must set this option to true.
|
||||
*
|
||||
* Once true, you can send the cookie minDebug to request debug mode output. The
|
||||
* cookie value should match the URIs you'd like to debug. E.g. to debug
|
||||
* /min/f=file1.js send the cookie minDebug=file1.js
|
||||
* You can manually enable debugging by appending "&debug" to a URI.
|
||||
* E.g. /min/?f=script1.js,script2.js&debug
|
||||
*
|
||||
* In 'debug' mode, Minify combines files with no minification and adds comments
|
||||
* to indicate line #s of the original files.
|
||||
*/
|
||||
$min_allowDebugFlag = false;
|
||||
|
||||
|
||||
/**
|
||||
* Allow use of the Minify URI Builder app. If you no longer need
|
||||
* this, set to false.
|
||||
|
@@ -35,8 +35,15 @@ foreach ($min_symlinks as $uri => $target) {
|
||||
$min_serveOptions['minApp']['allowDirs'][] = $target;
|
||||
}
|
||||
|
||||
if ($min_allowDebugFlag && isset($_GET['debug'])) {
|
||||
$min_serveOptions['debug'] = true;
|
||||
if ($min_allowDebugFlag) {
|
||||
if (! empty($_COOKIE['minDebug'])
|
||||
&& false !== strpos($_SERVER['REQUEST_URI'], $_COOKIE['minDebug'])) {
|
||||
$min_serveOptions['debug'] = true;
|
||||
}
|
||||
// allow GET to override
|
||||
if (isset($_GET['debug'])) {
|
||||
$min_serveOptions['debug'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($min_errorLogger) {
|
||||
|
@@ -75,9 +75,8 @@ class HTTP_ConditionalGet {
|
||||
/**
|
||||
* @param array $spec options
|
||||
*
|
||||
* 'isPublic': (bool) if true, the Cache-Control header will contain
|
||||
* "public", allowing proxies to cache the content. Otherwise "private" will
|
||||
* be sent, allowing only browser caching. (default false)
|
||||
* 'isPublic': (bool) if false, the Cache-Control header will contain
|
||||
* "private", allowing only browser caching. (default false)
|
||||
*
|
||||
* 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers
|
||||
* will be sent with content. This is recommended.
|
||||
@@ -150,7 +149,10 @@ class HTTP_ConditionalGet {
|
||||
} elseif (isset($spec['contentHash'])) { // Use the hash as the ETag
|
||||
$this->_setEtag($spec['contentHash'] . $etagAppend, $scope);
|
||||
}
|
||||
$this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}";
|
||||
$privacy = ($scope === 'private')
|
||||
? ', private'
|
||||
: '';
|
||||
$this->_headers['Cache-Control'] = "max-age={$maxAge}{$privacy}";
|
||||
// invalidate cache if disabled, otherwise check
|
||||
$this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate'])
|
||||
? false
|
||||
@@ -332,11 +334,8 @@ class HTTP_ConditionalGet {
|
||||
if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
return false;
|
||||
}
|
||||
$ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
|
||||
if (false !== ($semicolon = strrpos($ifModifiedSince, ';'))) {
|
||||
// IE has tacked on extra data to this header, strip it
|
||||
$ifModifiedSince = substr($ifModifiedSince, 0, $semicolon);
|
||||
}
|
||||
// strip off IE's extra data (semicolon)
|
||||
list($ifModifiedSince) = explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE'], 2);
|
||||
if (strtotime($ifModifiedSince) >= $this->_lmTime) {
|
||||
// Apache 2.2's behavior. If there was no ETag match, send the
|
||||
// non-encoded version of the ETag value.
|
||||
|
@@ -171,7 +171,8 @@ class JSMin {
|
||||
}
|
||||
if (ord($this->a) <= self::ORD_LF) {
|
||||
throw new JSMin_UnterminatedStringException(
|
||||
"Unterminated String: {$str}");
|
||||
"JSMin: Unterminated String at byte "
|
||||
. $this->inputIndex . ": {$str}");
|
||||
}
|
||||
$str .= $this->a;
|
||||
if ($this->a === '\\') {
|
||||
@@ -198,7 +199,8 @@ class JSMin {
|
||||
$pattern .= $this->a;
|
||||
} elseif (ord($this->a) <= self::ORD_LF) {
|
||||
throw new JSMin_UnterminatedRegExpException(
|
||||
"Unterminated RegExp: {$pattern}");
|
||||
"JSMin: Unterminated RegExp at byte "
|
||||
. $this->inputIndex .": {$pattern}");
|
||||
}
|
||||
$this->output .= $this->a;
|
||||
}
|
||||
@@ -310,7 +312,9 @@ class JSMin {
|
||||
return ' ';
|
||||
}
|
||||
} elseif ($get === null) {
|
||||
throw new JSMin_UnterminatedCommentException("Unterminated Comment: /*{$comment}");
|
||||
throw new JSMin_UnterminatedCommentException(
|
||||
"JSMin: Unterminated comment at byte "
|
||||
. $this->inputIndex . ": /*{$comment}");
|
||||
}
|
||||
$comment .= $get;
|
||||
}
|
||||
|
@@ -227,6 +227,8 @@ class Minify {
|
||||
);
|
||||
if (self::$_options['maxAge'] > 0) {
|
||||
$cgOptions['maxAge'] = self::$_options['maxAge'];
|
||||
} elseif (self::$_options['debug']) {
|
||||
$cgOptions['invalidate'] = true;
|
||||
}
|
||||
$cg = new HTTP_ConditionalGet($cgOptions);
|
||||
if ($cg->cacheIsValid) {
|
||||
@@ -267,7 +269,7 @@ class Minify {
|
||||
// the goal is to use only the cache methods to sniff the length and
|
||||
// output the content, as they do not require ever loading the file into
|
||||
// memory.
|
||||
$cacheId = 'minify_' . self::_getCacheId();
|
||||
$cacheId = self::_getCacheId();
|
||||
$fullCacheId = (self::$_options['encodeMethod'])
|
||||
? $cacheId . '.gz'
|
||||
: $cacheId;
|
||||
@@ -489,7 +491,12 @@ class Minify {
|
||||
if ($minifier) {
|
||||
self::$_controller->loadMinifier($minifier);
|
||||
// get source content and minify it
|
||||
$pieces[] = call_user_func($minifier, $source->getContent(), $options);
|
||||
try {
|
||||
$pieces[] = call_user_func($minifier, $source->getContent(), $options);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Exception in " . $source->getId() .
|
||||
": " . $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$pieces[] = $source->getContent();
|
||||
}
|
||||
@@ -515,17 +522,23 @@ class Minify {
|
||||
*
|
||||
* Any settings that could affect output are taken into consideration
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getCacheId()
|
||||
protected static function _getCacheId($prefix = 'minify')
|
||||
{
|
||||
return md5(serialize(array(
|
||||
$name = preg_replace('/[^a-zA-Z0-9\\.=_,]/', '', self::$_controller->selectionId);
|
||||
$name = preg_replace('/\\.+/', '.', $name);
|
||||
$name = substr($name, 0, 250 - 34 - strlen($prefix));
|
||||
$md5 = md5(serialize(array(
|
||||
Minify_Source::getDigest(self::$_controller->sources)
|
||||
,self::$_options['minifiers']
|
||||
,self::$_options['minifierOptions']
|
||||
,self::$_options['postprocessor']
|
||||
,self::$_options['bubbleCssImports']
|
||||
)));
|
||||
return "{$prefix}_{$name}_{$md5}";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -144,6 +144,15 @@ abstract class Minify_Controller_Base {
|
||||
*/
|
||||
public $sources = array();
|
||||
|
||||
/**
|
||||
* The setupSources() method may choose to set this, making it easier to
|
||||
* recognize a particular set of sources/settings in the cache folder. It
|
||||
* will be filtered and truncated to make the final cache id <= 250 bytes.
|
||||
*
|
||||
* @var string short name to place inside cache id
|
||||
*/
|
||||
public $selectionId = '';
|
||||
|
||||
/**
|
||||
* Mix in default controller options with user-given options
|
||||
*
|
||||
|
@@ -41,6 +41,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
|
||||
return $options;
|
||||
}
|
||||
|
||||
$this->selectionId = "g=" . $_GET['g'];
|
||||
$files = $cOptions['groups'][$_GET['g']];
|
||||
// if $files is a single object, casting will break it
|
||||
if (is_object($files)) {
|
||||
@@ -70,7 +71,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
|
||||
// respond to. Ideally there should be only one way to reference a file.
|
||||
if (// verify at least one file, files are single comma separated,
|
||||
// and are all same extension
|
||||
! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f'])
|
||||
! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f'], $m)
|
||||
// no "//"
|
||||
|| strpos($_GET['f'], '//') !== false
|
||||
// no "\"
|
||||
@@ -81,11 +82,13 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
|
||||
$this->log("GET param 'f' invalid (see MinApp.php line 63)");
|
||||
return $options;
|
||||
}
|
||||
$ext = ".{$m[1]}";
|
||||
$files = explode(',', $_GET['f']);
|
||||
if ($files != array_unique($files)) {
|
||||
$this->log("Duplicate files specified");
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (isset($_GET['b'])) {
|
||||
// check for validity
|
||||
if (preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b'])
|
||||
@@ -104,6 +107,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
|
||||
foreach ((array)$cOptions['allowDirs'] as $allowDir) {
|
||||
$allowDirs[] = realpath(str_replace('//', $_SERVER['DOCUMENT_ROOT'] . '/', $allowDir));
|
||||
}
|
||||
$basenames = array(); // just for cache id
|
||||
foreach ($files as $file) {
|
||||
$path = $_SERVER['DOCUMENT_ROOT'] . $base . $file;
|
||||
$file = realpath($path);
|
||||
@@ -115,8 +119,10 @@ class Minify_Controller_MinApp extends Minify_Controller_Base {
|
||||
return $options;
|
||||
} else {
|
||||
$sources[] = $this->_getFileSource($file, $cOptions);
|
||||
$basenames[] = basename($file, $ext);
|
||||
}
|
||||
}
|
||||
$this->selectionId = implode(',', $basenames) . $ext;
|
||||
}
|
||||
if ($sources) {
|
||||
$this->sources = $sources;
|
||||
|
@@ -40,14 +40,19 @@ class Minify_Controller_Page extends Minify_Controller_Base {
|
||||
$sourceSpec = array(
|
||||
'filepath' => $options['file']
|
||||
);
|
||||
$f = $options['file'];
|
||||
} else {
|
||||
// strip controller options
|
||||
$sourceSpec = array(
|
||||
'content' => $options['content']
|
||||
,'id' => $options['id']
|
||||
);
|
||||
$f = $options['id'];
|
||||
unset($options['content'], $options['id']);
|
||||
}
|
||||
// something like "builder,index.php" or "directory,file.html"
|
||||
$this->selectionId = strtr(substr($f, 1 + strlen(dirname(dirname($f)))), '/\\', ',,');
|
||||
|
||||
if (isset($options['minifyAll'])) {
|
||||
// this will be the 2nd argument passed to Minify_HTML::minify()
|
||||
$sourceSpec['minifyOptions'] = array(
|
||||
|
4
min_unit_tests/.htaccess
Normal file
4
min_unit_tests/.htaccess
Normal file
@@ -0,0 +1,4 @@
|
||||
<IfModule mod_env.c>
|
||||
# In case AddOutputFilterByType has been added
|
||||
SetEnv no-gzip
|
||||
</IfModule>
|
@@ -29,7 +29,7 @@ function test_Minify()
|
||||
'Vary' => 'Accept-Encoding',
|
||||
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
|
||||
'ETag' => "\"pub{$lastModified}\"",
|
||||
'Cache-Control' => 'max-age=1800, public',
|
||||
'Cache-Control' => 'max-age=1800',
|
||||
'_responseCode' => 'HTTP/1.0 304 Not Modified',
|
||||
)
|
||||
);
|
||||
@@ -49,7 +49,7 @@ function test_Minify()
|
||||
|
||||
assertTrue(
|
||||
! class_exists('Minify_CSS', false)
|
||||
&& ! class_exists('Minify_Cache', false)
|
||||
&& ! class_exists('Minify_Cache_File', false)
|
||||
,'Minify : cache, and minifier classes aren\'t loaded for 304s'
|
||||
);
|
||||
|
||||
@@ -70,11 +70,13 @@ function test_Minify()
|
||||
'Vary' => 'Accept-Encoding',
|
||||
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
|
||||
'ETag' => "\"pub{$lastModified}\"",
|
||||
'Cache-Control' => 'max-age=86400, public',
|
||||
'Cache-Control' => 'max-age=86400',
|
||||
'Content-Length' => strlen($content),
|
||||
'Content-Type' => 'application/x-javascript; charset=utf-8',
|
||||
)
|
||||
);
|
||||
unset($_SERVER['HTTP_IF_NONE_MATCH']);
|
||||
unset($_SERVER['HTTP_IF_MODIFIED_SINCE']);
|
||||
$output = Minify::serve('Files', array(
|
||||
'files' => array(
|
||||
$minifyTestPath . '/email.js'
|
||||
@@ -185,7 +187,7 @@ function test_Minify()
|
||||
'Vary' => 'Accept-Encoding',
|
||||
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
|
||||
'ETag' => "\"pub{$lastModified}\"",
|
||||
'Cache-Control' => 'max-age=0, public',
|
||||
'Cache-Control' => 'max-age=0',
|
||||
'Content-Length' => strlen($expectedContent),
|
||||
'Content-Type' => 'text/css; charset=utf-8',
|
||||
)
|
||||
|
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
//phpinfo(); exit();
|
||||
|
||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
// called directly
|
||||
if (isset($_GET['getOutputCompression'])) {
|
||||
@@ -9,6 +11,10 @@ if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
if (isset($_GET['hello'])) {
|
||||
// try to disable (may not work)
|
||||
ini_set('zlib.output_compression', '0');
|
||||
$type = ($_GET['hello'] == 'js')
|
||||
? 'application/x-javascript'
|
||||
: "text/{$_GET['hello']}";
|
||||
header("Content-Type: {$type}");
|
||||
echo 'World!';
|
||||
exit();
|
||||
}
|
||||
@@ -61,41 +67,72 @@ function test_environment()
|
||||
. " or .htaccess.\n";
|
||||
}
|
||||
|
||||
$fp = fopen($thisUrl . '?hello=1', 'r', false, stream_context_create(array(
|
||||
'http' => array(
|
||||
'method' => "GET",
|
||||
'header' => "Accept-Encoding: deflate, gzip\r\n"
|
||||
)
|
||||
)));
|
||||
|
||||
$meta = stream_get_meta_data($fp);
|
||||
|
||||
$passed = true;
|
||||
foreach ($meta['wrapper_data'] as $i => $header) {
|
||||
if ((preg_match('@^Content-Length: (\\d+)$@i', $header, $m) && $m[1] !== '6')
|
||||
|| preg_match('@^Content-Encoding:@i', $header, $m)
|
||||
) {
|
||||
$passed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$streamContents = stream_get_contents($fp);
|
||||
if ($passed && $streamContents !== 'World!') {
|
||||
$passed = false;
|
||||
}
|
||||
assertTrue(
|
||||
$passed
|
||||
,'environment : PHP/server does not auto-HTTP-encode content'
|
||||
$testJs = _test_environment_getHello($thisUrl . '?hello=js');
|
||||
$passed = assertTrue(
|
||||
$testJs['length'] == 6
|
||||
,'environment : PHP/server should not auto-encode application/x-javascript output'
|
||||
);
|
||||
fclose($fp);
|
||||
|
||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
if (! $passed) {
|
||||
echo "\nReturned content should be 6 bytes and not HTTP encoded.\n"
|
||||
. "Headers returned by: {$thisUrl}?hello=1\n\n";
|
||||
var_export($meta['wrapper_data']);
|
||||
$testCss = _test_environment_getHello($thisUrl . '?hello=css');
|
||||
$passed = $passed && assertTrue(
|
||||
$testCss['length'] == 6
|
||||
,'environment : PHP/server should not auto-encode text/css output'
|
||||
);
|
||||
|
||||
$testHtml = _test_environment_getHello($thisUrl . '?hello=html');
|
||||
$passed = $passed && assertTrue(
|
||||
$testHtml['length'] == 6
|
||||
,'environment : PHP/server should not auto-encode text/html output'
|
||||
);
|
||||
|
||||
if (! $passed) {
|
||||
$testFake = _test_environment_getHello($thisUrl . '?hello=faketype');
|
||||
if ($testFake['length'] == 6) {
|
||||
echo "!NOTE: environment : Server does not auto-encode arbitrary types. This\n"
|
||||
. " may indicate that the auto-encoding is caused by Apache's \n"
|
||||
. " AddOutputFilterByType.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _test_environment_getHello($url)
|
||||
{
|
||||
$fp = fopen($url, 'r', false, stream_context_create(array(
|
||||
'http' => array(
|
||||
'method' => "GET",
|
||||
'timeout' => '10',
|
||||
'header' => "Accept-Encoding: deflate, gzip\r\n",
|
||||
)
|
||||
)));
|
||||
$meta = stream_get_meta_data($fp);
|
||||
$encoding = '';
|
||||
$length = 0;
|
||||
foreach ($meta['wrapper_data'] as $i => $header) {
|
||||
if (preg_match('@^Content-Length:\\s*(\\d+)$@i', $header, $m)) {
|
||||
$length = $m[1];
|
||||
} elseif (preg_match('@^Content-Encoding:\\s*(\\S+)$@i', $header, $m)) {
|
||||
if ($m[1] !== 'identity') {
|
||||
$encoding = $m[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$streamContents = stream_get_contents($fp);
|
||||
fclose($fp);
|
||||
|
||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
if ($length != 6) {
|
||||
echo "\nReturned content should be 6 bytes and not HTTP encoded.\n"
|
||||
. "Headers returned by: {$url}\n\n";
|
||||
var_export($meta['wrapper_data']);
|
||||
echo "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'length' => $length
|
||||
,'encoding' => $encoding
|
||||
,'bytes' => $streamContents
|
||||
);
|
||||
}
|
||||
|
||||
test_environment();
|
||||
|
Reference in New Issue
Block a user