protected function seek($selector, &$ret, $lowercase = false)
{
global $debugObject;
if (is_object($debugObject)) {
$debugObject->debugLogEntry(1);
}
list($tag, $key, $val, $exp, $no_key) = $selector;
// xpath index
if ($tag && $key && is_numeric($key)) {
$count = 0;
foreach ($this->children as $c) {
if ($tag === '*' || $tag === $c->tag) {
if (++$count == $key) {
$ret[$c->_[HDOM_INFO_BEGIN]] = 1;
return;
}
}
}
return;
}
$end = !empty($this->_[HDOM_INFO_END]) ? $this->_[HDOM_INFO_END] : 0;
if ($end == 0) {
$parent = $this->parent;
while (!isset($parent->_[HDOM_INFO_END]) && $parent !== null) {
$end -= 1;
$parent = $parent->parent;
}
$end += $parent->_[HDOM_INFO_END];
}
for ($i = $this->_[HDOM_INFO_BEGIN] + 1; $i < $end; ++$i) {
$node = $this->dom->nodes[$i];
$pass = true;
if ($tag === '*' && !$key) {
if (in_array($node, $this->children, true)) {
$ret[$i] = 1;
}
continue;
}
// compare tag
if ($tag && $tag != $node->tag && $tag !== '*') {
$pass = false;
}
// compare key
if ($pass && $key) {
if ($no_key) {
if (isset($node->attr[$key])) {
$pass = false;
}
} else {
if ($key != "plaintext" && !isset($node->attr[$key])) {
$pass = false;
}
}
}
// compare value
if ($pass && $key && $val && $val !== '*') {
// If they have told us that this is a "plaintext" search then we want the plaintext of the node - right?
if ($key == "plaintext") {
// $node->plaintext actually returns $node->text();
$nodeKeyValue = $node->text();
} else {
// this is a normal search, we want the value of that attribute of the tag.
$nodeKeyValue = $node->attr[$key];
}
if (is_object($debugObject)) {
$debugObject->debugLog(2, "testing node: " . $node->tag . " for attribute: " . $key . $exp . $val . " where nodes value is: " . $nodeKeyValue);
}
//PaperG - If lowercase is set, do a case insensitive test of the value of the selector.
if ($lowercase) {
$check = $this->match($exp, strtolower($val), strtolower($nodeKeyValue));
} else {
$check = $this->match($exp, $val, $nodeKeyValue);
}
if (is_object($debugObject)) {
$debugObject->debugLog(2, "after match: " . ($check ? "true" : "false"));
}
// handle multiple class
if (!$check && strcasecmp($key, 'class') === 0) {
foreach (explode(' ', $node->attr[$key]) as $k) {
// Without this, there were cases where leading, trailing, or double spaces lead to our comparing blanks - bad form.
if (!empty($k)) {
if ($lowercase) {
$check = $this->match($exp, strtolower($val), strtolower($k));
} else {
$check = $this->match($exp, $val, $k);
}
if ($check) {
break;
}
}
}
}
if (!$check) {
$pass = false;
}
}
if ($pass) {
$ret[$i] = 1;
}
unset($node);
}
// It's passed by reference so this is actually what this function returns.
if (is_object($debugObject)) {
$debugObject->debugLog(1, "EXIT - ret: ", $ret);
}
}