public function testParseAnB() { // even $this->assertEquals(array(2, 0), Util::parseAnB('even')); // odd $this->assertEquals(array(2, 1), Util::parseAnB('odd')); // 5 $this->assertEquals(array(0, 5), Util::parseAnB('5')); // +5 $this->assertEquals(array(0, 5), Util::parseAnB('+5')); // n $this->assertEquals(array(1, 0), Util::parseAnB('n')); // 2n $this->assertEquals(array(2, 0), Util::parseAnB('2n')); // -234n $this->assertEquals(array(-234, 0), Util::parseAnB('-234n')); // -2n+1 $this->assertEquals(array(-2, 1), Util::parseAnB('-2n+1')); // -2n + 1 $this->assertEquals(array(-2, 1), Util::parseAnB(' -2n + 1 ')); // +2n-1 $this->assertEquals(array(2, -1), Util::parseAnB('2n-1')); $this->assertEquals(array(2, -1), Util::parseAnB('2n - 1')); // -n + 3 $this->assertEquals(array(-1, 3), Util::parseAnB('-n+3')); // Test invalid values $this->assertEquals(array(0, 0), Util::parseAnB('obviously + invalid')); }
/** * Provides functionality for all "An+B" rules. * Provides ntoh-child and also the functionality required for: * *- nth-last-child *- even *- odd *- first *- last *- eq *- nth *- nth-of-type *- first-of-type *- last-of-type *- nth-last-of-type * * See also QueryPath::CSS::DOMTraverser::Util::parseAnB(). */ protected function isNthChild($node, $value, $reverse = FALSE, $byType = FALSE) { list($groupSize, $elementInGroup) = Util::parseAnB($value); $parent = $node->parentNode; if (empty($parent) || $groupSize == 0 && $elementInGroup == 0 || $groupSize > 0 && $elementInGroup > $groupSize) { return FALSE; } // First we need to find the position of $node in other elements. if ($reverse) { $pos = $this->nodePositionFromEnd($node, $byType); } else { $pos = $this->nodePositionFromStart($node, $byType); } // If group size is 0, we just check to see if this // is the nth element: if ($groupSize == 0) { return $pos == $elementInGroup; } // Next, we normalize $elementInGroup if ($elementInGroup < 0) { $elementInGroup = $groupSize + $elementInGroup; } $prod = ($pos - $elementInGroup) / $groupSize; // fprintf(STDOUT, "%d n + %d on %d is %3.5f\n", $groupSize, $elementInGroup, $pos, $prod); return is_int($prod) && $prod >= 0; }