package.xml0000664000175000017500000001041512653734422011310 0ustar janjan 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/LICENSE0000664000175000017500000000215112653734422024545 0ustar janjanCopyright (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.php0000664000175000017500000002060612653734422026021 0ustar janjan (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.php0000664000175000017500000000133612653734422024256 0ustar janjan * @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.php0000664000175000017500000000013212653734422026213 0ustar janjanrun(); Horde_JavascriptMinify_Jsmin-1.0.2/test/Horde/JavascriptMinify/Jsmin/bootstrap.php0000664000175000017500000000014312653734422026477 0ustar janjan * @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.xml0000664000175000017500000000031112653734422026157 0ustar janjan ../../../../lib