Skip to content

Commit 899c929

Browse files
committed
Fix parser issue always returning direct descendant
1 parent da0ff45 commit 899c929

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

src/Symfony/Component/CssSelector/Parser/Parser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ private function parseRelativeNode($stream): array {
271271
$next = $stream->getNext();
272272

273273
if($next->isDelimiter(['+','-','>','~'])) {
274-
$combinator = $stream->getNext()->getValue();
274+
$combinator = $next->getValue();
275275
$stream->skipWhitespace();
276276
$next = $stream->getNext();
277277
} else {

src/Symfony/Component/CssSelector/XPath/Extension/NodeExtension.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,9 @@ public function translateElement(Node\ElementNode $node): XPathExpr
183183

184184
public function translateRelation(Node\RelationNode $node, Translator $translator): XPathExpr
185185
{
186-
$xpath = $translator->nodeToXPath($node->getSelector());
187186
$combinator = $node->getCombinator();
188187

189-
return $xpath->addCondition(sprintf('count(%s) > 0', $translator->addRelativeCombination($combinator,$node->getSelector(),$node->getSubSelector())));
188+
return $translator->addRelativeCombination($combinator,$node->getSelector(),$node->getSubSelector());
190189
}
191190

192191
public function getName(): string
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\CssSelector\XPath\Extension;
13+
14+
use Symfony\Component\CssSelector\XPath\XPathExpr;
15+
16+
/**
17+
* XPath expression translator combination extension.
18+
*
19+
* This component is a port of the Python cssselect library,
20+
* which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
21+
*
22+
* @author Franck Ranaivo-Harisoa <franckranaivo@gmail.com>
23+
*
24+
* @internal
25+
*/
26+
class RelationExtension extends AbstractExtension
27+
{
28+
public function getRelativeCombinationTranslators(): array
29+
{
30+
return [
31+
' ' => $this->translateRelationDescendant(...),
32+
'>' => $this->translateRelationChild(...),
33+
'+' => $this->translateRelationDirectAdjacent(...),
34+
'~' => $this->translateRelationIndirectAdjacent(...),
35+
];
36+
}
37+
38+
public function translateRelationDescendant(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
39+
{
40+
return $xpath->join('[descendant-or-self::', $combinedXpath, ']', true);
41+
}
42+
43+
public function translateRelationChild(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
44+
{
45+
return $xpath->join('[./', $combinedXpath,']');
46+
}
47+
48+
public function translateRelationDirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
49+
{
50+
return $xpath
51+
->addCondition(sprintf('following-sibling::*[(name() = \'%s\') and (position() = 1)]',$combinedXpath->getElement()));
52+
}
53+
54+
public function translateRelationIndirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
55+
{
56+
return $xpath->join('[following-sibling::', $combinedXpath,']');
57+
}
58+
59+
public function getName(): string
60+
{
61+
return 'relation';
62+
}
63+
}

0 commit comments

Comments
 (0)