]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/oyejorge/less.php/lib/Less/Tree/Dimension.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / oyejorge / less.php / lib / Less / Tree / Dimension.php
1 <?php
2
3 /**
4  * Dimension
5  *
6  * @package Less
7  * @subpackage tree
8  */
9 class Less_Tree_Dimension extends Less_Tree{
10
11         public $value;
12         public $unit;
13         public $type = 'Dimension';
14
15     public function __construct($value, $unit = null){
16         $this->value = floatval($value);
17
18                 if( $unit && ($unit instanceof Less_Tree_Unit) ){
19                         $this->unit = $unit;
20                 }elseif( $unit ){
21                         $this->unit = new Less_Tree_Unit( array($unit) );
22                 }else{
23                         $this->unit = new Less_Tree_Unit( );
24                 }
25     }
26
27     public function accept( $visitor ){
28                 $this->unit = $visitor->visitObj( $this->unit );
29         }
30
31     public function compile(){
32         return $this;
33     }
34
35     public function toColor() {
36         return new Less_Tree_Color(array($this->value, $this->value, $this->value));
37     }
38
39     /**
40      * @see Less_Tree::genCSS
41      */
42         public function genCSS( $output ){
43
44                 if( Less_Parser::$options['strictUnits'] && !$this->unit->isSingular() ){
45                         throw new Less_Exception_Compiler("Multiple units in dimension. Correct the units or use the unit function. Bad unit: ".$this->unit->toString());
46                 }
47
48                 $value = Less_Functions::fround( $this->value );
49                 $strValue = (string)$value;
50
51                 if( $value !== 0 && $value < 0.000001 && $value > -0.000001 ){
52                         // would be output 1e-6 etc.
53                         $strValue = number_format($strValue,10);
54                         $strValue = preg_replace('/\.?0+$/','', $strValue);
55                 }
56
57                 if( Less_Parser::$options['compress'] ){
58                         // Zero values doesn't need a unit
59                         if( $value === 0 && $this->unit->isLength() ){
60                                 $output->add( $strValue );
61                                 return $strValue;
62                         }
63
64                         // Float values doesn't need a leading zero
65                         if( $value > 0 && $value < 1 && $strValue[0] === '0' ){
66                                 $strValue = substr($strValue,1);
67                         }
68                 }
69
70                 $output->add( $strValue );
71                 $this->unit->genCSS( $output );
72         }
73
74     public function __toString(){
75         return $this->toCSS();
76     }
77
78     // In an operation between two Dimensions,
79     // we default to the first Dimension's unit,
80     // so `1px + 2em` will yield `3px`.
81
82     /**
83      * @param string $op
84      */
85     public function operate( $op, $other){
86
87                 $value = Less_Functions::operate( $op, $this->value, $other->value);
88                 $unit = clone $this->unit;
89
90                 if( $op === '+' || $op === '-' ){
91
92                         if( !$unit->numerator && !$unit->denominator ){
93                                 $unit->numerator = $other->unit->numerator;
94                                 $unit->denominator = $other->unit->denominator;
95                         }elseif( !$other->unit->numerator && !$other->unit->denominator ){
96                                 // do nothing
97                         }else{
98                                 $other = $other->convertTo( $this->unit->usedUnits());
99
100                                 if( Less_Parser::$options['strictUnits'] && $other->unit->toString() !== $unit->toCSS() ){
101                                         throw new Less_Exception_Compiler("Incompatible units. Change the units or use the unit function. Bad units: '" . $unit->toString() . "' and " . $other->unit->toString() . "'.");
102                                 }
103
104                                 $value = Less_Functions::operate( $op, $this->value, $other->value);
105                         }
106                 }elseif( $op === '*' ){
107                         $unit->numerator = array_merge($unit->numerator, $other->unit->numerator);
108                         $unit->denominator = array_merge($unit->denominator, $other->unit->denominator);
109                         sort($unit->numerator);
110                         sort($unit->denominator);
111                         $unit->cancel();
112                 }elseif( $op === '/' ){
113                         $unit->numerator = array_merge($unit->numerator, $other->unit->denominator);
114                         $unit->denominator = array_merge($unit->denominator, $other->unit->numerator);
115                         sort($unit->numerator);
116                         sort($unit->denominator);
117                         $unit->cancel();
118                 }
119                 return new Less_Tree_Dimension( $value, $unit);
120     }
121
122         public function compare($other) {
123                 if ($other instanceof Less_Tree_Dimension) {
124
125                         if( $this->unit->isEmpty() || $other->unit->isEmpty() ){
126                                 $a = $this;
127                                 $b = $other;
128                         } else {
129                                 $a = $this->unify();
130                                 $b = $other->unify();
131                                 if( $a->unit->compare($b->unit) !== 0 ){
132                                         return -1;
133                                 }
134                         }
135                         $aValue = $a->value;
136                         $bValue = $b->value;
137
138                         if ($bValue > $aValue) {
139                                 return -1;
140                         } elseif ($bValue < $aValue) {
141                                 return 1;
142                         } else {
143                                 return 0;
144                         }
145                 } else {
146                         return -1;
147                 }
148         }
149
150     public function unify() {
151                 return $this->convertTo(array('length'=> 'px', 'duration'=> 's', 'angle' => 'rad' ));
152         }
153
154     public function convertTo($conversions) {
155                 $value = $this->value;
156                 $unit = clone $this->unit;
157
158                 if( is_string($conversions) ){
159                         $derivedConversions = array();
160                         foreach( Less_Tree_UnitConversions::$groups as $i ){
161                                 if( isset(Less_Tree_UnitConversions::${$i}[$conversions]) ){
162                                         $derivedConversions = array( $i => $conversions);
163                                 }
164                         }
165                         $conversions = $derivedConversions;
166                 }
167
168
169                 foreach($conversions as $groupName => $targetUnit){
170                         $group = Less_Tree_UnitConversions::${$groupName};
171
172                         //numerator
173                         foreach($unit->numerator as $i => $atomicUnit){
174                                 $atomicUnit = $unit->numerator[$i];
175                                 if( !isset($group[$atomicUnit]) ){
176                                         continue;
177                                 }
178
179                                 $value = $value * ($group[$atomicUnit] / $group[$targetUnit]);
180
181                                 $unit->numerator[$i] = $targetUnit;
182                         }
183
184                         //denominator
185                         foreach($unit->denominator as $i => $atomicUnit){
186                                 $atomicUnit = $unit->denominator[$i];
187                                 if( !isset($group[$atomicUnit]) ){
188                                         continue;
189                                 }
190
191                                 $value = $value / ($group[$atomicUnit] / $group[$targetUnit]);
192
193                                 $unit->denominator[$i] = $targetUnit;
194                         }
195                 }
196
197                 $unit->cancel();
198
199                 return new Less_Tree_Dimension( $value, $unit);
200     }
201 }