bug #26010 [CssSelector] For AND operator, the left operand should have parentheses, not only right operand (Arnaud CHASSEUX)
This PR was merged into the 2.7 branch.
Discussion
----------
[CssSelector] For AND operator, the left operand should have parentheses, not only right operand
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
From https://github.com/symfony/css-selector/pull/3
Commits
-------
76b40dc
[CssSelector] For AND operator, the left operand should have parentheses, not only right operand
This commit is contained in:
commit
1111da7363
@ -48,7 +48,7 @@ class CssSelectorTest extends TestCase
|
|||||||
array('h1', 'h1'),
|
array('h1', 'h1'),
|
||||||
array('foo|h1', 'foo:h1'),
|
array('foo|h1', 'foo:h1'),
|
||||||
array('h1, h2, h3', 'h1 | h2 | h3'),
|
array('h1, h2, h3', 'h1 | h2 | h3'),
|
||||||
array('h1:nth-child(3n+1)', "*/*[name() = 'h1' and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"),
|
array('h1:nth-child(3n+1)', "*/*[(name() = 'h1') and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"),
|
||||||
array('h1 > p', 'h1/p'),
|
array('h1 > p', 'h1/p'),
|
||||||
array('h1#foo', "h1[@id = 'foo']"),
|
array('h1#foo', "h1[@id = 'foo']"),
|
||||||
array('h1.foo', "h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"),
|
array('h1.foo', "h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"),
|
||||||
|
@ -102,18 +102,20 @@ class TranslatorTest extends TestCase
|
|||||||
array('e[foo^="bar"]', "e[@foo and starts-with(@foo, 'bar')]"),
|
array('e[foo^="bar"]', "e[@foo and starts-with(@foo, 'bar')]"),
|
||||||
array('e[foo$="bar"]', "e[@foo and substring(@foo, string-length(@foo)-2) = 'bar']"),
|
array('e[foo$="bar"]', "e[@foo and substring(@foo, string-length(@foo)-2) = 'bar']"),
|
||||||
array('e[foo*="bar"]', "e[@foo and contains(@foo, 'bar')]"),
|
array('e[foo*="bar"]', "e[@foo and contains(@foo, 'bar')]"),
|
||||||
|
array('e[foo!="bar"]', "e[not(@foo) or @foo != 'bar']"),
|
||||||
|
array('e[foo!="bar"][foo!="baz"]', "e[(not(@foo) or @foo != 'bar') and (not(@foo) or @foo != 'baz')]"),
|
||||||
array('e[hreflang|="en"]', "e[@hreflang and (@hreflang = 'en' or starts-with(@hreflang, 'en-'))]"),
|
array('e[hreflang|="en"]', "e[@hreflang and (@hreflang = 'en' or starts-with(@hreflang, 'en-'))]"),
|
||||||
array('e:nth-child(1)', "*/*[name() = 'e' and (position() = 1)]"),
|
array('e:nth-child(1)', "*/*[(name() = 'e') and (position() = 1)]"),
|
||||||
array('e:nth-last-child(1)', "*/*[name() = 'e' and (position() = last() - 0)]"),
|
array('e:nth-last-child(1)', "*/*[(name() = 'e') and (position() = last() - 0)]"),
|
||||||
array('e:nth-last-child(2n+2)', "*/*[name() = 'e' and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"),
|
array('e:nth-last-child(2n+2)', "*/*[(name() = 'e') and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"),
|
||||||
array('e:nth-of-type(1)', '*/e[position() = 1]'),
|
array('e:nth-of-type(1)', '*/e[position() = 1]'),
|
||||||
array('e:nth-last-of-type(1)', '*/e[position() = last() - 0]'),
|
array('e:nth-last-of-type(1)', '*/e[position() = last() - 0]'),
|
||||||
array('div e:nth-last-of-type(1) .aclass', "div/descendant-or-self::*/e[position() = last() - 0]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' aclass ')]"),
|
array('div e:nth-last-of-type(1) .aclass', "div/descendant-or-self::*/e[position() = last() - 0]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' aclass ')]"),
|
||||||
array('e:first-child', "*/*[name() = 'e' and (position() = 1)]"),
|
array('e:first-child', "*/*[(name() = 'e') and (position() = 1)]"),
|
||||||
array('e:last-child', "*/*[name() = 'e' and (position() = last())]"),
|
array('e:last-child', "*/*[(name() = 'e') and (position() = last())]"),
|
||||||
array('e:first-of-type', '*/e[position() = 1]'),
|
array('e:first-of-type', '*/e[position() = 1]'),
|
||||||
array('e:last-of-type', '*/e[position() = last()]'),
|
array('e:last-of-type', '*/e[position() = last()]'),
|
||||||
array('e:only-child', "*/*[name() = 'e' and (last() = 1)]"),
|
array('e:only-child', "*/*[(name() = 'e') and (last() = 1)]"),
|
||||||
array('e:only-of-type', 'e[last() = 1]'),
|
array('e:only-of-type', 'e[last() = 1]'),
|
||||||
array('e:empty', 'e[not(*) and not(string-length())]'),
|
array('e:empty', 'e[not(*) and not(string-length())]'),
|
||||||
array('e:EmPTY', 'e[not(*) and not(string-length())]'),
|
array('e:EmPTY', 'e[not(*) and not(string-length())]'),
|
||||||
@ -127,7 +129,7 @@ class TranslatorTest extends TestCase
|
|||||||
array('e:nOT(*)', 'e[0]'),
|
array('e:nOT(*)', 'e[0]'),
|
||||||
array('e f', 'e/descendant-or-self::*/f'),
|
array('e f', 'e/descendant-or-self::*/f'),
|
||||||
array('e > f', 'e/f'),
|
array('e > f', 'e/f'),
|
||||||
array('e + f', "e/following-sibling::*[name() = 'f' and (position() = 1)]"),
|
array('e + f', "e/following-sibling::*[(name() = 'f') and (position() = 1)]"),
|
||||||
array('e ~ f', 'e/following-sibling::f'),
|
array('e ~ f', 'e/following-sibling::f'),
|
||||||
array('div#container p', "div[@id = 'container']/descendant-or-self::*/p"),
|
array('div#container p', "div[@id = 'container']/descendant-or-self::*/p"),
|
||||||
);
|
);
|
||||||
|
@ -57,7 +57,7 @@ class XPathExpr
|
|||||||
*/
|
*/
|
||||||
public function addCondition($condition)
|
public function addCondition($condition)
|
||||||
{
|
{
|
||||||
$this->condition = $this->condition ? sprintf('%s and (%s)', $this->condition, $condition) : $condition;
|
$this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ class XPathExpr
|
|||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function join($combiner, XPathExpr $expr)
|
public function join($combiner, self $expr)
|
||||||
{
|
{
|
||||||
$path = $this->__toString().$combiner;
|
$path = $this->__toString().$combiner;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user