Вход Регистрация
Файл: public/min/lib/MyMin.php
Строк: 253
<?php
/**
 * MyMin - JSMin like alternative parser for JavaScript
 *
 * This class is a jsmin alternative, based on same parser logic but modified
 * to mantain performances and to parse correctly JavaScript conditional comments too.
 * 
 * SERVER SIDE
 * PHP 5 or greater is required.
 * This code is compatible with every error_reporting level (E_ALL | E_STRICT)
 * The best practice to use this code is caching results without run-time
 * evaluation (your server should be stressed too much with big files)
 *
 * Permission is hereby granted to use this version of the library under the
 * same terms as jsmin.php, which has the following license:
 *
 * --
 * 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.
 * --
 *
 * @class MyMin
 * @author    Andrea Giammarchi <http://www.3site.eu>
 * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
 * @copyright 2007 Ryan Grove <ryan@wonko.com> (PHP port)
 * @copyright 2007 Andrea Giammarchi (improvements + MyMinCompressor + MyMinCSS)
 * @license http://opensource.org/licenses/mit-license.php MIT License
 * @version 1.0.1 (2007-10-05) - updated 2008-02-17
 */

// -- Class MyMin -------------------------------------------------------------- 
class MyMin {

    const            
/* char */        LF    "n",
                        
SPACE    ' ',
                        
EOS    "x00";

    protected        
/* boolean */    $cc_on;

    protected        
/* char */        $a,
                        
$ahead,
                        
$b;

    protected        
/* int */        $index    0,
                        
$length;
    
    protected        
/* string */    $input,
                        
$output "";

    
// -- Public Static Methods ----------------------------------------------------
    
static    public    final    function    /* string */    parse(/* string */ $input/* boolean */ $cc_on true){
        return    
"".(new MyMin($input$cc_on));
    }
    
    
// -- Public Instance Methods --------------------------------------------------
    
public    final    function        /* object */    __construct(/* string */ $input/* boolean */ $cc_on true){
        
$this->input preg_replace("/(rn|nr|r|n)+/"self::LFtrim($input));
        
$this->length strlen($this->input);
        
$this->cc_on $cc_on;
        
$this->$this->ahead self::SPACE;
        
$this->self::LF;
        
$this->action(3);
        while(
$this->!== self::EOS){
            switch(
$this->a){
                case    
self::SPACE:
                    
$this->action($this->isAlNum($this->b) ? 2);
                    break;
                case    
self::LF:
                    switch(
$this->b){
                        case    
'{':
                        case    
'[':
                        case    
'(':
                        case    
'+':
                        case    
'-':
                            
$this->action(1);
                            break;
                        case    
self::SPACE:
                            
$this->action(3);
                            break;
                        default:
                            
$this->action($this->isAlNum($this->b) ? 2);
                            break;
                    }
                    break;
                default:
                    switch(
$this->b){
                        case    
self::SPACE:
                            
$this->action($this->isAlNum($this->a) ? 3);
                            break;
                        case    
self::LF:
                            switch(
$this->a){
                                case    
'}':
                                case    
']':
                                case    
')':
                                case    
'+':
                                case    
'-':
                                case    
'"':
                                case    
''':
                                    $this->action(1);
                                    break;
                                default:
                                    $this->action($this->isAlNum($this->a) ? 1 : 3);
                                    break;
                            }
                            break;
                        default:
                            $this->action(1);
                            break;
                    }
                    break;
            }
        }
    }

    public    final    function        /* string */    __toString(/* void */){
        return    str_replace("nn", "n", ltrim($this->output));
    }
    
    // -- Protected Instance Methods -----------------------------------------------
    protected    function        /* void */        action(/* int */ $i){
        switch($i){
            case    1:
                $this->output .= $this->a;
            case    2:
                $this->a = $this->b;
                if($this->a === ''' 
|| $this->=== '"'){
                    while(
true){
                        
$this->output .= $this->a;
                        if(!
$this->nextCharNoSlash($this->b"Unterminated string literal."))
                            break;
                    }
                }
            case    
3:
                
$this->$this->next();
                if(
$this->=== '/'){
                    switch(
$this->a){
                        case    
self::LF:
                        case    
self::SPACE:
                            if(!
$this->spaceBeforeRegExp($this->output))
                                break;
                        
                        case    
'{':
                        case    
';':
                    
                        case    
'(':
                        case    
',':
                        case    
'=':
                        case    
':':
                        case    
'[':
                        case    
'!':
                        case    
'&':
                        case    
'|':
                        case    
'?':
                            
$this->output .= $this->a.$this->b;
                            while(
$this->nextCharNoSlash('/'"Unterminated regular expression literal."))
                                
$this->output .= $this->a;
                            
$this->$this->next();
                            break;
                    }
                }
                break;
        }
    }
    
    protected    function        
/* void */        appendComment(/* int */ $pos/* string */ $open/* string */ $close) {
        
$this->output .= $this->a.$open.(new MyMin(substr($this->input$this->index$pos $this->index), $this->cc_on)).$close;
        
$this->index $pos;
        
$this->self::LF;
    }

    protected    function        
/* void */        conditionalComment(/* char */ $find) {
        
$single $find === self::LF;
        
$pos strpos($this->input$find$this->index);
        if(
$pos === false){
            if(
$single)
                
$pos $this->length;
            else
                throw new 
MyMinException("Unterminated comment.");
        }
        
$this->appendComment($pos$single "//" "/*"$find);
    }
    
    protected    function        
/* char */        get(/* void */) {
        
$c $this->ahead;
        
$this->ahead self::EOS;
        if(
$c === self::EOS && $this->index $this->length)
            
$c $this->input{$this->index++};
        return    (
$c === self::EOS || $c === self::LF || $c >= self::SPACE) ? $c self::SPACE;
    }
    
    protected    function        
/* boolean */    isAlNum(/* char */ $c) {
        return    
$c 126 || $c === '\' || preg_match('/^(w|$)$/', $c);
    }

    protected    function        /* char */        next(/* void */) {
        $c = $this->get();
        $loop = true;
        if($c === '
/'){
            switch($this->ahead = $this->get()){
                case    '
/':
                    if($this->cc_on && $this->input{$this->index} === '
@')
                        $this->conditionalComment(self::LF);
                    while($loop){
                        $c = $this->get();
                        if($c <= self::LF)
                            $loop = false;
                    }
                    break;
                case '
*':
                    $this->get();
                    if($this->cc_on && $this->input{$this->index} === '
@')
                        $this->conditionalComment("*/");
                    while($loop){
                        switch($this->get()){
                            case    '
*':
                                if(($this->ahead = $this->get()) === '
/'){
                                    $this->get();
                                    $c = self::SPACE;
                                    $loop = false;
                                }
                                break;
                            case    self::EOS:
                                throw new MyMinException("Unterminated comment.");
                        }
                    }
                    break;
            }
        }
        return $c;
    }
    
    protected    function        /* boolean */    nextCharNoSlash(/* char */ $c, /* string */ $message) {
        $loop = true;
        $this->a = $this->get();
        if($this->a === $c)
            $loop = false;
        else{
            if($this->a === '
\'){
                $this->output .= $this->a;
                $this->a = $this->get();
            }
            if($this->a <= self::LF)
                throw new MyMinException($message);
        }
        return    $loop;
    }
    
    protected    function        /* boolean */    spaceBeforeRegExp(/* string */ $output){
        for(
            $i = 0,
            $length = strlen($output),
            $reserved = array("case", "else", "in", "return", "typeof"),
            $result = false,
            $tmp = "";
            $i < 5 && !$result;
            $i++
        ){
            if($length === strlen($reserved[$i]))
                $result = $reserved[$i] === $output;
            else if($length > strlen($reserved[$i])){
                $tmp = substr($output, $length - strlen($reserved[$i]) - 1);
                $result = substr($tmp, 1) === $reserved[$i] && !$this->isAlNum($tmp{0});
            }
        };
        return    $length < 2 ? true : $result;
    }
}

// -- MyMin Exceptions ---------------------------------------------------------
class MyMinException extends Exception {}
Онлайн: 2
Реклама