mirror of
https://github.com/gtbu/Typesetter-5.3-p8.git
synced 2024-11-21 21:59:12 +01:00
jsrink update 1.65
This commit is contained in:
parent
8dcffe119b
commit
bf8c93a53a
2 changed files with 132 additions and 30 deletions
162
include/thirdparty/JShrink/Minifier.php
vendored
162
include/thirdparty/JShrink/Minifier.php
vendored
|
@ -74,6 +74,20 @@ class Minifier
|
|||
*/
|
||||
protected $c;
|
||||
|
||||
/**
|
||||
* This character is only active when certain look ahead actions take place.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $last_char;
|
||||
|
||||
/**
|
||||
* This character is only active when certain look ahead actions take place.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Contains the options for the current minification process.
|
||||
*
|
||||
|
@ -95,6 +109,9 @@ class Minifier
|
|||
*/
|
||||
protected static $defaultOptions = ['flaggedComments' => true];
|
||||
|
||||
|
||||
protected static $keywords = ["delete", "do", "for", "in", "instanceof", "return", "typeof", "yield"];
|
||||
|
||||
/**
|
||||
* Contains lock ids which are used to replace certain code patterns and
|
||||
* prevent them from being minified
|
||||
|
@ -115,17 +132,11 @@ class Minifier
|
|||
public static function minify($js, $options = [])
|
||||
{
|
||||
try {
|
||||
ob_start();
|
||||
|
||||
$jshrink = new Minifier();
|
||||
$js = $jshrink->lock($js);
|
||||
$jshrink->minifyDirectToOutput($js, $options);
|
||||
|
||||
// Sometimes there's a leading new line, so we trim that out here.
|
||||
$js = ltrim(ob_get_clean());
|
||||
$js = ltrim($jshrink->minifyToString($js, $options));
|
||||
$js = $jshrink->unlock($js);
|
||||
unset($jshrink);
|
||||
|
||||
return $js;
|
||||
} catch (\Exception $e) {
|
||||
if (isset($jshrink)) {
|
||||
|
@ -134,9 +145,6 @@ class Minifier
|
|||
$jshrink->clean();
|
||||
unset($jshrink);
|
||||
}
|
||||
|
||||
// without this call things get weird, with partially outputted js.
|
||||
ob_end_clean();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
@ -148,11 +156,12 @@ class Minifier
|
|||
* @param string $js The raw javascript to be minified
|
||||
* @param array $options Various runtime options in an associative array
|
||||
*/
|
||||
protected function minifyDirectToOutput($js, $options)
|
||||
protected function minifyToString($js, $options)
|
||||
{
|
||||
$this->initialize($js, $options);
|
||||
$this->loop();
|
||||
$this->clean();
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,7 +173,7 @@ class Minifier
|
|||
protected function initialize($js, $options)
|
||||
{
|
||||
$this->options = array_merge(static::$defaultOptions, $options);
|
||||
$this->input = str_replace(["\r\n", '/**/', "\r"], ["\n", "", "\n"], $js);
|
||||
$this->input = $js;
|
||||
|
||||
// We add a newline to the end of the script to make it easier to deal
|
||||
// with comments at the bottom of the script- this prevents the unclosed
|
||||
|
@ -177,7 +186,9 @@ class Minifier
|
|||
// Populate "a" with a new line, "b" with the first character, before
|
||||
// entering the loop
|
||||
$this->a = "\n";
|
||||
$this->b = $this->getReal();
|
||||
$this->b = "\n";
|
||||
$this->last_char = "\n";
|
||||
$this->output = "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,6 +203,13 @@ class Minifier
|
|||
'[' => true,
|
||||
'@' => true];
|
||||
|
||||
|
||||
protected function echo($char) {
|
||||
$this->output .= $char;
|
||||
$this->last_char = $char[-1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The primary action occurs here. This function loops through the input string,
|
||||
* outputting anything that's relevant and discarding anything that is not.
|
||||
|
@ -201,10 +219,11 @@ class Minifier
|
|||
while ($this->a !== false && !is_null($this->a) && $this->a !== '') {
|
||||
switch ($this->a) {
|
||||
// new lines
|
||||
case "\r":
|
||||
case "\n":
|
||||
// if the next line is something that can't stand alone preserve the newline
|
||||
if ($this->b !== false && isset($this->noNewLineCharacters[$this->b])) {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
$this->saveString();
|
||||
break;
|
||||
}
|
||||
|
@ -220,7 +239,7 @@ class Minifier
|
|||
// no break
|
||||
case ' ':
|
||||
if (static::isAlphaNumeric($this->b)) {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
}
|
||||
|
||||
$this->saveString();
|
||||
|
@ -228,14 +247,15 @@ class Minifier
|
|||
|
||||
default:
|
||||
switch ($this->b) {
|
||||
case "\r":
|
||||
case "\n":
|
||||
if (strpos('}])+-"\'', $this->a) !== false) {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
$this->saveString();
|
||||
break;
|
||||
} else {
|
||||
if (static::isAlphaNumeric($this->a)) {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
$this->saveString();
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +274,7 @@ class Minifier
|
|||
continue 3;
|
||||
}
|
||||
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
$this->saveString();
|
||||
break;
|
||||
}
|
||||
|
@ -263,9 +283,27 @@ class Minifier
|
|||
// do reg check of doom
|
||||
$this->b = $this->getReal();
|
||||
|
||||
if (($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false)) {
|
||||
$this->saveRegex();
|
||||
if ($this->b == '/') {
|
||||
$valid_tokens = "(,=:[!&|?\n";
|
||||
|
||||
# Find last "real" token, excluding spaces.
|
||||
$last_token = $this->a;
|
||||
if ($last_token == " ") {
|
||||
$last_token = $this->last_char;
|
||||
}
|
||||
|
||||
if (strpos($valid_tokens, $last_token) !== false) {
|
||||
// Regex can appear unquoted after these symbols
|
||||
$this->saveRegex();
|
||||
} else if ($this->endsInKeyword()) {
|
||||
// This block checks for the "return" token before the slash.
|
||||
$this->saveRegex();
|
||||
}
|
||||
}
|
||||
|
||||
// if (($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false)) {
|
||||
// $this->saveRegex();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,6 +346,12 @@ class Minifier
|
|||
$this->index++;
|
||||
}
|
||||
|
||||
# Convert all line endings to unix standard.
|
||||
# `\r\n` converts to `\n\n` and is minified.
|
||||
if ($char == "\r") {
|
||||
$char = "\n";
|
||||
}
|
||||
|
||||
// Normalize all whitespace except for the newline character into a
|
||||
// standard space.
|
||||
if ($char !== "\n" && $char < "\x20") {
|
||||
|
@ -317,6 +361,36 @@ class Minifier
|
|||
return $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the next character without moving the index forward.
|
||||
*
|
||||
*
|
||||
* @return string The next character
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function peek()
|
||||
{
|
||||
if ($this->index >= $this->len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$char = $this->input[$this->index];
|
||||
# Convert all line endings to unix standard.
|
||||
# `\r\n` converts to `\n\n` and is minified.
|
||||
if ($char == "\r") {
|
||||
$char = "\n";
|
||||
}
|
||||
|
||||
// Normalize all whitespace except for the newline character into a
|
||||
// standard space.
|
||||
if ($char !== "\n" && $char < "\x20") {
|
||||
return ' ';
|
||||
}
|
||||
|
||||
# Return the next character but don't push the index.
|
||||
return $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function gets the next "real" character. It is essentially a wrapper
|
||||
* around the getChar function that skips comments. This has significant
|
||||
|
@ -387,6 +461,15 @@ class Minifier
|
|||
$this->getChar(); // current C
|
||||
$thirdCommentString = $this->getChar();
|
||||
|
||||
// Detect a completely empty comment, ie `/**/`
|
||||
if ($thirdCommentString == "*") {
|
||||
$peekChar = $this->peek();
|
||||
if ($peekChar == "/") {
|
||||
$this->index++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// kill everything up to the next */ if it's there
|
||||
if ($this->getNext('*/')) {
|
||||
$this->getChar(); // get *
|
||||
|
@ -400,17 +483,17 @@ class Minifier
|
|||
// If conditional comments or flagged comments are not the first thing in the script
|
||||
// we need to echo a and fill it with a space before moving on.
|
||||
if ($startIndex > 0) {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
$this->a = " ";
|
||||
|
||||
// If the comment started on a new line we let it stay on the new line
|
||||
if ($this->input[($startIndex - 1)] === "\n") {
|
||||
echo "\n";
|
||||
$this->echo("\n");
|
||||
}
|
||||
}
|
||||
|
||||
$endPoint = ($this->index - 1) - $startIndex;
|
||||
echo substr($this->input, $startIndex, $endPoint);
|
||||
$this->echo(substr($this->input, $startIndex, $endPoint));
|
||||
|
||||
$this->c = $char;
|
||||
|
||||
|
@ -476,7 +559,7 @@ class Minifier
|
|||
$stringType = $this->a;
|
||||
|
||||
// Echo out that starting quote
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
|
||||
// Loop until the string is done
|
||||
// Grab the very next character and load it into a
|
||||
|
@ -495,7 +578,7 @@ class Minifier
|
|||
// block below.
|
||||
case "\n":
|
||||
if ($stringType === '`') {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
} else {
|
||||
throw new \RuntimeException('Unclosed string at position: ' . $startpos);
|
||||
}
|
||||
|
@ -515,14 +598,14 @@ class Minifier
|
|||
}
|
||||
|
||||
// echo out the escaped character and restart the loop.
|
||||
echo $this->a . $this->b;
|
||||
$this->echo($this->a . $this->b);
|
||||
break;
|
||||
|
||||
|
||||
// Since we're not dealing with any special cases we simply
|
||||
// output the character and continue our loop.
|
||||
default:
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,7 +618,11 @@ class Minifier
|
|||
*/
|
||||
protected function saveRegex()
|
||||
{
|
||||
echo $this->a . $this->b;
|
||||
if ($this->a != " ") {
|
||||
$this->echo($this->a);
|
||||
}
|
||||
|
||||
$this->echo($this->b);
|
||||
|
||||
while (($this->a = $this->getChar()) !== false) {
|
||||
if ($this->a === '/') {
|
||||
|
@ -543,7 +630,7 @@ class Minifier
|
|||
}
|
||||
|
||||
if ($this->a === '\\') {
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
$this->a = $this->getChar();
|
||||
}
|
||||
|
||||
|
@ -551,7 +638,7 @@ class Minifier
|
|||
throw new \RuntimeException('Unclosed regex pattern at position: ' . $this->index);
|
||||
}
|
||||
|
||||
echo $this->a;
|
||||
$this->echo($this->a);
|
||||
}
|
||||
$this->b = $this->getReal();
|
||||
}
|
||||
|
@ -567,6 +654,21 @@ class Minifier
|
|||
return preg_match('/^[\w\$\pL]$/', $char) === 1 || $char == '/';
|
||||
}
|
||||
|
||||
protected function endsInKeyword() {
|
||||
|
||||
# When this function is called A is not yet assigned to output.
|
||||
$testOutput = $this->output . $this->a;
|
||||
|
||||
foreach(static::$keywords as $keyword) {
|
||||
if (preg_match('/[^\w]'.$keyword.'[ ]?$/i', $testOutput) === 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Replace patterns in the given string and store the replacement
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue