scssphp
scssphp copied to clipboard
Error "Array to String conversion" when handling pseudo + attribute selector
I tried to compile the latest uikit version but it fails hard with an error.
Problem is this type of selector:
:where([class*='foo']) p {
// ...
}
To be more precise it's this at transition.scss
:
:where(.uk-transition-fade),
:where([class*='uk-transition-scale']),
:where([class*='uk-transition-slide']) {
--uk-position-translate-x: 0;
--uk-position-translate-y: 0;
}
https://github.com/uikit/uikit/blob/87801983205aa9bb81a122c4e0f1b96b5117c169/src/scss/components/transition.scss#L51-L56
The error happens at array_diff
which compares two incompatible nested array structures I guess:
https://github.com/scssphp/scssphp/blob/c54b0a33d296807bc44ca1305882b2d9f49a3632/src/Compiler.php#L773-L780
Debug:

Please provide an actual reproducing case. The code snippet you gave does not trigger any error when I run it.
Reproducing case:
:where(.uk-transition-fade),
:where([class*='uk-transition-scale']),
:where([class*='uk-transition-slide']) {
--uk-position-translate-x: 0;
--uk-position-translate-y: 0;
}
.a {
color: blue;
}
.b {
@extend .a;
}
I tried to debug it, but our handling of selectors in 1.x is a huge mess and I did not manage to fix the issue.
Hi, I got now the same error. But i have no idea which scss result in this error. I got this error after I update scssphp.
How can I get the SCSS which is resulting this error? Or how can I solve this?
I got this error after I update scssphp.
Updating from which version to which one ?
@stof I upgrade it from 1.10.2 to 1.11.0. I use scssphp inside of the Kirby CMS but this should not affect scssphp.
The problem may be are the child arrays and maybe this is the solution:
add this function to scssphp/src/Compiler.php
protected function diff_recursive($array1, $array2) {
$difference=array();
foreach($array1 as $key => $value) {
if(is_array($value) && isset($array2[$key])){ // it's an array and both have the key
$new_diff = diff_recursive($value, $array2[$key]);
if( !empty($new_diff) )
$difference[$key] = $new_diff;
} else if(is_string($value) && !in_array($value, $array2)) { // the value is a string and it's not in array B
$difference[$key] = $value . " is missing from the second array";
} else if(!is_numeric($key) && !array_key_exists($key, $array2)) { // the key is not numberic and is missing from array B
$difference[$key] = "Missing from the second array";
}
}
return $difference;
}
and in function matchExtends use this new function instead of array_diff
// check that we are not building an infinite loop of extensions
// if the new part is just including a previous part don't try to extend anymore
if (\count($part) > 1) {
foreach ($partsPile as $previousPart) {
// old
// if (! \count(array_diff($previousPart, $part))) {
// continue 2;
// }
// new
if (! \count($this->diff_recursive($previousPart, $part))) {
continue 2;
}
}
}
I can confirm the error with scssphp v1.11.1 when trying to combine picoCss. The problematic line of code is the highlighted one:
a:is([aria-current], :hover, :active, :focus),
a:is([aria-current], :hover, :active, :focus),
[role=link]:is([aria-current], :hover, :active, :focus) {
--color: var(--primary-hover);
--text-decoration: underline;
}
The solution from @baggyownz works!
@MDevster Please provide a reproducer of the issue.
Taking only the code snippet you gave in your comment compiles without triggering the bug, so it is not a reproducer.
Hi, I'm facing the same problem.
Here is a reproducer:
%heading {
margin-top: 0;
}
h1 {
@extend %heading;
}
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
When I execute pcss from the command line with the given snippet, l get the warning:
bin/pscss -s expanded problem.scss out.css
PHP Warning: Array to string conversion in /home/claus/Workspace/codebarista/scssphp/src/Compiler.php on line 927
Here are the values of $previousPart
and $part
that cause the warning in array_diff
:
$previousPart =
array(2) {
[0]=>
string(4) "abbr"
[1]=>
string(15) ":where([title])"
}
$part =
array(3) {
[0]=>
string(1) "["
[1]=>
array(3) {
[0]=>
string(6) "string"
[1]=>
string(0) ""
[2]=>
array(1) {
[0]=>
string(5) "title"
}
}
[2]=>
string(1) "]"
}
Had the same problem while using SASS placeholder selectors in my Typo3 v11.5.36 installation.
Using the solution of @baggyownz worked: https://github.com/scssphp/scssphp/issues/606#issuecomment-1739092199
Would be nice to get an official bugfix down the line.