| @@ -43,8 +43,9 @@ | ||
| 43 | 43 | private array $extensions = []; |
| 44 | 44 | |
| 45 | 45 | private array $nodeTranslators = []; |
| 46 | 46 | private array $combinationTranslators = []; |
| 47 | + private array $relativeCombinationTranslators = []; | |
| 47 | 48 | private array $functionTranslators = []; |
| 48 | 49 | private array $pseudoClassTranslators = []; |
| 49 | 50 | private array $attributeMatchingTranslators = []; |
| 50 | 51 | |
| @@ -57,8 +58,9 @@ | ||
| 57 | 58 | ->registerExtension(new Extension\CombinationExtension()) |
| 58 | 59 | ->registerExtension(new Extension\FunctionExtension()) |
| 59 | 60 | ->registerExtension(new Extension\PseudoClassExtension()) |
| 60 | 61 | ->registerExtension(new Extension\AttributeMatchingExtension()) |
| 62 | + ->registerExtension(new Extension\RelationExtension()) | |
| 61 | 63 | ; |
| 62 | 64 | } |
| 63 | 65 | |
| 64 | 66 | public static function getXpathLiteral(string $element): string |
| @@ -90,9 +92,8 @@ | ||
| 90 | 92 | public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string |
| 91 | 93 | { |
| 92 | 94 | $selectors = $this->parseSelectors($cssExpr); |
| 93 | 95 | |
| 94 | - /** @var SelectorNode $selector */ | |
| 95 | 96 | foreach ($selectors as $index => $selector) { |
| 96 | 97 | if (null !== $selector->getPseudoElement()) { |
| 97 | 98 | throw new ExpressionErrorException('Pseudo-elements are not supported.'); |
| 98 | 99 | } |
| @@ -119,8 +120,9 @@ | ||
| 119 | 120 | $this->combinationTranslators = array_merge($this->combinationTranslators, $extension->getCombinationTranslators()); |
| 120 | 121 | $this->functionTranslators = array_merge($this->functionTranslators, $extension->getFunctionTranslators()); |
| 121 | 122 | $this->pseudoClassTranslators = array_merge($this->pseudoClassTranslators, $extension->getPseudoClassTranslators()); |
| 122 | 123 | $this->attributeMatchingTranslators = array_merge($this->attributeMatchingTranslators, $extension->getAttributeMatchingTranslators()); |
| 124 | + $this->relativeCombinationTranslators = array_merge($this->relativeCombinationTranslators, $extension->getRelativeCombinationTranslators()); | |
| 123 | 125 | |
| 124 | 126 | return $this; |
| 125 | 127 | } |
| 126 | 128 | |
| @@ -167,8 +169,20 @@ | ||
| 167 | 169 | throw new ExpressionErrorException(\sprintf('Combiner "%s" not supported.', $combiner)); |
| 168 | 170 | } |
| 169 | 171 | |
| 170 | 172 | return $this->combinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath)); |
| 173 | + } | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * @throws ExpressionErrorException | |
| 177 | + */ | |
| 178 | + public function addRelativeCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr | |
| 179 | + { | |
| 180 | + if (!isset($this->relativeCombinationTranslators[$combiner])) { | |
| 181 | + throw new ExpressionErrorException(\sprintf('Combiner "%s" not supported.', $combiner)); | |
| 182 | + } | |
| 183 | + | |
| 184 | + return $this->relativeCombinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath)); | |
| 171 | 185 | } |
| 172 | 186 | |
| 173 | 187 | /** |
| 174 | 188 | * @throws ExpressionErrorException |