Description
Symfony version(s) affected
^7.2
Description
Selector [hidden]:where(:is(span))
should return : "descendant-or-self::*[(@hidden) and (name() = 'span')]"
but returns : "descendant-or-self::*[(@hidden) or (name() = 'span')]"
.
Selector [hidden]:where(:not(span))
will affect each descendant and self tag.
How to reproduce
test.php
<?php
require __DIR__ . "/vendor/autoload.php";
use Symfony\Component\CssSelector\CssSelectorConverter;
$converter = new CssSelectorConverter();
$css = "span:where(:is(#foo))";
var_dump( $converter->toXPath( $css ) );
echo "\n\n";
$css = "span:where(:not(#foo))";
var_dump( $converter->toXPath( $css ) );
echo "\n\n";
$css = "[hidden]:where(:is(span))";
var_dump( $converter->toXPath( $css ) );
echo "\n\n";
$css = "[hidden]:where(:not(span))";
var_dump( $converter->toXPath( $css ) );
echo "\n\n";
composer.json
{
"require": {
"symfony/css-selector": "^7.2"
}
}
Returns :
string(37) "descendant-or-self::span[@id = 'foo']"
string(42) "descendant-or-self::span[not(@id = 'foo')]"
string(53) "descendant-or-self::*[(@hidden) or (name() = 'span')]"
string(58) "descendant-or-self::*[(@hidden) or (not(name() = 'span'))]"
Instead of :
string(37) "descendant-or-self::span[@id = 'foo']"
string(42) "descendant-or-self::span[not(@id = 'foo')]"
string(53) "descendant-or-self::*[(@hidden) and (name() = 'span')]"
string(58) "descendant-or-self::*[(@hidden) and (not(name() = 'span'))]"
Possible Solution
This is related to the NodeExtension
class translateSpecificityAdjustment
method returns 'or' as condition only.
symfony/css-selector/XPath/Extension/NodeExtension.php
line 115
:
public function translateSpecificityAdjustment(Node\SpecificityAdjustmentNode $node, Translator $translator): XPathExpr
{
$xpath = $translator->nodeToXPath($node->selector);
foreach ($node->arguments as $argument) {
$expr = $translator->nodeToXPath($argument);
$expr->addNameTest();
if ($condition = $expr->getCondition()) {
$xpath->addCondition($condition, 'or');
}
}
return $xpath;
}
Replacing 'or' with 'and' make this work but 4 other tests are obviously failing now.
I have to dig more into this but I would be glad to suggest a pull request for this if I am not wrong.
Additional Context
Tailwind CSS v4 adds a base selector in file node_modules/tailwindcss/preflight.css
line 381 :
[hidden]:where(:not([hidden='until-found'])) {
display: none !important;
}
When using package CssToInlineStyles
to inline Tailwind css classes into a html file, each tag from that file gets an additional display style display : none !important
.
