2021-02-15 21:29:38 +01:00
< ? php
/**
2023-07-07 22:33:10 +02:00
* @ private
2021-02-15 21:29:38 +01:00
*/
class Less_Tree_Dimension extends Less_Tree {
public $value ;
public $unit ;
public $type = 'Dimension' ;
public function __construct ( $value , $unit = null ) {
$this -> value = floatval ( $value );
if ( $unit && ( $unit instanceof Less_Tree_Unit ) ) {
$this -> unit = $unit ;
} elseif ( $unit ) {
2023-07-07 22:33:10 +02:00
$this -> unit = new Less_Tree_Unit ( [ $unit ] );
2021-02-15 21:29:38 +01:00
} else {
$this -> unit = new Less_Tree_Unit ();
}
}
public function accept ( $visitor ) {
$this -> unit = $visitor -> visitObj ( $this -> unit );
}
public function toColor () {
2023-07-07 22:33:10 +02:00
return new Less_Tree_Color ( [ $this -> value , $this -> value , $this -> value ] );
2021-02-15 21:29:38 +01:00
}
/**
* @ see Less_Tree :: genCSS
*/
public function genCSS ( $output ) {
if ( Less_Parser :: $options [ 'strictUnits' ] && ! $this -> unit -> isSingular () ) {
2023-07-07 22:33:10 +02:00
throw new Less_Exception_Compiler ( " Multiple units in dimension. Correct the units or use the unit function. Bad unit: " . $this -> unit -> toString () );
2021-02-15 21:29:38 +01:00
}
$value = Less_Functions :: fround ( $this -> value );
$strValue = ( string ) $value ;
if ( $value !== 0 && $value < 0.000001 && $value > - 0.000001 ) {
// would be output 1e-6 etc.
2023-07-07 22:33:10 +02:00
$strValue = number_format ( ( float ) $strValue , 10 );
2021-02-15 21:29:38 +01:00
$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 );
2023-07-07 22:33:10 +02:00
return ;
2021-02-15 21:29:38 +01:00
}
// 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 () {
2023-07-07 22:33:10 +02:00
return $this -> convertTo ( [ 'length' => 'px' , 'duration' => 's' , 'angle' => 'rad' ] );
2021-02-15 21:29:38 +01:00
}
public function convertTo ( $conversions ) {
$value = $this -> value ;
$unit = clone $this -> unit ;
if ( is_string ( $conversions ) ) {
2023-07-07 22:33:10 +02:00
$derivedConversions = [];
2021-02-15 21:29:38 +01:00
foreach ( Less_Tree_UnitConversions :: $groups as $i ) {
if ( isset ( Less_Tree_UnitConversions :: ${$i} [ $conversions ] ) ) {
2023-07-07 22:33:10 +02:00
$derivedConversions = [ $i => $conversions ];
2021-02-15 21:29:38 +01:00
}
}
$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 );
}
}