Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
90.79% |
69 / 76 |
|
72.73% |
8 / 11 |
CRAP | |
0.00% |
0 / 1 |
Less_Tree | |
90.79% |
69 / 76 |
|
72.73% |
8 / 11 |
47.65 | |
0.00% |
0 / 1 |
toCSS | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
genCSS | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
compile | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
_operate | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
5 | |||
fround | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
3.04 | |||
outputRuleset | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
4 | |||
accept | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
nodeCompare | |
95.83% |
23 / 24 |
|
0.00% |
0 / 1 |
21 | |||
numericCompare | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
ReferencedArray | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
__set_state | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | /** |
4 | * Tree |
5 | */ |
6 | class Less_Tree { |
7 | |
8 | public $parensInOp = false; |
9 | public $extendOnEveryPath; |
10 | public $allExtends; |
11 | |
12 | /** |
13 | * @var Less_Parser |
14 | * @see less-3.13.1.js#Node.prototype.parse |
15 | */ |
16 | public static $parse; |
17 | |
18 | /** |
19 | * @see less-2.5.3.js#Node.prototype.toCSS |
20 | */ |
21 | public function toCSS() { |
22 | $output = new Less_Output(); |
23 | $this->genCSS( $output ); |
24 | return $output->toString(); |
25 | } |
26 | |
27 | /** |
28 | * Generate CSS by adding it to the output object |
29 | * |
30 | * @param Less_Output $output The output |
31 | * @return void |
32 | */ |
33 | public function genCSS( $output ) { |
34 | } |
35 | |
36 | public function compile( $env ) { |
37 | return $this; |
38 | } |
39 | |
40 | /** |
41 | * @param string $op |
42 | * @param float $a |
43 | * @param float $b |
44 | * @see less-2.5.3.js#Node.prototype._operate |
45 | */ |
46 | protected function _operate( $op, $a, $b ) { |
47 | switch ( $op ) { |
48 | case '+': |
49 | return $a + $b; |
50 | case '-': |
51 | return $a - $b; |
52 | case '*': |
53 | return $a * $b; |
54 | case '/': |
55 | return $a / $b; |
56 | } |
57 | } |
58 | |
59 | /** |
60 | * @see less-2.5.3.js#Node.prototype.fround |
61 | */ |
62 | protected function fround( $value ) { |
63 | if ( $value === 0 ) { |
64 | return $value; |
65 | } |
66 | |
67 | // TODO: Migrate to passing $env. |
68 | if ( Less_Parser::$options['numPrecision'] ) { |
69 | $p = pow( 10, Less_Parser::$options['numPrecision'] ); |
70 | return round( $value * $p ) / $p; |
71 | } |
72 | return $value; |
73 | } |
74 | |
75 | /** |
76 | * @param Less_Output $output |
77 | * @param Less_Tree_Ruleset[] $rules |
78 | */ |
79 | public static function outputRuleset( $output, $rules ) { |
80 | $ruleCnt = count( $rules ); |
81 | Less_Environment::$tabLevel++; |
82 | |
83 | // Compressed |
84 | if ( Less_Parser::$options['compress'] ) { |
85 | $output->add( '{' ); |
86 | for ( $i = 0; $i < $ruleCnt; $i++ ) { |
87 | $rules[$i]->genCSS( $output ); |
88 | } |
89 | |
90 | $output->add( '}' ); |
91 | Less_Environment::$tabLevel--; |
92 | return; |
93 | } |
94 | |
95 | // Non-compressed |
96 | $tabSetStr = "\n" . str_repeat( Less_Parser::$options['indentation'], Less_Environment::$tabLevel - 1 ); |
97 | $tabRuleStr = $tabSetStr . Less_Parser::$options['indentation']; |
98 | |
99 | $output->add( " {" ); |
100 | for ( $i = 0; $i < $ruleCnt; $i++ ) { |
101 | $output->add( $tabRuleStr ); |
102 | $rules[$i]->genCSS( $output ); |
103 | } |
104 | Less_Environment::$tabLevel--; |
105 | $output->add( $tabSetStr . '}' ); |
106 | } |
107 | |
108 | public function accept( $visitor ) { |
109 | } |
110 | |
111 | /** |
112 | * @param Less_Tree $a |
113 | * @param Less_Tree $b |
114 | * @return int|null |
115 | * @see less-2.5.3.js#Node.compare |
116 | */ |
117 | public static function nodeCompare( $a, $b ) { |
118 | // Less_Tree subclasses that implement compare() are: |
119 | // Anonymous, Color, Dimension, Quoted, Unit |
120 | $aHasCompare = ( $a instanceof Less_Tree_Anonymous || $a instanceof Less_Tree_Color |
121 | || $a instanceof Less_Tree_Dimension || $a instanceof Less_Tree_Quoted || $a instanceof Less_Tree_Unit |
122 | ); |
123 | $bHasCompare = ( $b instanceof Less_Tree_Anonymous || $b instanceof Less_Tree_Color |
124 | || $b instanceof Less_Tree_Dimension || $b instanceof Less_Tree_Quoted || $b instanceof Less_Tree_Unit |
125 | ); |
126 | |
127 | if ( $aHasCompare && |
128 | !( $b instanceof Less_Tree_Quoted || $b instanceof Less_Tree_Anonymous ) |
129 | ) { |
130 | // for "symmetric results" force toCSS-based comparison via b.compare() |
131 | // of Quoted or Anonymous if either value is one of those |
132 | // @phan-suppress-next-line PhanUndeclaredMethod |
133 | return $a->compare( $b ); |
134 | } elseif ( $bHasCompare ) { |
135 | $res = $b->compare( $a ); |
136 | // In JS, `-undefined` produces NAN, which, just like undefined |
137 | // will enter the the default/false branch of Less_Tree_Condition#compile. |
138 | // In PHP, `-null` is 0. To ensure parity, preserve the null. |
139 | return $res !== null ? -$res : null; |
140 | } elseif ( get_class( $a ) !== get_class( $b ) ) { |
141 | return null; |
142 | } |
143 | |
144 | // Less_Tree subclasses that have an array value: Less_Tree_Expression, Less_Tree_Value |
145 | // @phan-suppress-next-line PhanUndeclaredProperty |
146 | $aval = $a->value ?? []; |
147 | $bval = $b->value ?? []; |
148 | if ( !( $a instanceof Less_Tree_Expression || $a instanceof Less_Tree_Value ) ) { |
149 | return $aval === $bval ? 0 : null; |
150 | } |
151 | '@phan-var Less_Tree[] $aval'; |
152 | '@phan-var Less_Tree[] $bval'; |
153 | if ( count( $aval ) !== count( $bval ) ) { |
154 | return null; |
155 | } |
156 | foreach ( $aval as $i => $item ) { |
157 | if ( self::nodeCompare( $item, $bval[$i] ) !== 0 ) { |
158 | return null; |
159 | } |
160 | } |
161 | return 0; |
162 | } |
163 | |
164 | /** |
165 | * @param string|float|int $a |
166 | * @param string|float|int $b |
167 | * @return int|null |
168 | * @see less-2.5.3.js#Node.numericCompare |
169 | */ |
170 | public static function numericCompare( $a, $b ) { |
171 | return $a < $b ? -1 |
172 | : ( $a === $b ? 0 |
173 | : ( $a > $b ? 1 |
174 | // NAN is not greater, less, or equal |
175 | : null |
176 | ) |
177 | ); |
178 | } |
179 | |
180 | public static function ReferencedArray( $rules ) { |
181 | foreach ( $rules as $rule ) { |
182 | if ( method_exists( $rule, 'markReferenced' ) ) { |
183 | $rule->markReferenced(); |
184 | } |
185 | } |
186 | } |
187 | |
188 | /** |
189 | * Requires php 5.3+ |
190 | */ |
191 | public static function __set_state( $args ) { |
192 | $class = get_called_class(); |
193 | $obj = new $class( null, null, null, null ); |
194 | foreach ( $args as $key => $val ) { |
195 | $obj->$key = $val; |
196 | } |
197 | return $obj; |
198 | } |
199 | |
200 | } |