diff options
| author | Jano Slota <jano@alokal.eu> | 2014-05-05 22:55:36 +0200 |
|---|---|---|
| committer | czaks <marcin@6irc.net> | 2014-05-07 11:17:32 +0200 |
| commit | c25b8f01c560ca97ca8a9dc217b495966aaa4d7f (patch) | |
| tree | 54d4c0aaa98a7cb581832094de4e707c9ae9ac93 /inc/lib/minify/Minify | |
| parent | 593560956c629fb2df9b97b5afe9c1eb2666652b (diff) | |
Updated minify, jQuery, MixItUp and Tooltipster
Diffstat (limited to 'inc/lib/minify/Minify')
| -rwxr-xr-x | inc/lib/minify/Minify/Build.php | 2 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/CSS.php | 22 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/CSS/UriRewriter.php | 11 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Cache/File.php | 4 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Controller/Base.php | 28 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Controller/Files.php | 2 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Controller/Groups.php | 2 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Controller/MinApp.php | 19 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Controller/Page.php | 19 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Controller/Version1.php | 11 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/HTML.php | 53 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/HTML/Helper.php | 54 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/JS/ClosureCompiler.php | 179 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/Lines.php | 10 | ||||
| -rwxr-xr-x | inc/lib/minify/Minify/YUICompressor.php | 20 |
15 files changed, 271 insertions, 165 deletions
diff --git a/inc/lib/minify/Minify/Build.php b/inc/lib/minify/Minify/Build.php index e625165e..1185fbe7 100755 --- a/inc/lib/minify/Minify/Build.php +++ b/inc/lib/minify/Minify/Build.php @@ -4,8 +4,6 @@ * @package Minify */ -require_once 'Minify/Source.php'; - /** * Maintain a single last modification time for a group of Minify sources to * allow use of far off Expires headers in Minify. diff --git a/inc/lib/minify/Minify/CSS.php b/inc/lib/minify/Minify/CSS.php index 49882e9d..32414551 100755 --- a/inc/lib/minify/Minify/CSS.php +++ b/inc/lib/minify/Minify/CSS.php @@ -56,6 +56,7 @@ class Minify_CSS { public static function minify($css, $options = array())
{
$options = array_merge(array(
+ 'compress' => true,
'removeCharsets' => true,
'preserveComments' => true,
'currentDir' => null,
@@ -67,21 +68,20 @@ class Minify_CSS { if ($options['removeCharsets']) {
$css = preg_replace('/@charset[^;]+;\\s*/', '', $css);
}
- require_once 'Minify/CSS/Compressor.php';
- if (! $options['preserveComments']) {
- $css = Minify_CSS_Compressor::process($css, $options);
- } else {
- require_once 'Minify/CommentPreserver.php';
- $css = Minify_CommentPreserver::process(
- $css
- ,array('Minify_CSS_Compressor', 'process')
- ,array($options)
- );
+ if ($options['compress']) {
+ if (! $options['preserveComments']) {
+ $css = Minify_CSS_Compressor::process($css, $options);
+ } else {
+ $css = Minify_CommentPreserver::process(
+ $css
+ ,array('Minify_CSS_Compressor', 'process')
+ ,array($options)
+ );
+ }
}
if (! $options['currentDir'] && ! $options['prependRelativePath']) {
return $css;
}
- require_once 'Minify/CSS/UriRewriter.php';
if ($options['currentDir']) {
return Minify_CSS_UriRewriter::rewrite(
$css
diff --git a/inc/lib/minify/Minify/CSS/UriRewriter.php b/inc/lib/minify/Minify/CSS/UriRewriter.php index 8845f156..43cc2548 100755 --- a/inc/lib/minify/Minify/CSS/UriRewriter.php +++ b/inc/lib/minify/Minify/CSS/UriRewriter.php @@ -70,7 +70,7 @@ class Minify_CSS_UriRewriter { // rewrite $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/' ,array(self::$className, '_processUriCB'), $css); - $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/' + $css = preg_replace_callback('/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/' ,array(self::$className, '_processUriCB'), $css); return $css; @@ -94,7 +94,7 @@ class Minify_CSS_UriRewriter { // append $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/' ,array(self::$className, '_processUriCB'), $css); - $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/' + $css = preg_replace_callback('/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/' ,array(self::$className, '_processUriCB'), $css); self::$_prependPath = null; @@ -282,11 +282,8 @@ class Minify_CSS_UriRewriter { ? $m[1] : substr($m[1], 1, strlen($m[1]) - 2); } - // analyze URI - if ('/' !== $uri[0] // root-relative - && false === strpos($uri, '//') // protocol (non-data) - && 0 !== strpos($uri, 'data:') // data protocol - ) { + // if not root/scheme relative and not starts with scheme + if (!preg_match('~^(/|[a-z]+\:)~', $uri)) { // URI is file-relative: rewrite depending on options if (self::$_prependPath === null) { $uri = self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks); diff --git a/inc/lib/minify/Minify/Cache/File.php b/inc/lib/minify/Minify/Cache/File.php index 3fa6b18f..c228eb2b 100755 --- a/inc/lib/minify/Minify/Cache/File.php +++ b/inc/lib/minify/Minify/Cache/File.php @@ -98,6 +98,9 @@ class Minify_Cache_File { { if ($this->_locking) { $fp = fopen($this->_path . '/' . $id, 'rb'); + if (!$fp) { + return false; + } flock($fp, LOCK_SH); $ret = stream_get_contents($fp); flock($fp, LOCK_UN); @@ -186,7 +189,6 @@ class Minify_Cache_File { */ protected function _log($msg) { - require_once 'Minify/Logger.php'; Minify_Logger::log($msg); } diff --git a/inc/lib/minify/Minify/Controller/Base.php b/inc/lib/minify/Minify/Controller/Base.php index 240b5449..5a863290 100755 --- a/inc/lib/minify/Minify/Controller/Base.php +++ b/inc/lib/minify/Minify/Controller/Base.php @@ -79,33 +79,6 @@ abstract class Minify_Controller_Base { } /** - * Load any code necessary to execute the given minifier callback. - * - * The controller is responsible for loading minification code on demand - * via this method. This built-in function will only load classes for - * static method callbacks where the class isn't already defined. It uses - * the PEAR convention, so, given array('Jimmy_Minifier', 'minCss'), this - * function will include 'Jimmy/Minifier.php'. - * - * If you need code loaded on demand and this doesn't suit you, you'll need - * to override this function in your subclass. - * @see Minify_Controller_Page::loadMinifier() - * - * @param callback $minifierCallback callback of minifier function - * - * @return null - */ - public function loadMinifier($minifierCallback) - { - if (is_array($minifierCallback) - && is_string($minifierCallback[0]) - && !class_exists($minifierCallback[0], false)) { - - require str_replace('_', '/', $minifierCallback[0]) . '.php'; - } - } - - /** * Is a user-given file within an allowable directory, existing, * and having an extension js/css/html/txt ? * @@ -244,7 +217,6 @@ abstract class Minify_Controller_Base { * @return null */ public function log($msg) { - require_once 'Minify/Logger.php'; Minify_Logger::log($msg); } } diff --git a/inc/lib/minify/Minify/Controller/Files.php b/inc/lib/minify/Minify/Controller/Files.php index 83f028ad..f084cd07 100755 --- a/inc/lib/minify/Minify/Controller/Files.php +++ b/inc/lib/minify/Minify/Controller/Files.php @@ -4,8 +4,6 @@ * @package Minify */ -require_once 'Minify/Controller/Base.php'; - /** * Controller class for minifying a set of files * diff --git a/inc/lib/minify/Minify/Controller/Groups.php b/inc/lib/minify/Minify/Controller/Groups.php index 2d4e43b2..c4c25db1 100755 --- a/inc/lib/minify/Minify/Controller/Groups.php +++ b/inc/lib/minify/Minify/Controller/Groups.php @@ -4,8 +4,6 @@ * @package Minify */ -require_once 'Minify/Controller/Base.php'; - /** * Controller class for serving predetermined groups of minimized sets, selected * by PATH_INFO diff --git a/inc/lib/minify/Minify/Controller/MinApp.php b/inc/lib/minify/Minify/Controller/MinApp.php index d47c60d9..6943ee6b 100755 --- a/inc/lib/minify/Minify/Controller/MinApp.php +++ b/inc/lib/minify/Minify/Controller/MinApp.php @@ -4,8 +4,6 @@ * @package Minify */ -require_once 'Minify/Controller/Base.php'; - /** * Controller class for requests to /min/index.php * @@ -22,6 +20,13 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { * @return array Minify options */ public function setupSources($options) { + // PHP insecure by default: realpath() and other FS functions can't handle null bytes. + foreach (array('g', 'b', 'f') as $key) { + if (isset($_GET[$key])) { + $_GET[$key] = str_replace("\x00", '', (string)$_GET[$key]); + } + } + // filter controller options $cOptions = array_merge( array( @@ -36,7 +41,6 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { $sources = array(); $this->selectionId = ''; $firstMissingResource = null; - if (isset($_GET['g'])) { // add group(s) $this->selectionId .= 'g=' . $_GET['g']; @@ -195,9 +199,12 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { protected function _getFileSource($file, $cOptions) { $spec['filepath'] = $file; - if ($cOptions['noMinPattern'] - && preg_match($cOptions['noMinPattern'], basename($file))) { - $spec['minifier'] = ''; + if ($cOptions['noMinPattern'] && preg_match($cOptions['noMinPattern'], basename($file))) { + if (preg_match('~\.css$~i', $file)) { + $spec['minifyOptions']['compress'] = false; + } else { + $spec['minifier'] = ''; + } } return new Minify_Source($spec); } diff --git a/inc/lib/minify/Minify/Controller/Page.php b/inc/lib/minify/Minify/Controller/Page.php index de471e12..1095fb46 100755 --- a/inc/lib/minify/Minify/Controller/Page.php +++ b/inc/lib/minify/Minify/Controller/Page.php @@ -4,8 +4,6 @@ * @package Minify */ -require_once 'Minify/Controller/Base.php'; - /** * Controller class for serving a single HTML page * @@ -59,7 +57,6 @@ class Minify_Controller_Page extends Minify_Controller_Base { 'cssMinifier' => array('Minify_CSS', 'minify') ,'jsMinifier' => array('JSMin', 'minify') ); - $this->_loadCssJsMinifiers = true; unset($options['minifyAll']); } $this->sources[] = new Minify_Source($sourceSpec); @@ -67,21 +64,5 @@ class Minify_Controller_Page extends Minify_Controller_Base { $options['contentType'] = Minify::TYPE_HTML; return $options; } - - protected $_loadCssJsMinifiers = false; - - /** - * @see Minify_Controller_Base::loadMinifier() - */ - public function loadMinifier($minifierCallback) - { - if ($this->_loadCssJsMinifiers) { - // Minify will not call for these so we must manually load - // them when Minify/HTML.php is called for. - require_once 'Minify/CSS.php'; - require_once 'JSMin.php'; - } - parent::loadMinifier($minifierCallback); // load Minify/HTML.php - } } diff --git a/inc/lib/minify/Minify/Controller/Version1.php b/inc/lib/minify/Minify/Controller/Version1.php index 5279d36d..91fcf614 100755 --- a/inc/lib/minify/Minify/Controller/Version1.php +++ b/inc/lib/minify/Minify/Controller/Version1.php @@ -4,8 +4,6 @@ * @package Minify */ -require_once 'Minify/Controller/Base.php'; - /** * Controller class for emulating version 1 of minify.php (mostly a proof-of-concept) * @@ -26,6 +24,11 @@ class Minify_Controller_Version1 extends Minify_Controller_Base { * */ public function setupSources($options) { + // PHP insecure by default: realpath() and other FS functions can't handle null bytes. + if (isset($_GET['files'])) { + $_GET['files'] = str_replace("\x00", '', (string)$_GET['files']); + } + self::_setupDefines(); if (MINIFY_USE_CACHE) { $cacheDir = defined('MINIFY_CACHE_DIR') @@ -51,8 +54,7 @@ class Minify_Controller_Version1 extends Minify_Controller_Base { ) { return $options; } - $extension = $m[1]; - + $files = explode(',', $_GET['files']); if (count($files) > MINIFY_MAX_FILES) { return $options; @@ -63,7 +65,6 @@ class Minify_Controller_Version1 extends Minify_Controller_Base { . DIRECTORY_SEPARATOR; $prependAbsPaths = $_SERVER['DOCUMENT_ROOT']; - $sources = array(); $goodFiles = array(); $hasBadSource = false; diff --git a/inc/lib/minify/Minify/HTML.php b/inc/lib/minify/Minify/HTML.php index e9453ffb..40f73076 100755 --- a/inc/lib/minify/Minify/HTML.php +++ b/inc/lib/minify/Minify/HTML.php @@ -1,22 +1,26 @@ <?php
/**
- * Class Minify_HTML
+ * Class Minify_HTML
* @package Minify
*/
/**
* Compress HTML
*
- * This is a heavy regex-based removal of whitespace, unnecessary comments and
+ * This is a heavy regex-based removal of whitespace, unnecessary comments and
* tokens. IE conditional comments are preserved. There are also options to have
- * STYLE and SCRIPT blocks compressed by callback functions.
- *
+ * STYLE and SCRIPT blocks compressed by callback functions.
+ *
* A test suite is available.
- *
+ *
* @package Minify
* @author Stephen Clay <steve@mrclay.org>
*/
class Minify_HTML {
+ /**
+ * @var boolean
+ */
+ protected $_jsCleanComments = true;
/**
* "Minify" an HTML page
@@ -27,21 +31,21 @@ class Minify_HTML { *
* 'cssMinifier' : (optional) callback function to process content of STYLE
* elements.
- *
+ *
* 'jsMinifier' : (optional) callback function to process content of SCRIPT
* elements. Note: the type attribute is ignored.
- *
+ *
* 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
* unset, minify will sniff for an XHTML doctype.
- *
+ *
* @return string
*/
public static function minify($html, $options = array()) {
- $min = new Minify_HTML($html, $options);
+ $min = new self($html, $options);
return $min->process();
}
-
-
+
+
/**
* Create a minifier object
*
@@ -51,14 +55,14 @@ class Minify_HTML { *
* 'cssMinifier' : (optional) callback function to process content of STYLE
* elements.
- *
+ *
* 'jsMinifier' : (optional) callback function to process content of SCRIPT
* elements. Note: the type attribute is ignored.
- *
+ *
+ * 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block
+ *
* 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
* unset, minify will sniff for an XHTML doctype.
- *
- * @return null
*/
public function __construct($html, $options = array())
{
@@ -72,9 +76,12 @@ class Minify_HTML { if (isset($options['jsMinifier'])) {
$this->_jsMinifier = $options['jsMinifier'];
}
+ if (isset($options['jsCleanComments'])) {
+ $this->_jsCleanComments = (bool)$options['jsCleanComments'];
+ }
}
-
-
+
+
/**
* Minify the markeup given in the constructor
*
@@ -124,7 +131,7 @@ class Minify_HTML { // remove ws around block/undisplayed elements
$this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body'
- .'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
+ .'|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
.'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta'
.'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)'
.'|ul)\\b[^>]*>)/i', '$1', $this->_html);
@@ -213,17 +220,19 @@ class Minify_HTML { // whitespace surrounding? preserve at least one space
$ws1 = ($m[1] === '') ? '' : ' ';
$ws2 = ($m[4] === '') ? '' : ' ';
-
+
// remove HTML comments (and ending "//" if present)
- $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
-
+ if ($this->_jsCleanComments) {
+ $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
+ }
+
// remove CDATA section markers
$js = $this->_removeCdata($js);
// minify
$minifier = $this->_jsMinifier
? $this->_jsMinifier
- : 'trim';
+ : 'trim';
$js = call_user_func($minifier, $js);
return $this->_reservePlace($this->_needsCdata($js)
diff --git a/inc/lib/minify/Minify/HTML/Helper.php b/inc/lib/minify/Minify/HTML/Helper.php index 807fdc9c..f92ab854 100755 --- a/inc/lib/minify/Minify/HTML/Helper.php +++ b/inc/lib/minify/Minify/HTML/Helper.php @@ -15,10 +15,10 @@ class Minify_HTML_Helper { public $minAppUri = '/min'; public $groupsConfigFile = ''; - /* + /** * Get an HTML-escaped Minify URI for a group or set of files * - * @param mixed $keyOrFiles a group key or array of filepaths/URIs + * @param string|array $keyOrFiles a group key or array of filepaths/URIs * @param array $opts options: * 'farExpires' : (default true) append a modified timestamp for cache revving * 'debug' : (default false) append debug flag @@ -51,8 +51,12 @@ class Minify_HTML_Helper { return htmlspecialchars($uri, ENT_QUOTES, $opts['charset']); } - /* + /** * Get non-HTML-escaped URI to minify the specified files + * + * @param bool $farExpires + * @param bool $debug + * @return string */ public function getRawUri($farExpires = true, $debug = false) { @@ -74,6 +78,12 @@ class Minify_HTML_Helper { return $path; } + /** + * Set the files that will comprise the URI we're building + * + * @param array $files + * @param bool $checkLastModified + */ public function setFiles($files, $checkLastModified = true) { $this->_groupKey = null; @@ -94,6 +104,12 @@ class Minify_HTML_Helper { $this->_filePaths = $files; } + /** + * Set the group of files that will comprise the URI we're building + * + * @param string $key + * @param bool $checkLastModified + */ public function setGroup($key, $checkLastModified = true) { $this->_groupKey = $key; @@ -103,13 +119,23 @@ class Minify_HTML_Helper { } if (is_file($this->groupsConfigFile)) { $gc = (require $this->groupsConfigFile); - if (isset($gc[$key])) { - $this->_lastModified = self::getLastModified($gc[$key]); + $keys = explode(',', $key); + foreach ($keys as $key) { + if (isset($gc[$key])) { + $this->_lastModified = self::getLastModified($gc[$key], $this->_lastModified); + } } } } } - + + /** + * Get the max(lastModified) of all files + * + * @param array|string $sources + * @param int $lastModified + * @return int + */ public static function getLastModified($sources, $lastModified = 0) { $max = $lastModified; @@ -142,13 +168,19 @@ class Minify_HTML_Helper { * @return mixed a common char or '' if any do not match */ protected static function _getCommonCharAtPos($arr, $pos) { - $l = count($arr); + if (!isset($arr[0][$pos])) { + return ''; + } $c = $arr[0][$pos]; - if ($c === '' || $l === 1) + $l = count($arr); + if ($l === 1) { return $c; - for ($i = 1; $i < $l; ++$i) - if ($arr[$i][$pos] !== $c) + } + for ($i = 1; $i < $l; ++$i) { + if ($arr[$i][$pos] !== $c) { return ''; + } + } return $c; } @@ -157,11 +189,11 @@ class Minify_HTML_Helper { * * @param array $paths root-relative URIs of files * @param string $minRoot root-relative URI of the "min" application + * @return string */ protected static function _getShortestUri($paths, $minRoot = '/min/') { $pos = 0; $base = ''; - $c; while (true) { $c = self::_getCommonCharAtPos($paths, $pos); if ($c === '') { diff --git a/inc/lib/minify/Minify/JS/ClosureCompiler.php b/inc/lib/minify/Minify/JS/ClosureCompiler.php index f4ed5bdb..e067d7c8 100755 --- a/inc/lib/minify/Minify/JS/ClosureCompiler.php +++ b/inc/lib/minify/Minify/JS/ClosureCompiler.php @@ -14,13 +14,68 @@ * @todo can use a stream wrapper to unit test this? */ class Minify_JS_ClosureCompiler { - const URL = 'http://closure-compiler.appspot.com/compile'; /** - * Minify Javascript code via HTTP request to the Closure Compiler API + * @var string The option key for the maximum POST byte size + */ + const OPTION_MAX_BYTES = 'maxBytes'; + + /** + * @var string The option key for additional params. @see __construct + */ + const OPTION_ADDITIONAL_OPTIONS = 'additionalParams'; + + /** + * @var string The option key for the fallback Minifier + */ + const OPTION_FALLBACK_FUNCTION = 'fallbackFunc'; + + /** + * @var string The option key for the service URL + */ + const OPTION_COMPILER_URL = 'compilerUrl'; + + /** + * @var int The default maximum POST byte size according to https://developers.google.com/closure/compiler/docs/api-ref + */ + const DEFAULT_MAX_BYTES = 200000; + + /** + * @var string[] $DEFAULT_OPTIONS The default options to pass to the compiler service + * + * @note This would be a constant if PHP allowed it + */ + private static $DEFAULT_OPTIONS = array( + 'output_format' => 'text', + 'compilation_level' => 'SIMPLE_OPTIMIZATIONS' + ); + + /** + * @var string $url URL of compiler server. defaults to Google's + */ + protected $serviceUrl = 'http://closure-compiler.appspot.com/compile'; + + /** + * @var int $maxBytes The maximum JS size that can be sent to the compiler server in bytes + */ + protected $maxBytes = self::DEFAULT_MAX_BYTES; + + /** + * @var string[] $additionalOptions Additional options to pass to the compiler service + */ + protected $additionalOptions = array(); + + /** + * @var callable Function to minify JS if service fails. Default is JSMin + */ + protected $fallbackMinifier = array('JSMin', 'minify'); + + /** + * Minify JavaScript code via HTTP request to a Closure Compiler API * * @param string $js input code - * @param array $options unused at this point + * @param array $options Options passed to __construct(). @see __construct + * * @return string */ public static function minify($js, array $options = array()) @@ -30,63 +85,101 @@ class Minify_JS_ClosureCompiler { } /** + * @param array $options Options with keys available below: + * + * fallbackFunc : (callable) function to minify if service unavailable. Default is JSMin. * - * @param array $options + * compilerUrl : (string) URL to closure compiler server * - * fallbackFunc : default array($this, 'fallback'); + * maxBytes : (int) The maximum amount of bytes to be sent as js_code in the POST request. + * Defaults to 200000. + * + * additionalParams : (string[]) Additional parameters to pass to the compiler server. Can be anything named + * in https://developers.google.com/closure/compiler/docs/api-ref except for js_code and + * output_info */ public function __construct(array $options = array()) { - $this->_fallbackFunc = isset($options['fallbackMinifier']) - ? $options['fallbackMinifier'] - : array($this, '_fallback'); + if (isset($options[self::OPTION_FALLBACK_FUNCTION])) { + $this->fallbackMinifier = $options[self::OPTION_FALLBACK_FUNCTION]; + } + if (isset($options[self::OPTION_COMPILER_URL])) { + $this->serviceUrl = $options[self::OPTION_COMPILER_URL]; + } + if (isset($options[self::OPTION_ADDITIONAL_OPTIONS]) && is_array($options[self::OPTION_ADDITIONAL_OPTIONS])) { + $this->additionalOptions = $options[self::OPTION_ADDITIONAL_OPTIONS]; + } + if (isset($options[self::OPTION_MAX_BYTES])) { + $this->maxBytes = (int) $options[self::OPTION_MAX_BYTES]; + } } + /** + * Call the service to perform the minification + * + * @param string $js JavaScript code + * @return string + * @throws Minify_JS_ClosureCompiler_Exception + */ public function min($js) { - $postBody = $this->_buildPostBody($js); - $bytes = (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) - ? mb_strlen($postBody, '8bit') - : strlen($postBody); - if ($bytes > 200000) { - throw new Minify_JS_ClosureCompiler_Exception( - 'POST content larger than 200000 bytes' - ); + $postBody = $this->buildPostBody($js); + + if ($this->maxBytes > 0) { + $bytes = (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) + ? mb_strlen($postBody, '8bit') + : strlen($postBody); + if ($bytes > $this->maxBytes) { + throw new Minify_JS_ClosureCompiler_Exception( + 'POST content larger than ' . $this->maxBytes . ' bytes' + ); + } } - $response = $this->_getResponse($postBody); + + $response = $this->getResponse($postBody); + if (preg_match('/^Error\(\d\d?\):/', $response)) { - if (is_callable($this->_fallbackFunc)) { + if (is_callable($this->fallbackMinifier)) { + // use fallback $response = "/* Received errors from Closure Compiler API:\n$response" . "\n(Using fallback minifier)\n*/\n"; - $response .= call_user_func($this->_fallbackFunc, $js); + $response .= call_user_func($this->fallbackMinifier, $js); } else { throw new Minify_JS_ClosureCompiler_Exception($response); } } + if ($response === '') { - $errors = $this->_getResponse($this->_buildPostBody($js, true)); + $errors = $this->getResponse($this->buildPostBody($js, true)); throw new Minify_JS_ClosureCompiler_Exception($errors); } + return $response; } - - protected $_fallbackFunc = null; - protected function _getResponse($postBody) + /** + * Get the response for a given POST body + * + * @param string $postBody + * @return string + * @throws Minify_JS_ClosureCompiler_Exception + */ + protected function getResponse($postBody) { $allowUrlFopen = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen')); + if ($allowUrlFopen) { - $contents = file_get_contents(self::URL, false, stream_context_create(array( + $contents = file_get_contents($this->serviceUrl, false, stream_context_create(array( 'http' => array( 'method' => 'POST', - 'header' => 'Content-type: application/x-www-form-urlencoded', + 'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close\r\n", 'content' => $postBody, 'max_redirects' => 0, 'timeout' => 15, ) ))); } elseif (defined('CURLOPT_POST')) { - $ch = curl_init(self::URL); + $ch = curl_init($this->serviceUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); @@ -100,33 +193,37 @@ class Minify_JS_ClosureCompiler { "Could not make HTTP request: allow_url_open is false and cURL not available" ); } + if (false === $contents) { throw new Minify_JS_ClosureCompiler_Exception( "No HTTP response from server" ); } - return trim($contents); - } - protected function _buildPostBody($js, $returnErrors = false) - { - return http_build_query(array( - 'js_code' => $js, - 'output_info' => ($returnErrors ? 'errors' : 'compiled_code'), - 'output_format' => 'text', - 'compilation_level' => 'SIMPLE_OPTIMIZATIONS' - ), null, '&'); + return trim($contents); } /** - * Default fallback function if CC API fails - * @param string $js + * Build a POST request body + * + * @param string $js JavaScript code + * @param bool $returnErrors * @return string */ - protected function _fallback($js) + protected function buildPostBody($js, $returnErrors = false) { - require_once 'JSMin.php'; - return JSMin::minify($js); + return http_build_query( + array_merge( + self::$DEFAULT_OPTIONS, + $this->additionalOptions, + array( + 'js_code' => $js, + 'output_info' => ($returnErrors ? 'errors' : 'compiled_code') + ) + ), + null, + '&' + ); } } diff --git a/inc/lib/minify/Minify/Lines.php b/inc/lib/minify/Minify/Lines.php index ca8afa1b..e999a6c2 100755 --- a/inc/lib/minify/Minify/Lines.php +++ b/inc/lib/minify/Minify/Lines.php @@ -55,7 +55,11 @@ class Minify_Lines { $newLines = array(); while (null !== ($line = array_shift($lines))) { if (('' !== $id) && (0 == $i % 50)) { - array_push($newLines, '', "/* {$id} */", ''); + if ($inComment) { + array_push($newLines, '', "/* {$id} *|", ''); + } else { + array_push($newLines, '', "/* {$id} */", ''); + } } ++$i; $newLines[] = self::_addNote($line, $i, $inComment, $padTo); @@ -65,7 +69,6 @@ class Minify_Lines { // check for desired URI rewriting if (isset($options['currentDir'])) { - require_once 'Minify/CSS/UriRewriter.php'; Minify_CSS_UriRewriter::$debugText = ''; $content = Minify_CSS_UriRewriter::rewrite( $content @@ -93,6 +96,9 @@ class Minify_Lines { */ private static function _eolInComment($line, $inComment) { + // crude way to avoid things like // */ + $line = preg_replace('~//.*?(\\*/|/\\*).*~', '', $line); + while (strlen($line)) { $search = $inComment ? '*/' diff --git a/inc/lib/minify/Minify/YUICompressor.php b/inc/lib/minify/Minify/YUICompressor.php index c5bd8a1e..5762e890 100755 --- a/inc/lib/minify/Minify/YUICompressor.php +++ b/inc/lib/minify/Minify/YUICompressor.php @@ -13,14 +13,17 @@ * Java environment. * * <code> - * Minify_YUICompressor::$jarFile = '/path/to/yuicompressor-2.3.5.jar'; + * Minify_YUICompressor::$jarFile = '/path/to/yuicompressor-2.4.6.jar'; * Minify_YUICompressor::$tempDir = '/tmp'; * $code = Minify_YUICompressor::minifyJs( * $code * ,array('nomunge' => true, 'line-break' => 1000) * ); * </code> - * + * + * Note: In case you run out stack (default is 512k), you may increase stack size in $options: + * array('stack-size' => '2048k') + * * @todo unit tests, $options docs * * @package Minify @@ -87,7 +90,7 @@ class Minify_YUICompressor { { self::_prepare(); if (! ($tmpFile = tempnam(self::$tempDir, 'yuic_'))) { - throw new Exception('Minify_YUICompressor : could not create temp file.'); + throw new Exception('Minify_YUICompressor : could not create temp file in "'.self::$tempDir.'".'); } file_put_contents($tmpFile, $content); exec(self::_getCmd($options, $type, $tmpFile), $output, $result_code); @@ -108,10 +111,15 @@ class Minify_YUICompressor { ,'nomunge' => false ,'preserve-semi' => false ,'disable-optimizations' => false + ,'stack-size' => '' ) ,$userOptions ); - $cmd = self::$javaExecutable . ' -jar ' . escapeshellarg(self::$jarFile) + $cmd = self::$javaExecutable + . (!empty($o['stack-size']) + ? ' -Xss' . $o['stack-size'] + : '') + . ' -jar ' . escapeshellarg(self::$jarFile) . " --type {$type}" . (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $o['charset']) ? " --charset {$o['charset']}" @@ -134,8 +142,8 @@ class Minify_YUICompressor { if (! is_file(self::$jarFile)) { throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not a valid file.'); } - if (! is_executable(self::$jarFile)) { - throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not executable.'); + if (! is_readable(self::$jarFile)) { + throw new Exception('Minify_YUICompressor : $jarFile('.self::$jarFile.') is not readable.'); } if (! is_dir(self::$tempDir)) { throw new Exception('Minify_YUICompressor : $tempDir('.self::$tempDir.') is not a valid direcotry.'); |
