1
0
mirror of https://github.com/mrclay/minify.git synced 2025-09-06 20:20:51 +02:00

24 Commits
2.3.0 ... 2.3.3

Author SHA1 Message Date
Elan Ruusamäe
1928e89208 Fix closure-compiler's error "redirection limit reached". fixes #618, #619
Merge branch 'v2.x-pr-618' into 2.x
2017-11-03 23:04:01 +02:00
Emanuele "ToX" Toscano
e4ba869444 Fix closure-compiler's "redirection limit reached"
Since a few days, the js minification was complaining about a redirection limit in the closure-compiler call. This was generating an error each time I have tried to use this tool.

After a bit of investigation I have found out that it was missing some parameters that are now mandatory. Plus, it now works in https only.
2017-11-03 23:02:03 +02:00
Elan Ruusamäe
2c83b82bfa update changelog 2017-06-08 20:49:34 +03:00
Elan Ruusamäe
32150b84b6 Merge pull request #600 from Quetzacoalt91/2.x
Cast value as int for PHP 7.1
2017-06-08 20:42:07 +03:00
Thomas N
48a34d6900 Cast value to normalize as int for PHP 7.1 2017-05-31 16:20:51 +01:00
Steve Clay
a36e201ab2 Simplify docs for CSSmin on Minify 2.x 2017-04-25 11:30:12 -04:00
Steve Clay
fefc85d481 Revert "Parse LastModified date without requiring global timezone"
This reverts commit 176fb1084f.
2017-04-03 15:58:28 -04:00
Steve Clay
21cc3e7224 Merge pull request #570 from mrclay/default_tz
Parse LastModified date without requiring global timezone
2017-03-13 11:07:16 -04:00
Steve Clay
176fb1084f Parse LastModified date without requiring global timezone
Fixes #568
2017-02-07 15:33:31 -05:00
Steve Clay
234b9459ca Merge pull request #564 from mrclay/empty_url_2x
URI rewriter passes through empty URLs
2017-01-18 21:08:30 -05:00
Steve Clay
8333f333be URI rewriter passes through empty URLs
Fixes #561
2017-01-18 21:05:07 -05:00
Steve Clay
2d2e06f438 Add temp location to server-info.php 2016-10-02 05:37:07 -04:00
Steve Clay
140673f5b6 Deleted references to WordPress 2016-09-04 10:23:51 -04:00
Steve Clay
49bd730e1a Merge pull request #537 from mrclay/sync_jsmin
Sync JSMin with mrclay/jsmin-php
2016-06-28 14:51:40 -04:00
Steve Clay
850e81c416 Merge pull request #540 from Dargmuesli/2.x
Prevent false mod_rewrite error
2016-06-24 23:39:40 -04:00
Jonas Thelemann
b37d837ff9 Prevent false mod_rewrite error
If Google's Closure Compiler API is enabled, rewriteTest.js is served as
"1;" instead of "1". Therefore the "Note: Your webserver does not seem
to support mod_rewrite (used in /min/.htaccess). Your Minify URIs will
contain '?', which may reduce the benefit of proxy cache servers." is
wrong. This is a simple workaround.
2016-06-25 01:19:44 +02:00
Steve Clay
42b18c1e2a Sync JSMin with mrclay/jsmin-php 2016-06-08 19:00:35 -04:00
Evgeny Mazovetskiy
6a2995f932 list allowDirs in exception to simplify debugging 2016-05-12 10:43:31 -04:00
Steve Clay
b38ed79042 Merge pull request #524 from mrclay/mrclay-mrclay-patch-1
Use $min_libPath in examples and move it within config.php
2016-05-12 10:28:59 -04:00
Steve Clay
bb6e4d5f2e Merge pull request #519 from mrclay/clip_path_517
No longer alters inline SVG id URLs
2016-04-18 21:13:51 -04:00
Steve Clay
28197576c6 Use $min_libPath in examples and move it within config.php
Fixes #522
2016-04-18 21:12:12 -04:00
Steve Clay
cff094781b No longer alters inline SVG id URLs
Fixes #517
2016-03-16 18:32:47 -04:00
Elan Ruusamäe
0eb2cfe78d Update README.md
fixes from googlecode migration
2016-03-13 14:55:23 +02:00
Steve Clay
2d3c417a51 Update README.md
Add news
2016-03-11 23:08:29 -05:00
16 changed files with 146 additions and 77 deletions

View File

@@ -1,6 +1,19 @@
Minify Release History
Version 2.3.0
Version 2.3.3 (2017-11-03)
* Fix closure-compiler's error "redirection limit reached". #618, #619
Version 2.3.2 (2017-06-09)
* PHP 7.1 compatibility fix. #600
Version 2.3.1 (2017-04-03)
* No longer alters inline SVG id URLs. #517, #519
* Use $min_libPath in examples and move it within config.php. #522, #524
* Prevent false mod_rewrite error. #540
* Sync JSMin with mrclay/jsmin-php. #537
* URI rewriter passes through empty URLs. #561, #564
Version 2.3.0 (2016-03-11)
* Adds `$min_concatOnly` option to just concatenate files
* Deprecates use of Minify_Loader
* Deprecates use of Minify_Logger
@@ -116,7 +129,7 @@ Version 2.1.0 (2008-09-18)
* Better IIS support
* Improved minifier classes:
* JS: preserves IE conditional comments
* CSS: smaller output, preserves more hacks and valid CSS syntax,
* CSS: smaller output, preserves more hacks and valid CSS syntax,
shorter line lengths, other bug fixes
* HTML: smaller output, shorter line lengths, other bug fixes
* Default Cache-Control: max-age of 30 minutes
@@ -133,15 +146,15 @@ Version 2.0.1 (2008-05-31)
* E_STRICT compliance (Cache_Lite_File).
Version 2.0.0 (2008-05-22)
* Complete code overhaul. Minify is now a PEAR-style class and toolkit
* Complete code overhaul. Minify is now a PEAR-style class and toolkit
for building customized minifying file servers.
* Content-Encoding: deflate/gzip/compress, based on request headers
* Expanded CSS and HTML minifiers with test cases
* Easily plug-in 3rd-party minifiers (like Packer)
* Plug-able front end controller allows changing the way files are chosen
* Compression & encoding modules lazy-loaded as needed (304 responses use
* Compression & encoding modules lazy-loaded as needed (304 responses use
use minimal code)
* Separate utility classes for HTTP encoding and cache control
* Separate utility classes for HTTP encoding and cache control
Version 1.0.1 (2007-05-05)
* Fixed various problems resolving pathnames when hosted on an NFS mount.

View File

@@ -12,14 +12,10 @@ The stats above are from a [brief walkthrough](http://mrclay.org/index.php/2008/
Relative URLs in CSS files are rewritten to compensate for being served from a different directory.
Wordpress User?
---------------
News
----
Consider instead using a dedicated WordPress plugin for more deep integration and simpler installation. E.g.:
- [BWP Minify](http://wordpress.org/extend/plugins/bwp-minify/)
- [W3 Total Cache](http://wordpress.org/extend/plugins/w3-total-cache/)
Unfortunately we can't support the WordPress plugins here.
Version [2.3.0](https://github.com/mrclay/minify/releases/tag/2.3.0) was released, mainly to deprecate some classes that will be removed in 3.0.
Installation
------------
@@ -76,4 +72,4 @@ Acknowledgments
Minify was inspired by [jscsscomp](http://code.google.com/p/jscsscomp/) by Maxim Martynyuk and by the article [Supercharged JavaScript](http://www.hunlock.com/blogs/Supercharged_Javascript) by Patrick Hunlock.
The [JSMin library](http://www.crockford.com/javascript/jsmin.html) used for !JavaScript minification was originally written by Douglas Crockford and was [ported to PHP](https://github.com/mrclay/jsmin-php) by Ryan Grove specifically for use in Minify.
The [JSMin library](http://www.crockford.com/javascript/jsmin.html) used for JavaScript minification was originally written by Douglas Crockford and was [ported to PHP](https://github.com/mrclay/jsmin-php) by Ryan Grove specifically for use in Minify.

View File

@@ -7,7 +7,7 @@ By default, Minify uses [Minify\_Cache\_File](http://code.google.com/p/minify/so
### APC
```
require 'lib/Minify/Cache/APC.php';
require "$min_libPath/Minify/Cache/APC.php";
$min_cachePath = new Minify_Cache_APC();
```
@@ -15,7 +15,7 @@ $min_cachePath = new Minify_Cache_APC();
You must create and connect your Memcache object then pass it to `Minify_Cache_Memcache`'s constructor.
```
require 'lib/Minify/Cache/Memcache.php';
require "$min_libPath/Minify/Cache/Memcache.php";
$memcache = new Memcache;
$memcache->connect('localhost', 11211);
$min_cachePath = new Minify_Cache_Memcache($memcache);
@@ -67,24 +67,6 @@ $min_serveOptions['minifiers']['text/css'] = 'yuiCss';
Minify has added Túbal Martín's [PHP port](https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port/blob/master/cssmin.php) of the YUI Compressor's CSSmin. While it is not completely integrated yet, you may try it out:
```
function yuiCssPort($css, $options) {
$compressor = new CSSmin();
$css = $compressor->run($css, 9999999);
$css = Minify_CSS_UriRewriter::rewrite(
$css,
$options['currentDir'],
isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT'],
isset($options['symlinks']) ? $options['symlinks'] : array()
);
return $css;
}
$min_serveOptions['minifiers']['text/css'] = 'yuiCssPort';
```
As of commit [218f37](https://github.com/mrclay/minify/commit/218f37fb44f9be2ea138cf9efb8b7f6dc84bad7f), this is easier:
```
$min_serveOptions['minifiers']['text/css'] = array('Minify_CSSmin', 'minify');
```
@@ -154,4 +136,4 @@ function postProcess($content, $type) {
}
$min_serveOptions['postprocessor'] = 'postProcess';
```
This function is only called once immediately after minification and its output is stored in the cache.
This function is only called once immediately after minification and its output is stored in the cache.

View File

@@ -12,7 +12,7 @@ var MUB = {
$.ajax({
url : '../f=' + testUri + '&' + (new Date()).getTime(),
success : function (data) {
if (data === '1') {
if (data === '1' || data === '1;') {
MUB._minRoot = '/min/';
$('span.minRoot').html('/min/');
} else

View File

@@ -60,11 +60,19 @@ $min_allowDebugFlag = false;
//$min_cachePath = '/tmp';
//$min_cachePath = preg_replace('/^\\d+;/', '', session_save_path());
/**
* Path to Minify's lib folder. If you happen to move it, change
* this accordingly.
*/
$min_libPath = dirname(__FILE__) . '/lib';
/**
* To use APC/Memcache/ZendPlatform for cache storage, require the class and
* set $min_cachePath to an instance. Example below:
*/
//require dirname(__FILE__) . '/lib/Minify/Cache/APC.php';
//require "$min_libPath/Minify/Cache/APC.php";
//$min_cachePath = new Minify_Cache_APC();
@@ -187,12 +195,5 @@ $min_symlinks = array();
$min_uploaderHoursBehind = 0;
/**
* Path to Minify's lib folder. If you happen to move it, change
* this accordingly.
*/
$min_libPath = dirname(__FILE__) . '/lib';
// try to disable output_compression (may not have an effect)
ini_set('zlib.output_compression', '0');

View File

@@ -766,12 +766,12 @@ class CSSmin
{
if (is_string($size)) {
switch (substr($size, -1)) {
case 'M': case 'm': return $size * 1048576;
case 'K': case 'k': return $size * 1024;
case 'G': case 'g': return $size * 1073741824;
case 'M': case 'm': return (int) $size * 1048576;
case 'K': case 'k': return (int) $size * 1024;
case 'G': case 'g': return (int) $size * 1073741824;
}
}
return (int) $size;
}
}
}

View File

@@ -108,6 +108,11 @@ class JSMin {
$mbIntEnc = mb_internal_encoding();
mb_internal_encoding('8bit');
}
if (isset($this->input[0]) && $this->input[0] === "\xef") {
$this->input = substr($this->input, 3);
}
$this->input = str_replace("\r\n", "\n", $this->input);
$this->inputLength = strlen($this->input);
@@ -271,37 +276,39 @@ class JSMin {
protected function isRegexpLiteral()
{
if (false !== strpos("(,=:[!&|?+-~*{;", $this->a)) {
// we obviously aren't dividing
// we can't divide after these tokens
return true;
}
// we have to check for a preceding keyword, and we don't need to pattern
// match over the whole output.
$recentOutput = substr($this->output, -10);
// check if return/typeof directly precede a pattern without a space
foreach (array('return', 'typeof') as $keyword) {
if ($this->a !== substr($keyword, -1)) {
// certainly wasn't keyword
continue;
}
if (preg_match("~(^|[\\s\\S])" . substr($keyword, 0, -1) . "$~", $recentOutput, $m)) {
if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
return true;
}
// check if first non-ws token is "/" (see starts-regex.js)
$length = strlen($this->output);
if ($this->a === ' ' || $this->a === "\n") {
if ($length < 2) { // weird edge case
return true;
}
}
// check all keywords
if ($this->a === ' ' || $this->a === "\n") {
if (preg_match('~(^|[\\s\\S])(?:case|else|in|return|typeof)$~', $recentOutput, $m)) {
if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
return true;
}
}
// if the "/" follows a keyword, it must be a regexp, otherwise it's best to assume division
$subject = $this->output . trim($this->a);
if (!preg_match('/(?:case|else|in|return|typeof)$/', $subject, $m)) {
// not a keyword
return false;
}
return false;
// can't be sure it's a keyword yet (see not-regexp.js)
$charBeforeKeyword = substr($subject, 0 - strlen($m[0]) - 1, 1);
if ($this->isAlphaNum($charBeforeKeyword)) {
// this is really an identifier ending in a keyword, e.g. "xreturn"
return false;
}
// it's a regexp. Remove unneeded whitespace after keyword
if ($this->a === ' ' || $this->a === "\n") {
$this->a = '';
}
return true;
}
/**

View File

@@ -66,16 +66,20 @@ class Minify_CSS_UriRewriter {
self::$debugText .= "\n";
$css = self::_trimUrls($css);
$css = self::_owlifySvgPaths($css);
// rewrite
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
,array(self::$className, '_processUriCB'), $css);
$css = preg_replace_callback('/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/'
,array(self::$className, '_processUriCB'), $css);
$css = self::_unOwlify($css);
return $css;
}
/**
* In CSS content, prepend a path to relative URIs
*
@@ -90,6 +94,8 @@ class Minify_CSS_UriRewriter {
self::$_prependPath = $path;
$css = self::_trimUrls($css);
$css = self::_owlifySvgPaths($css);
// append
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
@@ -97,6 +103,8 @@ class Minify_CSS_UriRewriter {
$css = preg_replace_callback('/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/'
,array(self::$className, '_processUriCB'), $css);
$css = self::_unOwlify($css);
self::$_prependPath = null;
return $css;
}
@@ -282,6 +290,11 @@ class Minify_CSS_UriRewriter {
? $m[1]
: substr($m[1], 1, strlen($m[1]) - 2);
}
if ($uri === '') {
return $m[0];
}
// if not root/scheme relative and not starts with scheme
if (!preg_match('~^(/|[a-z]+\:)~', $uri)) {
// URI is file-relative: rewrite depending on options
@@ -304,4 +317,30 @@ class Minify_CSS_UriRewriter {
? "@import {$quoteChar}{$uri}{$quoteChar}"
: "url({$quoteChar}{$uri}{$quoteChar})";
}
/**
* Mungs some inline SVG URL declarations so they won't be touched
*
* @link https://github.com/mrclay/minify/issues/517
* @see _unOwlify
*
* @param string $css
* @return string
*/
private static function _owlifySvgPaths($css) {
return preg_replace('~\b((?:clip-path|mask|-webkit-mask)\s*\:\s*)url(\(\s*#\w+\s*\))~', '$1owl$2', $css);
}
/**
* Undo work of _owlify
*
* @see _owlifySvgPaths
*
* @param string $css
* @return string
*/
private static function _unOwlify($css) {
return preg_replace('~\b((?:clip-path|mask|-webkit-mask)\s*\:\s*)owl~', '$1url', $css);
}
}

View File

@@ -126,7 +126,9 @@ abstract class Minify_Controller_Base {
return true;
}
}
throw new Exception("File '$file' is outside \$allowDirs. If the path is"
$allowDirs = implode(';', array_values($allowDirs));
throw new Exception("File '$file' is outside \$allowDirs ($allowDirs). If the path is"
. " resolved via an alias/symlink, look into the \$min_symlinks option."
. " E.g. \$min_symlinks['/" . dirname($uri) . "'] = '" . dirname($file) . "';");
}

View File

@@ -53,7 +53,7 @@ class Minify_JS_ClosureCompiler {
/**
* @var string $url URL of compiler server. defaults to Google's
*/
protected $serviceUrl = 'http://closure-compiler.appspot.com/compile';
protected $serviceUrl = 'https://closure-compiler.appspot.com/compile';
/**
* @var int $maxBytes The maximum JS size that can be sent to the compiler server in bytes
@@ -172,6 +172,9 @@ class Minify_JS_ClosureCompiler {
$contents = file_get_contents($this->serviceUrl, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'compilation_level' => 'SIMPLE',
'output_format' => 'text',
'output_info' => 'compiled_code',
'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close\r\n",
'content' => $postBody,
'max_redirects' => 0,

View File

@@ -16,10 +16,13 @@ if (!$enabled) {
header('Content-Type: text/plain');
$file = __FILE__;
$tmp = sys_get_temp_dir();
echo <<<EOD
__FILE__ : $file
SCRIPT_FILENAME : {$_SERVER['SCRIPT_FILENAME']}
DOCUMENT_ROOT : {$_SERVER['DOCUMENT_ROOT']}
SCRIPT_NAME : {$_SERVER['SCRIPT_NAME']}
REQUEST_URI : {$_SERVER['REQUEST_URI']}
Cache directory : $tmp
EOD;

View File

@@ -8,10 +8,16 @@
@import url("/css/foo.css"); /* abs, should not alter */
@import url(/css2/foo.css); /* abs, should not alter */
@import url(foo:bar); /* scheme, should not alter */
@import url(); /* empty, should not alter */
foo {clip-path:url(#c1)} /* inline clip path, should not alter */
foo {clip-path:url(/_test_files/css_uriRewriter/foo.svg#c1)}
foo {mask: url(#c1)} /* should not alter */
foo {-webkit-mask: url(#c1)} /* should not alter */
foo {background:url('/_test_files/css_uriRewriter/bar/foo.png')}
foo {background:url('http://foo.com/css/foo.css');} /* scheme, should not alter */
foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */
foo {background:url(foo:bar);} /* scheme, should not alter */
foo {background:url("/_test_files/css_uriRewriter/foo bar.jpg");}
foo {background:url("");} /* empty, should not alter */
@import url('/_test_files/css_uriRewriter/foo bar.css');
@import "/_test_files/css_uriRewriter/foo bar.css";

View File

@@ -8,10 +8,16 @@
@import url("/css/foo.css"); /* abs, should not alter */
@import url(/css2/foo.css); /* abs, should not alter */
@import url(foo:bar); /* scheme, should not alter */
@import url(); /* empty, should not alter */
foo {clip-path:url(#c1)} /* inline clip path, should not alter */
foo {clip-path:url(http://cnd.com/A/B/foo.svg#c1)}
foo {mask: url(#c1)} /* should not alter */
foo {-webkit-mask: url(#c1)} /* should not alter */
foo {background:url('http://cnd.com/A/B/bar/foo.png')}
foo {background:url('http://foo.com/css/foo.css');} /* scheme, should not alter */
foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */
foo {background:url(foo:bar);} /* scheme, should not alter */
foo {background:url("http://cnd.com/A/B/foo bar.jpg");}
foo {background:url("");} /* empty, should not alter */
@import url('http://cnd.com/A/B/foo bar.css');
@import "http://cnd.com/A/B/foo bar.css";

View File

@@ -8,10 +8,16 @@
@import url("/css/foo.css"); /* abs, should not alter */
@import url(/css2/foo.css); /* abs, should not alter */
@import url(foo:bar); /* scheme, should not alter */
@import url(); /* empty, should not alter */
foo {clip-path:url(#c1)} /* inline clip path, should not alter */
foo {clip-path:url(//cnd.com/A/B/foo.svg#c1)}
foo {mask: url(#c1)} /* should not alter */
foo {-webkit-mask: url(#c1)} /* should not alter */
foo {background:url('//cnd.com/A/B/bar/foo.png')}
foo {background:url('http://foo.com/css/foo.css');} /* scheme, should not alter */
foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */
foo {background:url(foo:bar);} /* scheme, should not alter */
foo {background:url("//cnd.com/A/B/foo bar.jpg");}
foo {background:url("");} /* empty, should not alter */
@import url('//cnd.com/A/B/foo bar.css');
@import "//cnd.com/A/B/foo bar.css";

View File

@@ -8,10 +8,16 @@
@import url("/css/foo.css"); /* abs, should not alter */
@import url(/css2/foo.css); /* abs, should not alter */
@import url(foo:bar); /* scheme, should not alter */
@import url(); /* empty, should not alter */
foo {clip-path:url(#c1)} /* inline clip path, should not alter */
foo {clip-path:url(foo.svg#c1)}
foo {mask: url( #c1 )} /* should not alter */
foo {-webkit-mask: url( #c1 )} /* should not alter */
foo {background:url('bar/foo.png')}
foo {background:url('http://foo.com/css/foo.css');} /* scheme, should not alter */
foo {background:url("//foo.com/css/foo.css");} /* protocol relative, should not alter */
foo {background:url(foo:bar);} /* scheme, should not alter */
foo {background:url("foo bar.jpg");}
foo {background:url("");} /* empty, should not alter */
@import url('foo bar.css');
@import "foo bar.css";

View File

@@ -1,3 +1,2 @@
function testIssue74(){return /'/;}
!function(s){return /^[£$€?.]/.test(s);}();typeof
/ ' /;x=/ [/] /;1/foo;(2)/foo;function(){return/foo/};function(){return typeof/foo/};
function testIssue74(){return/'/;}
!function(s){return/^[£$€?.]/.test(s);}();typeof/ ' /;x=/ [/] /;1/foo;(2)/foo;function(){return/foo/};function(){return typeof/foo/};