Version 4.7.23
This commit is contained in:
1 parent
7124a02564
commit
25ddeb65d6
1791 files changed
+76990
-44452
No files matched your search
+190
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace Garfix\JsMinify;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* This minifier removes whitespace and comments from a Javascript string.
|
||||
*
|
||||
* See docs for information.
|
||||
*
|
||||
* @author Patrick van Bergen
|
||||
*/
|
||||
class Minifier
|
||||
{
|
||||
const FLAGGED_COMMENTS = 'flaggedComments';
|
||||
|
||||
protected static $defaultOptions = [
|
||||
self::FLAGGED_COMMENTS => true
|
||||
];
|
||||
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* Processes a javascript string and returns only the required characters,
|
||||
* stripping out all unneeded whitespace and comments.
|
||||
*
|
||||
* @param string $js The raw javascript to be minified
|
||||
* @param array $options Various runtime options in an associative array
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function minify($js, $options = [])
|
||||
{
|
||||
$minifier = new Minifier($options);
|
||||
return $minifier->minifyUsingCallbacks($js);
|
||||
}
|
||||
|
||||
public function __construct($options)
|
||||
{
|
||||
$this->options = array_merge(static::$defaultOptions, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $js The raw javascript to be minified
|
||||
* @return string
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function minifyUsingCallbacks($js)
|
||||
{
|
||||
$e = MinifierExpressions::get();
|
||||
|
||||
// treat all newlines as unix newlines, to keep working with newlines simple
|
||||
$shrunkText = str_replace(["\r\n", "\r"], ["\n", "\n"], $js);
|
||||
|
||||
// remove comments
|
||||
$exp1 = "~(?:" . implode("|", $e->tokenExpressions) . ")~su";
|
||||
$shrunkText = preg_replace_callback($exp1, [$this, 'removeComments'], $shrunkText);
|
||||
MinifierError::checkRegexpError();
|
||||
|
||||
// rewrite blocks by inserting whitespace placeholders
|
||||
$exp2 = "~(?:" . implode("|", $e->allExpressions) . ")~su";
|
||||
$shrunkText = preg_replace_callback($exp2, [$this, 'processBlocks'], $shrunkText);
|
||||
MinifierError::checkRegexpError();
|
||||
|
||||
// remove all remaining space (without the newlines)
|
||||
$shrunkText = preg_replace("~" . $e->someWhitespace . "~", '', $shrunkText);
|
||||
MinifierError::checkRegexpError();
|
||||
|
||||
// reduce consecutive newlines to single one
|
||||
$shrunkText = preg_replace("~[\\n]+~", "\n", $shrunkText);
|
||||
MinifierError::checkRegexpError();
|
||||
|
||||
// remove newlines that may safely be removed
|
||||
foreach ($e->safeNewlines as $safeNewline) {
|
||||
$shrunkText = preg_replace("~" . $safeNewline . "~", "", $shrunkText);
|
||||
MinifierError::checkRegexpError();
|
||||
}
|
||||
|
||||
// replace whitespace placeholders by their original whitespace
|
||||
$shrunkText = str_replace($e->whitespaceArrayPlaceholders, $e->whitespaceArrayNewline, $shrunkText);
|
||||
MinifierError::checkRegexpError();
|
||||
|
||||
// remove leading and trailing whitespace
|
||||
return trim($shrunkText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all comments that need to be removed
|
||||
* The newlines that are added here may later be removed again
|
||||
*
|
||||
* @param $matches
|
||||
* @return mixed|string
|
||||
*/
|
||||
protected function removeComments($matches)
|
||||
{
|
||||
$e = MinifierExpressions::get();
|
||||
|
||||
// the fully matching text
|
||||
$match = $matches[0];
|
||||
|
||||
if (!empty($matches['lineComment'])) {
|
||||
// not empty because this might glue words together
|
||||
return "\n";
|
||||
}
|
||||
if (!empty($matches['starComment'])) {
|
||||
|
||||
// create a version without leading and trailing whitespace
|
||||
$trimmed = trim($match, $e->whitespaceCharsNewline);
|
||||
|
||||
switch ($trimmed[2]) {
|
||||
case '@':
|
||||
// IE conditional comment
|
||||
return $match;
|
||||
case '!':
|
||||
if ($this->options[self::FLAGGED_COMMENTS]) {
|
||||
// option says: leave flagged comments in
|
||||
return $match;
|
||||
}
|
||||
}
|
||||
// multi line comment; not empty because this might glue words together
|
||||
return "\n";
|
||||
}
|
||||
|
||||
// leave other matches unchanged
|
||||
return $match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the code for all blocks (they contain whitespace that should be conserved)
|
||||
* No early returns: all code must reach `end` and have the whitespace replaced by placeholders
|
||||
*
|
||||
* @param $matches
|
||||
* @return array|mixed|string|string[]
|
||||
*/
|
||||
protected function processBlocks($matches)
|
||||
{
|
||||
$e = MinifierExpressions::get();
|
||||
|
||||
// the fully matching text
|
||||
$match = $matches[0];
|
||||
|
||||
// create a version without leading and trailing whitespace
|
||||
$trimmed = trim($match, $e->whitespaceCharsNewline);
|
||||
|
||||
// Should be handled before optional whitespace
|
||||
if (!empty($matches['requiredSpace'])) {
|
||||
$match = strpos($matches['requiredSpace'], "\n") === false ? " " : "\n";
|
||||
goto end;
|
||||
}
|
||||
// + followed by +, or - followed by -
|
||||
if (!empty($matches['plus']) || !empty($matches['min'])) {
|
||||
$match = ' ';
|
||||
goto end;
|
||||
}
|
||||
if (!empty($matches['doubleQuote'])) {
|
||||
// remove line continuation
|
||||
$match = str_replace("\\\n", "", $match);
|
||||
goto end;
|
||||
}
|
||||
if (!empty($matches['starComment'])) {
|
||||
switch ($trimmed[2]) {
|
||||
case '@':
|
||||
// IE conditional comment
|
||||
$match = $trimmed;
|
||||
goto end;
|
||||
case '!':
|
||||
if ($this->options[self::FLAGGED_COMMENTS]) {
|
||||
// ensure newlines before and after
|
||||
$match = "\n" . $trimmed . "\n";
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
// simple multi line comment; will have been removed in the first step
|
||||
goto end;
|
||||
}
|
||||
if (!empty($matches['regexp'])) {
|
||||
// regular expression
|
||||
// only if the space after the regexp contains a newline, keep it
|
||||
preg_match("~^" . $e->regexp . "(?P<post>" . $e->optionalWhitespaceNewline . ")" . "$~su",
|
||||
$match, $newMatches);
|
||||
$postfix = strpos($newMatches['post'], "\n") === false ? "" : "\n";
|
||||
$match = $trimmed . $postfix;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
return str_replace($e->whitespaceArrayNewline, $e->whitespaceArrayPlaceholders, $match);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user