Update scssphp/scssphp to 1.8.1
authorTim Düsterhus <duesterhus@woltlab.com>
Mon, 20 Sep 2021 14:07:25 +0000 (16:07 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Mon, 20 Sep 2021 14:07:25 +0000 (16:07 +0200)
This is for PHP 8.1 compatibility.

wcfsetup/install/files/lib/system/api/composer.lock
wcfsetup/install/files/lib/system/api/composer/installed.json
wcfsetup/install/files/lib/system/api/composer/installed.php
wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss
wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php

index 39cb52b39994e65e1e758c42f94cbc0658673ffa..77e7e850e185e2696c8b3519d57230bcd3b0c59f 100644 (file)
         },
         {
             "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": {
                 "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"
             ],
             "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",
index cd82eb334bee9e4d9ddbb078198f9c593f8a18c7..ea20c260ec00548bd6074dbf91c30da5b66f9eff 100644 (file)
         },
         {
             "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": {
                 "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"
                 "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"
             ],
             ],
             "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"
         },
             "install-path": "../true/punycode"
         }
     ],
-    "dev": true,
+    "dev": false,
     "dev-package-names": []
 }
index 5ef8dfbe905869c3057deb701d668f92991da672..ff9bcb2ee43d6f2e9baad33b0eaf1e78cf435cd2 100644 (file)
@@ -7,7 +7,7 @@
         'aliases' => array(),
         'reference' => NULL,
         'name' => '__root__',
-        'dev' => true,
+        'dev' => false,
     ),
     'versions' => array(
         '__root__' => array(
             '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(
index 18c136acb94504112b4c883f599964a657c8c8cb..e62239830f3df22b02838a2f163fea080c78984b 100644 (file)
@@ -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) {
index 1c6d7625c5ef49497652e65c3433cece5b806a4a..86cd396bf76fc2f5cc4424719ece4f7d2f711d07 100644 (file)
@@ -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"
             "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": ""
                 }
             }
index b9d42bb1df4059626fb78d825c17a72e0458db86..58ba795ab8da97d83790a380954f620634cef021 100644 (file)
@@ -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;
index 78f86bac536ddffa74557182e58a3f6f8b3703ef..b326906b5c1f5ec95ac64e5e3254b31a04dfb4de 100644 (file)
@@ -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');
index ab54885e7cf57aceb2d228c8f90f5f61151b9a52..3ba2f67f9d5e20f4f9312472f07cbbd39a40e2ba 100644 (file)
@@ -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;
index b103b4bf5e425223acd1921400467ed2d3cf2541..62c8006a124a6f11004fa64ea833b66b82ddcff8 100644 (file)
@@ -19,5 +19,5 @@ namespace ScssPhp\ScssPhp;
  */
 class Version
 {
-    const VERSION = '1.6.0';
+    const VERSION = '1.8.1';
 }