Skip to content

[CssSelector] Mistranslated :disabled w.r.t. fieldset elements. #58297

Open
@nielsdos

Description

@nielsdos

Symfony version(s) affected

7.x, probably lower too

Description

Consider the following HTML:

<fieldset id="outer" disabled="disabled">
    <fieldset id="target1"></fieldset>
    <legend>
        <fieldset id="target2"></fieldset>
    </legend>
    <legend>
        <fieldset id="target3"></fieldset>
    </legend>
</fieldset>

When I query :disabled I expect to see three elements returned (all fieldsets except target2):

  • outer
  • target1
  • target3

Here's the relevant section from the HTML spec:

https://html.spec.whatwg.org/multipage/form-elements.html#concept-fieldset-disabled

The relevant condition for disabled is:

It is a descendant of another fieldset element whose disabled attribute is specified, and is not a descendant of that fieldset element's first legend element child, if any.

Reproducer below.

This was discovered because of a report of a divergation between Symfony's CssSelector and PHP 8.4's native CSS support. I.e. the following PHP 8.4 code produces the right result:

$dom = Dom\HTMLDocument::createFromString(<<<HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<fieldset id="outer" disabled="disabled">
    <fieldset id="target1"></fieldset>
    <legend>
        <fieldset id="target2"></fieldset>
    </legend>
    <legend>
        <fieldset id="target3"></fieldset>
    </legend>
</fieldset>
</html> 
HTML);

foreach ($dom->querySelectorAll(':disabled') as $node) {
    var_dump($node->id);
}

How to reproduce

<?php

require __DIR__.'/vendor/autoload.php';

use Symfony\Component\CssSelector\CssSelectorConverter;

$converter = new CssSelectorConverter();
$xpath = $converter->toXPath(":disabled");
echo $xpath, "\n";

$dom = new DOMDocument;
$dom->loadHTML(<<<HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<fieldset id="outer" disabled="disabled">
    <fieldset id="target1"></fieldset>
    <legend>
        <fieldset id="target2"></fieldset>
    </legend>
    <legend>
        <fieldset id="target3"></fieldset>
    </legend>
</fieldset>
</html> 
HTML);

$xp = new DOMXPath($dom);
foreach ($xp->query($xpath) as $node) {
    var_dump($node->id);
}

Possible Solution

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions