9 class Less_Tree_Dimension extends Less_Tree{
13 public $type = 'Dimension';
15 public function __construct($value, $unit = null){
16 $this->value = floatval($value);
18 if( $unit && ($unit instanceof Less_Tree_Unit) ){
21 $this->unit = new Less_Tree_Unit( array($unit) );
23 $this->unit = new Less_Tree_Unit( );
27 public function accept( $visitor ){
28 $this->unit = $visitor->visitObj( $this->unit );
31 public function compile(){
35 public function toColor() {
36 return new Less_Tree_Color(array($this->value, $this->value, $this->value));
40 * @see Less_Tree::genCSS
42 public function genCSS( $output ){
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());
48 $value = Less_Functions::fround( $this->value );
49 $strValue = (string)$value;
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);
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 );
64 // Float values doesn't need a leading zero
65 if( $value > 0 && $value < 1 && $strValue[0] === '0' ){
66 $strValue = substr($strValue,1);
70 $output->add( $strValue );
71 $this->unit->genCSS( $output );
74 public function __toString(){
75 return $this->toCSS();
78 // In an operation between two Dimensions,
79 // we default to the first Dimension's unit,
80 // so `1px + 2em` will yield `3px`.
85 public function operate( $op, $other){
87 $value = Less_Functions::operate( $op, $this->value, $other->value);
88 $unit = clone $this->unit;
90 if( $op === '+' || $op === '-' ){
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 ){
98 $other = $other->convertTo( $this->unit->usedUnits());
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() . "'.");
104 $value = Less_Functions::operate( $op, $this->value, $other->value);
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);
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);
119 return new Less_Tree_Dimension( $value, $unit);
122 public function compare($other) {
123 if ($other instanceof Less_Tree_Dimension) {
125 if( $this->unit->isEmpty() || $other->unit->isEmpty() ){
130 $b = $other->unify();
131 if( $a->unit->compare($b->unit) !== 0 ){
138 if ($bValue > $aValue) {
140 } elseif ($bValue < $aValue) {
150 public function unify() {
151 return $this->convertTo(array('length'=> 'px', 'duration'=> 's', 'angle' => 'rad' ));
154 public function convertTo($conversions) {
155 $value = $this->value;
156 $unit = clone $this->unit;
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);
165 $conversions = $derivedConversions;
169 foreach($conversions as $groupName => $targetUnit){
170 $group = Less_Tree_UnitConversions::${$groupName};
173 foreach($unit->numerator as $i => $atomicUnit){
174 $atomicUnit = $unit->numerator[$i];
175 if( !isset($group[$atomicUnit]) ){
179 $value = $value * ($group[$atomicUnit] / $group[$targetUnit]);
181 $unit->numerator[$i] = $targetUnit;
185 foreach($unit->denominator as $i => $atomicUnit){
186 $atomicUnit = $unit->denominator[$i];
187 if( !isset($group[$atomicUnit]) ){
191 $value = $value / ($group[$atomicUnit] / $group[$targetUnit]);
193 $unit->denominator[$i] = $targetUnit;
199 return new Less_Tree_Dimension( $value, $unit);