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'));
 }
Example #2
0
 /**
  * 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;
 }
Example #3
0
 /**
  * Check to see if DOMNode has all of the given attributes.
  *
  * This can handle namespaced attributes, including namespace
  * wildcards.
  */
 protected function matchAttributes($node, $attributes)
 {
     if (empty($attributes)) {
         return TRUE;
     }
     foreach ($attributes as $attr) {
         $val = isset($attr['value']) ? $attr['value'] : NULL;
         // Namespaced attributes.
         if (isset($attr['ns']) && $attr['ns'] != '*') {
             $nsuri = $node->lookupNamespaceURI($attr['ns']);
             if (empty($nsuri) || !$node->hasAttributeNS($nsuri, $attr['name'])) {
                 return FALSE;
             }
             $matches = Util::matchesAttributeNS($node, $attr['name'], $nsuri, $val, $attr['op']);
         } elseif (isset($attr['ns']) && $attr['ns'] == '*' && $node->hasAttributes()) {
             // Cycle through all of the attributes in the node. Note that
             // these are DOMAttr objects.
             $matches = FALSE;
             $name = $attr['name'];
             foreach ($node->attributes as $attrNode) {
                 if ($attrNode->localName == $name) {
                     $nsuri = $attrNode->namespaceURI;
                     $matches = Util::matchesAttributeNS($node, $name, $nsuri, $val, $attr['op']);
                 }
             }
         } else {
             $matches = Util::matchesAttribute($node, $attr['name'], $val, $attr['op']);
         }
         if (!$matches) {
             return FALSE;
         }
     }
     return TRUE;
 }