protected function runQuery($XQuery, $selector = null, $compare = null)
{
if ($compare && !method_exists($this, $compare)) {
return false;
}
$stack = array();
if (!$this->elements) {
$this->debug('Stack empty, skipping...');
}
// var_dump($this->elements[0]->nodeType);
// element, document
foreach ($this->stack(array(1, 9, 13)) as $k => $stackNode) {
$detachAfter = false;
// to work on detached nodes we need temporary place them somewhere
// thats because context xpath queries sucks ;]
$testNode = $stackNode;
while ($testNode) {
if (!$testNode->parentNode && !$this->isRoot($testNode)) {
$this->root->appendChild($testNode);
$detachAfter = $testNode;
break;
}
$testNode = isset($testNode->parentNode) ? $testNode->parentNode : null;
}
// XXX tmp ?
$xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html') : $this->getNodeXpath($stackNode);
// FIXME pseudoclasses-only query, support XML
$query = $XQuery == '//' && $xpath == '/html[1]' ? '//*' : $xpath . $XQuery;
$this->debug("XPATH: {$query}");
// run query, get elements
$nodes = $this->xpath->query($query);
$this->debug('QUERY FETCHED');
if (!$nodes->length) {
$this->debug('Nothing found');
}
$debug = array();
foreach ($nodes as $node) {
$matched = false;
if ($compare) {
phpQuery::$debug ? $this->debug('Found: ' . $this->whois($node) . ", comparing with {$compare}()") : null;
$phpQueryDebug = phpQuery::$debug;
phpQuery::$debug = false;
// TODO ??? use phpQuery::callbackRun()
if (call_user_func_array(array($this, $compare), array($selector, $node))) {
$matched = true;
}
phpQuery::$debug = $phpQueryDebug;
} else {
$matched = true;
}
if ($matched) {
if (phpQuery::$debug) {
$debug[] = $this->whois($node);
}
$stack[] = $node;
}
}
if (phpQuery::$debug) {
$this->debug('Matched ' . count($debug) . ': ' . implode(', ', $debug));
}
if ($detachAfter) {
$this->root->removeChild($detachAfter);
}
}
$this->elements = $stack;
}