You are here

public function FunctionExtension::translateNthChild in Zircon Profile 8.0

Same name and namespace in other branches
  1. 8 vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php \Symfony\Component\CssSelector\XPath\Extension\FunctionExtension::translateNthChild()

Parameters

XPathExpr $xpath:

FunctionNode $function:

bool $last:

bool $addNameTest:

Return value

XPathExpr

Throws

ExpressionErrorException

3 calls to FunctionExtension::translateNthChild()
FunctionExtension::translateNthLastChild in vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php
FunctionExtension::translateNthLastOfType in vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php
FunctionExtension::translateNthOfType in vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php

File

vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php, line 56

Class

FunctionExtension
XPath expression translator function extension.

Namespace

Symfony\Component\CssSelector\XPath\Extension

Code

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
}