/** * @param DOMNode $node * @param string $selector * @return bool * @throws \QueryPath\CSS\ParseException */ public function matches(DOMNode $node, $selector) { $traverser = new DOMTraverser(new \SPLObjectStorage()); $handler = new Selector(); $parser = new Parser($selector, $handler); $parser->parse(); foreach ($handler as $selectorGroup) { if ($traverser->matchesSelector($node, $selectorGroup)) { return true; } } return false; }
/** * Given a selector, find the matches in the given DOM. * * This is the main function for querying the DOM using a CSS * selector. * * @param string $selector * The selector. * @retval object SPLObjectStorage * An SPLObjectStorage containing a list of matched * DOMNode objects. */ public function find($selector) { // Setup $handler = new Selector(); $parser = new Parser($selector, $handler); $parser->parse(); $this->selector = $handler; //$selector = $handler->toArray(); $found = $this->newMatches(); foreach ($handler as $selectorGroup) { // fprintf(STDOUT, "Selector group.\n"); // Initialize matches if necessary. if ($this->initialized) { $candidates = $this->matches; } else { //if (empty($selectorGroup)) { // fprintf(STDOUT, "%s", print_r($handler->toArray(), TRUE)); //} $candidates = $this->initialMatch($selectorGroup[0], $this->matches); //$this->initialized = TRUE; } foreach ($candidates as $candidate) { // fprintf(STDOUT, "Testing %s against %s.\n", $candidate->tagName, $selectorGroup[0]); if ($this->matchesSelector($candidate, $selectorGroup)) { // $this->debug('Attaching ' . $candidate->nodeName); $found->attach($candidate); } } } $this->setMatches($found); return $this; }
public function testAllCombo() { $selector = '*|ele1 > ele2.class1 + ns1|ele3.class2[attr=simple] ~ .class2[attr2~="longer string of text."]:pseudoClass(value) .class3::pseudoElement'; $expect = array(new TestEvent(TestEvent::elementNS, 'ele1', '*'), new TestEvent(TestEvent::directDescendant), new TestEvent(TestEvent::element, 'ele2'), new TestEvent(TestEvent::elementClass, 'class1'), new TestEvent(TestEvent::adjacent), new TestEvent(TestEvent::elementNS, 'ele3', 'ns1'), new TestEvent(TestEvent::elementClass, 'class2'), new TestEvent(TestEvent::attribute, 'attr', 'simple', EventHandler::isExactly), new TestEvent(TestEvent::sibling), new TestEvent(TestEvent::elementClass, 'class2'), new TestEvent(TestEvent::attribute, 'attr2', 'longer string of text.', EventHandler::containsWithSpace), new TestEvent(TestEvent::pseudoClass, 'pseudoClass', 'value'), new TestEvent(TestEvent::anyDescendant), new TestEvent(TestEvent::elementClass, 'class3'), new TestEvent(TestEvent::pseudoElement, 'pseudoElement')); $handler = new TestEventHandler(); $handler->expects($expect); $parser = new Parser($selector, $handler); $parser->parse(); //$handler->dumpStack(); $this->assertTrue($handler->success()); /* // Again, with spaces this time: $selector = ' *|ele1 > ele2. class1 + ns1|ele3. class2[ attr=simple] ~ .class2[attr2 ~= "longer string of text."]:pseudoClass(value) .class3::pseudoElement'; $handler = new TestEventHandler(); $handler->expects($expect); $parser = new Parser($selector, $handler); $parser->parse(); $handler->dumpStack(); $this->assertTrue($handler->success()); */ }