value = floatval( $value ); if ( $unit && ( $unit instanceof Less_Tree_Unit ) ) { $this->unit = $unit; } elseif ( $unit ) { $this->unit = new Less_Tree_Unit( array( $unit ) ); } else { $this->unit = new Less_Tree_Unit(); } } public function accept( $visitor ) { $this->unit = $visitor->visitObj( $this->unit ); } public function compile() { return $this; } public function toColor() { return new Less_Tree_Color( array( $this->value, $this->value, $this->value ) ); } /** * @see Less_Tree::genCSS */ public function genCSS( $output ) { if ( Less_Parser::$options['strictUnits'] && !$this->unit->isSingular() ) { throw new Less_Exception_Compiler( "Multiple units in dimension. Correct the units or use the unit function. Bad unit: ".$this->unit->toString() ); } $value = Less_Functions::fround( $this->value ); $strValue = (string)$value; if ( $value !== 0 && $value < 0.000001 && $value > -0.000001 ) { // would be output 1e-6 etc. $strValue = number_format( $strValue, 10 ); $strValue = preg_replace( '/\.?0+$/', '', $strValue ); } if ( Less_Parser::$options['compress'] ) { // Zero values doesn't need a unit if ( $value === 0 && $this->unit->isLength() ) { $output->add( $strValue ); return $strValue; } // Float values doesn't need a leading zero if ( $value > 0 && $value < 1 && $strValue[0] === '0' ) { $strValue = substr( $strValue, 1 ); } } $output->add( $strValue ); $this->unit->genCSS( $output ); } public function __toString() { return $this->toCSS(); } // In an operation between two Dimensions, // we default to the first Dimension's unit, // so `1px + 2em` will yield `3px`. /** * @param string $op */ public function operate( $op, $other ) { $value = Less_Functions::operate( $op, $this->value, $other->value ); $unit = clone $this->unit; if ( $op === '+' || $op === '-' ) { if ( !$unit->numerator && !$unit->denominator ) { $unit->numerator = $other->unit->numerator; $unit->denominator = $other->unit->denominator; } elseif ( !$other->unit->numerator && !$other->unit->denominator ) { // do nothing } else { $other = $other->convertTo( $this->unit->usedUnits() ); if ( Less_Parser::$options['strictUnits'] && $other->unit->toString() !== $unit->toCSS() ) { throw new Less_Exception_Compiler( "Incompatible units. Change the units or use the unit function. Bad units: '" . $unit->toString() . "' and " . $other->unit->toString() . "'." ); } $value = Less_Functions::operate( $op, $this->value, $other->value ); } } elseif ( $op === '*' ) { $unit->numerator = array_merge( $unit->numerator, $other->unit->numerator ); $unit->denominator = array_merge( $unit->denominator, $other->unit->denominator ); sort( $unit->numerator ); sort( $unit->denominator ); $unit->cancel(); } elseif ( $op === '/' ) { $unit->numerator = array_merge( $unit->numerator, $other->unit->denominator ); $unit->denominator = array_merge( $unit->denominator, $other->unit->numerator ); sort( $unit->numerator ); sort( $unit->denominator ); $unit->cancel(); } return new Less_Tree_Dimension( $value, $unit ); } public function compare( $other ) { if ( $other instanceof Less_Tree_Dimension ) { if ( $this->unit->isEmpty() || $other->unit->isEmpty() ) { $a = $this; $b = $other; } else { $a = $this->unify(); $b = $other->unify(); if ( $a->unit->compare( $b->unit ) !== 0 ) { return -1; } } $aValue = $a->value; $bValue = $b->value; if ( $bValue > $aValue ) { return -1; } elseif ( $bValue < $aValue ) { return 1; } else { return 0; } } else { return -1; } } public function unify() { return $this->convertTo( array( 'length' => 'px', 'duration' => 's', 'angle' => 'rad' ) ); } public function convertTo( $conversions ) { $value = $this->value; $unit = clone $this->unit; if ( is_string( $conversions ) ) { $derivedConversions = array(); foreach ( Less_Tree_UnitConversions::$groups as $i ) { if ( isset( Less_Tree_UnitConversions::${$i}[$conversions] ) ) { $derivedConversions = array( $i => $conversions ); } } $conversions = $derivedConversions; } foreach ( $conversions as $groupName => $targetUnit ) { $group = Less_Tree_UnitConversions::${$groupName}; // numerator foreach ( $unit->numerator as $i => $atomicUnit ) { $atomicUnit = $unit->numerator[$i]; if ( !isset( $group[$atomicUnit] ) ) { continue; } $value = $value * ( $group[$atomicUnit] / $group[$targetUnit] ); $unit->numerator[$i] = $targetUnit; } // denominator foreach ( $unit->denominator as $i => $atomicUnit ) { $atomicUnit = $unit->denominator[$i]; if ( !isset( $group[$atomicUnit] ) ) { continue; } $value = $value / ( $group[$atomicUnit] / $group[$targetUnit] ); $unit->denominator[$i] = $targetUnit; } } $unit->cancel(); return new Less_Tree_Dimension( $value, $unit ); } }