Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
59 / 59
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
Less_Environment
100.00% covered (success)
100.00%
59 / 59
100.00% covered (success)
100.00%
7 / 7
16
100.00% covered (success)
100.00%
1 / 1
 Init
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
2
 copyEvalEnv
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 isMathOn
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 isPathRelative
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 normalizePath
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
7
 unshiftFrame
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 shiftFrame
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * @private
4 */
5class Less_Environment {
6
7    /**
8     * Information about the current file - for error reporting and importing and making urls relative etc.
9     *
10     * - rootpath: rootpath to append to URLs
11     *
12     * @var array|null
13     */
14    public $currentFileInfo;
15
16    /** @var bool Whether we are currently importing multiple copies */
17    public $importMultiple = false;
18
19    /**
20     * @var array
21     */
22    public $frames = [];
23
24    /** @var Less_Tree_Media[] */
25    public $mediaBlocks = [];
26    /** @var Less_Tree_Media[] */
27    public $mediaPath = [];
28
29    public static $parensStack = 0;
30
31    public static $tabLevel = 0;
32
33    public static $lastRule = false;
34
35    public static $_outputMap;
36
37    public static $mixin_stack = 0;
38
39    public static $mathOn = true;
40
41    /**
42     * @var array
43     */
44    public $functions = [];
45
46    public function Init() {
47        self::$parensStack = 0;
48        self::$tabLevel = 0;
49        self::$lastRule = false;
50        self::$mixin_stack = 0;
51
52        if ( Less_Parser::$options['compress'] ) {
53
54            self::$_outputMap = [
55                ','    => ',',
56                ': ' => ':',
57                ''  => '',
58                ' ' => ' ',
59                ':' => ' :',
60                '+' => '+',
61                '~' => '~',
62                '>' => '>',
63                '|' => '|',
64                '^' => '^',
65                '^^' => '^^'
66            ];
67
68        } else {
69
70            self::$_outputMap = [
71                ','    => ', ',
72                ': ' => ': ',
73                ''  => '',
74                ' ' => ' ',
75                ':' => ' :',
76                '+' => ' + ',
77                '~' => ' ~ ',
78                '>' => ' > ',
79                '|' => '|',
80                '^' => ' ^ ',
81                '^^' => ' ^^ '
82            ];
83
84        }
85    }
86
87    public function copyEvalEnv( $frames = [] ) {
88        $new_env = new self();
89        $new_env->frames = $frames;
90        return $new_env;
91    }
92
93    /**
94     * @return bool
95     * @see Eval.prototype.isMathOn in less.js 3.0.0 https://github.com/less/less.js/blob/v3.0.0/dist/less.js#L1007
96     */
97    public static function isMathOn() {
98        if ( !self::$mathOn ) {
99            return false;
100        }
101        return !Less_Parser::$options['strictMath'] || self::$parensStack;
102    }
103
104    /**
105     * @param string $path
106     * @return bool
107     * @see less-2.5.3.js#Eval.isPathRelative
108     */
109    public static function isPathRelative( $path ) {
110        return !preg_match( '/^(?:[a-z-]+:|\/|#)/', $path );
111    }
112
113    /**
114     * Canonicalize a path by resolving references to '/./', '/../'
115     * Does not remove leading "../"
116     * @param string $path or url
117     * @return string Canonicalized path
118     */
119    public static function normalizePath( $path ) {
120        $segments = explode( '/', $path );
121        $segments = array_reverse( $segments );
122
123        $path = [];
124        $path_len = 0;
125
126        while ( $segments ) {
127            $segment = array_pop( $segments );
128            switch ( $segment ) {
129
130                case '.':
131                    break;
132
133                case '..':
134                    // @phan-suppress-next-line PhanTypeInvalidDimOffset False positive
135                    if ( !$path_len || ( $path[$path_len - 1] === '..' ) ) {
136                        $path[] = $segment;
137                        $path_len++;
138                    } else {
139                        array_pop( $path );
140                        $path_len--;
141                    }
142                    break;
143
144                default:
145                    $path[] = $segment;
146                    $path_len++;
147                    break;
148            }
149        }
150
151        return implode( '/', $path );
152    }
153
154    public function unshiftFrame( $frame ) {
155        array_unshift( $this->frames, $frame );
156    }
157
158    public function shiftFrame() {
159        return array_shift( $this->frames );
160    }
161
162}