diff --git a/Node/FunctionNode.php b/Node/FunctionNode.php index de44600..9bc3c24 100644 --- a/Node/FunctionNode.php +++ b/Node/FunctionNode.php @@ -63,7 +63,7 @@ public function getSpecificity(): Specificity public function __toString(): string { - $arguments = implode(', ', array_map(fn (Token $token) => "'".$token->getValue()."'", $this->arguments)); + $arguments = implode(', ', array_map(static fn (Token $token) => "'".$token->getValue()."'", $this->arguments)); return \sprintf('%s[%s:%s(%s)]', $this->getNodeName(), $this->selector, $this->name, $arguments ? '['.$arguments.']' : ''); } diff --git a/Node/MatchingNode.php b/Node/MatchingNode.php index 9b59503..76d516d 100644 --- a/Node/MatchingNode.php +++ b/Node/MatchingNode.php @@ -36,7 +36,7 @@ public function getSpecificity(): Specificity { $argumentsSpecificity = array_reduce( $this->arguments, - fn ($c, $n) => 1 === $n->getSpecificity()->compareTo($c) ? $n->getSpecificity() : $c, + static fn ($c, $n) => 1 === $n->getSpecificity()->compareTo($c) ? $n->getSpecificity() : $c, new Specificity(0, 0, 0), ); @@ -46,7 +46,7 @@ public function getSpecificity(): Specificity public function __toString(): string { $selectorArguments = array_map( - fn ($n): string => ltrim((string) $n, '*'), + static fn ($n): string => ltrim((string) $n, '*'), $this->arguments, ); diff --git a/Node/SpecificityAdjustmentNode.php b/Node/SpecificityAdjustmentNode.php index 58659cc..d1bc5c9 100644 --- a/Node/SpecificityAdjustmentNode.php +++ b/Node/SpecificityAdjustmentNode.php @@ -40,7 +40,7 @@ public function getSpecificity(): Specificity public function __toString(): string { $selectorArguments = array_map( - fn ($n) => ltrim((string) $n, '*'), + static fn ($n) => ltrim((string) $n, '*'), $this->arguments, ); diff --git a/Parser/Parser.php b/Parser/Parser.php index 5a93a70..b5dc932 100644 --- a/Parser/Parser.php +++ b/Parser/Parser.php @@ -57,9 +57,9 @@ public static function parseSeries(array $tokens): array } } - $joined = trim(implode('', array_map(fn (Token $token) => $token->getValue(), $tokens))); + $joined = trim(implode('', array_map(static fn (Token $token) => $token->getValue(), $tokens))); - $int = function ($string) { + $int = static function ($string) { if (!is_numeric($string)) { throw SyntaxErrorException::stringAsFunctionArgument(); } diff --git a/Parser/Tokenizer/TokenizerEscaping.php b/Parser/Tokenizer/TokenizerEscaping.php index bb504e4..428e32b 100644 --- a/Parser/Tokenizer/TokenizerEscaping.php +++ b/Parser/Tokenizer/TokenizerEscaping.php @@ -44,7 +44,7 @@ public function escapeUnicodeAndNewLine(string $value): string private function replaceUnicodeSequences(string $value): string { - return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function ($match) { + return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), static function ($match) { $c = hexdec($match[1]); if (0x80 > $c %= 0x200000) { diff --git a/Tests/Parser/ParserTest.php b/Tests/Parser/ParserTest.php index 15b8a1b..2a5bc65 100644 --- a/Tests/Parser/ParserTest.php +++ b/Tests/Parser/ParserTest.php @@ -26,7 +26,7 @@ public function testParser($source, $representation) { $parser = new Parser(); - $this->assertEquals($representation, array_map(fn (SelectorNode $node) => (string) $node->getTree(), $parser->parse($source))); + $this->assertEquals($representation, array_map(static fn (SelectorNode $node) => (string) $node->getTree(), $parser->parse($source))); } #[DataProvider('getParserExceptionTestData')] diff --git a/Tests/XPath/TranslatorTest.php b/Tests/XPath/TranslatorTest.php index 621a61e..17b104b 100644 --- a/Tests/XPath/TranslatorTest.php +++ b/Tests/XPath/TranslatorTest.php @@ -236,6 +236,10 @@ public static function getCssToXPathTestData() [':scope', '*[1]'], ['e:is(section, article) h1', "e[(name() = 'section') or (name() = 'article')]/descendant-or-self::*/h1"], ['e:where(section, article) h1', "e[(name() = 'section') or (name() = 'article')]/descendant-or-self::*/h1"], + ['[hidden]:where(:is(span))', "*[(@hidden) and (name() = 'span')]"], + ['[hidden]:where(:not(span))', "*[(@hidden) and (not(name() = 'span'))]"], + ['[hidden]:is(span, div)', "*[(@hidden) and ((name() = 'span') or (name() = 'div'))]"], + ['[hidden]:where(:not([hidden=until-found]))', "*[(@hidden) and (not(@hidden = 'until-found'))]"], ]; } diff --git a/XPath/Extension/NodeExtension.php b/XPath/Extension/NodeExtension.php index 4cd46fa..622677a 100644 --- a/XPath/Extension/NodeExtension.php +++ b/XPath/Extension/NodeExtension.php @@ -99,31 +99,34 @@ public function translateNegation(Node\NegationNode $node, Translator $translato public function translateMatching(Node\MatchingNode $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; + return $this->translateMatchingOrSpecificityAdjustment($node->selector, $node->arguments, $translator); } public function translateSpecificityAdjustment(Node\SpecificityAdjustmentNode $node, Translator $translator): XPathExpr { - $xpath = $translator->nodeToXPath($node->selector); + return $this->translateMatchingOrSpecificityAdjustment($node->selector, $node->arguments, $translator); + } - foreach ($node->arguments as $argument) { + /** + * @param array $arguments + */ + private function translateMatchingOrSpecificityAdjustment(Node\NodeInterface $selector, array $arguments, Translator $translator): XPathExpr + { + $xpath = $translator->nodeToXPath($selector); + + $conditions = []; + foreach ($arguments as $argument) { $expr = $translator->nodeToXPath($argument); $expr->addNameTest(); - if ($condition = $expr->getCondition()) { - $xpath->addCondition($condition, 'or'); + if ('' !== $condition = $expr->getCondition()) { + $conditions[] = $condition; } } + if ($conditions) { + $xpath->addCondition(1 === \count($conditions) ? $conditions[0] : '('.implode(') or (', $conditions).')'); + } + return $xpath; } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 546093d..3517283 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ - + trigger_deprecation Doctrine\Deprecations\Deprecation::trigger Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside