1
0
mirror of https://github.com/mrclay/minify.git synced 2025-03-13 17:09:39 +01:00

Fixes Gcode issue 256, improve readability

This commit is contained in:
Steve Clay 2013-03-29 10:01:17 -04:00
parent faec60fff6
commit c95d6bac4e
4 changed files with 73 additions and 22 deletions

View File

@ -116,8 +116,8 @@ class JSMin {
// determine next command
$command = self::ACTION_KEEP_A; // default
if ($this->a === ' ') {
if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
&& ($this->b === $this->lastByteOut)) {
if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
&& ($this->b === $this->lastByteOut)) {
// Don't delete this space. If we do, the addition/subtraction
// could be parsed as a post-increment
} elseif (! $this->isAlphaNum($this->b)) {
@ -129,13 +129,13 @@ class JSMin {
// in case of mbstring.func_overload & 2, must check for null b,
// otherwise mb_strpos will give WARNING
} elseif ($this->b === null
|| (false === strpos('{[(+-', $this->b)
|| (false === strpos('{[(+-!~', $this->b)
&& ! $this->isAlphaNum($this->b))) {
$command = self::ACTION_DELETE_A;
}
} elseif (! $this->isAlphaNum($this->a)) {
if ($this->b === ' '
|| ($this->b === "\n"
|| ($this->b === "\n"
&& (false === strpos('}])+-"\'', $this->a)))) {
$command = self::ACTION_DELETE_A_B;
}
@ -160,7 +160,7 @@ class JSMin {
*/
protected function action($command)
{
if ($command === self::ACTION_DELETE_A_B
if ($command === self::ACTION_DELETE_A_B
&& $this->b === ' '
&& ($this->a === '+' || $this->a === '-')) {
// Note: we're at an addition/substraction operator; the inputIndex
@ -175,20 +175,20 @@ class JSMin {
$this->output .= $this->a;
$this->lastByteOut = $this->a;
// fallthrough
// fallthrough intentional
case self::ACTION_DELETE_A:
$this->a = $this->b;
if ($this->a === "'" || $this->a === '"') { // string literal
$str = $this->a; // in case needed for exception
while (true) {
for(;;) {
$this->output .= $this->a;
$this->lastByteOut = $this->a;
$this->a = $this->get();
$this->a = $this->get();
if ($this->a === $this->b) { // end quote
break;
}
if (ord($this->a) <= self::ORD_LF) {
if ($this->isEOF($this->a)) {
throw new JSMin_UnterminatedStringException(
"JSMin: Unterminated String at byte "
. $this->inputIndex . ": {$str}");
@ -198,27 +198,49 @@ class JSMin {
$this->output .= $this->a;
$this->lastByteOut = $this->a;
$this->a = $this->get();
$this->a = $this->get();
$str .= $this->a;
}
}
}
// fallthrough
// fallthrough intentional
case self::ACTION_DELETE_A_B:
$this->b = $this->next();
if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal
if ($this->b === '/' && $this->isRegexpLiteral()) {
$this->output .= $this->a . $this->b;
$pattern = '/'; // in case needed for exception
while (true) {
$pattern = '/'; // keep entire pattern in case we need to report it in the exception
for(;;) {
$this->a = $this->get();
$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
break; // while (true)
} elseif ($this->a === '\\') {
$this->output .= $this->a;
$this->a = $this->get();
$pattern .= $this->a;
} elseif (ord($this->a) <= self::ORD_LF) {
$this->a = $this->get();
$pattern .= $this->a;
} elseif ($this->isEOF($this->a)) {
throw new JSMin_UnterminatedRegExpException(
"JSMin: Unterminated RegExp at byte "
. $this->inputIndex .": {$pattern}");
@ -286,6 +308,17 @@ class JSMin {
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.
*
@ -336,7 +369,7 @@ class JSMin {
{
$this->get();
$comment = '';
while (true) {
for(;;) {
$get = $this->get();
if ($get === '*') {
if ($this->peek() === '/') { // end of comment reached

View File

@ -0,0 +1,5 @@
!function(){}(window)
!function(){}(window)
x = / [/] /;

View File

@ -0,0 +1,3 @@
!function(){}(window)
!function(){}(window)
x=/ [/] /;

View File

@ -8,7 +8,7 @@ function test_JSMin()
$src = file_get_contents($thisDir . '/_test_files/js/before.js');
$minExpected = file_get_contents($thisDir . '/_test_files/js/before.min.js');
$minOutput = JSMin::minify($src);
$passed = assertTrue($minExpected == $minOutput, 'JSMin : Overall');
assertTrue($minExpected == $minOutput, 'JSMin : Overall');
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";
@ -18,7 +18,17 @@ function test_JSMin()
$src = file_get_contents($thisDir . '/_test_files/js/issue144.js');
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue144.min.js');
$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'])) {
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\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');
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue132.min.js');
$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'])) {
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\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');
$minExpected = file_get_contents($thisDir . '/_test_files/js/issue74.min.js');
$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'])) {
echo "\n---Output: " .countBytes($minOutput). " bytes\n\n{$minOutput}\n\n";
echo "---Expected: " .countBytes($minExpected). " bytes\n\n{$minExpected}\n\n";