mirror of
https://github.com/mrclay/minify.git
synced 2025-04-21 04:41:54 +02:00
Perf update for JSmin (Minify_Javascript), + phpDocs for public HTTP_* class APIs, minor Minify fix, private members changed to protected to allow easier subclassing.
This commit is contained in:
parent
7a3d7129b4
commit
e8ac1dc8d0
@ -32,49 +32,43 @@
|
||||
*/
|
||||
class HTTP_ConditionalGet {
|
||||
|
||||
private $headers = array();
|
||||
private $lmTime = null;
|
||||
private $etag = null;
|
||||
/**
|
||||
* Does the client have a valid copy of the requested resource?
|
||||
*
|
||||
* You'll want to check this after instantiating the object. If true, do
|
||||
* not send content, just call sendHeaders() if you haven't already.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $cacheIsValid = null;
|
||||
|
||||
public function getHeaders() {
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on the PHP config, PHP will buffer all output and set
|
||||
* Content-Length for you. If it doesn't, or you flush() while sending data,
|
||||
* you'll want to call this to let the client know up front.
|
||||
* @param array $spec options
|
||||
*
|
||||
* 'isPublic': (bool) if true, the Cache-Control header will contain
|
||||
* "public", allowing proxy caches to cache the content. Otherwise
|
||||
* "private" will be sent, allowing only browsers to cache. (default false)
|
||||
*
|
||||
* 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers
|
||||
* will be sent with content. This is recommended.
|
||||
*
|
||||
* 'contentHash': (string) if given, only the ETag header can be sent with
|
||||
* content (only HTTP1.1 clients can conditionally GET). The given string
|
||||
* should be short with no quote characters and always change when the
|
||||
* resource changes (recommend md5()). This is not needed/used if
|
||||
* lastModifiedTime is given.
|
||||
*
|
||||
* 'invalidate': (bool) if true, the client cache will be considered invalid
|
||||
* without testing. Effectively this disables conditional GET.
|
||||
* (default false)
|
||||
*
|
||||
* 'setExpires': (mixed) set this to a timestamp or GMT date to send an
|
||||
* Expires header with the content instead of ETag/Last-Modified. If given,
|
||||
* Conditional GETs will not be performed, but the public/private
|
||||
* Cache-Control header will still be sent. (default null)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function setContentLength($bytes) {
|
||||
return $this->headers['Content-Length'] = $bytes;
|
||||
}
|
||||
|
||||
public function sendHeaders() {
|
||||
$headers = $this->headers;
|
||||
if (array_key_exists('_responseCode', $headers)) {
|
||||
header($headers['_responseCode']);
|
||||
unset($headers['_responseCode']);
|
||||
}
|
||||
foreach ($headers as $name => $val) {
|
||||
header($name . ': ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
private function setEtag($hash, $scope) {
|
||||
$this->etag = '"' . $hash
|
||||
. substr($scope, 0, 3)
|
||||
. '"';
|
||||
$this->headers['ETag'] = $this->etag;
|
||||
}
|
||||
|
||||
private function setLastModified($time) {
|
||||
$this->lmTime = (int)$time;
|
||||
$this->headers['Last-Modified'] = self::gmtdate($time);
|
||||
}
|
||||
|
||||
// TODO: allow custom Cache-Control directives, but offer pre-configured
|
||||
// "modes" for common cache models
|
||||
public function __construct($spec) {
|
||||
$scope = (isset($spec['isPublic']) && $spec['isPublic'])
|
||||
? 'public'
|
||||
@ -84,7 +78,7 @@ class HTTP_ConditionalGet {
|
||||
if (is_numeric($spec['setExpires'])) {
|
||||
$spec['setExpires'] = self::gmtdate($spec['setExpires']);
|
||||
}
|
||||
$this->headers = array(
|
||||
$this->_headers = array(
|
||||
'Cache-Control' => $scope
|
||||
,'Expires' => $spec['setExpires']
|
||||
);
|
||||
@ -93,41 +87,114 @@ class HTTP_ConditionalGet {
|
||||
}
|
||||
if (isset($spec['lastModifiedTime'])) {
|
||||
// base both headers on time
|
||||
$this->setLastModified($spec['lastModifiedTime']);
|
||||
$this->setEtag($spec['lastModifiedTime'], $scope);
|
||||
$this->_setLastModified($spec['lastModifiedTime']);
|
||||
$this->_setEtag($spec['lastModifiedTime'], $scope);
|
||||
} else {
|
||||
// hope to use ETag
|
||||
if (isset($spec['contentHash'])) {
|
||||
$this->setEtag($spec['contentHash'], $scope);
|
||||
$this->_setEtag($spec['contentHash'], $scope);
|
||||
}
|
||||
}
|
||||
$this->headers['Cache-Control'] = "max-age=0, {$scope}, must-revalidate";
|
||||
$this->_headers['Cache-Control'] = "max-age=0, {$scope}, must-revalidate";
|
||||
// invalidate cache if disabled, otherwise check
|
||||
$this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate'])
|
||||
? false
|
||||
: $this->isCacheValid();
|
||||
: $this->_isCacheValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of output headers to be sent
|
||||
*
|
||||
* In the case of 304 responses, this array will only contain the response
|
||||
* code header: array('_responseCode' => 'HTTP/1.0 304 Not Modified')
|
||||
*
|
||||
* Otherwise something like:
|
||||
* <code>
|
||||
* array(
|
||||
* 'Cache-Control' => 'max-age=0, public, must-revalidate'
|
||||
* ,'ETag' => '"foobar"'
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Content-Length header in bytes
|
||||
*
|
||||
* With most PHP configs, as long as you don't flush() output, this method
|
||||
* is not needed and PHP will buffer all output and set Content-Length for
|
||||
* you. Otherwise you'll want to call this to let the client know up front.
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @return int copy of input $bytes
|
||||
*/
|
||||
public function setContentLength($bytes) {
|
||||
return $this->_headers['Content-Length'] = $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send headers
|
||||
*
|
||||
* @see getHeaders()
|
||||
*
|
||||
* Note this doesn't "clear" the headers. Calling sendHeaders() will
|
||||
* call header() again (but probably have not effect) and getHeaders() will
|
||||
* still return the headers.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function sendHeaders() {
|
||||
$headers = $this->_headers;
|
||||
if (array_key_exists('_responseCode', $headers)) {
|
||||
header($headers['_responseCode']);
|
||||
unset($headers['_responseCode']);
|
||||
}
|
||||
foreach ($headers as $name => $val) {
|
||||
header($name . ': ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
protected $_headers = array();
|
||||
protected $_lmTime = null;
|
||||
protected $_etag = null;
|
||||
|
||||
protected function _setEtag($hash, $scope) {
|
||||
$this->_etag = '"' . $hash
|
||||
. substr($scope, 0, 3)
|
||||
. '"';
|
||||
$this->_headers['ETag'] = $this->_etag;
|
||||
}
|
||||
|
||||
protected function _setLastModified($time) {
|
||||
$this->_lmTime = (int)$time;
|
||||
$this->_headers['Last-Modified'] = self::gmtdate($time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine validity of client cache and queue 304 header if valid
|
||||
*/
|
||||
private function isCacheValid()
|
||||
protected function _isCacheValid()
|
||||
{
|
||||
if (null === $this->etag) {
|
||||
if (null === $this->_etag) {
|
||||
// ETag was our backup, so we know we don't have lmTime either
|
||||
return false;
|
||||
}
|
||||
$isValid = ($this->resourceMatchedEtag() || $this->resourceNotModified());
|
||||
if ($isValid) {
|
||||
// overwrite headers, only need 304
|
||||
$this->headers = array(
|
||||
$this->_headers = array(
|
||||
'_responseCode' => 'HTTP/1.0 304 Not Modified'
|
||||
);
|
||||
}
|
||||
return $isValid;
|
||||
}
|
||||
|
||||
private function resourceMatchedEtag() {
|
||||
protected function resourceMatchedEtag() {
|
||||
if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
return false;
|
||||
}
|
||||
@ -136,14 +203,14 @@ class HTTP_ConditionalGet {
|
||||
: $_SERVER['HTTP_IF_NONE_MATCH'];
|
||||
$cachedEtags = split(',', $cachedEtagList);
|
||||
foreach ($cachedEtags as $cachedEtag) {
|
||||
if (trim($cachedEtag) == $this->etag) {
|
||||
if (trim($cachedEtag) == $this->_etag) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resourceNotModified() {
|
||||
protected function resourceNotModified() {
|
||||
if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
return false;
|
||||
}
|
||||
@ -154,11 +221,10 @@ class HTTP_ConditionalGet {
|
||||
// IE has tacked on extra data to this header, strip it
|
||||
$ifModifiedSince = substr($ifModifiedSince, 0, $semicolon);
|
||||
}
|
||||
return ($ifModifiedSince == self::gmtdate($this->lmTime));
|
||||
return ($ifModifiedSince == self::gmtdate($this->_lmTime));
|
||||
}
|
||||
|
||||
private static function gmtdate($ts) {
|
||||
protected static function gmtdate($ts) {
|
||||
return gmdate('D, d M Y H:i:s \G\M\T', $ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ class HTTP_ConditionalGet_Build {
|
||||
file_put_contents($file, "{$this->lastModified}|{$nextCheck}");
|
||||
}
|
||||
|
||||
private static function _scan($max, $path, $options)
|
||||
protected static function _scan($max, $path, $options)
|
||||
{
|
||||
$d = dir($path);
|
||||
while (false !== ($entry = $d->read())) {
|
||||
|
@ -23,70 +23,134 @@
|
||||
*/
|
||||
class HTTP_Encoder {
|
||||
|
||||
/**
|
||||
* Default compression level for zlib operations
|
||||
*
|
||||
* This level is used if encode() is not given a $compressionLevel
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $compressionLevel = 6;
|
||||
private static $clientEncodeMethod = null;
|
||||
|
||||
private $content = '';
|
||||
private $headers = array();
|
||||
|
||||
private $encodeMethod = array('', '');
|
||||
|
||||
/**
|
||||
* Get an HTTP Encoder object
|
||||
*
|
||||
* @param array $spec options
|
||||
*
|
||||
* 'content': (string required) content to be encoded
|
||||
*
|
||||
* 'type': (string) if set, the Content-Type header will have this value.
|
||||
*
|
||||
* 'method: (string) only set this if you are forcing a particular encoding
|
||||
* method. If not set, the best method will be chosen by getAcceptedEncoding()
|
||||
* The available methods are 'gzip', 'deflate', 'compress', and '' (no
|
||||
* encoding)
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function __construct($spec) {
|
||||
if (isset($spec['content'])) {
|
||||
$this->content = $spec['content'];
|
||||
}
|
||||
$this->headers['Content-Length'] = strlen($this->content);
|
||||
$this->_content = $spec['content'];
|
||||
$this->_headers['Content-Length'] = (string)strlen($this->_content);
|
||||
if (isset($spec['type'])) {
|
||||
$this->headers['Content-Type'] = $spec['type'];
|
||||
$this->_headers['Content-Type'] = $spec['type'];
|
||||
}
|
||||
if (self::$clientEncodeMethod === null) {
|
||||
self::$clientEncodeMethod = self::getAcceptedEncoding();
|
||||
if (self::$_clientEncodeMethod === null) {
|
||||
self::$_clientEncodeMethod = self::getAcceptedEncoding();
|
||||
}
|
||||
if (isset($spec['method'])
|
||||
&& in_array($spec['method'], array('gzip', 'deflate', 'compress', '')))
|
||||
{
|
||||
$this->encodeMethod = array($spec['method'], $spec['method']);
|
||||
$this->_encodeMethod = array($spec['method'], $spec['method']);
|
||||
} else {
|
||||
$this->encodeMethod = self::$clientEncodeMethod;
|
||||
$this->_encodeMethod = self::$_clientEncodeMethod;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content in current form
|
||||
*
|
||||
* Call after encode() for encoded content.
|
||||
*
|
||||
* return string
|
||||
*/
|
||||
public function getContent() {
|
||||
return $this->content;
|
||||
return $this->_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of output headers to be sent
|
||||
*
|
||||
* E.g.
|
||||
* <code>
|
||||
* array(
|
||||
* 'Content-Length' => '615'
|
||||
* ,'Content-Encoding' => 'x-gzip'
|
||||
* ,'Vary' => 'Accept-Encoding'
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
return $this->headers;
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the file and headers (encoded or not)
|
||||
* Send output headers
|
||||
*
|
||||
* You must call this before headers are sent and it probably cannot be
|
||||
* used in conjunction with zlib output buffering / mod_gzip. Errors are
|
||||
* not handled purposefully.
|
||||
*
|
||||
* @see getHeaders()
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function sendHeaders() {
|
||||
foreach ($this->_headers as $name => $val) {
|
||||
header($name . ': ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send output headers and content
|
||||
*
|
||||
* A shortcut for sendHeaders() and echo getContent()
|
||||
*
|
||||
* You must call this before headers are sent and it probably cannot be
|
||||
* used in conjunction with zlib output buffering / mod_gzip. Errors are
|
||||
* not handled purposefully.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function sendAll() {
|
||||
$this->sendHeaders();
|
||||
echo $this->content;
|
||||
echo $this->_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send just the headers
|
||||
* Determine the client's best encoding method from the HTTP Accept-Encoding
|
||||
* header.
|
||||
*
|
||||
* If no Accept-Encoding header is set, or the browser is IE before v6 SP2,
|
||||
* this will return ('', ''), the "identity" encoding.
|
||||
*
|
||||
* A syntax-aware scan is done of the Accept-Encoding, so the method must
|
||||
* be non 0. The methods are favored in order of gzip, deflate, then
|
||||
* compress.
|
||||
*
|
||||
* Note: this value is cached internally for the entire PHP execution
|
||||
*
|
||||
* @return array two values, 1st is the actual encoding method, 2nd is the
|
||||
* alias of that method to use in the Content-Encoding header (some browsers
|
||||
* call gzip "x-gzip" etc.)
|
||||
*/
|
||||
public function sendHeaders() {
|
||||
foreach ($this->headers as $name => $val) {
|
||||
header($name . ': ' . $val);
|
||||
}
|
||||
}
|
||||
|
||||
// returns array(encoding, encoding to use in Content-Encoding header)
|
||||
// eg. array('gzip', 'x-gzip')
|
||||
public static function getAcceptedEncoding() {
|
||||
if (self::$clientEncodeMethod !== null) {
|
||||
return self::$clientEncodeMethod;
|
||||
if (self::$_clientEncodeMethod !== null) {
|
||||
return self::$_clientEncodeMethod;
|
||||
}
|
||||
if (! isset($_SERVER['HTTP_ACCEPT_ENCODING'])
|
||||
|| self::isBuggyIe())
|
||||
|| self::_isBuggyIe())
|
||||
{
|
||||
return array('', '');
|
||||
}
|
||||
@ -104,37 +168,55 @@ class HTTP_Encoder {
|
||||
}
|
||||
|
||||
/**
|
||||
* If conditionsEncode the content
|
||||
* @return bool success
|
||||
* Encode (compress) the content
|
||||
*
|
||||
* If the encode method is '' (none) or compression level is 0, or the 'zlib'
|
||||
* extension isn't loaded, we return false.
|
||||
*
|
||||
* Then the appropriate gz_* function is called to compress the content. If
|
||||
* this fails, false is returned.
|
||||
*
|
||||
* If successful, the Content-Length header is updated, and Content-Encoding
|
||||
* and Vary headers are added.
|
||||
*
|
||||
* @param int $compressionLevel given to zlib functions. If not given, the
|
||||
* class default will be used.
|
||||
*
|
||||
* @return bool success true if the content was actually compressed
|
||||
*/
|
||||
public function encode($compressionLevel = null) {
|
||||
if (null === $compressionLevel) {
|
||||
$compressionLevel = self::$compressionLevel;
|
||||
}
|
||||
if ('' === $this->encodeMethod[0]
|
||||
if ('' === $this->_encodeMethod[0]
|
||||
|| ($compressionLevel == 0)
|
||||
|| !extension_loaded('zlib'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ($this->encodeMethod[0] === 'gzip') {
|
||||
$encoded = gzencode($this->content, $compressionLevel);
|
||||
} elseif ($this->encodeMethod[0] === 'deflate') {
|
||||
$encoded = gzdeflate($this->content, $compressionLevel);
|
||||
if ($this->_encodeMethod[0] === 'gzip') {
|
||||
$encoded = gzencode($this->_content, $compressionLevel);
|
||||
} elseif ($this->_encodeMethod[0] === 'deflate') {
|
||||
$encoded = gzdeflate($this->_content, $compressionLevel);
|
||||
} else {
|
||||
$encoded = gzcompress($this->content, $compressionLevel);
|
||||
$encoded = gzcompress($this->_content, $compressionLevel);
|
||||
}
|
||||
if (false === $encoded) {
|
||||
return false;
|
||||
}
|
||||
$this->headers['Content-Length'] = strlen($encoded);
|
||||
$this->headers['Content-Encoding'] = $this->encodeMethod[1];
|
||||
$this->headers['Vary'] = 'Accept-Encoding';
|
||||
$this->content = $encoded;
|
||||
$this->_headers['Content-Length'] = strlen($encoded);
|
||||
$this->_headers['Content-Encoding'] = $this->_encodeMethod[1];
|
||||
$this->_headers['Vary'] = 'Accept-Encoding';
|
||||
$this->_content = $encoded;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function isBuggyIe()
|
||||
protected static $_clientEncodeMethod = null;
|
||||
protected $content = '';
|
||||
protected $headers = array();
|
||||
protected $encodeMethod = array('', '');
|
||||
|
||||
protected static function _isBuggyIe()
|
||||
{
|
||||
if (strstr($_SERVER['HTTP_USER_AGENT'], 'Opera')
|
||||
|| !preg_match('/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i', $_SERVER['HTTP_USER_AGENT'], $m))
|
||||
|
@ -146,16 +146,15 @@ class Minify {
|
||||
$cg = new HTTP_ConditionalGet($cgOptions);
|
||||
if ($cg->cacheIsValid) {
|
||||
// client's cache is valid
|
||||
if (self::$_options['quiet']) {
|
||||
return array(
|
||||
'success' => true
|
||||
,'statusCode' => 304
|
||||
,'content' => ''
|
||||
,'headers' => array()
|
||||
);
|
||||
} else {
|
||||
if (! self::$_options['quiet']) {
|
||||
$cg->sendHeaders();
|
||||
}
|
||||
}
|
||||
return array(
|
||||
'success' => true
|
||||
,'statusCode' => 304
|
||||
,'content' => ''
|
||||
,'headers' => array()
|
||||
);
|
||||
}
|
||||
// client will need output
|
||||
$headers = $cg->getHeaders();
|
||||
@ -216,22 +215,22 @@ class Minify {
|
||||
/**
|
||||
* @var mixed null if disk cache is not to be used
|
||||
*/
|
||||
private static $_cachePath = null;
|
||||
protected static $_cachePath = null;
|
||||
|
||||
/**
|
||||
* @var Minify_Controller active controller for current request
|
||||
*/
|
||||
private static $_controller = null;
|
||||
protected static $_controller = null;
|
||||
|
||||
/**
|
||||
* @var array options for current request
|
||||
*/
|
||||
private static $_options = null;
|
||||
protected static $_options = null;
|
||||
|
||||
/**
|
||||
* @var Cache_Lite_File cache obj for current request
|
||||
*/
|
||||
private static $_cache = null;
|
||||
protected static $_cache = null;
|
||||
|
||||
|
||||
|
||||
@ -247,7 +246,7 @@ class Minify {
|
||||
*
|
||||
* @return string minified, encoded content
|
||||
*/
|
||||
private static function _fetchContent($encodeMethod)
|
||||
protected static function _fetchContent($encodeMethod)
|
||||
{
|
||||
$cacheId = self::_getCacheId(self::$_controller->sources, self::$_options)
|
||||
. $encodeMethod;
|
||||
@ -278,7 +277,7 @@ class Minify {
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private static function _setupCache() {
|
||||
protected static function _setupCache() {
|
||||
// until the patch is rolled into PEAR, we'll provide the
|
||||
// class in our package
|
||||
require_once dirname(__FILE__) . '/Cache/Lite/File.php';
|
||||
@ -297,7 +296,7 @@ class Minify {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _combineMinify() {
|
||||
protected static function _combineMinify() {
|
||||
$type = self::$_options['contentType']; // ease readability
|
||||
|
||||
// when combining scripts, make sure all statements separated
|
||||
@ -366,7 +365,7 @@ class Minify {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _encode($content)
|
||||
protected static function _encode($content)
|
||||
{
|
||||
if (self::$_options['encodeMethod'] === ''
|
||||
|| ! self::$_options['encodeOutput']) {
|
||||
@ -389,7 +388,7 @@ class Minify {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _getCacheId() {
|
||||
protected static function _getCacheId() {
|
||||
return md5(serialize(array(
|
||||
Minify_Source::getDigest(self::$_controller->sources)
|
||||
,self::$_options['minifiers']
|
||||
|
@ -87,17 +87,17 @@ class Minify_CSS {
|
||||
*
|
||||
* I.e. are some browsers targetted until the next comment?
|
||||
*/
|
||||
private static $_inHack = false;
|
||||
protected static $_inHack = false;
|
||||
|
||||
/**
|
||||
* @var string string to be prepended to relative URIs
|
||||
*/
|
||||
private static $_tempPrepend = '';
|
||||
protected static $_tempPrepend = '';
|
||||
|
||||
/**
|
||||
* @var string path of this stylesheet for rewriting purposes
|
||||
*/
|
||||
private static $_tempCurrentPath = '';
|
||||
protected static $_tempCurrentPath = '';
|
||||
|
||||
/**
|
||||
* Process what looks like a comment and return a replacement
|
||||
@ -106,7 +106,7 @@ class Minify_CSS {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _commentCB($m)
|
||||
protected static function _commentCB($m)
|
||||
{
|
||||
$m = $m[1];
|
||||
// $m is everything after the opening tokens and before the closing tokens
|
||||
@ -148,12 +148,12 @@ class Minify_CSS {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _selectorsCB($m)
|
||||
protected static function _selectorsCB($m)
|
||||
{
|
||||
return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
|
||||
}
|
||||
|
||||
private static function _urlCB($m)
|
||||
protected static function _urlCB($m)
|
||||
{
|
||||
$isImport = (0 === strpos($m[0], '@import'));
|
||||
if ($isImport) {
|
||||
|
@ -54,7 +54,7 @@ class Minify_Controller_Page extends Minify_Controller_Base {
|
||||
return $options;
|
||||
}
|
||||
|
||||
private $_loadCssJsMinifiers = false;
|
||||
protected $_loadCssJsMinifiers = false;
|
||||
|
||||
/**
|
||||
* @see Minify_Controller_Base::loadMinifier()
|
||||
|
@ -84,21 +84,21 @@ class Minify_HTML {
|
||||
return $html;
|
||||
}
|
||||
|
||||
private static $_isXhtml = false;
|
||||
private static $_replacementHash = null;
|
||||
private static $_pres = array();
|
||||
private static $_scripts = array();
|
||||
private static $_styles = array();
|
||||
private static $_cssMinifier = null;
|
||||
private static $_jsMinifier = null;
|
||||
protected static $_isXhtml = false;
|
||||
protected static $_replacementHash = null;
|
||||
protected static $_pres = array();
|
||||
protected static $_scripts = array();
|
||||
protected static $_styles = array();
|
||||
protected static $_cssMinifier = null;
|
||||
protected static $_jsMinifier = null;
|
||||
|
||||
private static function _removePreCB($m)
|
||||
protected static function _removePreCB($m)
|
||||
{
|
||||
self::$_pres[] = $m[1];
|
||||
return self::$_replacementHash . 'PRE' . count(self::$_pres);
|
||||
}
|
||||
|
||||
private static function _removeStyleCB($m)
|
||||
protected static function _removeStyleCB($m)
|
||||
{
|
||||
$openStyle = $m[1];
|
||||
$css = $m[2];
|
||||
@ -123,7 +123,7 @@ class Minify_HTML {
|
||||
return self::$_replacementHash . 'STYLE' . count(self::$_styles);
|
||||
}
|
||||
|
||||
private static function _removeScriptCB($m)
|
||||
protected static function _removeScriptCB($m)
|
||||
{
|
||||
$openScript = $m[1];
|
||||
$js = $m[2];
|
||||
@ -147,14 +147,14 @@ class Minify_HTML {
|
||||
return self::$_replacementHash . 'SCRIPT' . count(self::$_scripts);
|
||||
}
|
||||
|
||||
private static function _removeCdata($str)
|
||||
protected static function _removeCdata($str)
|
||||
{
|
||||
return (false !== strpos($str, '<![CDATA['))
|
||||
? str_replace(array('<![CDATA[', ']]>'), '', $str)
|
||||
: $str;
|
||||
}
|
||||
|
||||
private static function _needsCdata($str)
|
||||
protected static function _needsCdata($str)
|
||||
{
|
||||
return (self::$_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
|
||||
}
|
||||
|
@ -39,9 +39,9 @@
|
||||
* @package Minify_Javascript
|
||||
* @author Ryan Grove <ryan@wonko.com>
|
||||
* @copyright 2002 Douglas Crockford <douglas@crockford.com> (JSMin.c)
|
||||
* @copyright 2007 Ryan Grove <ryan@wonko.com> (PHP port)
|
||||
* @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
|
||||
* @license http://opensource.org/licenses/mit-license.php MIT License
|
||||
* @version 1.1.0 (2007-06-01)
|
||||
* @version 1.1.1 (2008-03-03)
|
||||
* @link http://code.google.com/p/jsmin-php/
|
||||
*/
|
||||
|
||||
@ -55,7 +55,7 @@ class Minify_Javascript {
|
||||
private $inputIndex = 0;
|
||||
private $inputLength = 0;
|
||||
private $lookAhead = null;
|
||||
private $output = array();
|
||||
private $output = '';
|
||||
|
||||
// -- Public Static Methods --------------------------------------------------
|
||||
|
||||
@ -74,15 +74,15 @@ class Minify_Javascript {
|
||||
private function action($d) {
|
||||
switch($d) {
|
||||
case 1:
|
||||
$this->output[] = $this->a;
|
||||
$this->output .= $this->a;
|
||||
|
||||
case 2:
|
||||
$this->a = $this->b;
|
||||
|
||||
if ($this->a === "'" || $this->a === '"') {
|
||||
for (;;) {
|
||||
$this->output[] = $this->a;
|
||||
$this->a = $this->get();
|
||||
$this->output .= $this->a;
|
||||
$this->a = $this->get();
|
||||
|
||||
if ($this->a === $this->b) {
|
||||
break;
|
||||
@ -93,8 +93,8 @@ class Minify_Javascript {
|
||||
}
|
||||
|
||||
if ($this->a === '\\') {
|
||||
$this->output[] = $this->a;
|
||||
$this->a = $this->get();
|
||||
$this->output .= $this->a;
|
||||
$this->a = $this->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,25 +107,23 @@ class Minify_Javascript {
|
||||
$this->a === ':' || $this->a === '[' || $this->a === '!' ||
|
||||
$this->a === '&' || $this->a === '|' || $this->a === '?')) {
|
||||
|
||||
$this->output[] = $this->a;
|
||||
$this->output[] = $this->b;
|
||||
$this->output .= $this->a;
|
||||
$this->output .= $this->b;
|
||||
|
||||
for (;;) {
|
||||
$this->a = $this->get();
|
||||
|
||||
if ($this->a === '/') {
|
||||
break;
|
||||
}
|
||||
elseif ($this->a === '\\') {
|
||||
$this->output[] = $this->a;
|
||||
$this->a = $this->get();
|
||||
}
|
||||
elseif (ord($this->a) <= self::ORD_LF) {
|
||||
} elseif ($this->a === '\\') {
|
||||
$this->output .= $this->a;
|
||||
$this->a = $this->get();
|
||||
} elseif (ord($this->a) <= self::ORD_LF) {
|
||||
throw new Minify_JavascriptException('Unterminated regular expression '.
|
||||
'literal.');
|
||||
}
|
||||
|
||||
$this->output[] = $this->a;
|
||||
$this->output .= $this->a;
|
||||
}
|
||||
|
||||
$this->b = $this->next();
|
||||
@ -141,8 +139,7 @@ class Minify_Javascript {
|
||||
if ($this->inputIndex < $this->inputLength) {
|
||||
$c = $this->input[$this->inputIndex];
|
||||
$this->inputIndex += 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$c = null;
|
||||
}
|
||||
}
|
||||
@ -167,8 +164,7 @@ class Minify_Javascript {
|
||||
case ' ':
|
||||
if (self::isAlphaNum($this->b)) {
|
||||
$this->action(1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->action(2);
|
||||
}
|
||||
break;
|
||||
@ -237,7 +233,7 @@ class Minify_Javascript {
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $this->output);
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
private function next() {
|
||||
|
@ -129,8 +129,8 @@ class Minify_Source {
|
||||
return 'text/plain';
|
||||
}
|
||||
|
||||
private $_content = null;
|
||||
private $_filepath = null;
|
||||
private $_id = null;
|
||||
protected $_content = null;
|
||||
protected $_filepath = null;
|
||||
protected $_id = null;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user