Example #1
0
 /** @dataProvider getParseSeriesExceptionTestData */
 public function testParseSeriesException($series)
 {
     $parser = new Parser();
     $selectors = $parser->parse(sprintf(':nth-child(%s)', $series));
     $this->assertCount(1, $selectors);
     /** @var FunctionNode $function */
     $function = $selectors[0]->getTree();
     $this->setExpectedException('Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException');
     Parser::parseSeries($function->getArguments());
 }
Example #2
0
 /**
  * @param XPathExpr    $xpath
  * @param FunctionNode $function
  * @param boolean      $last
  * @param boolean      $addNameTest
  *
  * @return XPathExpr
  *
  * @throws ExpressionErrorException
  */
 public function translateNthChild(XPathExpr $xpath, FunctionNode $function, $last = false, $addNameTest = true)
 {
     try {
         list($a, $b) = Parser::parseSeries($function->getArguments());
     } catch (SyntaxErrorException $e) {
         throw new ExpressionErrorException(sprintf('Invalid series: %s', implode(', ', $function->getArguments())), 0, $e);
     }
     $xpath->addStarPrefix();
     if ($addNameTest) {
         $xpath->addNameTest();
     }
     if (0 === $a) {
         return $xpath->addCondition('position() = ' . ($last ? 'last() - ' . $b : $b));
     }
     if ($last) {
         // todo: verify if this is right
         $a = -$a;
         $b = -$b;
     }
     $conditions = 1 === $a ? array() : array(sprintf('(position() %s) mod %s = 0', $b > 0 ? (string) -$b : '+' . -$b, $a));
     if ($b >= 0) {
         $conditions[] = 'position() >= ' . $b;
     } elseif ($last) {
         $conditions[] = sprintf('position() < (last() %s)', $b);
     }
     // todo: handle an+b, odd, even
     // an+b means every-a, plus b, e.g., 2n+1 means odd
     // 0n+b means b
     // n+0 means a=1, i.e., all elements
     // an means every a elements, i.e., 2n means even
     // -n means -1n
     // -1n+6 means elements 6 and previous
     return empty($conditions) ? $xpath : $xpath->addCondition(implode(' and ', $conditions));
 }
Example #3
0
 /**
  * @param XPathExpr    $xpath
  * @param FunctionNode $function
  * @param bool         $last
  * @param bool         $addNameTest
  *
  * @return XPathExpr
  *
  * @throws ExpressionErrorException
  */
 public function translateNthChild(XPathExpr $xpath, FunctionNode $function, $last = false, $addNameTest = true)
 {
     try {
         list($a, $b) = Parser::parseSeries($function->getArguments());
     } catch (SyntaxErrorException $e) {
         throw new ExpressionErrorException(sprintf('Invalid series: %s', implode(', ', $function->getArguments())), 0, $e);
     }
     $xpath->addStarPrefix();
     if ($addNameTest) {
         $xpath->addNameTest();
     }
     if (0 === $a) {
         return $xpath->addCondition('position() = ' . ($last ? 'last() - ' . ($b - 1) : $b));
     }
     if ($a < 0) {
         if ($b < 1) {
             return $xpath->addCondition('false()');
         }
         $sign = '<=';
     } else {
         $sign = '>=';
     }
     $expr = 'position()';
     if ($last) {
         $expr = 'last() - ' . $expr;
         $b--;
     }
     if (0 !== $b) {
         $expr .= ' - ' . $b;
     }
     $conditions = array(sprintf('%s %s 0', $expr, $sign));
     if (1 !== $a && -1 !== $a) {
         $conditions[] = sprintf('(%s) mod %d = 0', $expr, $a);
     }
     return $xpath->addCondition(implode(' and ', $conditions));
     // todo: handle an+b, odd, even
     // an+b means every-a, plus b, e.g., 2n+1 means odd
     // 0n+b means b
     // n+0 means a=1, i.e., all elements
     // an means every a elements, i.e., 2n means even
     // -n means -1n
     // -1n+6 means elements 6 and previous
 }