package.xml0000664000175000017500000000622412242644674011316 0ustar janjan Horde_Text_Filter_Jsmin pear.horde.org Horde Text Filter - Jsmin PHP Driver The JSMin javascript minifier driver for use with the Horde_Text_Filter package. Michael Slusarz slusarz slusarz@horde.org yes 2013-11-19 1.0.0 1.0.0 stable stable JSMin * [mms] Initial release. 5.3.0 1.7.0 Horde_Text_Filter pear.horde.org 2.2.0 3.0.0alpha1 3.0.0alpha1 1.0.0 1.0.0 stable stable 2013-11-19 JSMin * [mms] Initial release. Horde_Text_Filter_Jsmin-1.0.0/doc/Horde/Text/Filter/Jsmin/LICENSE0000664000175000017500000000215112242644674022404 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_Text_Filter_Jsmin-1.0.0/lib/Horde/Text/Filter/Jsmin.php0000664000175000017500000002055612242644674022122 0ustar janjan (jsmin.c) * (c) 2008 Ryan Grove (PHP port) * Copyright 2009-2013 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-2013 Horde LLC * @license JSMin * @package Text_Filter_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-2013 Horde LLC * @license JSMin * @package Text_Filter_Jsmin */ class Horde_Text_Filter_Jsmin { /* 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_Text_Filter_Jsmin-1.0.0/test/Horde/Text/Filter/Jsmin/AllTests.php0000664000175000017500000000013212242644674024052 0ustar janjanrun(); Horde_Text_Filter_Jsmin-1.0.0/test/Horde/Text/Filter/Jsmin/bootstrap.php0000664000175000017500000000014312242644674024336 0ustar janjan * @category Horde * @license JSMin * @package Text_Filter_Jsmin * @subpackage UnitTests */ class Horde_Text_Filter_Jsmin_JsminTest extends PHPUnit_Framework_TestCase { public function testJsmin() { $javascript = <<assertEquals( "function foo(bar)\n{if(bar==2){return true;}else{return false;}}", Horde_Text_Filter::filter($javascript, 'JavascriptMinify') ); } // 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; $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;}", Horde_Text_Filter::filter($javascript, 'JavascriptMinify') ); } public function testBug12787() { $js = "function foo(a) { return/\//.test(a); }"; $this->assertEquals( 'function foo(a){return/\//.test(a);}', Horde_Text_Filter::filter($js, 'JavascriptMinify') ); $js2 = 'var a = 0, b = c / 100 | 0;'; $this->assertNotEquals( $js2, Horde_Text_Filter::filter($js2, 'JavascriptMinify') ); } } Horde_Text_Filter_Jsmin-1.0.0/test/Horde/Text/Filter/Jsmin/phpunit.xml0000664000175000017500000000031412242644674024021 0ustar janjan ../../../../../lib