Skip to content

Commit

Permalink
Merge "Less_Functions: Avoid clobbering clamp() with internal helper"
Browse files Browse the repository at this point in the history
  • Loading branch information
jenkins-bot authored and Gerrit Code Review committed May 3, 2024
2 parents b965853 + 337108c commit e964e7b
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 84 deletions.
103 changes: 33 additions & 70 deletions lib/Less/Functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,11 @@ public function __construct( $env, array $currentFileInfo = null ) {
$this->currentFileInfo = $currentFileInfo;
}

/**
* @param string $op
* @param float $a
* @param float $b
*/
public static function operate( $op, $a, $b ) {
switch ( $op ) {
case '+':
return $a + $b;
case '-':
return $a - $b;
case '*':
return $a * $b;
case '/':
return $a / $b;
}
}

public static function clamp( $val, $max = 1 ) {
private static function _clamp( $val, $max = 1 ) {
return min( max( $val, 0 ), $max );
}

public static function fround( $value ) {
if ( $value === 0 ) {
return $value;
}

if ( Less_Parser::$options['numPrecision'] ) {
$p = pow( 10, Less_Parser::$options['numPrecision'] );
return round( $value * $p ) / $p;
}
return $value;
}

public static function number( $n ) {
private static function _number( $n ) {
if ( $n instanceof Less_Tree_Dimension ) {
return floatval( $n->unit->is( '%' ) ? $n->value / 100 : $n->value );
} elseif ( is_numeric( $n ) ) {
Expand All @@ -58,11 +28,11 @@ public static function number( $n ) {
}
}

public static function scaled( $n, $size = 255 ) {
private static function _scaled( $n, $size = 255 ) {
if ( $n instanceof Less_Tree_Dimension && $n->unit->is( '%' ) ) {
return (float)$n->value * $size / 100;
} else {
return self::number( $n );
return self::_number( $n );
}
}

Expand All @@ -74,10 +44,13 @@ public function rgb( $r = null, $g = null, $b = null ) {
}

public function rgba( $r = null, $g = null, $b = null, $a = null ) {
$rgb = [ $r, $g, $b ];
$rgb = array_map( [ __CLASS__, 'scaled' ], $rgb );
$rgb = [
self::_scaled( $r ),
self::_scaled( $g ),
self::_scaled( $b )
];

$a = self::number( $a );
$a = self::_number( $a );
return new Less_Tree_Color( $rgb, $a );
}

Expand All @@ -86,10 +59,10 @@ public function hsl( $h, $s, $l ) {
}

public function hsla( $h, $s, $l, $a ) {
$h = fmod( self::number( $h ), 360 ) / 360; // Classic % operator will change float to int
$s = self::clamp( self::number( $s ) );
$l = self::clamp( self::number( $l ) );
$a = self::clamp( self::number( $a ) );
$h = fmod( self::_number( $h ), 360 ) / 360; // Classic % operator will change float to int
$s = self::_clamp( self::_number( $s ) );
$l = self::_clamp( self::_number( $l ) );
$a = self::_clamp( self::_number( $a ) );

$m2 = $l <= 0.5 ? $l * ( $s + 1 ) : $l + $s - $l * $s;

Expand Down Expand Up @@ -132,10 +105,10 @@ public function hsv( $h, $s, $v ) {
* @param float $a
*/
public function hsva( $h, $s, $v, $a ) {
$h = ( ( self::number( $h ) % 360 ) / 360 ) * 360;
$s = self::number( $s );
$v = self::number( $v );
$a = self::number( $a );
$h = ( ( self::_number( $h ) % 360 ) / 360 ) * 360;
$s = self::_number( $s );
$v = self::_number( $v );
$a = self::_number( $a );

$i = (int)floor( (int)( $h / 60 ) % 6 );
$f = ( $h / 60 ) - $i;
Expand Down Expand Up @@ -292,7 +265,7 @@ public function saturate( $color = null, $amount = null, $method = null ) {
$hsl['s'] += $hsl['s'] * $amount->value / 100;
} else {
$hsl['s'] += $amount->value / 100;
} $hsl['s'] = self::clamp( $hsl['s'] );
} $hsl['s'] = self::_clamp( $hsl['s'] );

return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
Expand All @@ -317,7 +290,7 @@ public function desaturate( $color = null, $amount = null, $method = null ) {
$hsl['s'] -= $amount->value / 100;
}

$hsl['s'] = self::clamp( $hsl['s'] );
$hsl['s'] = self::_clamp( $hsl['s'] );

return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
Expand All @@ -338,7 +311,7 @@ public function lighten( $color = null, $amount = null, $method = null ) {
$hsl['l'] += $amount->value / 100;
}

$hsl['l'] = self::clamp( $hsl['l'] );
$hsl['l'] = self::_clamp( $hsl['l'] );

return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
Expand All @@ -357,7 +330,7 @@ public function darken( $color = null, $amount = null, $method = null ) {
} else {
$hsl['l'] -= $amount->value / 100;
}
$hsl['l'] = self::clamp( $hsl['l'] );
$hsl['l'] = self::_clamp( $hsl['l'] );

return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
Expand All @@ -378,7 +351,7 @@ public function fadein( $color = null, $amount = null, $method = null ) {
$hsl['a'] += $amount->value / 100;
}

$hsl['a'] = self::clamp( $hsl['a'] );
$hsl['a'] = self::_clamp( $hsl['a'] );
return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}

Expand All @@ -398,7 +371,7 @@ public function fadeout( $color = null, $amount = null, $method = null ) {
$hsl['a'] -= $amount->value / 100;
}

$hsl['a'] = self::clamp( $hsl['a'] );
$hsl['a'] = self::_clamp( $hsl['a'] );
return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}

Expand All @@ -413,7 +386,7 @@ public function fade( $color = null, $amount = null ) {
$hsl = $color->toHSL();

$hsl['a'] = $amount->value / 100;
$hsl['a'] = self::clamp( $hsl['a'] );
$hsl['a'] = self::_clamp( $hsl['a'] );
return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}

Expand Down Expand Up @@ -513,7 +486,7 @@ public function contrast( $color, $dark = null, $light = null, $threshold = null
if ( !$threshold ) {
$threshold = 0.43;
} else {
$threshold = self::number( $threshold );
$threshold = self::_number( $threshold );
}

if ( $color->luma() < $threshold ) {
Expand Down Expand Up @@ -562,7 +535,7 @@ public function replace( $string, $pattern, $replacement, $flags = null ) {
return new Less_Tree_Quoted( '', $result );
}

public static function replace_flags( $flags ) {
private static function replace_flags( $flags ) {
return str_replace( [ 'e', 'g' ], '', $flags );
}

Expand Down Expand Up @@ -696,8 +669,9 @@ private function _math( $fn, $unit, ...$args ) {
/**
* @param bool $isMin
* @param array<Less_Tree> $args
* @see less-2.5.3.js#minMax
*/
private function _minmax( $isMin, $args ) {
private function _minMax( $isMin, $args ) {
$arg_count = count( $args );

if ( $arg_count < 1 ) {
Expand Down Expand Up @@ -782,11 +756,11 @@ private function _minmax( $isMin, $args ) {
}

public function min( ...$args ) {
return $this->_minmax( true, $args );
return $this->_minMax( true, $args );
}

public function max( ...$args ) {
return $this->_minmax( false, $args );
return $this->_minMax( false, $args );
}

public function getunit( $n ) {
Expand Down Expand Up @@ -1054,17 +1028,6 @@ public function svggradient( $direction, ...$stops ) {
return new Less_Tree_Url( new Less_Tree_Anonymous( $returner ) );
}

/**
* Php version of javascript's `encodeURIComponent` function
*
* @param string $string The string to encode
* @return string The encoded string
*/
public static function encodeURIComponent( $string ) {
$revert = [ '%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')' ];
return strtr( rawurlencode( $string ), $revert );
}

// Color Blending
// ref: https://www.w3.org/TR/compositing-1/
public function colorBlend( $mode, $color1, $color2 ) {
Expand Down Expand Up @@ -1215,7 +1178,7 @@ public function average( $color1 = null, $color2 = null ) {
}

// non-w3c functions:
public function colorBlendAverage( $cb, $cs ) {
private function colorBlendAverage( $cb, $cs ) {
return ( $cb + $cs ) / 2;
}

Expand All @@ -1230,7 +1193,7 @@ public function negation( $color1 = null, $color2 = null ) {
return $this->colorBlend( [ $this, 'colorBlendNegation' ], $color1, $color2 );
}

public function colorBlendNegation( $cb, $cs ) {
private function colorBlendNegation( $cb, $cs ) {
return 1 - abs( $cb + $cs - 1 );
}

Expand Down
13 changes: 12 additions & 1 deletion lib/Less/SourceMap/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ public function __construct( Less_Tree_Ruleset $root, $contentsMap, $options = [
$this->options['sourceMapBasepath'] = $this->fixWindowsPath( $this->options['sourceMapBasepath'], true );
}

/**
* PHP version of JavaScript's `encodeURIComponent` function
*
* @param string $string The string to encode
* @return string The encoded string
*/
private static function encodeURIComponent( $string ) {
$revert = [ '%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')' ];
return strtr( rawurlencode( $string ), $revert );
}

/**
* Generates the CSS
*
Expand Down Expand Up @@ -122,7 +133,7 @@ public function generateCSS() {

// inline the map
if ( !$sourceMapUrl ) {
$sourceMapUrl = sprintf( 'data:application/json,%s', Less_Functions::encodeURIComponent( $sourceMapContent ) );
$sourceMapUrl = sprintf( 'data:application/json,%s', self::encodeURIComponent( $sourceMapContent ) );
}

if ( $sourceMapUrl ) {
Expand Down
35 changes: 35 additions & 0 deletions lib/Less/Tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,41 @@ public function compile( $env ) {
return $this;
}

/**
* @param string $op
* @param float $a
* @param float $b
* @see less-2.5.3.js#Node.prototype._operate
*/
protected function _operate( $op, $a, $b ) {
switch ( $op ) {
case '+':
return $a + $b;
case '-':
return $a - $b;
case '*':
return $a * $b;
case '/':
return $a / $b;
}
}

/**
* @see less-2.5.3.js#Node.prototype.fround
*/
protected function fround( $value ) {
if ( $value === 0 ) {
return $value;
}

// TODO: Migrate to passing $env.
if ( Less_Parser::$options['numPrecision'] ) {
$p = pow( 10, Less_Parser::$options['numPrecision'] );
return round( $value * $p ) / $p;
}
return $value;
}

/**
* @param Less_Output $output
* @param Less_Tree_Ruleset[] $rules
Expand Down
8 changes: 5 additions & 3 deletions lib/Less/Tree/Call.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,11 @@ public function compile( $env ) {
$result = Less_Tree_DefaultFunc::compile();
} else {
$func = null;
if ( method_exists( Less_Functions::class, $nameLC ) ) {
$functions = new Less_Functions( $env, $this->currentFileInfo );
$func = [ $functions, $nameLC ];
$functions = new Less_Functions( $env, $this->currentFileInfo );
$funcBuiltin = [ $functions, $nameLC ];
// Avoid method_exists() as that considers private utility functions too
if ( is_callable( $funcBuiltin ) ) {
$func = $funcBuiltin;
} elseif ( isset( $env->functions[$nameLC] ) && is_callable( $env->functions[$nameLC] ) ) {
$func = $env->functions[$nameLC];
}
Expand Down
18 changes: 14 additions & 4 deletions lib/Less/Tree/Color.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function genCSS( $output ) {

public function toCSS( $doNotCompress = false ) {
$compress = Less_Parser::$options['compress'] && !$doNotCompress;
$alpha = Less_Functions::fround( $this->alpha );
$alpha = $this->fround( $this->alpha );
if ( $this->value ) {
return $this->value;
}
Expand All @@ -72,7 +72,7 @@ public function toCSS( $doNotCompress = false ) {

$values = [];
foreach ( $this->rgb as $c ) {
$values[] = Less_Functions::clamp( round( $c ), 255 );
$values[] = $this->clamp( round( $c ), 255 );
}
$values[] = $alpha;

Expand Down Expand Up @@ -109,7 +109,7 @@ public function operate( $op, $other ) {
$rgb = [];
$alpha = $this->alpha * ( 1 - $other->alpha ) + $other->alpha;
for ( $c = 0; $c < 3; $c++ ) {
$rgb[$c] = Less_Functions::operate( $op, $this->rgb[$c], $other->rgb[$c] );
$rgb[$c] = $this->_operate( $op, $this->rgb[$c], $other->rgb[$c] );
}
return new self( $rgb, $alpha );
}
Expand Down Expand Up @@ -207,10 +207,20 @@ public function compare( $x ) {
$x->alpha === $this->alpha ) ? 0 : null;
}

/**
* @param int|float $val
* @param int $max
* @return int|float
* @see less-2.5.3.js#Color.prototype
*/
private function clamp( $val, $max ) {
return min( max( $val, 0 ), $max );
}

public function toHex( $v ) {
$ret = '#';
foreach ( $v as $c ) {
$c = Less_Functions::clamp( Less_Parser::round( $c ), 255 );
$c = $this->clamp( Less_Parser::round( $c ), 255 );
if ( $c < 16 ) {
$ret .= '0';
}
Expand Down

0 comments on commit e964e7b

Please sign in to comment.