From 83758607cd3a0574025dfa682df29329f9d5319b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 20 Sep 2021 16:07:25 +0200 Subject: [PATCH] Update scssphp/scssphp to 1.8.1 This is for PHP 8.1 compatibility. --- .../files/lib/system/api/composer.lock | 13 +- .../lib/system/api/composer/installed.json | 17 +- .../lib/system/api/composer/installed.php | 8 +- .../lib/system/api/scssphp/scssphp/bin/pscss | 6 +- .../system/api/scssphp/scssphp/composer.json | 27 +++- .../api/scssphp/scssphp/src/Compiler.php | 150 +++++++++++++----- .../api/scssphp/scssphp/src/Node/Number.php | 4 + .../system/api/scssphp/scssphp/src/Parser.php | 4 +- .../api/scssphp/scssphp/src/Version.php | 2 +- 9 files changed, 161 insertions(+), 70 deletions(-) diff --git a/wcfsetup/install/files/lib/system/api/composer.lock b/wcfsetup/install/files/lib/system/api/composer.lock index 39cb52b399..77e7e850e1 100644 --- a/wcfsetup/install/files/lib/system/api/composer.lock +++ b/wcfsetup/install/files/lib/system/api/composer.lock @@ -1268,16 +1268,16 @@ }, { "name": "scssphp/scssphp", - "version": "v1.6.0", + "version": "v1.8.1", "source": { "type": "git", "url": "https://github.com/scssphp/scssphp.git", - "reference": "b83594e2323c5d6e80785df3f91b9d1d32aad530" + "reference": "5e37759a63caf54392a4b709358a39ac7425a69f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/scssphp/zipball/b83594e2323c5d6e80785df3f91b9d1d32aad530", - "reference": "b83594e2323c5d6e80785df3f91b9d1d32aad530", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/5e37759a63caf54392a4b709358a39ac7425a69f", + "reference": "5e37759a63caf54392a4b709358a39ac7425a69f", "shasum": "" }, "require": { @@ -1291,6 +1291,7 @@ "sass/sass-spec": "*", "squizlabs/php_codesniffer": "~3.5", "symfony/phpunit-bridge": "^5.1", + "thoughtbot/bourbon": "^7.0", "twbs/bootstrap": "~5.0", "twbs/bootstrap4": "4.6.0", "zurb/foundation": "~6.5" @@ -1335,9 +1336,9 @@ ], "support": { "issues": "https://github.com/scssphp/scssphp/issues", - "source": "https://github.com/scssphp/scssphp/tree/v1.6.0" + "source": "https://github.com/scssphp/scssphp/tree/v1.8.1" }, - "time": "2021-07-02T16:28:10+00:00" + "time": "2021-09-18T21:20:53+00:00" }, { "name": "symfony/css-selector", diff --git a/wcfsetup/install/files/lib/system/api/composer/installed.json b/wcfsetup/install/files/lib/system/api/composer/installed.json index cd82eb334b..ea20c260ec 100644 --- a/wcfsetup/install/files/lib/system/api/composer/installed.json +++ b/wcfsetup/install/files/lib/system/api/composer/installed.json @@ -1296,17 +1296,17 @@ }, { "name": "scssphp/scssphp", - "version": "v1.6.0", - "version_normalized": "1.6.0.0", + "version": "v1.8.1", + "version_normalized": "1.8.1.0", "source": { "type": "git", "url": "https://github.com/scssphp/scssphp.git", - "reference": "b83594e2323c5d6e80785df3f91b9d1d32aad530" + "reference": "5e37759a63caf54392a4b709358a39ac7425a69f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/scssphp/zipball/b83594e2323c5d6e80785df3f91b9d1d32aad530", - "reference": "b83594e2323c5d6e80785df3f91b9d1d32aad530", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/5e37759a63caf54392a4b709358a39ac7425a69f", + "reference": "5e37759a63caf54392a4b709358a39ac7425a69f", "shasum": "" }, "require": { @@ -1320,6 +1320,7 @@ "sass/sass-spec": "*", "squizlabs/php_codesniffer": "~3.5", "symfony/phpunit-bridge": "^5.1", + "thoughtbot/bourbon": "^7.0", "twbs/bootstrap": "~5.0", "twbs/bootstrap4": "4.6.0", "zurb/foundation": "~6.5" @@ -1328,7 +1329,7 @@ "ext-iconv": "Can be used as fallback when ext-mbstring is not available", "ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv" }, - "time": "2021-07-02T16:28:10+00:00", + "time": "2021-09-18T21:20:53+00:00", "bin": [ "bin/pscss" ], @@ -1366,7 +1367,7 @@ ], "support": { "issues": "https://github.com/scssphp/scssphp/issues", - "source": "https://github.com/scssphp/scssphp/tree/v1.6.0" + "source": "https://github.com/scssphp/scssphp/tree/v1.8.1" }, "install-path": "../scssphp/scssphp" }, @@ -1571,6 +1572,6 @@ "install-path": "../true/punycode" } ], - "dev": true, + "dev": false, "dev-package-names": [] } diff --git a/wcfsetup/install/files/lib/system/api/composer/installed.php b/wcfsetup/install/files/lib/system/api/composer/installed.php index 5ef8dfbe90..ff9bcb2ee4 100644 --- a/wcfsetup/install/files/lib/system/api/composer/installed.php +++ b/wcfsetup/install/files/lib/system/api/composer/installed.php @@ -7,7 +7,7 @@ 'aliases' => array(), 'reference' => NULL, 'name' => '__root__', - 'dev' => true, + 'dev' => false, ), 'versions' => array( '__root__' => array( @@ -218,12 +218,12 @@ 'dev_requirement' => false, ), 'scssphp/scssphp' => array( - 'pretty_version' => 'v1.6.0', - 'version' => '1.6.0.0', + 'pretty_version' => 'v1.8.1', + 'version' => '1.8.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../scssphp/scssphp', 'aliases' => array(), - 'reference' => 'b83594e2323c5d6e80785df3f91b9d1d32aad530', + 'reference' => '5e37759a63caf54392a4b709358a39ac7425a69f', 'dev_requirement' => false, ), 'symfony/css-selector' => array( diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss index 18c136acb9..e62239830f 100644 --- a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss +++ b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss @@ -26,7 +26,7 @@ use ScssPhp\ScssPhp\Parser; use ScssPhp\ScssPhp\Version; $style = null; -$loadPaths = null; +$loadPaths = []; $dumpTree = false; $inputFile = null; $changeDir = false; @@ -148,7 +148,7 @@ EOT; $value = parseArgument($i, array('-I', '--load-path')); if (isset($value)) { - $loadPaths = $value; + $loadPaths[] = $value; continue; } @@ -188,7 +188,7 @@ if ($dumpTree) { $scss = new Compiler(); if ($loadPaths) { - $scss->setImportPaths(explode(PATH_SEPARATOR, $loadPaths)); + $scss->setImportPaths($loadPaths); } if ($style) { diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json index 1c6d7625c5..86cd396bf7 100644 --- a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json +++ b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json @@ -40,6 +40,7 @@ "sass/sass-spec": "*", "squizlabs/php_codesniffer": "~3.5", "symfony/phpunit-bridge": "^5.1", + "thoughtbot/bourbon": "^7.0", "twbs/bootstrap": "~5.0", "twbs/bootstrap4": "4.6.0", "zurb/foundation": "~6.5" @@ -49,16 +50,34 @@ "type": "package", "package": { "name": "sass/sass-spec", - "version": "2021.06.30", + "version": "2021.09.15", "source": { "type": "git", "url": "https://github.com/sass/sass-spec.git", - "reference": "e348959657f1e274cef658283436a311a925a673" + "reference": "eb2d7a0865c1faf0b55a39ff962b24aca9b4c955" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sass/sass-spec/zipball/e348959657f1e274cef658283436a311a925a673", - "reference": "e348959657f1e274cef658283436a311a925a673", + "url": "https://api.github.com/repos/sass/sass-spec/zipball/eb2d7a0865c1faf0b55a39ff962b24aca9b4c955", + "reference": "eb2d7a0865c1faf0b55a39ff962b24aca9b4c955", + "shasum": "" + } + } + }, + { + "type": "package", + "package": { + "name": "thoughtbot/bourbon", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/thoughtbot/bourbon.git", + "reference": "fbe338ee6807e7f7aa996d82c8a16f248bb149b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thoughtbot/bourbon/zipball/fbe338ee6807e7f7aa996d82c8a16f248bb149b3", + "reference": "fbe338ee6807e7f7aa996d82c8a16f248bb149b3", "shasum": "" } } diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php index b9d42bb1df..58ba795ab8 100644 --- a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php +++ b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php @@ -193,6 +193,11 @@ class Compiler */ protected $sourceMapOptions = []; + /** + * @var bool + */ + private $charset = true; + /** * @var string|\ScssPhp\ScssPhp\Formatter */ @@ -221,6 +226,8 @@ class Compiler protected $storeEnv; /** * @var bool|null + * + * @deprecated */ protected $charsetSeen; /** @@ -463,7 +470,6 @@ class Compiler $this->env = null; $this->scope = null; $this->storeEnv = null; - $this->charsetSeen = null; $this->shouldEvaluate = null; $this->ignoreCallStackMessage = false; $this->parsedFiles = []; @@ -516,11 +522,9 @@ class Compiler $prefix = ''; - if (!$this->charsetSeen) { - if (strlen($out) !== Util::mbStrlen($out)) { - $prefix = '@charset "UTF-8";' . "\n"; - $out = $prefix . $out; - } + if ($this->charset && strlen($out) !== Util::mbStrlen($out)) { + $prefix = '@charset "UTF-8";' . "\n"; + $out = $prefix . $out; } $sourceMap = null; @@ -2877,10 +2881,6 @@ class Compiler break; case Type::T_CHARSET: - if (! $this->charsetSeen) { - $this->charsetSeen = true; - $this->appendRootDirective('@charset ' . $this->compileValue($child[1]) . ';', $out); - } break; case Type::T_CUSTOM_PROPERTY: @@ -3827,7 +3827,6 @@ EOL; // try to find a native lib function $normalizedName = $this->normalizeName($name); - $libName = null; if (isset($this->userFunctions[$normalizedName])) { // see if we can find a user function @@ -3836,10 +3835,45 @@ EOL; return [Type::T_FUNCTION_REFERENCE, 'user', $name, $f, $prototype]; } + $lowercasedName = strtolower($normalizedName); + + // Special functions overriding a CSS function are case-insensitive. We normalize them as lowercase + // to avoid the deprecation warning about the wrong case being used. + if ($lowercasedName === 'min' || $lowercasedName === 'max') { + $normalizedName = $lowercasedName; + } + if (($f = $this->getBuiltinFunction($normalizedName)) && \is_callable($f)) { $libName = $f[1]; $prototype = isset(static::$$libName) ? static::$$libName : null; + // All core functions have a prototype defined. Not finding the + // prototype can mean 2 things: + // - the function comes from a child class (deprecated just after) + // - the function was found with a different case, which relates to calling the + // wrong Sass function due to our camelCase usage (`fade-in()` vs `fadein()`), + // because PHP method names are case-insensitive while property names are + // case-sensitive. + if ($prototype === null || strtolower($normalizedName) !== $normalizedName) { + $r = new \ReflectionMethod($this, $libName); + $actualLibName = $r->name; + + if ($actualLibName !== $libName || strtolower($normalizedName) !== $normalizedName) { + $kebabCaseName = preg_replace('~(?<=\\w)([A-Z])~', '-$1', substr($actualLibName, 3)); + assert($kebabCaseName !== null); + $originalName = strtolower($kebabCaseName); + $warning = "Calling built-in functions with a non-standard name is deprecated since Scssphp 1.8.0 and will not work anymore in 2.0 (they will be treated as CSS function calls instead).\nUse \"$originalName\" instead of \"$name\"."; + @trigger_error($warning, E_USER_DEPRECATED); + $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); + $line = $this->sourceLine; + Warn::deprecation("$warning\n on line $line of $fname"); + + // Use the actual function definition + $prototype = isset(static::$$actualLibName) ? static::$$actualLibName : null; + $f[1] = $libName = $actualLibName; + } + } + if (\get_class($this) !== __CLASS__ && !isset($this->warnedChildFunctions[$libName])) { $r = new \ReflectionMethod($this, $libName); $declaringClass = $r->getDeclaringClass()->name; @@ -5498,6 +5532,25 @@ EOL; . 'Use source maps instead.', E_USER_DEPRECATED); } + /** + * Configures the handling of non-ASCII outputs. + * + * If $charset is `true`, this will include a `@charset` declaration or a + * UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII + * characters. Otherwise, it will never include a `@charset` declaration or a + * byte-order mark. + * + * [byte-order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 + * + * @param bool $charset + * + * @return void + */ + public function setCharset($charset) + { + $this->charset = $charset; + } + /** * Enable/disable source maps * @@ -5872,7 +5925,7 @@ EOL; } if (0 === strpos($normalizedPath, $normalizedRootDirectory)) { - return substr($normalizedPath, \strlen($normalizedRootDirectory)); + return substr($path, \strlen($normalizedRootDirectory)); } return $path; @@ -7209,9 +7262,13 @@ EOL; * @param array|Number $value * * @return integer|float + * + * @deprecated */ protected function coercePercent($value) { + @trigger_error(sprintf('"%s" is deprecated since 1.7.0.', __METHOD__), E_USER_DEPRECATED); + if ($value instanceof Number) { if ($value->hasUnit('%')) { return $value->getDimension() / 100; @@ -7438,7 +7495,7 @@ EOL; } } - return [Type::T_HSL, fmod($h, 360), $s * 100, $l / 5.1]; + return [Type::T_HSL, fmod($h + 360, 360), $s * 100, $l / 5.1]; } /** @@ -7719,7 +7776,7 @@ EOL; [$funcName . '(', $color[1], ', ', $color[2], ', ', $color[3], ', ', $alpha, ')']]; } } else { - $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']]; + $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ')']]; } break; @@ -8020,8 +8077,8 @@ EOL; // mix two colors protected static $libMix = [ - ['color1', 'color2', 'weight:0.5'], - ['color-1', 'color-2', 'weight:0.5'] + ['color1', 'color2', 'weight:50%'], + ['color-1', 'color-2', 'weight:50%'] ]; protected function libMix($args) { @@ -8029,25 +8086,26 @@ EOL; $first = $this->assertColor($first, 'color1'); $second = $this->assertColor($second, 'color2'); - $weight = $this->coercePercent($this->assertNumber($weight, 'weight')); + $weightScale = $this->assertNumber($weight, 'weight')->valueInRange(0, 100, 'weight') / 100; $firstAlpha = isset($first[4]) ? $first[4] : 1; $secondAlpha = isset($second[4]) ? $second[4] : 1; - $w = $weight * 2 - 1; - $a = $firstAlpha - $secondAlpha; + $normalizedWeight = $weightScale * 2 - 1; + $alphaDistance = $firstAlpha - $secondAlpha; - $w1 = (($w * $a === -1 ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2.0; - $w2 = 1.0 - $w1; + $combinedWeight = $normalizedWeight * $alphaDistance == -1 ? $normalizedWeight : ($normalizedWeight + $alphaDistance) / (1 + $normalizedWeight * $alphaDistance); + $weight1 = ($combinedWeight + 1) / 2.0; + $weight2 = 1.0 - $weight1; $new = [Type::T_COLOR, - $w1 * $first[1] + $w2 * $second[1], - $w1 * $first[2] + $w2 * $second[2], - $w1 * $first[3] + $w2 * $second[3], + $weight1 * $first[1] + $weight2 * $second[1], + $weight1 * $first[2] + $weight2 * $second[2], + $weight1 * $first[3] + $weight2 * $second[3], ]; if ($firstAlpha != 1.0 || $secondAlpha != 1.0) { - $new[] = $firstAlpha * $weight + $secondAlpha * (1 - $weight); + $new[] = $firstAlpha * $weightScale + $secondAlpha * (1 - $weightScale); } return $this->fixColor($new); @@ -8124,7 +8182,7 @@ EOL; } } - $hueValue = $hue->getDimension() % 360; + $hueValue = fmod($hue->getDimension(), 360); while ($hueValue < 0) { $hueValue += 360; @@ -8306,6 +8364,12 @@ EOL; { $hsl = $this->toHSL($color[1], $color[2], $color[3]); $hsl[$idx] += $amount; + + if ($idx !== 1) { + // Clamp the saturation and lightness + $hsl[$idx] = min(max(0, $hsl[$idx]), 100); + } + $out = $this->toRGB($hsl[1], $hsl[2], $hsl[3]); if (isset($color[4])) { @@ -8353,19 +8417,19 @@ EOL; return null; } - $color = $this->assertColor($value, 'color'); - $amount = 100 * $this->coercePercent($this->assertNumber($args[1], 'amount')); + $color = $this->assertColor($args[0], 'color'); + $amount = $this->assertNumber($args[1], 'amount'); - return $this->adjustHsl($color, 2, $amount); + return $this->adjustHsl($color, 2, $amount->valueInRange(0, 100, 'amount')); } protected static $libDesaturate = ['color', 'amount']; protected function libDesaturate($args) { $color = $this->assertColor($args[0], 'color'); - $amount = 100 * $this->coercePercent($this->assertNumber($args[1], 'amount')); + $amount = $this->assertNumber($args[1], 'amount'); - return $this->adjustHsl($color, 2, -$amount); + return $this->adjustHsl($color, 2, -$amount->valueInRange(0, 100, 'amount')); } protected static $libGrayscale = ['color']; @@ -8386,28 +8450,28 @@ EOL; return $this->adjustHsl($this->assertColor($args[0], 'color'), 1, 180); } - protected static $libInvert = ['color', 'weight:1']; + protected static $libInvert = ['color', 'weight:100%']; protected function libInvert($args) { $value = $args[0]; + $weight = $this->assertNumber($args[1], 'weight'); + if ($value instanceof Number) { + if ($weight->getDimension() != 100 || !$weight->hasUnit('%')) { + throw new SassScriptException('Only one argument may be passed to the plain-CSS invert() function.'); + } + return null; } - $weight = $this->coercePercent($this->assertNumber($args[1], 'weight')); - $color = $this->assertColor($value, 'color'); $inverted = $color; $inverted[1] = 255 - $inverted[1]; $inverted[2] = 255 - $inverted[2]; $inverted[3] = 255 - $inverted[3]; - if ($weight < 1) { - return $this->libMix([$inverted, $color, new Number($weight, '')]); - } - - return $inverted; + return $this->libMix([$inverted, $color, $weight]); } // increases opacity by amount @@ -8415,9 +8479,9 @@ EOL; protected function libOpacify($args) { $color = $this->assertColor($args[0], 'color'); - $amount = $this->coercePercent($this->assertNumber($args[1], 'amount')); + $amount = $this->assertNumber($args[1], 'amount'); - $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount; + $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount->valueInRange(0, 1, 'amount'); $color[4] = min(1, max(0, $color[4])); return $color; @@ -8434,9 +8498,9 @@ EOL; protected function libTransparentize($args) { $color = $this->assertColor($args[0], 'color'); - $amount = $this->coercePercent($this->assertNumber($args[1], 'amount')); + $amount = $this->assertNumber($args[1], 'amount'); - $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount; + $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount->valueInRange(0, 1, 'amount'); $color[4] = min(1, max(0, $color[4])); return $color; diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php index 78f86bac53..b326906b5c 100644 --- a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php +++ b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php @@ -149,6 +149,7 @@ class Number extends Node implements \ArrayAccess /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { if ($offset === -3) { @@ -174,6 +175,7 @@ class Number extends Node implements \ArrayAccess /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { switch ($offset) { @@ -200,6 +202,7 @@ class Number extends Node implements \ArrayAccess /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new \BadMethodCallException('Number is immutable'); @@ -208,6 +211,7 @@ class Number extends Node implements \ArrayAccess /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { throw new \BadMethodCallException('Number is immutable'); diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php index ab54885e7c..3ba2f67f9d 100644 --- a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php +++ b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php @@ -1580,7 +1580,9 @@ class Parser } else { list($line, $column) = $this->getSourcePosition($this->count); $file = $this->sourceName; - $this->logger->warn("Unterminated interpolations in multiline comments are deprecated and will be removed in ScssPhp 2.0, in \"$file\", line $line, column $column.", true); + if (!$this->discardComments) { + $this->logger->warn("Unterminated interpolations in multiline comments are deprecated and will be removed in ScssPhp 2.0, in \"$file\", line $line, column $column.", true); + } $comment[] = substr($this->buffer, $this->count, 2); $this->count += 2; diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php index b103b4bf5e..62c8006a12 100644 --- a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php +++ b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php @@ -19,5 +19,5 @@ namespace ScssPhp\ScssPhp; */ class Version { - const VERSION = '1.6.0'; + const VERSION = '1.8.1'; } -- 2.20.1