mirror of
https://github.com/mrclay/minify.git
synced 2025-08-07 06:36:29 +02:00
Fix up web-based tool and correct error byte in JSMin exceptions
This commit is contained in:
@@ -200,8 +200,9 @@ class JSMin {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($this->isEOF($this->a)) {
|
if ($this->isEOF($this->a)) {
|
||||||
|
$byte = $this->inputIndex - 1;
|
||||||
throw new JSMin_UnterminatedStringException(
|
throw new JSMin_UnterminatedStringException(
|
||||||
"JSMin: Unterminated String at byte {$this->inputIndex}: {$str}");
|
"JSMin: Unterminated String at byte {$byte}: {$str}");
|
||||||
}
|
}
|
||||||
$str .= $this->a;
|
$str .= $this->a;
|
||||||
if ($this->a === '\\') {
|
if ($this->a === '\\') {
|
||||||
@@ -251,8 +252,9 @@ class JSMin {
|
|||||||
$this->a = $this->get();
|
$this->a = $this->get();
|
||||||
$pattern .= $this->a;
|
$pattern .= $this->a;
|
||||||
} elseif ($this->isEOF($this->a)) {
|
} elseif ($this->isEOF($this->a)) {
|
||||||
|
$byte = $this->inputIndex - 1;
|
||||||
throw new JSMin_UnterminatedRegExpException(
|
throw new JSMin_UnterminatedRegExpException(
|
||||||
"JSMin: Unterminated RegExp at byte {$this->inputIndex}: {$pattern}");
|
"JSMin: Unterminated RegExp at byte {$byte}: {$pattern}");
|
||||||
}
|
}
|
||||||
$this->output .= $this->a;
|
$this->output .= $this->a;
|
||||||
$this->lastByteOut = $this->a;
|
$this->lastByteOut = $this->a;
|
||||||
|
@@ -63,8 +63,6 @@ class Minify_HTML {
|
|||||||
*
|
*
|
||||||
* 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
|
* 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
|
||||||
* unset, minify will sniff for an XHTML doctype.
|
* unset, minify will sniff for an XHTML doctype.
|
||||||
*
|
|
||||||
* @return null
|
|
||||||
*/
|
*/
|
||||||
public function __construct($html, $options = array())
|
public function __construct($html, $options = array())
|
||||||
{
|
{
|
||||||
|
@@ -6,6 +6,10 @@ function getPost($key) {
|
|||||||
: $_POST[$key];
|
: $_POST[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function h($txt) {
|
||||||
|
return htmlspecialchars($txt, ENT_QUOTES, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_POST['textIn'])) {
|
if (isset($_POST['textIn'])) {
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
$textIn = str_replace("\r\n", "\n", getPost('textIn'));
|
$textIn = str_replace("\r\n", "\n", getPost('textIn'));
|
||||||
@@ -17,7 +21,7 @@ if (isset($_POST['method']) && $_POST['method'] === 'Minify and serve') {
|
|||||||
if ($base) {
|
if ($base) {
|
||||||
$textIn = preg_replace(
|
$textIn = preg_replace(
|
||||||
'@(<head\\b[^>]*>)@i'
|
'@(<head\\b[^>]*>)@i'
|
||||||
,'$1<base href="' . htmlspecialchars($base, ENT_QUOTES, 'UTF-8') . '" />'
|
,'$1<base href="' . h($base) . '" />'
|
||||||
,$textIn
|
,$textIn
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -38,14 +42,15 @@ if (isset($_POST['method']) && $_POST['method'] === 'Minify and serve') {
|
|||||||
,'contentType' => Minify::TYPE_HTML
|
,'contentType' => Minify::TYPE_HTML
|
||||||
));
|
));
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
|
echo h($e->getMessage());
|
||||||
}
|
}
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$classes = array('Minify_HTML', 'JSMin', 'Minify_CSS', 'Minify_CSSmin', 'JSMinPlus');
|
$tpl = array();
|
||||||
|
$tpl['classes'] = array('Minify_HTML', 'JSMin', 'Minify_CSS', 'Minify_CSSmin', 'JSMinPlus');
|
||||||
|
|
||||||
if (isset($_POST['method']) && in_array($_POST['method'], $classes)) {
|
if (isset($_POST['method']) && in_array($_POST['method'], $tpl['classes'])) {
|
||||||
|
|
||||||
$args = array($textIn);
|
$args = array($textIn);
|
||||||
if ($_POST['method'] === 'Minify_HTML') {
|
if ($_POST['method'] === 'Minify_HTML') {
|
||||||
@@ -55,40 +60,78 @@ if (isset($_POST['method']) && in_array($_POST['method'], $classes)) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
$func = array($_POST['method'], 'minify');
|
$func = array($_POST['method'], 'minify');
|
||||||
$inOutBytes[0] = strlen($textIn);
|
$tpl['inBytes'] = strlen($textIn);
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
try {
|
try {
|
||||||
$textOut = call_user_func_array($func, $args);
|
$tpl['output'] = call_user_func_array($func, $args);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
|
$tpl['exceptionMsg'] = getExceptionMsg($e, $textIn);
|
||||||
exit;
|
$tpl['output'] = $textIn;
|
||||||
|
sendPage($tpl);
|
||||||
}
|
}
|
||||||
$elapsedTime = microtime(true) - $startTime;
|
$tpl['time'] = microtime(true) - $startTime;
|
||||||
$inOutBytes[1] = strlen($textOut);
|
$tpl['outBytes'] = strlen($tpl['output']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendPage($tpl);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Exception $e
|
||||||
|
* @param string $input
|
||||||
|
* @return string HTML
|
||||||
|
*/
|
||||||
|
function getExceptionMsg(Exception $e, $input) {
|
||||||
|
$msg = "<p>" . h($e->getMessage()) . "</p>";
|
||||||
|
if (0 === strpos(get_class($e), 'JSMin_Unterminated')
|
||||||
|
&& preg_match('~byte (\d+)~', $e->getMessage(), $m)) {
|
||||||
|
$msg .= "<pre>";
|
||||||
|
if ($m[1] > 200) {
|
||||||
|
$msg .= h(substr($input, ($m[1] - 200), 200));
|
||||||
|
} else {
|
||||||
|
$msg .= h(substr($input, 0, $m[1]));
|
||||||
|
}
|
||||||
|
$highlighted = isset($input[$m[1]]) ? h($input[$m[1]]) : '␄';
|
||||||
|
if ($highlighted === "\n") {
|
||||||
|
$highlighted = "⏎\n";
|
||||||
|
}
|
||||||
|
$msg .= "<span style='background:#c00;color:#fff'>$highlighted</span>";
|
||||||
|
$msg .= h(substr($input, $m[1] + 1, 200)) . "</span></pre>";
|
||||||
|
}
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw page
|
||||||
|
*
|
||||||
|
* @param array $vars
|
||||||
|
*/
|
||||||
|
function sendPage($vars) {
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html><head><title>minifyTextarea</title></head>
|
<!DOCTYPE html><head><title>minifyTextarea</title></head>
|
||||||
<?php
|
<?php
|
||||||
if (isset($inOutBytes)) {
|
if (isset($vars['exceptionMsg'])) {
|
||||||
|
echo $vars['exceptionMsg'];
|
||||||
|
}
|
||||||
|
if (isset($vars['time'])) {
|
||||||
echo "
|
echo "
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Bytes in</th><td>{$inOutBytes[0]} (after line endings normalized to <code>\\n</code>)</td></tr>
|
<tr><th>Bytes in</th><td>{$vars['inBytes']} (after line endings normalized to <code>\\n</code>)</td></tr>
|
||||||
<tr><th>Bytes out</th><td>{$inOutBytes[1]} (reduced " . round(100 - (100 * $inOutBytes[1] / $inOutBytes[0])) . "%)</td></tr>
|
<tr><th>Bytes out</th><td>{$vars['outBytes']} (reduced " . round(100 - (100 * $vars['outBytes'] / $vars['inBytes'])) . "%)</td></tr>
|
||||||
<tr><th>Time (s)</th><td>" . round($elapsedTime, 5) . "</td></tr>
|
<tr><th>Time (s)</th><td>" . round($vars['time'], 5) . "</td></tr>
|
||||||
</table>
|
</table>
|
||||||
";
|
";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<form action="?2" method="post">
|
<form action="?2" method="post">
|
||||||
<p><label>Content<br><textarea name="textIn" cols="80" rows="35" style="width:99%"><?php
|
<p><label>Content<br><textarea name="textIn" cols="80" rows="35" style="width:99%"><?php
|
||||||
if (isset($textOut)) {
|
if (isset($vars['output'])) {
|
||||||
echo htmlspecialchars($textOut, ENT_QUOTES, 'UTF-8');
|
echo h($vars['output']);
|
||||||
}
|
}
|
||||||
?></textarea></label></p>
|
?></textarea></label></p>
|
||||||
<p>Minify with:
|
<p>Minify with:
|
||||||
<?php foreach ($classes as $minClass): ?>
|
<?php foreach ($vars['classes'] as $minClass): ?>
|
||||||
<input type="submit" name="method" value="<?php echo $minClass; ?>">
|
<input type="submit" name="method" value="<?php echo $minClass; ?>">
|
||||||
<?php endForEach; ?>
|
<?php endForEach; ?>
|
||||||
</p>
|
</p>
|
||||||
@@ -98,3 +141,35 @@ if (isset($textOut)) {
|
|||||||
<label>Insert BASE element w/ href: <input type="text" name="base" size="20"></label>
|
<label>Insert BASE element w/ href: <input type="text" name="base" size="20"></label>
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
<?php if (isset($vars['selectByte'])) { ?>
|
||||||
|
<script>
|
||||||
|
function selectText(el, begin, end) {
|
||||||
|
var len = el.value.length;
|
||||||
|
end = end || len;
|
||||||
|
if (begin == null) {
|
||||||
|
el.select();
|
||||||
|
} else {
|
||||||
|
if (el.setSelectionRange) {
|
||||||
|
el.setSelectionRange(begin, end);
|
||||||
|
} else {
|
||||||
|
if (el.createTextRange) {
|
||||||
|
var tr = el.createTextRange()
|
||||||
|
,c = "character";
|
||||||
|
tr.moveStart(c, begin);
|
||||||
|
tr.moveEnd(c, end - len);
|
||||||
|
tr.select();
|
||||||
|
} else {
|
||||||
|
el.select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
window.onload = function () {
|
||||||
|
var ta = document.querySelector('textarea[name="textIn"]');
|
||||||
|
selectText(ta, <?= $vars['selectByte'] ?>, <?= ($vars['selectByte'] + 1) ?>);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<?php }
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
@@ -60,13 +60,17 @@ function test_JSMin()
|
|||||||
test_JSMin_exception('"Hello'
|
test_JSMin_exception('"Hello'
|
||||||
,'Unterminated String'
|
,'Unterminated String'
|
||||||
,'JSMin_UnterminatedStringException'
|
,'JSMin_UnterminatedStringException'
|
||||||
,"JSMin: Unterminated String at byte 6: \"Hello");
|
,"JSMin: Unterminated String at byte 5: \"Hello");
|
||||||
|
|
||||||
test_JSMin_exception("return /regexp\n}"
|
test_JSMin_exception("return /regexp\n}"
|
||||||
,'Unterminated RegExp'
|
,'Unterminated RegExp'
|
||||||
,'JSMin_UnterminatedRegExpException'
|
,'JSMin_UnterminatedRegExpException'
|
||||||
,"JSMin: Unterminated RegExp at byte 15: /regexp\n");
|
,"JSMin: Unterminated RegExp at byte 14: /regexp\n");
|
||||||
test_JSMin_exception("return/regexp\n}"
|
test_JSMin_exception("return/regexp\n}"
|
||||||
|
,'Unterminated RegExp'
|
||||||
|
,'JSMin_UnterminatedRegExpException'
|
||||||
|
,"JSMin: Unterminated RegExp at byte 13: /regexp\n");
|
||||||
|
test_JSMin_exception(";return/regexp\n}"
|
||||||
,'Unterminated RegExp'
|
,'Unterminated RegExp'
|
||||||
,'JSMin_UnterminatedRegExpException'
|
,'JSMin_UnterminatedRegExpException'
|
||||||
,"JSMin: Unterminated RegExp at byte 14: /regexp\n");
|
,"JSMin: Unterminated RegExp at byte 14: /regexp\n");
|
||||||
@@ -74,15 +78,11 @@ function test_JSMin()
|
|||||||
,'Unterminated RegExp'
|
,'Unterminated RegExp'
|
||||||
,'JSMin_UnterminatedRegExpException'
|
,'JSMin_UnterminatedRegExpException'
|
||||||
,"JSMin: Unterminated RegExp at byte 15: /regexp\n");
|
,"JSMin: Unterminated RegExp at byte 15: /regexp\n");
|
||||||
test_JSMin_exception(";return /regexp\n}"
|
|
||||||
,'Unterminated RegExp'
|
|
||||||
,'JSMin_UnterminatedRegExpException'
|
|
||||||
,"JSMin: Unterminated RegExp at byte 16: /regexp\n");
|
|
||||||
|
|
||||||
test_JSMin_exception("typeof/regexp\n}"
|
test_JSMin_exception("typeof/regexp\n}"
|
||||||
,'Unterminated RegExp'
|
,'Unterminated RegExp'
|
||||||
,'JSMin_UnterminatedRegExpException'
|
,'JSMin_UnterminatedRegExpException'
|
||||||
,"JSMin: Unterminated RegExp at byte 14: /regexp\n");
|
,"JSMin: Unterminated RegExp at byte 13: /regexp\n");
|
||||||
|
|
||||||
test_JSMin_exception("/* Comment "
|
test_JSMin_exception("/* Comment "
|
||||||
,'Unterminated Comment'
|
,'Unterminated Comment'
|
||||||
|
Reference in New Issue
Block a user