diff options
| -rw-r--r-- | HISTORY | 1 | ||||
| -rw-r--r-- | framework/Web/Javascripts/clientscripts.php | 876 | 
2 files changed, 219 insertions, 658 deletions
| @@ -3,6 +3,7 @@ Version 3.1.0 RC To be released  BUG: Ticket#605 - TDatePicker don't works in 3.1.b on linux server (Wei)  BUG: Ticket#606 - TColorPicker bug in Full mode (Wei)  ENH: Ticket#601 - TRectangleHotSpot and javascript onclick handler (Qiang) +ENH: Ticket#613 - clientscripts.php is made PHP4-compliant (Qiang)  ENH: Add javascript references for "slider" and "dragdrop" for TClientScript::PradoScripts (Wei)  ENH: Added PatternModifiers property to TRegularExpressionValidator (Wei)  CHG: <div> tags are used instead of <span> when TDataList.RepeatLayout is Raw (Qiang) diff --git a/framework/Web/Javascripts/clientscripts.php b/framework/Web/Javascripts/clientscripts.php index 1070a8d0..f66ebb3d 100644 --- a/framework/Web/Javascripts/clientscripts.php +++ b/framework/Web/Javascripts/clientscripts.php @@ -138,16 +138,7 @@ function combine_javascript($files)   */
  function minify_javascript($content, $files)
  {
 -	$jsMin = new JSMin($content, false);
 -	try
 -	{
 -		return $jsMin->minify();
 -	}
 -	catch (Exception $e)
 -	{
 -		error_log('Prado client script: unable to strip javascript comments in one or more files in "'.implode(', ', $files).'"');
 -		return $content;
 -	}
 +	return jsm_minify($content);
  }
  /**
 @@ -257,704 +248,273 @@ function supports_gzip_encoding()  	}
  }
 -define('JSMIN_AS_LIB', true);
 -
 -/**
 -* JSMin_lib.php (for PHP 4, 5)
 -*
 -* PHP adaptation of JSMin, published by Douglas Crockford as jsmin.c, also based
 -* on its Java translation by John Reilly.
 -*
 -* Permission is hereby granted to use the PHP version under the same conditions
 -* as jsmin.c, which has the following notice :
 -*
 -* ----------------------------------------------------------------------------
 -*
 -* 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.
 -*/
 -
 -/**
 -* Version of this PHP translation.
 -*/
 -
 -define('JSMIN_VERSION', '0.2');
 -
 -/**
 -* How fgetc() reports an End Of File.
 -* N.B. : use === and not == to test the result of fgetc() ! (see manual)
 -*/
 -
 -define('EOF', FALSE);
 -
 -/**
 -* Some ASCII character ordinals.
 -* N.B. : PHP identifiers are case-insensitive !
 -*/
 -
 -define('ORD_NL', ord("\n"));
 -define('ORD_space', ord(' '));
 -define('ORD_cA', ord('A'));
 -define('ORD_cZ', ord('Z'));
 -define('ORD_a', ord('a'));
 -define('ORD_z', ord('z'));
 -define('ORD_0', ord('0'));
 -define('ORD_9', ord('9'));
 -
 -/**
 -* Generic exception class related to JSMin.
 -*/
 -class JSMinException extends Exception {
 -}
 -
 -/**
 -* A JSMin exception indicating that a file provided for input or output could not be properly opened.
 -*/
 -
 -class FileOpenFailedJSMinException extends JSMinException {
 -}
 -
 -/**
 -* A JSMin exception indicating that an unterminated comment was encountered in input.
 -*/
 -
 -class UnterminatedCommentJSMinException extends JSMinException {
 -}
 -
 -/**
 -* A JSMin exception indicatig that an unterminated string literal was encountered in input.
 -*/
 -
 -class UnterminatedStringLiteralJSMinException extends JSMinException {
 -}
 -
  /**
 -* A JSMin exception indicatig that an unterminated regular expression lieteral was encountered in input.
 -*/
 -
 -class UnterminatedRegExpLiteralJSMinException extends JSMinException {
 -}
 -
 -/**
 - * Constant describing an {@link action()} : Output A. Copy B to A. Get the next B.
 - */
 -
 -define ('JSMIN_ACT_FULL', 1);
 -
 -/**
 - * Constant describing an {@link action()} : Copy B to A. Get the next B. (Delete A).
 - */
 -
 -define ('JSMIN_ACT_BUF', 2);
 -
 -/**
 - * Constant describing an {@link action()} : Get the next B. (Delete B).
 + * JSMin: the following jsm_* functions are adapted from JSMin_lib.php
 + * written by Douglas Crockford. Below is the original copyright notice:
 + *
 + * PHP adaptation of JSMin, published by Douglas Crockford as jsmin.c, also based
 + * on its Java translation by John Reilly.
 + *
 + * Permission is hereby granted to use the PHP version under the same conditions
 + * as jsmin.c, which has the following notice :
 + *
 + * ----------------------------------------------------------------------------
 + *
 + * 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.
   */
 -define ('JSMIN_ACT_IMM', 3);
 -
 -/**
 -* Main JSMin application class.
 -*
 -* Example of use :
 -*
 -* $jsMin = new JSMin(...input..., ...output...);
 -* $jsMin->minify();
 -*
 -* Do not specify input and/or output (or default to '-') to use stdin and/or stdout.
 -*/
 -
 -class JSMin {
 -
 -    /**
 -     * The input stream, from which to read a JS file to minimize. Obtained by fopen().
 -     * NB: might be a string instead of a stream
 -     * @var SplFileObject | string
 -     */
 -    var $in;
 -
 -    /**
 -     * The output stream, in which to write the minimized JS file. Obtained by fopen().
 -     * NB: might be a string instead of a stream
 -     * @var SplFileObject | string
 -     */
 -    var $out;
 -
 -    /**
 -     * Temporary I/O character (A).
 -     * @var string
 -     */
 -    var $theA;
 +$jsm_in='';
 +$jsm_out='';
 +$jsm_length=0;
 +$jsm_pos=0;
 +$jsm_c1='';
 +$jsm_c2='';
 -    /**
 -     * Temporary I/O character (B).
 -     * @var string
 -     */
 -    var $theB;
 -
 -	/** variables used for string-based parsing **/
 -	var $inLength = 0;
 -	var $inPos = 0;
 -	var $isString = false;
 -
 -    /**
 -     * Indicates whether a character is alphanumeric or _, $, \ or non-ASCII.
 -     *
 -     * @param   string      $c  The single character to test.
 -     * @return  boolean     Whether the char is a letter, digit, underscore, dollar, backslash, or non-ASCII.
 -     */
 -    function isAlphaNum($c) {
 -
 -        // Get ASCII value of character for C-like comparisons
 -
 -        $a = ord($c);
 -
 -        // Compare using defined character ordinals, or between PHP strings
 -        // Note : === is micro-faster than == when types are known to be the same
 +function jsm_minify($jsCode)
 +{
 +	global $jsm_in, $jsm_out, $jsm_length, $jsm_pos, $jsm_c1, $jsm_c2;
 -        return
 -            ($a >= ORD_a && $a <= ORD_z) ||
 -            ($a >= ORD_0 && $a <= ORD_9) ||
 -            ($a >= ORD_cA && $a <= ORD_cZ) ||
 -            $c === '_' || $c === '$' || $c === '\\' || $a > 126
 -        ;
 -    }
 +	$jsm_in=$jsCode;
 +	$jsm_out='';
 +	$jsm_length=strlen($jsCode);
 +	$jsm_pos=0;
 -    /**
 -     * Get the next character from the input stream.
 -     *
 -     * If said character is a control character, translate it to a space or linefeed.
 -     *
 -     * @return  string      The next character from the specified input stream.
 -     * @see     $in
 -     * @see     peek()
 -     */
 -    function get() {
 +    // Initialize A and run the first (minimal) action
 +    $jsm_c1="\n";
 +    jsm_next();
 -        // Get next input character and advance position in file
 -		if ($this->isString) {
 -			if ($this->inPos < $this->inLength) {
 -				$c = $this->in[$this->inPos];
 -				++$this->inPos;
 -			}
 -			else {
 -				return EOF;
 -			}
 +    // Proceed all the way to the end of the input file
 +	while($jsm_c1!==false)
 +	{
 +		if($jsm_c1===' ')
 +		{
 +			if(jsm_isAlphaNum($jsm_c2))
 +                jsm_write($jsm_c1);
 +            else
 +                jsm_buffer();
 +		}
 +		else if($jsm_c1==="\n")
 +		{
 +			if($jsm_c2===' ')
 +				jsm_next();
 +			else if(jsm_isAlphaNum($jsm_c2) || $jsm_c2==='{' || $jsm_c2==='[' || $jsm_c2==='(' || $jsm_c2==='+' || $jsm_c2==='-')
 +				jsm_write($jsm_c1);
 +			else
 +				jsm_buffer();
  		}
  		else
 -	        $c = $this->in->fgetc();
 -
 -        // Test for non-problematic characters
 -
 -        if ($c === "\n" || $c === EOF || ord($c) >= ORD_space) {
 -            return $c;
 -        }
 -
 -        // else
 -        // Make linefeeds into newlines
 -
 -        if ($c === "\r") {
 -            return "\n";
 -        }
 -
 -        // else
 -        // Consider space
 -
 -        return ' ';
 -    }
 -
 -    /**
 -     * Get the next character from the input stream, without gettng it.
 -     *
 -     * @return  string      The next character from the specified input stream, without advancing the position
 -     *                      in the underlying file.
 -     * @see     $in
 -     * @see     get()
 -     */
 -    function peek() {
 -
 -		if ($this->isString) {
 -			if ($this->inPos < $this->inLength) {
 -				$c = $this->in[$this->inPos];
 +		{
 +			if($jsm_c2===' ')
 +			{
 +				if(jsm_isAlphaNum($jsm_c1))
 +					jsm_write($jsm_c1);
 +				else
 +					jsm_next();
  			}
 -			else {
 -				return EOF;
 +			else if($jsm_c2==="\n")
 +			{
 +				if(jsm_isAlphaNum($jsm_c1) || $jsm_c1==='}' || $jsm_c1===']' || $jsm_c1===')' || $jsm_c1==='+' || $jsm_c1==='-' || $jsm_c1==='"' || $jsm_c1==='\'')
 +					jsm_write($jsm_c1);
 +				else
 +					jsm_next();
  			}
 -		}
 -		else {
 -	        // Get next input character
 -
 -	        $c = $this->in->fgetc();
 -
 -	        // Regress position in file
 -
 -	        $this->in->fseek(-1, SEEK_CUR);
 -
 -	        // Return character obtained
 -	    }
 -
 -        return $c;
 -    }
 -
 -	/**
 -	 * Adds a char to the output steram / string
 -	 * @see $out
 -	 */
 -	function put($c)
 -	{
 -		if ($this->isString) {
 -			$this->out .= $c;
 -		}
 -		else {
 -			$this->out->fwrite($c);
 +			else
 +				jsm_write($jsm_c1);
  		}
  	}
 -    /**
 -     * Get the next character from the input stream, excluding comments.
 -     *
 -     * {@link peek()} is used to see if a '/' is followed by a '*' or '/'.
 -     * Multiline comments are actually returned as a single space.
 -     *
 -     * @return  string  The next character from the specified input stream, skipping comments.
 -     * @see     $in
 -     */
 -    function next() {
 -
 -        // Get next char from input, translated if necessary
 -
 -        $c = $this->get();
 -
 -        // Check comment possibility
 -
 -        if ($c == '/') {
 -
 -            // Look ahead : a comment is two slashes or slashes followed by asterisk (to be closed)
 -
 -            switch ($this->peek()) {
 +    return $jsm_out;
 +}
 -                case '/' :
 +function jsm_write()
 +{
 +	global $jsm_c1;
 -                    // Comment is up to the end of the line
 -                    // TOTEST : simple $this->in->fgets()
 +	jsm_put($jsm_c1);
 +	jsm_buffer();
 +}
 -                    while (true) {
 +function jsm_buffer()
 +{
 +	global $jsm_c1, $jsm_c2;
 -                        $c = $this->get();
 +    $tmpA=$jsm_c1=$jsm_c2;
 -                        if (ord($c) <= ORD_NL) {
 -                            return $c;
 -                        }
 -                    }
 +    // Treating a string as a single char : outputting it whole
 +    // Note that the string-opening char (" or ') is memorized in B
 -                case '*' :
 +    if($tmpA==='\'' || $tmpA==='"')
 +    {
 +	    while (true)
 +	    {
 +			// Output string contents
 +	        jsm_put($tmpA);
 -                    // Comment is up to comment close.
 -                    // Might not be terminated, if we hit the end of file.
 +	        // Get next character, watching out for termination of the current string,
 +	        // new line & co (then the string is not terminated !), or a backslash
 +	        // (upon which the following char is directly output to serve the escape mechanism)
 -                    while (true) {
 +	        $tmpA=$jsm_c1=jsm_get();
 -                        // N.B. not using switch() because of having to test EOF with ===
 +	        if($tmpA===$jsm_c2) // String terminated
 +	            break; // from while(true)
 -                        $c = $this->get();
 +	        if(ord($tmpA) <= ord("\n"))
 +	            die('Unterminated string literal');
 -                        if ($c == '*') {
 +	        if($tmpA==='\\')
 +	        {
 +	            // Escape next char immediately
 +	            jsm_put($tmpA);
 +	            $tmpA=$jsm_c1=jsm_get();
 +	        }
 +	    }
 +	}
 -                            // Comment termination if the char ahead is a slash
 +    jsm_next();
 +}
 -                            if ($this->peek() == '/') {
 +function jsm_next()
 +{
 +	global $jsm_c1, $jsm_c2;
 -                                // Advance again and make into a single space
 +    // Get the next B
 +    $jsm_c2=jsm_get2();
 -                                $this->get();
 -                                return ' ';
 -                            }
 -                        }
 -                        else if ($c === EOF) {
 +    // Special case of recognising regular expressions (beginning with /) that are
 +    // preceded by '(', ',' or '='
 +    $tmpA=$jsm_c1;
 -                            // Whoopsie
 -                            throw new UnterminatedCommentJSMinException();
 -                        }
 -                    }
 +    if($jsm_c2==='/' && ($tmpA==='(' || $tmpA===',' || $tmpA==='='))
 +    {
 +        // Output the two successive chars
 +        jsm_put($tmpA);
 +        jsm_put($jsm_c2);
 -                default :
 +        // Look for the end of the RE literal, watching out for escaped chars or a control /
 +        // end of line char (the RE literal then being unterminated !)
 +        while (true)
 +        {
 +		    $tmpA=$jsm_c1=jsm_get();
 -                    // Not a comment after all
 +            if($tmpA==='/')
 +                break; // from while(true)
 -                    return $c;
 +            if($tmpA==='\\')
 +            {
 +                // Escape next char immediately
 +                jsm_put($tmpA);
 +                $tmpA=$jsm_c1=jsm_get();
              }
 -        }
 -
 -        // No risk of a comment
 -
 -        return $c;
 -    }
 -
 -    /**
 -     * Do something !
 -     *
 -     * The action to perform is determined by the argument :
 -     *
 -     * JSMin::ACT_FULL : Output A. Copy B to A. Get the next B.
 -     * JSMin::ACT_BUF  : Copy B to A. Get the next B. (Delete A).
 -     * JSMin::ACT_IMM  : Get the next B. (Delete B).
 -     *
 -     * A string is treated as a single character. Also, regular expressions are recognized if preceded
 -     * by '(', ',' or '='.
 -     *
 -     * @param   int     $action     The action to perform : one of the JSMin::ACT_* constants.
 -     */
 -    function action($action) {
 -
 -        // Choice of possible actions
 -        // Note the frequent fallthroughs : the actions are decrementally "long"
 -
 -        switch ($action) {
 -
 -            case JSMIN_ACT_FULL :
 -
 -                // Write A to output, then fall through
 -
 -                $this->put($this->theA);
 -
 -            case JSMIN_ACT_BUF : // N.B. possible fallthrough from above
 -
 -                // Copy B to A
 -
 -                $tmpA = $this->theA = $this->theB;
 -
 -                // Treating a string as a single char : outputting it whole
 -                // Note that the string-opening char (" or ') is memorized in B
 -
 -                if ($tmpA == '\'' || $tmpA == '"') {
 -
 -                    while (true) {
 -
 -                        // Output string contents
 +            else if(ord($tmpA) <= ord("\n"))
 +                die('Unterminated regexp literal');
 -                        $this->put($tmpA);
 -
 -                        // Get next character, watching out for termination of the current string,
 -                        // new line & co (then the string is not terminated !), or a backslash
 -                        // (upon which the following char is directly output to serve the escape mechanism)
 -
 -                        $tmpA = $this->theA = $this->get();
 -
 -                        if ($tmpA == $this->theB) {
 -
 -                            // String terminated
 -
 -                            break; // from while(true)
 -                        }
 -
 -                        // else
 -
 -                        if (ord($tmpA) <= ORD_NL) {
 -
 -                            // Whoopsie
 -
 -                            throw new UnterminatedStringLiteralJSMinException();
 -                        }
 -
 -                        // else
 -
 -                        if ($tmpA == '\\') {
 -
 -                            // Escape next char immediately
 -
 -                            $this->put($tmpA);
 -                            $tmpA = $this->theA = $this->get();
 -                        }
 -                    }
 -                }
 -
 -            case JSMIN_ACT_IMM : // N.B. possible fallthrough from above
 -
 -                // Get the next B
 -
 -                $this->theB = $this->next();
 -
 -                // Special case of recognising regular expressions (beginning with /) that are
 -                // preceded by '(', ',' or '='
 -
 -                $tmpA = $this->theA;
 -
 -                if ($this->theB == '/' && ($tmpA == '(' || $tmpA == ',' || $tmpA == '=')) {
 -
 -                    // Output the two successive chars
 -
 -                    $this->put($tmpA);
 -                    $this->put($this->theB);
 -
 -                    // Look for the end of the RE literal, watching out for escaped chars or a control /
 -                    // end of line char (the RE literal then being unterminated !)
 -
 -                    while (true) {
 -
 -                        $tmpA = $this->theA = $this->get();
 -
 -                        if ($tmpA == '/') {
 -
 -                            // RE literal terminated
 -
 -                            break; // from while(true)
 -                        }
 -
 -                        // else
 -
 -                        if ($tmpA == '\\') {
 -
 -                            // Escape next char immediately
 -
 -                            $this->put($tmpA);
 -                            $tmpA = $this->theA = $this->get();
 -                        }
 -                        else if (ord($tmpA) <= ORD_NL) {
 -
 -                            // Whoopsie
 -
 -                            throw new UnterminatedRegExpLiteralJSMinException();
 -                        }
 -
 -                        // Output RE characters
 -
 -                        $this->put($tmpA);
 -                    }
 -
 -                    // Move forward after the RE literal
 -
 -                    $this->theB = $this->next();
 -                }
 -
 -            break;
 -            default :
 -				throw new JSMinException('Expected a JSMin::ACT_* constant in action().');
 +            // Output RE characters
 +            jsm_put($tmpA);
          }
 -    }
 -
 -    /**
 -     * Run the JSMin application : minify some JS code.
 -     *
 -     * The code is read from the input stream, and its minified version is written to the output one.
 -     * In case input is a string, minified vesrions is also returned by this function as string.
 -     * That is : characters which are insignificant to JavaScript are removed, as well as comments ;
 -     * tabs are replaced with spaces ; carriage returns are replaced with linefeeds, and finally most
 -     * spaces and linefeeds are deleted.
 -     *
 -     * Note : name was changed from jsmin() because PHP identifiers are case-insensitive, and it is already
 -     * the name of this class.
 -     *
 -     * @see     JSMin()
 -     * @return null | string
 -     */
 -    function minify() {
 -
 -        // Initialize A and run the first (minimal) action
 -
 -        $this->theA = "\n";
 -        $this->action(JSMIN_ACT_IMM);
 -
 -        // Proceed all the way to the end of the input file
 -
 -        while ($this->theA !== EOF) {
 -
 -            switch ($this->theA) {
 -
 -                case ' ' :
 -
 -                    if (JSMin::isAlphaNum($this->theB)) {
 -                        $this->action(JSMIN_ACT_FULL);
 -                    }
 -                    else {
 -                        $this->action(JSMIN_ACT_BUF);
 -                    }
 -
 -                break;
 -                case "\n" :
 -
 -                    switch ($this->theB) {
 -
 -                        case '{' : case '[' : case '(' :
 -                        case '+' : case '-' :
 -
 -                            $this->action(JSMIN_ACT_FULL);
 -
 -                        break;
 -                        case ' ' :
 -
 -                            $this->action(JSMIN_ACT_IMM);
 -
 -                        break;
 -                        default :
 -
 -                            if (JSMin::isAlphaNum($this->theB)) {
 -                                $this->action(JSMIN_ACT_FULL);
 -                            }
 -                            else {
 -                                $this->action(JSMIN_ACT_BUF);
 -                            }
 -
 -                        break;
 -                    }
 -
 -                break;
 -                default :
 -
 -                    switch ($this->theB) {
 -
 -                        case ' ' :
 -
 -                            if (JSMin::isAlphaNum($this->theA)) {
 -                                $this->action(JSMIN_ACT_FULL);
 -                                break;
 -                            }
 -
 -                            // else
 -
 -                            $this->action(JSMIN_ACT_IMM);
 -
 -                        break;
 -                        case "\n" :
 -
 -                            switch ($this->theA) {
 -
 -                                case '}' : case ']' : case ')' : case '+' :
 -                                case '-' : case '"' : case '\'' :
 -
 -                                    $this->action(JSMIN_ACT_FULL);
 +        // Move forward after the RE literal
 +        $jsm_c2=jsm_get2();
 +    }
 +}
 -                                break;
 -                                default :
 +function jsm_get()
 +{
 +	global $jsm_pos, $jsm_length, $jsm_in;
 -                                    if (JSMin::isAlphaNum($this->theA)) {
 -                                        $this->action(JSMIN_ACT_FULL);
 -                                    }
 -                                    else {
 -                                        $this->action(JSMIN_ACT_IMM);
 -                                    }
 +    // Get next input character and advance position in file
 +	if($jsm_pos < $jsm_length)
 +	{
 +		$c=$jsm_in[$jsm_pos++];
 +	    if($c==="\n" || ord($c) >= ord(' '))
 +	        return $c;
 +		else if($c==="\r")
 +	        return "\n";
 +		else
 +		    return ' ';
 +	}
 +	else
 +		return false;
 -                                break;
 -                            }
 +}
 -                        break;
 -                        default :
 +function jsm_peek()
 +{
 +	global $jsm_pos, $jsm_length, $jsm_in;
 +	if($jsm_pos < $jsm_length)
 +		return $jsm_in[$jsm_pos];
 +	else
 +		return false;
 +}
 -                            $this->action(JSMIN_ACT_FULL);
 +function jsm_put($c)
 +{
 +	global $jsm_out;
 +	$jsm_out .= $c;
 +}
 -                        break;
 -                    }
 +/**
 + * Get the next character from the input stream, excluding comments.
 + */
 +function jsm_get2()
 +{
 +    // Get next char from input, translated if necessary
 +    if(($c=jsm_get())!=='/')
 +    	return $c;
 -                break;
 -            }
 +    // Look ahead : a comment is two slashes or slashes followed by asterisk (to be closed)
 +	if(($c=jsm_peek())==='/')
 +	{
 +        // Comment is up to the end of the line
 +        while (true)
 +        {
 +            $c=jsm_get();
 +            if(ord($c)<=ord("\n"))
 +                return $c;
          }
 -
 -	    if ($this->isString) {
 -		    return $this->out;
 -
 -	    }
 -    }
 -
 -    /**
 -     * Prepare a new JSMin application.
 -     *
 -     * The next step is to {@link minify()} the input into the output.
 -     *
 -     * @param   string  $inFileName     The pathname of the input (unminified JS) file. STDIN if '-' or absent.
 -     * @param   string  $outFileName    The pathname of the output (minified JS) file. STDOUT if '-' or absent.
 -     *                                  If outFileName === FALSE, we assume that inFileName is in fact the string to be minified!!!
 -     * @param   array   $comments       Optional lines to present as comments at the beginning of the output.
 -     */
 -	function JSMin($inFileName = '-', $outFileName = '-', $comments = NULL) {
 -		if ($outFileName === FALSE) {
 -			$this->JSMin_String($inFileName, $comments);
 -		}
 -		else {
 -			$this->JSMin_File($inFileName, $outFileName, $comments);
 -		}
  	}
 -
 -    function JSMin_File($inFileName = '-', $outFileName = '-', $comments = NULL) {
 -
 -        // Recuperate input and output streams.
 -        // Use STDIN and STDOUT by default, if they are defined (CLI mode) and no file names are provided
 -
 -            if ($inFileName == '-')  $inFileName  = 'php://stdin';
 -            if ($outFileName == '-') $outFileName = 'php://stdout';
 -
 -            try {
 -
 -                $this->in = new SplFileObject($inFileName, 'rb', TRUE);
 -            }
 -            catch (Exception $e) {
 -
 -                throw new FileOpenFailedJSMinException(
 -                    'Failed to open "'.$inFileName.'" for reading only.'
 -                );
 -            }
 -
 -            try {
 -
 -                $this->out = new SplFileObject($outFileName, 'wb', TRUE);
 -            }
 -            catch (Exception $e) {
 -
 -                throw new FileOpenFailedJSMinException(
 -                    'Failed to open "'.$outFileName.'" for writing only.'
 -                );
 -            }
 -
 -			/*$this->in = fopen($inFileName, 'rb');
 -			if (!$this->in) {
 -				trigger_error('Failed to open "'.$inFileName, E_USER_ERROR);
 -			}
 -			$this->out = fopen($outFileName, 'wb');
 -			if (!$this->out) {
 -				trigger_error('Failed to open "'.$outFileName, E_USER_ERROR);
 -			}*/
 -
 -            // Present possible initial comments
 -
 -            if ($comments !== NULL) {
 -                foreach ($comments as $comm) {
 -                    $this->out->fwrite('// '.str_replace("\n", " ", $comm)."\n");
 +	else if($c==='*')
 +	{
 +        // Comment is up to comment close.
 +        // Might not be terminated, if we hit the end of file.
 +        while(true)
 +        {
 +            // N.B. not using switch() because of having to test EOF with ===
 +            $c=jsm_get();
 +            if($c==='*')
 +            {
 +			    // Comment termination if the char ahead is a slash
 +                if(jsm_peek()==='/')
 +                {
 +                    // Advance again and make into a single space
 +                    jsm_get();
 +                    return ' ';
                  }
              }
 -
 -    }
 -
 -    function JSMin_String($inString, $comments = NULL) {
 -        $this->in = $inString;
 -        $this->out = '';
 -		$this->inLength = strlen($inString);
 -		$this->inPos = 0;
 -		$this->isString = true;
 -
 -        if ($comments !== NULL) {
 -            foreach ($comments as $comm) {
 -                $this->out .= '// '.str_replace("\n", " ", $comm)."\n";
 -            }
 +            else if($c===false)
 +                die('Unterminated comment');
          }
  	}
 +	else
 +		return '/';
 +}
 +
 +/**
 + * Indicates whether a character is alphanumeric or _, $, \ or non-ASCII.
 + */
 +function jsm_isAlphaNum($c)
 +{
 +    return ctype_alnum($c) || $c==='_' || $c==='$' || $c==='\\' || ord($c)>126;
  }
  /************** OUTPUT *****************/
 | 
