package.xml 0000664 0001750 0001750 00000010415 12653734422 011310 0 ustar jan jan
Horde_JavascriptMinify_Jsmin
pear.horde.org
Horde Javascript Minifier - Jsmin PHP Driver
The JSMin javascript minifier driver for use with the Horde_JavascriptMinify package.
Michael Slusarz
slusarz
slusarz@horde.org
yes
2016-02-01
1.0.2
1.0.0
stable
stable
JSMin
* [jan] Mark PHP 7 as supported.
5.3.0
8.0.0alpha1
8.0.0alpha1
1.7.0
Horde_JavascriptMinify
pear.horde.org
1.1.0
2.0.0alpha1
2.0.0alpha1
1.0.0
1.0.0
stable
stable
2014-03-03
JSMin
* [mms] Initial release.
1.0.1
1.0.0
stable
stable
2014-05-02
JSMin
* [mms] Add commented list of original source URLs in minified output, in order to comply with any license terms contained in original files.
1.0.2
1.0.0
stable
stable
2016-02-01
JSMin
* [jan] Mark PHP 7 as supported.
Horde_JavascriptMinify_Jsmin-1.0.2/doc/Horde/JavascriptMinify/Jsmin/LICENSE 0000664 0001750 0001750 00000002151 12653734422 024545 0 ustar jan jan Copyright (c) 2002 Douglas Crockford (www.crockford.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Horde_JavascriptMinify_Jsmin-1.0.2/lib/Horde/JavascriptMinify/Jsmin/Minifier.php 0000664 0001750 0001750 00000020606 12653734422 026021 0 ustar jan jan (jsmin.c)
* (c) 2008 Ryan Grove (PHP port)
* Copyright 2009-2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (JSMin).
*
* @category Horde
* @copyright 2002 Douglas Crockford
* @copyright 2008 Ryan Grove
* @copyright 2009-2016 Horde LLC
* @license JSMin
* @package JavascriptMinify_Jsmin
*/
/**
* PHP implementation of Douglas Crockford's JSMin.
*
* See LICENSE for original JSMin license.
*
* Original PHP implementation:
* Version: 1.1.1 (2008-03-02)
* (c) 2008 Ryan Grove (PHP port)
* URL: http://code.google.com/p/jsmin-php/
*
* Additional cleanups/code by the Horde Project.
*
* @author Douglas Crockford
* @author Ryan Grove
* @author Michael Slusarz
* @category Horde
* @copyright 2002 Douglas Crockford
* @copyright 2008 Ryan Grove
* @copyright 2009-2016 Horde LLC
* @license JSMin
* @package JavascriptMinify_Jsmin
*/
class Horde_JavascriptMinify_Jsmin_Minifier
{
/* Constants. */
const ORD_LF = 10;
const ORD_SPACE = 32;
const ACTION_KEEP_A = 1;
const ACTION_DELETE_A = 2;
const ACTION_DELETE_A_B = 3;
/* Member variables. */
protected $_a = "\n";
protected $_b = '';
protected $_input;
protected $_inputIndex = 0;
protected $_inputLength;
protected $_keywords = array(
'case',
'else',
'in',
'return',
'typeof'
);
protected $_lookAhead = null;
protected $_output = '';
protected $_x = null;
protected $_y = null;
public function __construct($input)
{
$this->_input = str_replace("\r\n", "\n", $input);
$this->_inputLength = strlen($this->_input);
}
public function minify()
{
if ($this->_peek() == 0xef) {
$this->_get();
$this->_get();
$this->_get();
}
$this->_a = "\n";
$this->_action(self::ACTION_DELETE_A_B);
while (!is_null($this->_a)) {
$cmd = self::ACTION_KEEP_A;
switch ($this->_a) {
case ' ':
if (!$this->_isAlphaNum($this->_b)) {
$cmd = self::ACTION_DELETE_A;
}
break;
case "\n":
if ($this->_b === ' ') {
$cmd = self::ACTION_DELETE_A_B;
} elseif (!strspn($this->_b, '{[(+-!~') &&
!$this->_isAlphaNum($this->_b)) {
$cmd = self::ACTION_DELETE_A;
}
break;
default:
if (!$this->_isAlphaNum($this->_a) &&
(($this->_b === ' ') ||
(($this->_b === "\n" && !strspn($this->_a, '}])+-"\'`'))))) {
$cmd = self::ACTION_DELETE_A_B;
}
break;
}
$this->_action($cmd);
}
return trim($this->_output);
}
protected function _action($d)
{
switch ($d) {
case self::ACTION_KEEP_A:
$this->_output .= $this->_a;
if (strspn($this->_y, "\n ") &&
strspn($this->_a, '+-*/') &&
strspn($this->_b, '+-*/')) {
$this->_output .= $this->_y;
}
case self::ACTION_DELETE_A:
$this->_a = $this->_b;
if (strspn($this->_a, '\'"`')) {
while (true) {
$this->_output .= $this->_a;
$this->_a = $this->_get();
if ($this->_a === $this->_b) {
break;
}
if ($this->_a === '\\') {
$this->_output .= $this->_a;
$this->_a = $this->_get();
}
if (is_null($this->_a)) {
throw new Exception('Unterminated string literal.');
}
}
}
case self::ACTION_DELETE_A_B:
$oldindex = $this->_inputIndex;
$this->_b = $this->_next();
if (($this->_b === '/') && $this->_isRegexLiteral($oldindex)) {
$this->_output .= $this->_a;
if (strspn($this->_a, '/*')) {
$this->_output .= ' ';
}
$this->_output .= $this->_b;
while (true) {
$this->_a = $this->_get();
switch ($this->_a) {
case '[':
/* Inside a regex [...] set, which MAY contain a
* '/' itself. */
while (true) {
$this->_output .= $this->_a;
$this->_a = $this->_get();
if ($this->_a === ']') {
break;
} elseif ($this->_a === '\\') {
$this->_output .= $this->_a;
$this->_a = $this->_get();
} elseif (is_null($this->_a)) {
throw new Exception('Unterminated regular expression set in regex literal.');
}
}
break;
case '/':
switch ($this->_peek()) {
case '/':
case '*':
throw new Exception('Unterminated set in regular Expression literal.');
}
break 2;
case '\\':
$this->_output .= $this->_a;
$this->_a = $this->_get();
break;
}
if (is_null($this->_a)) {
throw new Exception('Unterminated regular expression literal.');
}
$this->_output .= $this->_a;
}
$this->_b = $this->_next();
}
}
}
protected function _get()
{
$c = $this->_lookAhead;
$this->_lookAhead = null;
if (is_null($c) &&
($this->_inputIndex < $this->_inputLength)) {
$c = $this->_input[$this->_inputIndex++];
}
if (is_null($c) || ($c === "\n") || (ord($c) >= self::ORD_SPACE)) {
return $c;
}
if ($c === "\r") {
return "\n";
}
return ' ';
}
protected function _isAlphaNum($c)
{
$c_ord = ord($c);
return (($c_ord > 126) ||
strspn($c, '_$\\') ||
($c_ord >= 97 && $c_ord <= 122) ||
($c_ord >= 48 && $c_ord <= 57) ||
($c_ord >= 65 && $c_ord <= 90));
}
protected function _isRegexLiteral($oldindex)
{
/* We aren't dividing. */
if (strspn($this->_a, "(,=:[!&|?+-~*/{;")) {
return true;
}
$curr = $oldindex;
while (--$curr >= 0 && $this->_isAlphaNum($this->_input[$curr])) {}
return in_array(
substr($this->_input, $curr + 1, $oldindex - $curr - 1),
$this->_keywords
);
}
protected function _next()
{
$c = $this->_get();
if ($c === '/') {
switch ($this->_peek()) {
case '/':
while (true) {
$c = $this->_get();
if (ord($c) <= self::ORD_LF) {
break;
}
}
break;
case '*':
$this->_get();
while ($c != ' ') {
switch ($this->_get()) {
case '*':
if ($this->_peek() === '/') {
$this->_get();
$c = ' ';
}
break;
case null:
throw new Exception('Unterminated comment.');
}
}
break;
}
}
$this->_y = $this->_x;
$this->_x = $c;
return $c;
}
protected function _peek()
{
$this->_lookAhead = $this->_get();
return $this->_lookAhead;
}
}
Horde_JavascriptMinify_Jsmin-1.0.2/lib/Horde/JavascriptMinify/Jsmin.php 0000664 0001750 0001750 00000001336 12653734422 024256 0 ustar jan jan
* @category Horde
* @copyright 2014-2016 Horde LLC
* @license JSMin
* @package JavascriptMinify_Jsmin
*/
class Horde_JavascriptMinify_Jsmin extends Horde_JavascriptMinify_Null
{
/**
*/
public function minify()
{
$jsmin = new Horde_JavascriptMinify_Jsmin_Minifier(parent::minify());
return $jsmin->minify() . $this->_sourceUrls();
}
}
Horde_JavascriptMinify_Jsmin-1.0.2/test/Horde/JavascriptMinify/Jsmin/AllTests.php 0000664 0001750 0001750 00000000132 12653734422 026213 0 ustar jan jan run();
Horde_JavascriptMinify_Jsmin-1.0.2/test/Horde/JavascriptMinify/Jsmin/bootstrap.php 0000664 0001750 0001750 00000000143 12653734422 026477 0 ustar jan jan
* @category Horde
* @license JSMin
* @package JavascriptMinify_Jsmin
* @subpackage UnitTests
*/
class Horde_JavascriptMinify_Jsmin_JsminTest extends PHPUnit_Framework_TestCase
{
public function testJsmin()
{
$javascript = <<assertEquals(
"function foo(bar)\n{if(bar==2){return true;}else{return false;}}",
$jsmin->minify()
);
}
// Example taken from jsmin.c source
public function testJsmin2()
{
$javascript = <<= 0;
if (is.ua.indexOf('opera') >= 0) {
is.ie = is.ns = false;
is.opera = true;
}
if (is.ua.indexOf('gecko') >= 0) {
is.ie = is.ns = false;
is.gecko = true;
}
EOT;
$jsmin = new Horde_JavascriptMinify_Jsmin($javascript);
$this->assertEquals(
"var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'}
is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;}
if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}",
$jsmin->minify()
);
}
public function testBug12787()
{
$js = "function foo(a) { return/\//.test(a); }";
$jsmin = new Horde_JavascriptMinify_Jsmin($js);
$this->assertEquals(
'function foo(a){return/\//.test(a);}',
$jsmin->minify()
);
$js2 = 'var a = 0, b = c / 100 | 0;';
$jsmin2 = new Horde_JavascriptMinify_Jsmin($js2);
$this->assertNotEquals(
$js2,
$jsmin2->minify()
);
}
}
Horde_JavascriptMinify_Jsmin-1.0.2/test/Horde/JavascriptMinify/Jsmin/phpunit.xml 0000664 0001750 0001750 00000000311 12653734422 026157 0 ustar jan jan
../../../../lib