mirror of
https://github.com/mrclay/minify.git
synced 2025-03-14 09:29:38 +01:00
Fixes Gcode issue 256, improve readability
This commit is contained in:
parent
faec60fff6
commit
c95d6bac4e
@ -116,8 +116,8 @@ class JSMin {
|
|||||||
// determine next command
|
// determine next command
|
||||||
$command = self::ACTION_KEEP_A; // default
|
$command = self::ACTION_KEEP_A; // default
|
||||||
if ($this->a === ' ') {
|
if ($this->a === ' ') {
|
||||||
if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
|
if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
|
||||||
&& ($this->b === $this->lastByteOut)) {
|
&& ($this->b === $this->lastByteOut)) {
|
||||||
// Don't delete this space. If we do, the addition/subtraction
|
// Don't delete this space. If we do, the addition/subtraction
|
||||||
// could be parsed as a post-increment
|
// could be parsed as a post-increment
|
||||||
} elseif (! $this->isAlphaNum($this->b)) {
|
} elseif (! $this->isAlphaNum($this->b)) {
|
||||||
@ -129,13 +129,13 @@ class JSMin {
|
|||||||
// in case of mbstring.func_overload & 2, must check for null b,
|
// in case of mbstring.func_overload & 2, must check for null b,
|
||||||
// otherwise mb_strpos will give WARNING
|
// otherwise mb_strpos will give WARNING
|
||||||
} elseif ($this->b === null
|
} elseif ($this->b === null
|
||||||
|| (false === strpos('{[(+-', $this->b)
|
|| (false === strpos('{[(+-!~', $this->b)
|
||||||
&& ! $this->isAlphaNum($this->b))) {
|
&& ! $this->isAlphaNum($this->b))) {
|
||||||
$command = self::ACTION_DELETE_A;
|
$command = self::ACTION_DELETE_A;
|
||||||
}
|
}
|
||||||
} elseif (! $this->isAlphaNum($this->a)) {
|
} elseif (! $this->isAlphaNum($this->a)) {
|
||||||
if ($this->b === ' '
|
if ($this->b === ' '
|
||||||
|| ($this->b === "\n"
|
|| ($this->b === "\n"
|
||||||
&& (false === strpos('}])+-"\'', $this->a)))) {
|
&& (false === strpos('}])+-"\'', $this->a)))) {
|
||||||
$command = self::ACTION_DELETE_A_B;
|
$command = self::ACTION_DELETE_A_B;
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ class JSMin {
|
|||||||
*/
|
*/
|
||||||
protected function action($command)
|
protected function action($command)
|
||||||
{
|
{
|
||||||
if ($command === self::ACTION_DELETE_A_B
|
if ($command === self::ACTION_DELETE_A_B
|
||||||
&& $this->b === ' '
|
&& $this->b === ' '
|
||||||
&& ($this->a === '+' || $this->a === '-')) {
|
&& ($this->a === '+' || $this->a === '-')) {
|
||||||
// Note: we're at an addition/substraction operator; the inputIndex
|
// Note: we're at an addition/substraction operator; the inputIndex
|
||||||
@ -175,20 +175,20 @@ class JSMin {
|
|||||||
$this->output .= $this->a;
|
$this->output .= $this->a;
|
||||||
$this->lastByteOut = $this->a;
|
$this->lastByteOut = $this->a;
|
||||||
|
|
||||||
// fallthrough
|
// fallthrough intentional
|
||||||
case self::ACTION_DELETE_A:
|
case self::ACTION_DELETE_A:
|
||||||
$this->a = $this->b;
|
$this->a = $this->b;
|
||||||
if ($this->a === "'" || $this->a === '"') { // string literal
|
if ($this->a === "'" || $this->a === '"') { // string literal
|
||||||
$str = $this->a; // in case needed for exception
|
$str = $this->a; // in case needed for exception
|
||||||
while (true) {
|
for(;;) {
|
||||||
$this->output .= $this->a;
|
$this->output .= $this->a;
|
||||||
$this->lastByteOut = $this->a;
|
$this->lastByteOut = $this->a;
|
||||||
|
|
||||||
$this->a = $this->get();
|
$this->a = $this->get();
|
||||||
if ($this->a === $this->b) { // end quote
|
if ($this->a === $this->b) { // end quote
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ord($this->a) <= self::ORD_LF) {
|
if ($this->isEOF($this->a)) {
|
||||||
throw new JSMin_UnterminatedStringException(
|
throw new JSMin_UnterminatedStringException(
|
||||||
"JSMin: Unterminated String at byte "
|
"JSMin: Unterminated String at byte "
|
||||||
. $this->inputIndex . ": {$str}");
|
. $this->inputIndex . ": {$str}");
|
||||||
@ -198,27 +198,49 @@ class JSMin {
|
|||||||
$this->output .= $this->a;
|
$this->output .= $this->a;
|
||||||
$this->lastByteOut = $this->a;
|
$this->lastByteOut = $this->a;
|
||||||
|
|
||||||
$this->a = $this->get();
|
$this->a = $this->get();
|
||||||
$str .= $this->a;
|
$str .= $this->a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// fallthrough
|
|
||||||
|
// fallthrough intentional
|
||||||
case self::ACTION_DELETE_A_B:
|
case self::ACTION_DELETE_A_B:
|
||||||
$this->b = $this->next();
|
$this->b = $this->next();
|
||||||
if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal
|
if ($this->b === '/' && $this->isRegexpLiteral()) {
|
||||||
$this->output .= $this->a . $this->b;
|
$this->output .= $this->a . $this->b;
|
||||||
$pattern = '/'; // in case needed for exception
|
$pattern = '/'; // keep entire pattern in case we need to report it in the exception
|
||||||
while (true) {
|
for(;;) {
|
||||||
$this->a = $this->get();
|
$this->a = $this->get();
|
||||||
$pattern .= $this->a;
|
$pattern .= $this->a;
|
||||||
|
if ($this->a === '[') {
|
||||||
|
for(;;) {
|
||||||
|
$this->output .= $this->a;
|
||||||
|
$this->a = $this->get();
|
||||||
|
$pattern .= $this->a;
|
||||||
|
if ($this->a === ']') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($this->a === '\\') {
|
||||||
|
$this->output .= $this->a;
|
||||||
|
$this->a = $this->get();
|
||||||
|
$pattern .= $this->a;
|
||||||
|
}
|
||||||
|
if ($this->isEOF($this->a)) {
|
||||||
|
throw new JSMin_UnterminatedRegExpException(
|
||||||
|
"JSMin: Unterminated set in RegExp at byte "
|
||||||
|
. $this->inputIndex .": {$pattern}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->a === '/') { // end pattern
|
if ($this->a === '/') { // end pattern
|
||||||
break; // while (true)
|
break; // while (true)
|
||||||
} elseif ($this->a === '\\') {
|
} elseif ($this->a === '\\') {
|
||||||
$this->output .= $this->a;
|
$this->output .= $this->a;
|
||||||
$this->a = $this->get();
|
$this->a = $this->get();
|
||||||
$pattern .= $this->a;
|
$pattern .= $this->a;
|
||||||
} elseif (ord($this->a) <= self::ORD_LF) {
|
} elseif ($this->isEOF($this->a)) {
|
||||||
throw new JSMin_UnterminatedRegExpException(
|
throw new JSMin_UnterminatedRegExpException(
|
||||||
"JSMin: Unterminated RegExp at byte "
|
"JSMin: Unterminated RegExp at byte "
|
||||||
. $this->inputIndex .": {$pattern}");
|
. $this->inputIndex .": {$pattern}");
|
||||||
@ -286,6 +308,17 @@ class JSMin {
|
|||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does $a indicate end of input?
|
||||||
|
*
|
||||||
|
* @param string $a
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function isEOF($a)
|
||||||
|
{
|
||||||
|
return ord($a) <= self::ORD_LF;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get next char. If is ctrl character, translate to a space or newline.
|
* Get next char. If is ctrl character, translate to a space or newline.
|
||||||
*
|
*
|
||||||
@ -336,7 +369,7 @@ class JSMin {
|
|||||||
{
|
{
|
||||||
$this->get();
|
$this->get();
|
||||||
$comment = '';
|
$comment = '';
|
||||||
while (true) {
|
for(;;) {
|
||||||
$get = $this->get();
|
$get = $this->get();
|
||||||
if ($get === '*') {
|
if ($get === '*') {
|
||||||
if ($this->peek() === '/') { // end of comment reached
|
if ($this->peek() === '/') { // end of comment reached
|
||||||
|
5
min_unit_tests/_test_files/js/issue256.js
Normal file
5
min_unit_tests/_test_files/js/issue256.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
!function(){}(window)
|
||||||
|
|
||||||
|
!function(){}(window)
|
||||||
|
|
||||||
|
x = / [/] /;
|
3
min_unit_tests/_test_files/js/issue256.min.js
vendored
Normal file
3
min_unit_tests/_test_files/js/issue256.min.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
!function(){}(window)
|
||||||
|
!function(){}(window)
|
||||||
|
x=/ [/] /;
|
@ -8,7 +8,7 @@ function test_JSMin()
|
|||||||
$src = file_get_contents($thisDir . '/_test_files/js/before.js');
|
$src = file_get_contents($thisDir . '/_test_files/js/before.js');
|
||||||
$minExpected = file_get_contents($thisDir . '/_test_files/js/before.min.js');
|
$minExpected = file_get_contents($thisDir . '/_test_files/js/before.min.js');
|
||||||
$minOutput = JSMin::minify($src);
|
$minOutput = JSMin::minify($src);
|
||||||
$passed = assertTrue($minExpected == $minOutput, 'JSMin : Overall');
|
assertTrue($minExpected == $minOutput, 'JSMin : Overall');
|
||||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||||
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
||||||
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
||||||
@ -18,7 +18,17 @@ function test_JSMin()
|
|||||||
$src = file_get_contents($thisDir . '/_test_files/js/issue144.js');
|
$src = file_get_contents($thisDir . '/_test_files/js/issue144.js');
|
||||||
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue144.min.js');
|
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue144.min.js');
|
||||||
$minOutput = JSMin::minify($src);
|
$minOutput = JSMin::minify($src);
|
||||||
$passed = assertTrue($minExpected == $minOutput, 'JSMin : Handle "+ ++a" syntax (Issue 144)');
|
assertTrue($minExpected == $minOutput, 'JSMin : Handle "+ ++a" syntax (Issue 144)');
|
||||||
|
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||||
|
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
||||||
|
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
||||||
|
echo "---Source: " .countBytes($src). " bytes\n\n{$src}\n\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$src = file_get_contents($thisDir . '/_test_files/js/issue256.js');
|
||||||
|
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue256.min.js');
|
||||||
|
$minOutput = JSMin::minify($src);
|
||||||
|
assertTrue($minExpected == $minOutput, 'JSMin : Handle \n!function()... (Issue 256)');
|
||||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||||
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
||||||
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
||||||
@ -29,7 +39,7 @@ function test_JSMin()
|
|||||||
$src = file_get_contents($thisDir . '/_test_files/js/issue132.js');
|
$src = file_get_contents($thisDir . '/_test_files/js/issue132.js');
|
||||||
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue132.min.js');
|
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue132.min.js');
|
||||||
$minOutput = JSMin::minify($src);
|
$minOutput = JSMin::minify($src);
|
||||||
$passed = assertTrue($minExpected == $minOutput, 'JSMin : mbstring.func_overload shouldn\'t cause failure (Issue 132)');
|
assertTrue($minExpected == $minOutput, 'JSMin : mbstring.func_overload shouldn\'t cause failure (Issue 132)');
|
||||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||||
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
||||||
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
||||||
@ -40,7 +50,7 @@ function test_JSMin()
|
|||||||
$src = file_get_contents($thisDir . '/_test_files/js/issue74.js');
|
$src = file_get_contents($thisDir . '/_test_files/js/issue74.js');
|
||||||
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue74.min.js');
|
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue74.min.js');
|
||||||
$minOutput = JSMin::minify($src);
|
$minOutput = JSMin::minify($src);
|
||||||
$passed = assertTrue($minExpected == $minOutput, 'JSMin : Quotes in RegExp literals (Issue 74)');
|
assertTrue($minExpected == $minOutput, 'JSMin : Quotes in RegExp literals (Issue 74)');
|
||||||
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||||
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
|
||||||
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user