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
12namespace Symfony\Component\CssSelector\XPath\Extension;
13
14use 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 Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
23 *
24 * @internal
25 */
26class CombinationExtension extends AbstractExtension
27{
28    /**
29     * {@inheritdoc}
30     */
31    public function getCombinationTranslators(): array
32    {
33        return [
34            ' ' => [$this, 'translateDescendant'],
35            '>' => [$this, 'translateChild'],
36            '+' => [$this, 'translateDirectAdjacent'],
37            '~' => [$this, 'translateIndirectAdjacent'],
38        ];
39    }
40
41    public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
42    {
43        return $xpath->join('/descendant-or-self::*/', $combinedXpath);
44    }
45
46    public function translateChild(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
47    {
48        return $xpath->join('/', $combinedXpath);
49    }
50
51    public function translateDirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
52    {
53        return $xpath
54            ->join('/following-sibling::', $combinedXpath)
55            ->addNameTest()
56            ->addCondition('position() = 1');
57    }
58
59    public function translateIndirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
60    {
61        return $xpath->join('/following-sibling::', $combinedXpath);
62    }
63
64    /**
65     * {@inheritdoc}
66     */
67    public function getName(): string
68    {
69        return 'combination';
70    }
71}
72