Plugin Directory

Changeset 943838


Ignore:
Timestamp:
07/06/2014 06:13:45 AM (12 years ago)
Author:
WebMaestro.Fr
Message:

v1.3 : wp_enqueue_style support and cache directory fix

Location:
less-compiler/trunk
Files:
1 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • less-compiler/trunk/css/less-compiler.css

    r912308 r943838  
    88    line-height: 1.4;
    99}
     10.toplevel_page_less .form-table th {
     11    display: none;
     12}
     13.toplevel_page_less .form-table td {
     14    padding-left: 0;
     15}
  • less-compiler/trunk/libs/less-parser/Cache.php

    r912308 r943838  
    2222     * @param array $less_files Array of .less files to compile
    2323     * @param array $parser_options Array of compiler options
    24      * @param boolean $use_cache Set to false to regenerate the css file
     24     * @param array $modify_vars Array of variables
    2525     * @return string Name of the css file
    2626     */
    27     public static function Get( $less_files, $parser_options = array(), $use_cache = true ){
     27    public static function Get( $less_files, $parser_options = array(), $modify_vars = array() ){
    2828
    2929
     
    3838
    3939        self::CheckCacheDir();
     40        $less_files = (array)$less_files;
     41
     42
     43        //create a file for variables
     44        if( !empty($modify_vars) ){
     45            $lessvars = Less_Parser::serializeVars($modify_vars);
     46            $vars_file = Less_Cache::$cache_dir.'lessphpvars_' . sha1($lessvars) . '.less';
     47
     48            if( !file_exists($vars_file) ){
     49                file_put_contents($vars_file, $lessvars);
     50            }
     51
     52            $less_files += array($vars_file => '/');
     53        }
     54
    4055
    4156        // generate name for compiled css file
    42         $less_files = (array)$less_files;
    4357        $hash = md5(json_encode($less_files));
    4458        $list_file = Less_Cache::$cache_dir.'lessphp_'.$hash.'.list';
    4559
    4660
    47         if( $use_cache === true ){
    48 
    49             // check cached content
    50             if( file_exists($list_file) ){
    51 
     61        // check cached content
     62        if( !isset($parser_options['use_cache']) || $parser_options['use_cache'] === true ){
     63            if( file_exists($list_file) ){
    5264
    5365                $list = explode("\n",file_get_contents($list_file));
     66
     67                //pop the cached name that should match $compiled_name
     68                $cached_name = array_pop($list);
     69                if( !preg_match('/^lessphp_[a-f0-9]+\.css$/',$cached_name) ){
     70                    $list[] = $cached_name;
     71                    $cached_name = false;
     72                }
    5473                $compiled_name = self::CompiledName($list);
    55                 $compiled_file = Less_Cache::$cache_dir.$compiled_name;
    56                 if( file_exists($compiled_file) ){
    57                     @touch($list_file);
    58                     @touch($compiled_file);
    59                     return $compiled_name;
    60                 }
    61             }
    62 
     74
     75                // if $cached_name != $compiled_name, we know we need to recompile
     76                if( !$cached_name || $cached_name === $compiled_name ){
     77
     78                    $output_file = self::OutputFile($compiled_name, $parser_options );
     79
     80                    if( $output_file && file_exists($output_file) ){
     81                        @touch($list_file);
     82                        @touch($output_file);
     83                        return basename($output_file); // for backwards compatibility, we just return the name of the file
     84                    }
     85                }
     86            }
    6387        }
    6488
     
    6892        }
    6993
     94        $compiled_name = self::CompiledName( $less_files );
     95        $output_file = self::OutputFile($compiled_name, $parser_options );
     96
    7097
    7198        //save the file list
    72         $cache = implode("\n",$less_files);
     99        $list = $less_files;
     100        $list[] = $compiled_name;
     101        $cache = implode("\n",$list);
    73102        file_put_contents( $list_file, $cache );
    74103
    75104
    76105        //save the css
    77         $compiled_name = self::CompiledName( $less_files );
    78         file_put_contents( Less_Cache::$cache_dir.$compiled_name, $compiled );
     106        file_put_contents( $output_file, $compiled );
    79107
    80108
     
    82110        self::CleanCache();
    83111
    84         return $compiled_name;
     112        return basename($output_file);
    85113    }
    86114
     
    90118     * @param array $less_files Array of .less files to compile
    91119     * @param array $parser_options Array of compiler options
     120     * @param array $modify_vars Array of variables
    92121     * @return string Name of the css file
    93122     */
    94     public static function Regen( $less_files, $parser_options = array() ){
    95         return self::Get( $less_files, $parser_options, false );
     123    public static function Regen( $less_files, $parser_options = array(), $modify_vars = array() ){
     124        $parser_options['use_cache'] = false;
     125        return self::Get( $less_files, $parser_options, $modify_vars );
    96126    }
    97127
     
    127157
    128158        return $compiled;
     159    }
     160
     161
     162    private static function OutputFile( $compiled_name, $parser_options ){
     163
     164        //custom output file
     165        if( !empty($parser_options['output']) ){
     166
     167            //relative to cache directory?
     168            if( preg_match('#[\\\\/]#',$parser_options['output']) ){
     169                return $parser_options['output'];
     170            }
     171
     172            return Less_Cache::$cache_dir.$parser_options['output'];
     173        }
     174
     175        return Less_Cache::$cache_dir.$compiled_name;
    129176    }
    130177
  • less-compiler/trunk/libs/less-parser/Less.php

    r912308 r943838  
    2727        'import_callback'       => null,
    2828        'cache_dir'             => null,
    29         'cache_method'          => 'php',           //false, 'serialize', 'php', 'var_export';
     29        'cache_method'          => 'php',           // false, 'serialize', 'php', 'var_export', 'callback';
     30        'cache_callback_get'    => null,
     31        'cache_callback_set'    => null,
    3032
    3133        'sourceMap'             => false,           // whether to output a source map
     
    140142    }
    141143
    142 
     144    /**
     145     * Registers a new custom function
     146     *
     147     * @param  string   $name     function name
     148     * @param  callable $callback callback
     149     */
     150    public function registerFunction($name, $callback) {
     151        $this->env->functions[$name] = $callback;
     152    }
     153
     154    /**
     155     * Removed an already registered function
     156     *
     157     * @param  string $name function name
     158     */
     159    public function unregisterFunction($name) {
     160        if( isset($this->env->functions[$name]) )
     161            unset($this->env->functions[$name]);
     162    }
    143163
    144164
     
    328348    public function ModifyVars( $vars ){
    329349
    330         $this->input = $this->serializeVars( $vars );
     350        $this->input = Less_Parser::serializeVars( $vars );
    331351        $this->_parse();
    332352
     
    447467
    448468        $cache_file = $this->CacheFile( $file_path );
    449         if( $cache_file && file_exists($cache_file) ){
    450             switch(Less_Parser::$options['cache_method']){
    451 
    452                 // Using serialize
    453                 // Faster but uses more memory
    454                 case 'serialize':
    455                     $cache = unserialize(file_get_contents($cache_file));
     469        if( $cache_file ){
     470            if( Less_Parser::$options['cache_method'] == 'callback' ){
     471                if( is_callable(Less_Parser::$options['cache_callback_get']) ){
     472                    $cache = call_user_func_array(
     473                        Less_Parser::$options['cache_callback_get'],
     474                        array($this, $file_path, $cache_file)
     475                    );
     476
    456477                    if( $cache ){
    457                         touch($cache_file);
    458478                        $this->UnsetInput();
    459479                        return $cache;
    460480                    }
    461                 break;
    462 
    463 
    464                 // Using generated php code
    465                 case 'var_export':
    466                 case 'php':
    467                 $this->UnsetInput();
    468                 return include($cache_file);
     481                }
     482
     483            }elseif( file_exists($cache_file) ){
     484                switch(Less_Parser::$options['cache_method']){
     485
     486                    // Using serialize
     487                    // Faster but uses more memory
     488                    case 'serialize':
     489                        $cache = unserialize(file_get_contents($cache_file));
     490                        if( $cache ){
     491                            touch($cache_file);
     492                            $this->UnsetInput();
     493                            return $cache;
     494                        }
     495                    break;
     496
     497
     498                    // Using generated php code
     499                    case 'var_export':
     500                    case 'php':
     501                    $this->UnsetInput();
     502                    return include($cache_file);
     503                }
    469504            }
    470505        }
     
    481516        //save the cache
    482517        if( $cache_file ){
    483 
    484             //msg('write cache file');
    485             switch(Less_Parser::$options['cache_method']){
    486                 case 'serialize':
    487                     file_put_contents( $cache_file, serialize($rules) );
    488                 break;
    489                 case 'php':
    490                     file_put_contents( $cache_file, '<?php return '.self::ArgString($rules).'; ?>' );
    491                 break;
    492                 case 'var_export':
    493                     //Requires __set_state()
    494                     file_put_contents( $cache_file, '<?php return '.var_export($rules,true).'; ?>' );
    495                 break;
    496             }
    497 
    498             Less_Cache::CleanCache();
     518            if( Less_Parser::$options['cache_method'] == 'callback' ){
     519                if( is_callable(Less_Parser::$options['cache_callback_set']) ){
     520                    call_user_func_array(
     521                        Less_Parser::$options['cache_callback_set'],
     522                        array($this, $file_path, $cache_file, $rules)
     523                    );
     524                }
     525
     526            }else{
     527                //msg('write cache file');
     528                switch(Less_Parser::$options['cache_method']){
     529                    case 'serialize':
     530                        file_put_contents( $cache_file, serialize($rules) );
     531                    break;
     532                    case 'php':
     533                        file_put_contents( $cache_file, '<?php return '.self::ArgString($rules).'; ?>' );
     534                    break;
     535                    case 'var_export':
     536                        //Requires __set_state()
     537                        file_put_contents( $cache_file, '<?php return '.var_export($rules,true).'; ?>' );
     538                    break;
     539                }
     540
     541                Less_Cache::CleanCache();
     542            }
    499543        }
    500544
     
    540584    public function CacheFile( $file_path ){
    541585
    542         if( $file_path && Less_Parser::$options['cache_method'] && Less_Cache::$cache_dir ){
     586        if( $file_path && $this->CacheEnabled() ){
    543587
    544588            $env = get_object_vars($this->env);
     
    637681    private function MatchFuncs($toks){
    638682
    639         foreach($toks as $tok){
    640             $match = $this->$tok();
    641             if( $match ){
    642                 return $match;
     683        if( $this->pos < $this->input_len ){
     684            foreach($toks as $tok){
     685                $match = $this->$tok();
     686                if( $match ){
     687                    return $match;
     688                }
    643689            }
    644690        }
     
    865911            $this->MatchChar('~');
    866912        }
    867         $str = $this->MatchReg('/\\G"((?:[^"\\\\\r\n]|\\\\.)*)"|\'((?:[^\'\\\\\r\n]|\\\\.)*)\'/');
     913
     914                // Fix for #124: match escaped newlines
     915                //$str = $this->MatchReg('/\\G"((?:[^"\\\\\r\n]|\\\\.)*)"|\'((?:[^\'\\\\\r\n]|\\\\.)*)\'/');
     916        $str = $this->MatchReg('/\\G"((?:[^"\\\\\r\n]|\\\\.|\\\\\r\n|\\\\[\n\r\f])*)"|\'((?:[^\'\\\\\r\n]|\\\\.|\\\\\r\n|\\\\[\n\r\f])*)\'/');
     917
    868918        if( $str ){
    869919            $result = $str[0][0] == '"' ? $str[1] : $str[2];
     
    15631613    //
    15641614    private function parseCombinator(){
    1565         $c = $this->input[$this->pos];
    1566         if ($c === '>' || $c === '+' || $c === '~' || $c === '|' || $c === '^' ){
    1567 
    1568             $this->pos++;
    1569             if( $this->input[$this->pos] === '^' ){
    1570                 $c = '^^';
     1615        if( $this->pos < $this->input_len ){
     1616            $c = $this->input[$this->pos];
     1617            if ($c === '>' || $c === '+' || $c === '~' || $c === '|' || $c === '^' ){
     1618
    15711619                $this->pos++;
    1572             }
    1573 
    1574             $this->skipWhitespace(0);
    1575 
    1576             return $c;
    1577         }
    1578 
    1579         if( $this->pos > 0 && $this->isWhitespace(-1) ){
    1580             return ' ';
     1620                if( $this->input[$this->pos] === '^' ){
     1621                    $c = '^^';
     1622                    $this->pos++;
     1623                }
     1624
     1625                $this->skipWhitespace(0);
     1626
     1627                return $c;
     1628            }
     1629
     1630            if( $this->pos > 0 && $this->isWhitespace(-1) ){
     1631                return ' ';
     1632            }
    15811633        }
    15821634    }
     
    16191671                    //error("Extend can only be used at the end of selector");
    16201672                //}
    1621                 $c = $this->input[ $this->pos ];
     1673                if( $this->pos < $this->input_len ){
     1674                    $c = $this->input[ $this->pos ];
     1675                }
    16221676                $elements[] = $e;
    16231677                $e = null;
     
    23792433    }
    23802434
    2381     public function serializeVars( $vars ){
     2435    public static function serializeVars( $vars ){
    23822436        $s = '';
    23832437
     
    24272481    public function NewObj0($class){
    24282482        $obj = new $class();
    2429         if( Less_Cache::$cache_dir ){
     2483        if( $this->CacheEnabled() ){
    24302484            $obj->cache_string = ' new '.$class.'()';
    24312485        }
     
    24352489    public function NewObj1($class, $arg){
    24362490        $obj = new $class( $arg );
    2437         if( Less_Cache::$cache_dir ){
     2491        if( $this->CacheEnabled() ){
    24382492            $obj->cache_string = ' new '.$class.'('.Less_Parser::ArgString($arg).')';
    24392493        }
     
    24432497    public function NewObj2($class, $args){
    24442498        $obj = new $class( $args[0], $args[1] );
    2445         if( Less_Cache::$cache_dir ){
     2499        if( $this->CacheEnabled() ){
    24462500            $this->ObjCache( $obj, $class, $args);
    24472501        }
     
    24512505    public function NewObj3($class, $args){
    24522506        $obj = new $class( $args[0], $args[1], $args[2] );
    2453         if( Less_Cache::$cache_dir ){
     2507        if( $this->CacheEnabled() ){
    24542508            $this->ObjCache( $obj, $class, $args);
    24552509        }
     
    24592513    public function NewObj4($class, $args){
    24602514        $obj = new $class( $args[0], $args[1], $args[2], $args[3] );
    2461         if( Less_Cache::$cache_dir ){
     2515        if( $this->CacheEnabled() ){
    24622516            $this->ObjCache( $obj, $class, $args);
    24632517        }
     
    24672521    public function NewObj5($class, $args){
    24682522        $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4] );
    2469         if( Less_Cache::$cache_dir ){
     2523        if( $this->CacheEnabled() ){
    24702524            $this->ObjCache( $obj, $class, $args);
    24712525        }
     
    24752529    public function NewObj6($class, $args){
    24762530        $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4], $args[5] );
    2477         if( Less_Cache::$cache_dir ){
     2531        if( $this->CacheEnabled() ){
    24782532            $this->ObjCache( $obj, $class, $args);
    24792533        }
     
    24832537    public function NewObj7($class, $args){
    24842538        $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6] );
    2485         if( Less_Cache::$cache_dir ){
     2539        if( $this->CacheEnabled() ){
    24862540            $this->ObjCache( $obj, $class, $args);
    24872541        }
     
    25302584    public static function WinPath($path){
    25312585        return str_replace('\\', '/', $path);
     2586    }
     2587
     2588    public function CacheEnabled(){
     2589        return (Less_Parser::$options['cache_method'] && (Less_Cache::$cache_dir || (Less_Parser::$options['cache_method'] == 'callback')));
    25322590    }
    25332591
     
    27542812    public static $mixin_stack = 0;
    27552813
     2814    /**
     2815     * @var array
     2816     */
     2817    public $functions = array();
     2818
    27562819
    27572820    public function Init(){
     
    28212884     *
    28222885     */
    2823     static function normalizePath($path){
     2886    public static function normalizePath($path){
    28242887
    28252888        $segments = explode('/',$path);
     
    28892952     * @param string $op
    28902953     */
    2891     static public function operate( $op, $a, $b ){
     2954    public static function operate( $op, $a, $b ){
    28922955        switch ($op) {
    28932956            case '+': return $a + $b;
     
    28982961    }
    28992962
    2900     static public function clamp($val, $max = 1){
     2963    public static function clamp($val, $max = 1){
    29012964        return min( max($val, 0), $max);
    29022965    }
    29032966
    2904     static function fround( $value ){
     2967    public static function fround( $value ){
    29052968
    29062969        if( $value === 0 ){
     
    29152978    }
    29162979
    2917     static public function number($n){
     2980    public static function number($n){
    29182981
    29192982        if ($n instanceof Less_Tree_Dimension) {
     
    29262989    }
    29272990
    2928     static public function scaled($n, $size = 255 ){
     2991    public static function scaled($n, $size = 255 ){
    29292992        if( $n instanceof Less_Tree_Dimension && $n->unit->is('%') ){
    29302993            return (float)$n->value * $size / 100;
     
    29703033     * @param double $h
    29713034     */
    2972     function hsla_hue($h, $m1, $m2){
     3035    public function hsla_hue($h, $m1, $m2){
    29733036        $h = $h < 0 ? $h + 1 : ($h > 1 ? $h - 1 : $h);
    29743037        if    ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6;
     
    33883451     * @param boolean $isMin
    33893452     */
    3390     function _minmax( $isMin, $args ){
     3453    private function _minmax( $isMin, $args ){
    33913454
    33923455        $arg_count = count($args);
     
    35833646    }
    35843647
    3585     function length($values){
     3648    public function length($values){
    35863649        $n = (property_exists($values,'value') && is_array($values->value)) ? count($values->value) : 1;
    35873650        return new Less_Tree_Dimension($n);
    35883651    }
    35893652
    3590     function datauri($mimetypeNode, $filePathNode = null ) {
     3653    public function datauri($mimetypeNode, $filePathNode = null ) {
    35913654
    35923655        $filePath = ( $filePathNode ? $filePathNode->value : null );
     
    36643727
    36653728    //svg-gradient
    3666     function svggradient( $direction ){
     3729    public function svggradient( $direction ){
    36673730
    36683731        $throw_message = 'svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]';
     
    38633926
    38643927    // non-w3c functions:
    3865     function colorBlendAverage($cb, $cs ){
     3928    public function colorBlendAverage($cb, $cs ){
    38663929        return ($cb + $cs) / 2;
    38673930    }
     
    38713934    }
    38723935
    3873     function colorBlendNegation($cb, $cs){
     3936    public function colorBlendNegation($cb, $cs){
    38743937        return 1 - abs($cb + $cs - 1);
    38753938    }
     
    38963959            '.jpg' => 'image/jpeg',
    38973960            '.jpeg'=> 'image/jpeg',
    3898             '.png' => 'image/png'
     3961            '.png' => 'image/png',
     3962            '.ttf' => 'application/x-font-ttf',
     3963            '.otf' => 'application/x-font-otf',
     3964            '.eot' => 'application/vnd.ms-fontobject',
     3965            '.woff' => 'application/x-font-woff',
     3966            '.svg' => 'image/svg+xml',
    38993967            );
    39003968
    3901     static function lookup( $filepath ){
     3969    public static function lookup( $filepath ){
    39023970        $parts = explode('.',$filepath);
    39033971        $ext = '.'.strtolower(array_pop($parts));
     
    39093977    }
    39103978
    3911     static function charsets_lookup( $type = null ){
     3979    public static function charsets_lookup( $type = null ){
    39123980        // assumes all text types are UTF-8
    39133981        return $type && preg_match('/^text\//',$type) ? 'UTF-8' : '';
    39143982    }
    3915 }
     3983}
     3984 
    39163985
    39173986/**
     
    40604129class Less_Visitor{
    40614130
    4062     var $methods = array();
    4063     var $_visitFnCache = array();
    4064 
    4065     function __construct(){
     4131    protected $methods = array();
     4132    protected $_visitFnCache = array();
     4133
     4134    public function __construct(){
    40664135        $this->_visitFnCache = get_class_methods(get_class($this));
    40674136        $this->_visitFnCache = array_flip($this->_visitFnCache);
    40684137    }
    40694138
    4070     function visitObj( $node ){
     4139    public function visitObj( $node ){
    40714140
    40724141        $funcName = 'visit'.$node->type;
     
    40924161    }
    40934162
    4094     function visitArray( $nodes ){
     4163    public function visitArray( $nodes ){
    40954164
    40964165        array_map( array($this,'visitObj'), $nodes);
     
    41094178class Less_VisitorReplacing extends Less_Visitor{
    41104179
    4111     function visitObj( $node ){
     4180    public function visitObj( $node ){
    41124181
    41134182        $funcName = 'visit'.$node->type;
     
    41354204    }
    41364205
    4137     function visitArray( $nodes ){
     4206    public function visitArray( $nodes ){
    41384207
    41394208        $newNodes = array();
     
    41514220    }
    41524221
    4153     function flatten( $arr, &$out ){
     4222    public function flatten( $arr, &$out ){
    41544223
    41554224        foreach($arr as $item){
     
    43234392    }
    43244393
    4325     function compare($x){
     4394    public function compare($x){
    43264395        if( !is_object($x) ){
    43274396            return -1;
     
    43644433    public $type = 'Assignment';
    43654434
    4366     function __construct($key, $val) {
     4435    public function __construct($key, $val) {
    43674436        $this->key = $key;
    43684437        $this->value = $val;
    43694438    }
    43704439
    4371     function accept( $visitor ){
     4440    public function accept( $visitor ){
    43724441        $this->value = $visitor->visitObj( $this->value );
    43734442    }
     
    44044473    public $type = 'Attribute';
    44054474
    4406     function __construct($key, $op, $value){
     4475    public function __construct($key, $op, $value){
    44074476        $this->key = $key;
    44084477        $this->op = $op;
     
    44104479    }
    44114480
    4412     function compile($env){
     4481    public function compile($env){
    44134482
    44144483        $key_obj = is_object($this->key);
     
    44284497     * @see Less_Tree::genCSS
    44294498     */
    4430     function genCSS( $output ){
     4499    public function genCSS( $output ){
    44314500        $output->add( $this->toCSS() );
    44324501    }
    44334502
    4434     function toCSS(){
     4503    public function toCSS(){
    44354504        $value = $this->key;
    44364505
     
    44544523    public $value;
    44554524
    4456     var $name;
    4457     var $args;
    4458     var $index;
    4459     var $currentFileInfo;
     4525    protected $name;
     4526    protected $args;
     4527    protected $index;
     4528    protected $currentFileInfo;
    44604529    public $type = 'Call';
    44614530
     
    44674536    }
    44684537
    4469     function accept( $visitor ){
     4538    public function accept( $visitor ){
    44704539        $this->args = $visitor->visitArray( $this->args );
    44714540    }
     
    45234592                    throw new Less_Exception_Compiler('error evaluating function `' . $this->name . '` '.$e->getMessage().' index: '. $this->index);
    45244593                }
     4594            } elseif( isset( $env->functions[$nameLC] ) && is_callable( $env->functions[$nameLC] ) ) {
     4595                try {
     4596                    $result = call_user_func_array( $env->functions[$nameLC], $args );
     4597                } catch (Exception $e) {
     4598                    throw new Less_Exception_Compiler('error evaluating function `' . $this->name . '` '.$e->getMessage().' index: '. $this->index);
     4599                }
    45254600            }
    45264601        }
     
    47074782
    47084783    //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
    4709     function toHSV() {
     4784    public function toHSV() {
    47104785        $r = $this->rgb[0] / 255;
    47114786        $g = $this->rgb[1] / 255;
     
    47554830    }
    47564831
    4757     function toHex( $v ){
     4832    public function toHex( $v ){
    47584833
    47594834        $ret = '#';
     
    49234998    static $value_;
    49244999
    4925     static function compile(){
     5000    public static function compile(){
    49265001        if( self::$error_ ){
    4927             throw Exception(self::$error_);
     5002            throw new Exception(self::$error_);
    49285003        }
    49295004        if( self::$value_ !== null ){
     
    49325007    }
    49335008
    4934     static function value( $v ){
     5009    public static function value( $v ){
    49355010        self::$value_ = $v;
    49365011    }
    49375012
    4938     static function error( $e ){
     5013    public static function error( $e ){
    49395014        self::$error_ = $e;
    49405015    }
    49415016
    4942     static function reset(){
     5017    public static function reset(){
    49435018        self::$value_ = self::$error_ = null;
    49445019    }
     
    49575032    public $type = 'DetachedRuleset';
    49585033
    4959     function __construct( $ruleset, $frames = null ){
     5034    public function __construct( $ruleset, $frames = null ){
    49605035        $this->ruleset = $ruleset;
    49615036        $this->frames = $frames;
    49625037    }
    49635038
    4964     function accept($visitor) {
     5039    public function accept($visitor) {
    49655040        $this->ruleset = $visitor->visitObj($this->ruleset);
    49665041    }
    49675042
    4968     function compile($env){
     5043    public function compile($env){
    49695044        if( $this->frames ){
    49705045            $frames = $this->frames;
     
    49755050    }
    49765051
    4977     function callEval($env) {
     5052    public function callEval($env) {
    49785053        if( $this->frames ){
    49795054            return $this->ruleset->compile( $env->copyEvalEnv( array_merge($this->frames,$env->frames) ) );
     
    50095084    }
    50105085
    5011     function accept( $visitor ){
     5086    public function accept( $visitor ){
    50125087        $this->unit = $visitor->visitObj( $this->unit );
    50135088    }
     
    51325207    }
    51335208
    5134     function unify() {
     5209    public function unify() {
    51355210        return $this->convertTo(array('length'=> 'px', 'duration'=> 's', 'angle' => 'rad' ));
    51365211    }
    51375212
    5138     function convertTo($conversions) {
     5213    public function convertTo($conversions) {
    51395214        $value = $this->value;
    51405215        $unit = clone $this->unit;
     
    52175292
    52185293
    5219     function accept( $visitor ){
     5294    public function accept( $visitor ){
    52205295        if( $this->rules ){
    52215296            $this->rules = $visitor->visitObj( $this->rules );
     
    52305305     * @see Less_Tree::genCSS
    52315306     */
    5232     function genCSS( $output ){
     5307    public function genCSS( $output ){
    52335308        $value = $this->value;
    52345309        $rules = $this->rules;
     
    53155390    }
    53165391
    5317     function accept( $visitor ){
     5392    public function accept( $visitor ){
    53185393        if( $this->value_is_object ){ //object or string
    53195394            $this->value = $visitor->visitObj( $this->value );
     
    53795454    }
    53805455
    5381     function accept( $visitor ){
     5456    public function accept( $visitor ){
    53825457        $this->value = $visitor->visitArray( $this->value );
    53835458    }
     
    54325507     * @see Less_Tree::genCSS
    54335508     */
    5434     function genCSS( $output ){
     5509    public function genCSS( $output ){
    54355510        $val_len = count($this->value);
    54365511        for( $i = 0; $i < $val_len; $i++ ){
     
    54425517    }
    54435518
    5444     function throwAwayComments() {
     5519    public function throwAwayComments() {
    54455520
    54465521        if( is_array($this->value) ){
     
    54835558     * @param integer $index
    54845559     */
    5485     function __construct($selector, $option, $index){
     5560    public function __construct($selector, $option, $index){
    54865561        static $i = 0;
    54875562        $this->selector = $selector;
     
    55045579    }
    55055580
    5506     function accept( $visitor ){
     5581    public function accept( $visitor ){
    55075582        $this->selector = $visitor->visitObj( $this->selector );
    55085583    }
    55095584
    5510     function compile( $env ){
     5585    public function compile( $env ){
    55115586        Less_Parser::$has_extends = true;
    55125587        $this->selector = $this->selector->compile($env);
     
    55155590    }
    55165591
    5517     function findSelfSelectors( $selectors ){
     5592    public function findSelfSelectors( $selectors ){
    55185593        $selfElements = array();
    55195594
     
    55615636    public $type = 'Import';
    55625637
    5563     function __construct($path, $features, $options, $index, $currentFileInfo = null ){
     5638    public function __construct($path, $features, $options, $index, $currentFileInfo = null ){
    55645639        $this->options = $options;
    55655640        $this->index = $index;
     
    55925667//
    55935668
    5594     function accept($visitor){
     5669    public function accept($visitor){
    55955670
    55965671        if( $this->features ){
     
    56075682     * @see Less_Tree::genCSS
    56085683     */
    5609     function genCSS( $output ){
     5684    public function genCSS( $output ){
    56105685        if( $this->css ){
    56115686
     
    56215696    }
    56225697
    5623     function toCSS(){
     5698    public function toCSS(){
    56245699        $features = $this->features ? ' ' . $this->features->toCSS() : '';
    56255700
     
    56345709     * @return string
    56355710     */
    5636     function getPath(){
     5711    public function getPath(){
    56375712        if ($this->path instanceof Less_Tree_Quoted) {
    56385713            $path = $this->path->value;
    5639             return ( isset($this->css) || preg_match('/(\.[a-z]*$)|([\?;].*)$/',$path)) ? $path : $path . '.less';
     5714            $path = ( isset($this->css) || preg_match('/(\.[a-z]*$)|([\?;].*)$/',$path)) ? $path : $path . '.less';
    56405715        } else if ($this->path instanceof Less_Tree_URL) {
    5641             return $this->path->value->value;
    5642         }
    5643         return null;
    5644     }
    5645 
    5646     function compileForImport( $env ){
     5716            $path = $this->path->value->value;
     5717        }else{
     5718            return null;
     5719        }
     5720
     5721        //remove query string and fragment
     5722        return preg_replace('/[\?#][^\?]*$/','',$path);
     5723    }
     5724
     5725    public function compileForImport( $env ){
    56475726        return new Less_Tree_Import( $this->path->compile($env), $this->features, $this->options, $this->index, $this->currentFileInfo);
    56485727    }
    56495728
    5650     function compilePath($env) {
     5729    public function compilePath($env) {
    56515730        $path = $this->path->compile($env);
    56525731        $rootpath = '';
     
    56725751    }
    56735752
    5674     function compile( $env ){
     5753    public function compile( $env ){
    56755754
    56765755        $evald = $this->compileForImport($env);
     
    57295808     * @param Less_Tree_Import $evald
    57305809     */
    5731     function PathAndUri(){
     5810    public function PathAndUri(){
    57325811
    57335812        $evald_path = $this->getPath();
     
    57805859     * @return Less_Tree_Media|array
    57815860     */
    5782     function ParseImport( $full_path, $uri, $env ){
     5861    public function ParseImport( $full_path, $uri, $env ){
    57835862
    57845863        $import_env = clone $env;
     
    59276006    }
    59286007
    5929     function accept( $visitor ){
     6008    public function accept( $visitor ){
    59306009        $this->features = $visitor->visitObj($this->features);
    59316010        $this->rules = $visitor->visitArray($this->rules);
     
    59356014     * @see Less_Tree::genCSS
    59366015     */
    5937     function genCSS( $output ){
     6016    public function genCSS( $output ){
    59386017
    59396018        $output->add( '@media ', $this->currentFileInfo, $this->index );
     
    60686147    }
    60696148
    6070     function bubbleSelectors($selectors) {
     6149    public function bubbleSelectors($selectors) {
    60716150
    60726151        if( !$selectors) return;
     
    61036182    }
    61046183
    6105     function genCSS( $output ){
     6184    public function genCSS( $output ){
    61066185
    61076186        $output->add(
     
    61306209    public $type = 'Negative';
    61316210
    6132     function __construct($node){
     6211    public function __construct($node){
    61336212        $this->value = $node;
    61346213    }
     
    61416220     * @see Less_Tree::genCSS
    61426221     */
    6143     function genCSS( $output ){
     6222    public function genCSS( $output ){
    61446223        $output->add( '-' );
    61456224        $this->value->genCSS( $output );
    61466225    }
    61476226
    6148     function compile($env) {
     6227    public function compile($env) {
    61496228        if( Less_Environment::isMathOn() ){
    61506229            $ret = new Less_Tree_Operation('*', array( new Less_Tree_Dimension(-1), $this->value ) );
     
    61776256    }
    61786257
    6179     function accept($visitor) {
     6258    public function accept($visitor) {
    61806259        $this->operands = $visitor->visitArray($this->operands);
    61816260    }
     
    62106289     * @see Less_Tree::genCSS
    62116290     */
    6212     function genCSS( $output ){
     6291    public function genCSS( $output ){
    62136292        $this->operands[0]->genCSS( $output );
    62146293        if( $this->isSpaced ){
     
    62406319    }
    62416320
    6242     function accept($visitor){
     6321    public function accept($visitor){
    62436322        $this->value = $visitor->visitObj($this->value);
    62446323    }
     
    62476326     * @see Less_Tree::genCSS
    62486327     */
    6249     function genCSS( $output ){
     6328    public function genCSS( $output ){
    62506329        $output->add( '(' );
    62516330        $this->value->genCSS( $output );
     
    63236402    }
    63246403
    6325     function compare($x) {
     6404    public function compare($x) {
    63266405
    63276406        if( !Less_Parser::is_method($x, 'toCSS') ){
     
    63736452    }
    63746453
    6375     function accept($visitor) {
     6454    public function accept($visitor) {
    63766455        $this->value = $visitor->visitObj( $this->value );
    63776456    }
     
    63806459     * @see Less_Tree::genCSS
    63816460     */
    6382     function genCSS( $output ){
     6461    public function genCSS( $output ){
    63836462
    63846463        $output->add( $this->name . Less_Environment::$_outputMap[': '], $this->currentFileInfo, $this->index);
     
    64416520
    64426521
    6443     function CompileName( $env, $name ){
     6522    public function CompileName( $env, $name ){
    64446523        $output = new Less_Output();
    64456524        foreach($name as $n){
     
    64496528    }
    64506529
    6451     function makeImportant(){
     6530    public function makeImportant(){
    64526531        return new Less_Tree_Rule($this->name, $this->value, '!important', $this->merge, $this->index, $this->currentFileInfo, $this->inline);
    64536532    }
     
    64806559    public $allExtends;
    64816560
    6482     var $ruleset_id;
    6483     var $originalRuleset;
    6484 
    6485     var $first_oelements;
     6561    public $ruleset_id;
     6562    public $originalRuleset;
     6563
     6564    public $first_oelements;
    64866565
    64876566    public function SetRulesetIndex(){
     
    65066585    }
    65076586
    6508     function accept( $visitor ){
     6587    public function accept( $visitor ){
    65096588        if( $this->paths ){
    65106589            $paths_len = count($this->paths);
     
    71107189    public $type = "RulesetCall";
    71117190
    7112     function __construct($variable){
     7191    public function __construct($variable){
    71137192        $this->variable = $variable;
    71147193    }
    71157194
    7116     function accept($visitor) {}
    7117 
    7118     function compile( $env ){
     7195    public function accept($visitor) {}
     7196
     7197    public function compile( $env ){
    71197198        $variable = new Less_Tree_Variable($this->variable);
    71207199        $detachedRuleset = $variable->compile($env);
     
    71707249    }
    71717250
    7172     function accept($visitor) {
     7251    public function accept($visitor) {
    71737252        $this->elements = $visitor->visitArray($this->elements);
    71747253        $this->extendList = $visitor->visitArray($this->extendList);
     
    71827261    }
    71837262
    7184     function createDerived( $elements, $extendList = null, $evaldCondition = null ){
     7263    public function createDerived( $elements, $extendList = null, $evaldCondition = null ){
    71857264        $newSelector = new Less_Tree_Selector( $elements, ($extendList ? $extendList : $this->extendList), null, $this->index, $this->currentFileInfo, $this->isReferenced);
    71867265        $newSelector->evaldCondition = $evaldCondition ? $evaldCondition : $this->evaldCondition;
     
    72677346     * @see Less_Tree::genCSS
    72687347     */
    7269     function genCSS( $output, $firstSelector = true ){
     7348    public function genCSS( $output, $firstSelector = true ){
    72707349
    72717350        if( !$firstSelector && $this->elements[0]->combinator === "" ){
     
    72787357    }
    72797358
    7280     function markReferenced(){
     7359    public function markReferenced(){
    72817360        $this->isReferenced = true;
    72827361    }
    72837362
    7284     function getIsReferenced(){
     7363    public function getIsReferenced(){
    72857364        return !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] || $this->isReferenced;
    72867365    }
    72877366
    7288     function getIsOutput(){
     7367    public function getIsOutput(){
    72897368        return $this->evaldCondition;
    72907369    }
     
    73357414    public $type = 'Unit';
    73367415
    7337     function __construct($numerator = array(), $denominator = array(), $backupUnit = null ){
     7416    public function __construct($numerator = array(), $denominator = array(), $backupUnit = null ){
    73387417        $this->numerator = $numerator;
    73397418        $this->denominator = $denominator;
     
    73417420    }
    73427421
    7343     function __clone(){
     7422    public function __clone(){
    73447423    }
    73457424
     
    73477426     * @see Less_Tree::genCSS
    73487427     */
    7349     function genCSS( $output ){
     7428    public function genCSS( $output ){
    73507429
    73517430        if( $this->numerator ){
     
    73597438    }
    73607439
    7361     function toString(){
     7440    public function toString(){
    73627441        $returnStr = implode('*',$this->numerator);
    73637442        foreach($this->denominator as $d){
     
    73677446    }
    73687447
    7369     function __toString(){
     7448    public function __toString(){
    73707449        return $this->toString();
    73717450    }
     
    73757454     * @param Less_Tree_Unit $other
    73767455     */
    7377     function compare($other) {
     7456    public function compare($other) {
    73787457        return $this->is( $other->toString() ) ? 0 : -1;
    73797458    }
    73807459
    7381     function is($unitString){
     7460    public function is($unitString){
    73827461        return $this->toString() === $unitString;
    73837462    }
    73847463
    7385     function isLength(){
     7464    public function isLength(){
    73867465        $css = $this->toCSS();
    73877466        return !!preg_match('/px|em|%|in|cm|mm|pc|pt|ex/',$css);
    73887467    }
    73897468
    7390     function isAngle() {
     7469    public function isAngle() {
    73917470        return isset( Less_Tree_UnitConversions::$angle[$this->toCSS()] );
    73927471    }
    73937472
    7394     function isEmpty(){
     7473    public function isEmpty(){
    73957474        return !$this->numerator && !$this->denominator;
    73967475    }
    73977476
    7398     function isSingular() {
     7477    public function isSingular() {
    73997478        return count($this->numerator) <= 1 && !$this->denominator;
    74007479    }
    74017480
    74027481
    7403     function usedUnits(){
     7482    public function usedUnits(){
    74047483        $result = array();
    74057484
     
    74237502    }
    74247503
    7425     function cancel(){
     7504    public function cancel(){
    74267505        $counter = array();
    74277506        $backup = null;
     
    75237602    }
    75247603
    7525     function accept( $visitor ){
     7604    public function accept( $visitor ){
    75267605        $this->value = $visitor->visitObj($this->value);
    75277606    }
     
    75307609     * @see Less_Tree::genCSS
    75317610     */
    7532     function genCSS( $output ){
     7611    public function genCSS( $output ){
    75337612        $output->add( 'url(' );
    75347613        $this->value->genCSS( $output );
     
    75947673    }
    75957674
    7596     function accept($visitor) {
     7675    public function accept($visitor) {
    75977676        $this->value = $visitor->visitArray($this->value);
    75987677    }
     
    76537732
    76547733        if( $this->name[1] === '@' ){
    7655             $v = new Less_Tree_Variable(substr($this->name, 1), $this->index + 1);
     7734            $v = new Less_Tree_Variable(substr($this->name, 1), $this->index + 1, $this->currentFileInfo);
    76567735            $name = '@' . $v->compile($env)->value;
    76577736        }else{
     
    76677746        foreach($env->frames as $frame){
    76687747            if( $v = $frame->variable($name) ){
     7748                $r = $v->value->compile($env);
    76697749                $this->evaluating = false;
    7670                 return $v->value->compile($env);
    7671             }
    7672         }
    7673 
    7674         throw new Less_Exception_Compiler("variable " . $name . " is undefined", null, $this->index );
     7750                return $r;
     7751            }
     7752        }
     7753
     7754        throw new Less_Exception_Compiler("variable " . $name . " is undefined in file ".$this->currentFileInfo["filename"], null, $this->index );
    76757755    }
    76767756
     
    77857865                $defaultResult = $defTrue;
    77867866                if( ($count[$defTrue] + $count[$defFalse]) > 1 ){
    7787                     throw Exception( 'Ambiguous use of `default()` found when matching for `'. $this->format($args) + '`' );
     7867                    throw new Exception( 'Ambiguous use of `default()` found when matching for `'. $this->format($args) + '`' );
    77887868                }
    77897869            }
     
    78237903
    78247904        }else{
    7825             throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined", null, $this->index);
     7905            throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in ".$this->currentFileInfo['filename'], null, $this->index);
    78267906        }
    78277907
     
    81268206    public $foundExtends;
    81278207
    8128     function __construct(){
     8208    public function __construct(){
    81298209        $this->contexts = array();
    81308210        $this->allExtendsStack = array(array());
     
    81358215     * @param Less_Tree_Ruleset $root
    81368216     */
    8137     function run($root){
     8217    public function run($root){
    81388218        $root = $this->visitObj($root);
    81398219        $root->allExtends =& $this->allExtendsStack[0];
     
    81418221    }
    81428222
    8143     function visitRule($ruleNode, &$visitDeeper ){
     8223    public function visitRule($ruleNode, &$visitDeeper ){
    81448224        $visitDeeper = false;
    81458225    }
    81468226
    8147     function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
     8227    public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
    81488228        $visitDeeper = false;
    81498229    }
    81508230
    8151     function visitRuleset($rulesetNode){
     8231    public function visitRuleset($rulesetNode){
    81528232
    81538233        if( $rulesetNode->root ){
     
    81858265    }
    81868266
    8187     function allExtendsStackPush($rulesetNode, $selectorPath, $extend, &$j){
     8267    public function allExtendsStackPush($rulesetNode, $selectorPath, $extend, &$j){
    81888268        $this->foundExtends = true;
    81898269        $extend = clone $extend;
     
    82008280
    82018281
    8202     function visitRulesetOut( $rulesetNode ){
     8282    public function visitRulesetOut( $rulesetNode ){
    82038283        if( !is_object($rulesetNode) || !$rulesetNode->root ){
    82048284            array_pop($this->contexts);
     
    82068286    }
    82078287
    8208     function visitMedia( $mediaNode ){
     8288    public function visitMedia( $mediaNode ){
    82098289        $mediaNode->allExtends = array();
    82108290        $this->allExtendsStack[] =& $mediaNode->allExtends;
    82118291    }
    82128292
    8213     function visitMediaOut(){
     8293    public function visitMediaOut(){
    82148294        array_pop($this->allExtendsStack);
    82158295    }
    82168296
    8217     function visitDirective( $directiveNode ){
     8297    public function visitDirective( $directiveNode ){
    82188298        $directiveNode->allExtends = array();
    82198299        $this->allExtendsStack[] =& $directiveNode->allExtends;
    82208300    }
    82218301
    8222     function visitDirectiveOut(){
     8302    public function visitDirectiveOut(){
    82238303        array_pop($this->allExtendsStack);
    82248304    }
     
    83808460     * @param Less_Tree_Ruleset $root
    83818461     */
    8382     function run( $root ){
     8462    public function run( $root ){
    83838463        return $this->visitObj($root);
    83848464    }
    83858465
    8386     function visitRule( $ruleNode, &$visitDeeper ){
     8466    public function visitRule( $ruleNode, &$visitDeeper ){
    83878467        $visitDeeper = false;
    83888468    }
    83898469
    8390     function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
     8470    public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
    83918471        $visitDeeper = false;
    83928472    }
    83938473
    8394     function visitRuleset( $rulesetNode ){
     8474    public function visitRuleset( $rulesetNode ){
    83958475
    83968476        $paths = array();
     
    84218501    }
    84228502
    8423     function visitRulesetOut(){
     8503    public function visitRulesetOut(){
    84248504        array_pop($this->contexts);
    84258505    }
    84268506
    8427     function visitMedia($mediaNode) {
     8507    public function visitMedia($mediaNode) {
    84288508        $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1];
    84298509
     
    89158995    private $charset;
    89168996
    8917     function __construct(){
     8997    public function __construct(){
    89188998        parent::__construct();
    89198999    }
     
    89229002     * @param Less_Tree_Ruleset $root
    89239003     */
    8924     function run( $root ){
     9004    public function run( $root ){
    89259005        return $this->visitObj($root);
    89269006    }
    89279007
    8928     function visitRule( $ruleNode ){
     9008    public function visitRule( $ruleNode ){
    89299009        if( $ruleNode->variable ){
    89309010            return array();
     
    89339013    }
    89349014
    8935     function visitMixinDefinition($mixinNode){
     9015    public function visitMixinDefinition($mixinNode){
    89369016        // mixin definitions do not get eval'd - this means they keep state
    89379017        // so we have to clear that state here so it isn't used if toCSS is called twice
     
    89409020    }
    89419021
    8942     function visitExtend(){
     9022    public function visitExtend(){
    89439023        return array();
    89449024    }
    89459025
    8946     function visitComment( $commentNode ){
     9026    public function visitComment( $commentNode ){
    89479027        if( $commentNode->isSilent() ){
    89489028            return array();
     
    89519031    }
    89529032
    8953     function visitMedia( $mediaNode, &$visitDeeper ){
     9033    public function visitMedia( $mediaNode, &$visitDeeper ){
    89549034        $mediaNode->accept($this);
    89559035        $visitDeeper = false;
     
    89619041    }
    89629042
    8963     function visitDirective( $directiveNode ){
     9043    public function visitDirective( $directiveNode ){
    89649044        if( isset($directiveNode->currentFileInfo['reference']) && (!property_exists($directiveNode,'isReferenced') || !$directiveNode->isReferenced) ){
    89659045            return array();
     
    89859065    }
    89869066
    8987     function checkPropertiesInRoot( $rulesetNode ){
     9067    public function checkPropertiesInRoot( $rulesetNode ){
    89889068
    89899069        if( !$rulesetNode->firstRoot ){
     
    90009080
    90019081
    9002     function visitRuleset( $rulesetNode, &$visitDeeper ){
     9082    public function visitRuleset( $rulesetNode, &$visitDeeper ){
    90039083
    90049084        $visitDeeper = false;
     
    90979177    }
    90989178
    9099     function _removeDuplicateRules( &$rules ){
     9179    protected function _removeDuplicateRules( &$rules ){
    91009180        // remove duplicates
    91019181        $ruleCache = array();
     
    91249204    }
    91259205
    9126     function _mergeRules( &$rules ){
     9206    protected function _mergeRules( &$rules ){
    91279207        $groups = array();
    91289208
     
    91769256    }
    91779257
    9178     static function toExpression($values){
     9258    public static function toExpression($values){
    91799259        $mapped = array();
    91809260        foreach($values as $p){
     
    91849264    }
    91859265
    9186     static function toValue($values){
     9266    public static function toValue($values){
    91879267        //return new Less_Tree_Value($values); ??
    91889268
     
    93639443     *
    93649444     */
    9365     function Chunks(){
     9445    protected function Chunks(){
    93669446        $level = 0;
    93679447        $parenLevel = 0;
     
    94909570    }
    94919571
    9492     function CharCode($pos){
     9572    public function CharCode($pos){
    94939573        return ord($this->input[$pos]);
    94949574    }
    94959575
    94969576
    9497     function fail( $msg, $index = null ){
     9577    public function fail( $msg, $index = null ){
    94989578
    94999579        if( !$index ){
     
    96239703                        count($sourceLines),                    // original_line
    96249704                        strlen($sourceColumns),                 // original_column
    9625                         $fileInfo['currentUri']
     9705                        $fileInfo
    96269706                );
    96279707            }else{
     
    96329712                        count($sourceLines) + $i,               // original_line
    96339713                        $i === 0 ? strlen($sourceColumns) : 0,  // original_column
    9634                         $fileInfo['currentUri']
     9714                        $fileInfo
    96359715                    );
    96369716                }
     
    98759955
    98769956            // base path for filename normalization
    9877             'sourceMapBasepath'     => ''
     9957            'sourceMapRootpath'     => '',
     9958
     9959            // base path for filename normalization
     9960            'sourceMapBasepath'   => ''
    98789961    );
    98799962
     
    99129995     */
    99139996    protected $sources = array();
     9997    protected $source_keys = array();
    99149998
    99159999    /**
     
    992810012
    992910013        // fix windows paths
    9930         if( isset($this->options['sourceMapBasepath']) ){
    9931             $this->options['sourceMapBasepath'] = str_replace('\\', '/', $this->options['sourceMapBasepath']);
     10014        if( !empty($this->options['sourceMapRootpath']) ){
     10015            $this->options['sourceMapRootpath'] = str_replace('\\', '/', $this->options['sourceMapRootpath']);
     10016            $this->options['sourceMapRootpath'] = rtrim($this->options['sourceMapRootpath'],'/').'/';
    993210017        }
    993310018    }
     
    999910084     */
    1000010085    protected function normalizeFilename($filename){
     10086
    1000110087        $filename = str_replace('\\', '/', $filename);
     10088        $rootpath = $this->getOption('sourceMapRootpath');
    1000210089        $basePath = $this->getOption('sourceMapBasepath');
    1000310090
    10004         if( $basePath && ($pos = strpos($filename, $basePath)) !== false ){
    10005             $filename = substr($filename, $pos + strlen($basePath));
    10006             if(strpos($filename, '\\') === 0 || strpos($filename, '/') === 0){
    10007                 $filename = substr($filename, 1);
    10008             }
    10009         }
    10010         return sprintf('%s%s', $this->getOption('sourceMapRootpath'), $filename);
     10091        // "Trim" the 'sourceMapBasepath' from the output filename.
     10092        if (strpos($filename, $basePath) === 0) {
     10093            $filename = substr($filename, strlen($basePath));
     10094        }
     10095
     10096        // Remove extra leading path separators.
     10097        if(strpos($filename, '\\') === 0 || strpos($filename, '/') === 0){
     10098            $filename = substr($filename, 1);
     10099        }
     10100
     10101        return $rootpath . $filename;
    1001110102    }
    1001210103
     
    1002010111     * @param string $sourceFile The original source file
    1002110112     */
    10022     public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $sourceFile){
     10113    public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $fileInfo ){
     10114
    1002310115        $this->mappings[] = array(
    1002410116            'generated_line' => $generatedLine,
     
    1002610118            'original_line' => $originalLine,
    1002710119            'original_column' => $originalColumn,
    10028             'source_file' => $sourceFile
     10120            'source_file' => $fileInfo['currentUri']
    1002910121        );
    1003010122
    10031 
    10032         $norm_file = $this->normalizeFilename($sourceFile);
    10033 
    10034         $this->sources[$norm_file] = $sourceFile;
     10123        $this->sources[$fileInfo['currentUri']] = $fileInfo['filename'];
    1003510124    }
    1003610125
     
    1006610155
    1006710156        // A list of original sources used by the 'mappings' entry.
    10068         $sourceMap['sources'] = array_keys($this->sources);
    10069 
     10157        $sourceMap['sources'] = array();
     10158        foreach($this->sources as $source_uri => $source_filename){
     10159            $sourceMap['sources'][] = $this->normalizeFilename($source_filename);
     10160        }
    1007010161
    1007110162
     
    1011810209        }
    1011910210
     10211        $this->source_keys = array_flip(array_keys($this->sources));
     10212
     10213
    1012010214        // group mappings by generated line number.
    1012110215        $groupedMap = $groupedMapEncoded = array();
     
    1014110235                // find the index
    1014210236                if( $m['source_file'] ){
    10143                     $index = $this->findFileIndex($this->normalizeFilename($m['source_file']));
     10237                    $index = $this->findFileIndex($m['source_file']);
    1014410238                    if( $index !== false ){
    1014510239                        $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex);
     
    1017110265     */
    1017210266    protected function findFileIndex($filename){
    10173         return array_search($filename, array_keys($this->sources));
     10267        return $this->source_keys[$filename];
    1017410268    }
    1017510269
  • less-compiler/trunk/libs/less-parser/Version.php

    r912308 r943838  
    99class Less_Version{
    1010
    11     const version = '1.7.0.1';          // The current build number of less.php
     11    const version = '1.7.0.2';          // The current build number of less.php
    1212    const less_version = '1.7';         // The less.js version that this build should be compatible with
    1313    const cache_version = '170';        // The parser cache version
  • less-compiler/trunk/libs/wm-settings/wm-settings.css

    r912308 r943838  
    22form.wrap p.submit {
    33    padding-top: 20px;
    4     border-top: 1px solid #dfdfdf;
     4    border-top: 1px solid #ddd;
    55}
    66form.wrap td .settings-error {
     
    1111    margin: 0.5em 0;
    1212}
     13form.wrap .wm-settings-tabs-header h3 {
     14    float: left;
     15    padding: 10px 15px;
     16    font-weight: 300;
     17    background-color: #fff;
     18    border: 1px solid #ddd;
     19    border-right: none;
     20    border-bottom: none;
     21    cursor: pointer;
     22}
     23form.wrap .wm-settings-tabs-header h3:hover {
     24    background-color: #f9f9f9;
     25}
     26form.wrap .wm-settings-tabs-header h3.wm-settings-tab-active {
     27    background-color: #f1f1f1;
     28}
     29form.wrap .wm-settings-tabs-header h3:last-child {
     30    border-right: 1px solid #ddd;
     31}
     32.wm-settings-tabs-header,
     33.wm-settings-tabs-content {
     34    clear: both;
     35}
  • less-compiler/trunk/libs/wm-settings/wm-settings.js

    r912308 r943838  
    11jQuery(document).ready(function ($) {
    22  'use strict';
     3  var tabs = $('.wm-settings-tab', 'form'),
     4    tabsHeader,
     5    tabsContent,
     6    active = 'wm-settings-tab-active',
     7    current = $('#wm-settings-current-tab');
     8  if (tabs.length) {
     9    tabsHeader = $('<div>').addClass('wm-settings-tabs-header').insertBefore('form .submit:first');
     10    tabsContent = $('<div>').addClass('wm-settings-tabs-content').insertAfter(tabsHeader);
     11    tabs.each(function(i, el) {
     12      var title = $(el).prev('h3').appendTo(tabsHeader),
     13        nextAll = $(el).nextAll(),
     14        tab = $('<div>').appendTo(tabsContent).hide();
     15      nextAll.each(function() {
     16        var tag = $(this).prop('tagName');
     17        if (tag === 'H3' || tag === 'INPUT') {
     18          return false;
     19        }
     20        $(this).appendTo(tab);
     21      });
     22      title.click(function(e) {
     23        e.preventDefault();
     24        if (!title.hasClass(active)) {
     25          current.val(i);
     26          $('.' + active, tabsContent).fadeOut('fast', function() {
     27            $('.' + active, 'form').removeClass(active);
     28            title.addClass(active);
     29            tab.fadeIn('fast').addClass(active);
     30          });
     31        }
     32      });
     33    });
     34    tabsHeader.children().eq(current.val()).addClass(active);
     35    tabsContent.children().eq(current.val()).show().addClass(active);
     36  }
    337  $('.wm-settings-media', 'form').each(function () {
    438    var frame,
  • less-compiler/trunk/libs/wm-settings/wm-settings.php

    r912308 r943838  
    11<?php
    22/*
    3 http://webmaestro.fr/wordpress-settings-api-options-pages/
     3Plugin Name: WebMaestro Settings
     4Plugin URI: http://webmaestro.fr/wordpress-settings-api-options-pages/
     5Author: Etienne Baudry
     6Author URI: http://webmaestro.fr
     7Description: Simplified options system for WordPress. Generates a default page for settings.
     8Version: 1.2.4
     9License: GNU General Public License
     10License URI: license.txt
     11Text Domain: wm-settings
     12GitHub Plugin URI: https://github.com/WebMaestroFr/wm-settings
     13GitHub Branch: master
    414*/
    515
     
    2838    $this->args  = array_merge( array(
    2939      'submit' => __( 'Save Settings', 'wm-settings' ),
    30       'reset'  => __( 'Reset Settings', 'wm-settings' )
     40      'reset'  => __( 'Reset Settings', 'wm-settings' ),
     41      'tabs'   => true
    3142    ), $args );
    3243    add_action( 'admin_menu', array( $this, 'admin_menu' ) );
     
    6374      }
    6475    }
     76    // This is really ugly, there must be a better way to deal with that active tab
     77    $current_tag = "wm_settings_{$this->page}_current_tab";
     78    if ( isset( $_POST[$current_tag] ) ) {
     79      update_option( $current_tag, (int) $_POST[$current_tag] );
     80    }
    6581  }
    6682
     
    146162  { ?>
    147163    <form action="options.php" method="POST" enctype="multipart/form-data" class="wrap">
     164      <input type="hidden" name="wm_settings_<?php echo $this->page; ?>_current_tab" value="<?php echo get_option( "wm_settings_{$this->page}_current_tab" ); ?>" id="wm-settings-current-tab">
    148165      <h2><?php echo $this->title; ?></h2>
    149166      <?php
    150167        // Avoid showing admin notice twice
    151         // TODO : Target the pages where it happens
    152168        if ( ! in_array( $this->menu['parent'], array( 'options-general.php' ) ) ) {
    153169          settings_errors();
     
    168184  {
    169185    extract( $args );
     186    echo "<input name='{$id}[{$this->page}_setting]' type='hidden' value='{$id}'";
     187    if ( $this->args['tabs'] && ! empty( $this->settings[$id]['title'] ) ) {
     188      echo " class='wm-settings-tab'";
     189    }
     190    echo " />";
    170191    if ( $text = $this->settings[$id]['description'] ) {
    171192      echo wpautop( $text );
    172193    }
    173     echo "<input name='{$id}[{$this->page}_setting]' type='hidden' value='{$id}' />";
    174194  }
    175195
     
    187207    {
    188208      case 'checkbox':
    189         $check = checked( 1, $value, false);
     209        $check = checked( 1, $value, false );
    190210        echo "<label><input {$attrs} id='{$id}' type='checkbox' value='1' {$check} />";
    191211        if ( $description ) { echo " {$description}"; }
     
    216236      case 'media':
    217237        echo "<fieldset class='wm-settings-media' id='{$id}'><input {$attrs} type='hidden' value='{$value}' />";
     238        echo "<p><a class='button button-large wm-select-media' title='{$label}'>" . sprintf( __( 'Select %s', 'wm-settings' ), $label ) . "</a> ";
     239        echo "<a class='button button-small wm-remove-media' title='{$label}'>" . sprintf( __( 'Remove %s', 'wm-settings' ), $label ) . "</a></p>";
    218240        if ( $value ) {
    219           echo wp_get_attachment_image( $value, 'medium' );
    220         }
    221         echo "<p><a class='button button-large wm-select-media' title='{$label}'>" . sprintf( __( 'Select %s', 'wm-settings' ), $label ) . "</a> ";
    222         echo "<a class='button button-small wm-remove-media' title='{$label}'>" . sprintf( __( 'Remove %s', 'wm-settings' ), $label ) . "</a></p>{$desc}</fieldset>";
     241          echo wpautop( wp_get_attachment_image( $value, 'medium' ) );
     242        }
     243        echo "{$desc}</fieldset>";
    223244        break;
    224245
     
    232253        foreach ( $options as $n => $label ) {
    233254          $a = preg_replace( "/name\=\'(.+)\'/", "name='$1[{$n}]'", $attrs );
    234           $check = checked( 1, $value[$n], false);
     255          $check = checked( 1, $value[$n], false );
    235256          $options[$n] = "<label><input {$a} type='checkbox' value='1' {$check} /> {$label}</label>";
    236257        }
     
    352373}
    353374
     375function wm_settings_plugin_priority()
     376{
     377    $wm_settings = plugin_basename( __FILE__ );
     378    $active_plugins = get_option( 'active_plugins' );
     379    if ( $order = array_search( $wm_settings, $active_plugins ) ) {
     380        array_splice( $active_plugins, $order, 1 );
     381        array_unshift( $active_plugins, $wm_settings );
     382        update_option( 'active_plugins', $active_plugins );
     383    }
     384}
     385add_action( 'activated_plugin', 'wm_settings_plugin_priority' );
     386
    354387}
    355388
  • less-compiler/trunk/plugin.php

    r919717 r943838  
    66Author URI: http://webmaestro.fr
    77Description: Less Compiler for Wordpress
    8 Version: 1.2.2
     8Version: 1.3
    99License: GNU General Public License
    1010License URI: license.txt
     
    6161        add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
    6262        // add_editor_style( get_stylesheet_directory_uri() . self::$output );
     63        add_filter( 'style_loader_src', array( __CLASS__, 'style_loader_src' ) );
    6364    }
    6465
     
    7172        ), array(
    7273            'less' => array(
    73                 'description' => '<p>' . sprintf( __( 'The resulting CSS will be compiled into <strong>%s</strong>. You can use the PHP function <code>less_output( $css_file );</code> to output an other file instead (relative to <strong>%s</strong>).', 'wm-less' ), self::$output, get_stylesheet_directory() ) . '</p><p>' . __( 'Import any LESS files to compile prior to this stylesheet with <code>less_import( $files_array );</code>.', 'wm-less' ) . '</p>',
     74                'description' => '<p>' .
     75                        sprintf( __( 'The resulting CSS will be compiled into <strong>%s</strong>.', 'wm-less' ), ltrim( self::$output, '/' ) ) .
     76                        ' ' . sprintf( __( 'You can use the PHP function <code>less_output( $css_file );</code> to output an other file instead (relative to <strong>%s</strong>).', 'wm-less' ), get_stylesheet_directory() ) .
     77                        ' ' . __( 'Do not set your theme\'s <strong>style.css</strong> as output !', 'wm-less' ) .
     78                    '</p><p>' .
     79                        __( 'Import any LESS files to compile prior to this stylesheet with <code>less_import( $files_array );</code>.', 'wm-less' ) .
     80                    '</p><p>' .
     81                        __( 'Alternatively, you can enqueue any LESS sheet the same way you would for your CSS : <code>wp_enqueue_style( $handle, $src, $deps, $ver, $media );</code>.', 'wm-less' ) .
     82                    '</p>',
    7483                'fields' => array(
    7584                    'compiler' => array(
     
    128137    {
    129138        require_once( plugin_dir_path( __FILE__ ) . 'libs/less-parser/Less.php' );
     139        $parser = new Less_Parser( array(
     140            'compress' => true,
     141            'cache_dir' => self::get_cache_dir()
     142        ) );
     143        $parser->SetImportDirs( array(
     144            get_stylesheet_directory() => '',
     145            get_template_directory() => ''
     146        ) );
    130147        try {
    131             $cache_dir = plugin_dir_path( __FILE__ ) . 'cache';
    132             if ( ! is_writable( $cache_dir ) ) {
    133                 add_action( 'admin_notices', array( __CLASS__, 'cache_permissions_notice' ) );
    134             }
    135             $parser = new Less_Parser( array(
    136                 'compress' => true,
    137                 'cache_dir' => is_writable( $cache_dir ) ? $cache_dir : null
    138             ) );
    139             $parser->SetImportDirs( array(
    140                 get_stylesheet_directory() => '',
    141                 get_template_directory() => ''
    142             ) );
    143148            foreach ( self::$imports as $file ) {
    144149                $parser->parse( "@import '{$file}';" );
     
    152157        }
    153158    }
     159    private static function get_cache_dir()
     160    {
     161        $cache_dir = ABSPATH . 'wp-content/cache';
     162        if ( ! is_dir( $cache_dir ) ) {
     163            mkdir( $cache_dir );
     164        }
     165        if ( ! is_writable( $cache_dir ) ) {
     166            add_action( 'admin_notices', array( __CLASS__, 'cache_permissions_notice' ) );
     167            return null;
     168        }
     169        return $cache_dir;
     170    }
    154171
    155172    public static function admin_enqueue_scripts( $hook_suffix )
    156173    {
    157174        if ( 'toplevel_page_less' == $hook_suffix ) {
    158             wp_enqueue_script( 'codemirror', plugin_dir_url( __FILE__ ) . '/js/codemirror.js' );
    159             wp_enqueue_script( 'codemirror-less', plugin_dir_url( __FILE__ ) . '/js/codemirror-less.js', array( 'codemirror' ) );
    160             wp_enqueue_script( 'less-compiler', plugin_dir_url( __FILE__ ) . '/js/less-compiler.js', array( 'codemirror-less' ) );
    161             wp_enqueue_style( 'codemirror', plugin_dir_url( __FILE__ ) . '/css/codemirror.css' );
    162             wp_enqueue_style( 'less-compiler', plugin_dir_url( __FILE__ ) . '/css/less-compiler.css' );
     175            wp_enqueue_script( 'codemirror', plugin_dir_url( __FILE__ ) . 'js/codemirror.js' );
     176            wp_enqueue_script( 'codemirror-less', plugin_dir_url( __FILE__ ) . 'js/codemirror-less.js', array( 'codemirror' ) );
     177            wp_enqueue_script( 'less-compiler', plugin_dir_url( __FILE__ ) . 'js/less-compiler.js', array( 'codemirror-less' ) );
     178            wp_enqueue_style( 'codemirror', plugin_dir_url( __FILE__ ) . 'css/codemirror.css' );
     179            wp_enqueue_style( 'less-compiler', plugin_dir_url( __FILE__ ) . 'css/less-compiler.css' );
    163180        }
    164181    }
     
    170187        }
    171188    }
     189
     190    public static function style_loader_src( $src )
     191    {
     192        $input = strtok( $src, '?' );
     193    if ( preg_match( '/\.less$/', $input ) ) {
     194            require_once( plugin_dir_path( __FILE__ ) . 'libs/less-parser/Less.php' );
     195            $input = str_replace( trailingslashit( site_url() ), ABSPATH, $input );
     196            if ( $cache_dir = self::get_cache_dir() ) {
     197                return trailingslashit( str_replace( ABSPATH, trailingslashit( site_url() ), $cache_dir ) ) . Less_Cache::Get( array(
     198                        $input => dirname( $input )
     199                    ), array(
     200                        'cache_dir' => $cache_dir
     201                    ) );
     202            }
     203            return null;
     204    }
     205    return $src;
     206    }
    172207}
    173208add_action( 'init', array( 'WM_Less', 'init' ) );
  • less-compiler/trunk/readme.txt

    r912476 r943838  
    55Requires at least: 3.9
    66Tested up to: 3.9.1
    7 Stable tag: 1.2
     7Stable tag: 1.3
    88License: GPLv2
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    3939  Import any LESS files to compile prior to the dashboard stylesheet.
    4040
     41- ```wp_enqueue_style( 'my-less-handle', 'http://example.com/css/mystyle.less', $deps, $ver, $media );```
     42
     43  Alternatively you can register and enqueue your LESS sheets the same way you would do for your CSS.
     44
     45
    4146You will most likely use these in your theme's `functions.php`.
    4247
    43 The plugin uses [**leafo**'s LESS compiler written in PHP](https://github.com/leafo/lessphp).
     48The plugin uses [the Less.php Compiler](http://lessphp.gpeasy.com/).
    4449
    4550== Installation ==
     
    6267== Changelog ==
    6368
    64 = 1.2 =
    65 * Minor fixes (typo, dependences)
     69= 1.3 =
     70* "wp_enqueue_style" support
     71* Moved cache directory to wp-content/cache
    6672
    67 = 1.0 =
    68 * First stable release
    69 
    70 == Upgrade Notice ==
     73= 1.2.2 =
     74* Menu icon and cache warning
    7175
    7276= 1.2 =
    7377* Minor fixes (typo, dependences)
    7478
    75 = 1.0 =
    76 First stable release
     79== Upgrade Notice ==
     80
     81= 1.3 =
     82* "wp_enqueue_style" support
     83* Moved cache directory to wp-content/cache
     84
     85= 1.2 =
     86* Minor fixes (typo, dependences)
Note: See TracChangeset for help on using the changeset viewer.