summaryrefslogtreecommitdiff
path: root/inc/lib/minify/Minify
diff options
context:
space:
mode:
authorJano Slota <jano@alokal.eu>2014-05-05 22:55:36 +0200
committerczaks <marcin@6irc.net>2014-05-07 11:17:32 +0200
commitc25b8f01c560ca97ca8a9dc217b495966aaa4d7f (patch)
tree54d4c0aaa98a7cb581832094de4e707c9ae9ac93 /inc/lib/minify/Minify
parent593560956c629fb2df9b97b5afe9c1eb2666652b (diff)
Updated minify, jQuery, MixItUp and Tooltipster
Diffstat (limited to 'inc/lib/minify/Minify')
-rwxr-xr-xinc/lib/minify/Minify/Build.php2
-rwxr-xr-xinc/lib/minify/Minify/CSS.php22
-rwxr-xr-xinc/lib/minify/Minify/CSS/UriRewriter.php11
-rwxr-xr-xinc/lib/minify/Minify/Cache/File.php4
-rwxr-xr-xinc/lib/minify/Minify/Controller/Base.php28
-rwxr-xr-xinc/lib/minify/Minify/Controller/Files.php2
-rwxr-xr-xinc/lib/minify/Minify/Controller/Groups.php2
-rwxr-xr-xinc/lib/minify/Minify/Controller/MinApp.php19
-rwxr-xr-xinc/lib/minify/Minify/Controller/Page.php19
-rwxr-xr-xinc/lib/minify/Minify/Controller/Version1.php11
-rwxr-xr-xinc/lib/minify/Minify/HTML.php53
-rwxr-xr-xinc/lib/minify/Minify/HTML/Helper.php54
-rwxr-xr-xinc/lib/minify/Minify/JS/ClosureCompiler.php179
-rwxr-xr-xinc/lib/minify/Minify/Lines.php10
-rwxr-xr-xinc/lib/minify/Minify/YUICompressor.php20
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.');