Skip to content

Commit b037cd5

Browse files
committed
MDL-79666 libraries: upgrade to version 1.12.1 of ScssPhp.
1 parent 810554e commit b037cd5

File tree

7 files changed

+160
-39
lines changed

7 files changed

+160
-39
lines changed

lib/scssphp/Block/CallableBlock.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
use ScssPhp\ScssPhp\Block;
1616
use ScssPhp\ScssPhp\Compiler\Environment;
17+
use ScssPhp\ScssPhp\Node\Number;
1718

1819
/**
1920
* @internal
@@ -26,7 +27,7 @@ class CallableBlock extends Block
2627
public $name;
2728

2829
/**
29-
* @var array|null
30+
* @var list<array{string, array|Number|null, bool}>|null
3031
*/
3132
public $args;
3233

lib/scssphp/Compiler.php

+72-30
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,33 @@ public function compile($code, $path = null)
458458
}
459459

460460
/**
461-
* Compile scss
461+
* Compiles the provided scss file into CSS.
462+
*
463+
* @param string $path
464+
*
465+
* @return CompilationResult
466+
*
467+
* @throws SassException when the source fails to compile
468+
*/
469+
public function compileFile($path)
470+
{
471+
$source = file_get_contents($path);
472+
473+
if ($source === false) {
474+
throw new \RuntimeException('Could not read the file content');
475+
}
476+
477+
return $this->compileString($source, $path);
478+
}
479+
480+
/**
481+
* Compiles the provided scss source code into CSS.
482+
*
483+
* If provided, the path is considered to be the path from which the source code comes
484+
* from, which will be used to resolve relative imports.
462485
*
463486
* @param string $source
464-
* @param string|null $path
487+
* @param string|null $path The path for the source, used to resolve relative imports
465488
*
466489
* @return CompilationResult
467490
*
@@ -548,7 +571,7 @@ public function compileString($source, $path = null)
548571

549572
$sourceMap = null;
550573

551-
if (! empty($out) && $this->sourceMap && $this->sourceMap !== self::SOURCE_MAP_NONE) {
574+
if (! empty($out) && $this->sourceMap !== self::SOURCE_MAP_NONE && $this->sourceMap) {
552575
assert($sourceMapGenerator !== null);
553576
$sourceMap = $sourceMapGenerator->generateJson($prefix);
554577
$sourceMapUrl = null;
@@ -1508,6 +1531,7 @@ protected function filterScopeWithWithout($scope, $with, $without)
15081531
// start from the root
15091532
while ($scope->parent && $scope->parent->type !== Type::T_ROOT) {
15101533
array_unshift($childStash, $scope);
1534+
\assert($scope->parent !== null);
15111535
$scope = $scope->parent;
15121536
}
15131537

@@ -2090,6 +2114,11 @@ protected function collapseSelectors($selectors)
20902114
foreach ($selector as $node) {
20912115
$compound = '';
20922116

2117+
if (!is_array($node)) {
2118+
$output[] = $node;
2119+
continue;
2120+
}
2121+
20932122
array_walk_recursive(
20942123
$node,
20952124
function ($value, $key) use (&$compound) {
@@ -2124,12 +2153,16 @@ private function collapseSelectorsAsList($selectors)
21242153
foreach ($selector as $node) {
21252154
$compound = '';
21262155

2127-
array_walk_recursive(
2128-
$node,
2129-
function ($value, $key) use (&$compound) {
2130-
$compound .= $value;
2131-
}
2132-
);
2156+
if (!is_array($node)) {
2157+
$compound .= $node;
2158+
} else {
2159+
array_walk_recursive(
2160+
$node,
2161+
function ($value, $key) use (&$compound) {
2162+
$compound .= $value;
2163+
}
2164+
);
2165+
}
21332166

21342167
if ($this->isImmediateRelationshipCombinator($compound)) {
21352168
if (\count($output)) {
@@ -2885,7 +2918,7 @@ protected function compileChild($child, OutputBlock $out)
28852918
{
28862919
if (isset($child[Parser::SOURCE_LINE])) {
28872920
$this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
2888-
$this->sourceLine = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
2921+
$this->sourceLine = $child[Parser::SOURCE_LINE];
28892922
$this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
28902923
} elseif (\is_array($child) && isset($child[1]->sourceLine) && $child[1] instanceof Block) {
28912924
$this->sourceIndex = $child[1]->sourceIndex;
@@ -4529,8 +4562,10 @@ public function compileValue($value, $quote = true)
45294562
return $colorName;
45304563
}
45314564

4532-
if (is_numeric($alpha)) {
4565+
if (\is_int($alpha) || \is_float($alpha)) {
45334566
$a = new Number($alpha, '');
4567+
} elseif (is_numeric($alpha)) {
4568+
$a = new Number((float) $alpha, '');
45344569
} else {
45354570
$a = $alpha;
45364571
}
@@ -5806,13 +5841,13 @@ public function findImport($url, $currentDir = null)
58065841

58075842
if (! \is_null($file)) {
58085843
if (\is_array($dir)) {
5809-
$callableDescription = (\is_object($dir[0]) ? \get_class($dir[0]) : $dir[0]).'::'.$dir[1];
5844+
$callableDescription = (\is_object($dir[0]) ? \get_class($dir[0]) : $dir[0]) . '::' . $dir[1];
58105845
} elseif ($dir instanceof \Closure) {
58115846
$r = new \ReflectionFunction($dir);
58125847
if (false !== strpos($r->name, '{closure}')) {
58135848
$callableDescription = sprintf('closure{%s:%s}', $r->getFileName(), $r->getStartLine());
58145849
} elseif ($class = $r->getClosureScopeClass()) {
5815-
$callableDescription = $class->name.'::'.$r->name;
5850+
$callableDescription = $class->name . '::' . $r->name;
58165851
} else {
58175852
$callableDescription = $r->name;
58185853
}
@@ -5925,15 +5960,15 @@ private function checkImportPathConflicts(array $paths)
59255960
private function tryImportPathWithExtensions($path)
59265961
{
59275962
$result = array_merge(
5928-
$this->tryImportPath($path.'.sass'),
5929-
$this->tryImportPath($path.'.scss')
5963+
$this->tryImportPath($path . '.sass'),
5964+
$this->tryImportPath($path . '.scss')
59305965
);
59315966

59325967
if ($result) {
59335968
return $result;
59345969
}
59355970

5936-
return $this->tryImportPath($path.'.css');
5971+
return $this->tryImportPath($path . '.css');
59375972
}
59385973

59395974
/**
@@ -5943,7 +5978,7 @@ private function tryImportPathWithExtensions($path)
59435978
*/
59445979
private function tryImportPath($path)
59455980
{
5946-
$partial = dirname($path).'/_'.basename($path);
5981+
$partial = dirname($path) . '/_' . basename($path);
59475982

59485983
$candidates = [];
59495984

@@ -5969,7 +6004,7 @@ private function tryImportPathAsDirectory($path)
59696004
return null;
59706005
}
59716006

5972-
return $this->checkImportPathConflicts($this->tryImportPathWithExtensions($path.'/index'));
6007+
return $this->checkImportPathConflicts($this->tryImportPathWithExtensions($path . '/index'));
59736008
}
59746009

59756010
/**
@@ -5984,7 +6019,7 @@ private function getPrettyPath($path)
59846019
}
59856020

59866021
$normalizedPath = $path;
5987-
$normalizedRootDirectory = $this->rootDirectory.'/';
6022+
$normalizedRootDirectory = $this->rootDirectory . '/';
59886023

59896024
if (\DIRECTORY_SEPARATOR === '\\') {
59906025
$normalizedRootDirectory = str_replace('\\', '/', $normalizedRootDirectory);
@@ -6371,8 +6406,6 @@ public static function isNativeFunction($name)
63716406
*/
63726407
protected function sortNativeFunctionArgs($functionName, $prototypes, $args)
63736408
{
6374-
static $parser = null;
6375-
63766409
if (! isset($prototypes)) {
63776410
$keyArgs = [];
63786411
$posArgs = [];
@@ -6526,7 +6559,7 @@ private function parseFunctionPrototype(array $prototype)
65266559
*
65276560
* @return array
65286561
*
6529-
* @phpstan-param non-empty-list<array{arguments: list<array{0: string, 1: string, 2: array|Number|null}>, rest_argument: string|null}> $prototypes
6562+
* @phpstan-param non-empty-array<array{arguments: list<array{0: string, 1: string, 2: array|Number|null}>, rest_argument: string|null}> $prototypes
65306563
* @phpstan-return array{arguments: list<array{0: string, 1: string, 2: array|Number|null}>, rest_argument: string|null}
65316564
*/
65326565
private function selectFunctionPrototype(array $prototypes, $positional, array $names)
@@ -6984,10 +7017,14 @@ protected function coerceValue($value)
69847017
return static::$null;
69857018
}
69867019

6987-
if (is_numeric($value)) {
7020+
if (\is_int($value) || \is_float($value)) {
69887021
return new Number($value, '');
69897022
}
69907023

7024+
if (is_numeric($value)) {
7025+
return new Number((float) $value, '');
7026+
}
7027+
69917028
if ($value === '') {
69927029
return static::$emptyString;
69937030
}
@@ -7675,9 +7712,9 @@ private function HWBtoRGB($hue, $whiteness, $blackness)
76757712
$b = min(1.0 - $w, $b);
76767713

76777714
$rgb = $this->toRGB($hue, 100, 50);
7678-
for($i = 1; $i < 4; $i++) {
7679-
$rgb[$i] *= (1.0 - $w - $b);
7680-
$rgb[$i] = round($rgb[$i] + 255 * $w + 0.0001);
7715+
for ($i = 1; $i < 4; $i++) {
7716+
$rgb[$i] *= (1.0 - $w - $b);
7717+
$rgb[$i] = round($rgb[$i] + 255 * $w + 0.0001);
76817718
}
76827719

76837720
return $rgb;
@@ -7704,7 +7741,6 @@ private function RGBtoHWB($red, $green, $blue)
77047741
if ((int) $d === 0) {
77057742
$h = 0;
77067743
} else {
7707-
77087744
if ($red == $max) {
77097745
$h = 60 * ($green - $blue) / $d;
77107746
} elseif ($green == $max) {
@@ -7714,7 +7750,7 @@ private function RGBtoHWB($red, $green, $blue)
77147750
}
77157751
}
77167752

7717-
return [Type::T_HWB, fmod($h, 360), $min / 255 * 100, 100 - $max / 255 *100];
7753+
return [Type::T_HWB, fmod($h, 360), $min / 255 * 100, 100 - $max / 255 * 100];
77187754
}
77197755

77207756

@@ -7923,7 +7959,13 @@ protected function alterColor(array $args, $operation, $fn)
79237959
$scale = $operation === 'scale';
79247960
$change = $operation === 'change';
79257961

7926-
/** @phpstan-var callable(string, float|int, bool=, bool=): (float|int|null) $getParam */
7962+
/**
7963+
* @param string $name
7964+
* @param float|int $max
7965+
* @param bool $checkPercent
7966+
* @param bool $assertPercent
7967+
* @return float|int|null
7968+
*/
79277969
$getParam = function ($name, $max, $checkPercent = false, $assertPercent = false) use (&$kwargs, $scale, $change) {
79287970
if (!isset($kwargs[$name])) {
79297971
return null;
@@ -8065,7 +8107,7 @@ protected function libAdjustColor($args)
80658107
protected static $libChangeColor = ['color', 'kwargs...'];
80668108
protected function libChangeColor($args)
80678109
{
8068-
return $this->alterColor($args,'change', function ($base, $alter, $max) {
8110+
return $this->alterColor($args, 'change', function ($base, $alter, $max) {
80698111
if ($alter === null) {
80708112
return $base;
80718113
}

lib/scssphp/Node/Number.php

+14-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
*
3434
* @template-implements \ArrayAccess<int, mixed>
3535
*/
36-
class Number extends Node implements \ArrayAccess
36+
class Number extends Node implements \ArrayAccess, \JsonSerializable
3737
{
3838
const PRECISION = 10;
3939

@@ -131,21 +131,31 @@ public function getDimension()
131131
}
132132

133133
/**
134-
* @return string[]
134+
* @return list<string>
135135
*/
136136
public function getNumeratorUnits()
137137
{
138138
return $this->numeratorUnits;
139139
}
140140

141141
/**
142-
* @return string[]
142+
* @return list<string>
143143
*/
144144
public function getDenominatorUnits()
145145
{
146146
return $this->denominatorUnits;
147147
}
148148

149+
/**
150+
* @return mixed
151+
*/
152+
#[\ReturnTypeWillChange]
153+
public function jsonSerialize()
154+
{
155+
// Passing a compiler instance makes the method output a Sass representation instead of a CSS one, supporting full units.
156+
return $this->output(new Compiler());
157+
}
158+
149159
/**
150160
* @return bool
151161
*/
@@ -554,7 +564,7 @@ public function equals(Number $other)
554564

555565
try {
556566
return $this->coerceUnits($other, function ($num1, $num2) {
557-
return round($num1,self::PRECISION) == round($num2, self::PRECISION);
567+
return round($num1, self::PRECISION) == round($num2, self::PRECISION);
558568
});
559569
} catch (SassScriptException $e) {
560570
return false;

lib/scssphp/OutputStyle.php

+53
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,62 @@
11
<?php
22

3+
/**
4+
* SCSSPHP
5+
*
6+
* @copyright 2012-2020 Leaf Corcoran
7+
*
8+
* @license http://opensource.org/licenses/MIT MIT
9+
*
10+
* @link http://scssphp.github.io/scssphp
11+
*/
12+
313
namespace ScssPhp\ScssPhp;
414

515
final class OutputStyle
616
{
717
const EXPANDED = 'expanded';
818
const COMPRESSED = 'compressed';
19+
20+
/**
21+
* Converts a string to an output style.
22+
*
23+
* Using this method allows to write code which will support both
24+
* versions 1.12+ and 2.0 of Scssphp. In 2.0, OutputStyle will be
25+
* an enum instead of using string constants.
26+
*
27+
* @param string $string
28+
*
29+
* @return self::*
30+
*/
31+
public static function fromString($string)
32+
{
33+
switch ($string) {
34+
case 'expanded':
35+
return self::EXPANDED;
36+
37+
case 'compressed':
38+
return self::COMPRESSED;
39+
40+
default:
41+
throw new \InvalidArgumentException('Invalid output style');
42+
}
43+
}
44+
45+
/**
46+
* Converts an output style to a string supported by {@see OutputStyle::fromString()}.
47+
*
48+
* Using this method allows to write code which will support both
49+
* versions 1.12+ and 2.0 of Scssphp. In 2.0, OutputStyle will be
50+
* an enum instead of using string constants.
51+
* The returned string representation is guaranteed to be compatible
52+
* between 1.12 and 2.0.
53+
*
54+
* @param self::* $outputStyle
55+
*
56+
* @return string
57+
*/
58+
public static function toString($outputStyle)
59+
{
60+
return $outputStyle;
61+
}
962
}

0 commit comments

Comments
 (0)