phpQueryObject::parseSelector PHP Method

parseSelector() protected method

protected parseSelector ( $query )
    protected function parseSelector($query)
    {
        // clean spaces
        // TODO include this inside parsing ?
        $query = trim(preg_replace('@\\s+@', ' ', preg_replace('@\\s*(>|\\+|~)\\s*@', '\\1', $query)));
        $queries = array(array());
        if (!$query) {
            return $queries;
        }
        $return =& $queries[0];
        $specialChars = array('>', ' ');
        //		$specialCharsMapping = array('/' => '>');
        $specialCharsMapping = array();
        $strlen = mb_strlen($query);
        $classChars = array('.', '-');
        $pseudoChars = array('-');
        $tagChars = array('*', '|', '-');
        // split multibyte string
        // http://code.google.com/p/phpquery/issues/detail?id=76
        $_query = array();
        for ($i = 0; $i < $strlen; ++$i) {
            $_query[] = mb_substr($query, $i, 1);
        }
        $query = $_query;
        // it works, but i dont like it...
        $i = 0;
        while ($i < $strlen) {
            $c = $query[$i];
            $tmp = '';
            // TAG
            if ($this->isChar($c) || in_array($c, $tagChars)) {
                while (isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) {
                    $tmp .= $query[$i];
                    ++$i;
                }
                $return[] = $tmp;
                // IDs
            } elseif ($c == '#') {
                ++$i;
                while (isset($query[$i]) && ($this->isChar($query[$i]) || $query[$i] == '-')) {
                    $tmp .= $query[$i];
                    ++$i;
                }
                $return[] = '#' . $tmp;
                // SPECIAL CHARS
            } elseif (in_array($c, $specialChars)) {
                $return[] = $c;
                ++$i;
                // MAPPED SPECIAL MULTICHARS
                //			} else if ( $c.$query[$i+1] == '//') {
                //				$return[] = ' ';
                //				$i = $i+2;
                // MAPPED SPECIAL CHARS
            } elseif (isset($specialCharsMapping[$c])) {
                $return[] = $specialCharsMapping[$c];
                ++$i;
                // COMMA
            } elseif ($c == ',') {
                $queries[] = array();
                $return =& $queries[count($queries) - 1];
                ++$i;
                while (isset($query[$i]) && $query[$i] == ' ') {
                    $i++;
                }
                // CLASSES
            } elseif ($c == '.') {
                while (isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) {
                    $tmp .= $query[$i];
                    ++$i;
                }
                $return[] = $tmp;
                // ~ General Sibling Selector
            } elseif ($c == '~') {
                $spaceAllowed = true;
                $tmp .= $query[$i++];
                while (isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) || $query[$i] == '*' || $query[$i] == ' ' && $spaceAllowed)) {
                    if ($query[$i] != ' ') {
                        $spaceAllowed = false;
                    }
                    $tmp .= $query[$i];
                    ++$i;
                }
                $return[] = $tmp;
                // + Adjacent sibling selectors
            } elseif ($c == '+') {
                $spaceAllowed = true;
                $tmp .= $query[$i++];
                while (isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) || $query[$i] == '*' || $spaceAllowed && $query[$i] == ' ')) {
                    if ($query[$i] != ' ') {
                        $spaceAllowed = false;
                    }
                    $tmp .= $query[$i];
                    ++$i;
                }
                $return[] = $tmp;
                // ATTRS
            } elseif ($c == '[') {
                $stack = 1;
                $tmp .= $c;
                while (isset($query[++$i])) {
                    $tmp .= $query[$i];
                    if ($query[$i] == '[') {
                        ++$stack;
                    } elseif ($query[$i] == ']') {
                        --$stack;
                        if (!$stack) {
                            break;
                        }
                    }
                }
                $return[] = $tmp;
                ++$i;
                // PSEUDO CLASSES
            } elseif ($c == ':') {
                $stack = 1;
                $tmp .= $query[$i++];
                while (isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) {
                    $tmp .= $query[$i];
                    ++$i;
                }
                // with arguments ?
                if (isset($query[$i]) && $query[$i] == '(') {
                    $tmp .= $query[$i];
                    $stack = 1;
                    while (isset($query[++$i])) {
                        $tmp .= $query[$i];
                        if ($query[$i] == '(') {
                            ++$stack;
                        } elseif ($query[$i] == ')') {
                            --$stack;
                            if (!$stack) {
                                break;
                            }
                        }
                    }
                    $return[] = $tmp;
                    ++$i;
                } else {
                    $return[] = $tmp;
                }
            } else {
                ++$i;
            }
        }
        foreach ($queries as $k => $q) {
            if (isset($q[0])) {
                if (isset($q[0][0]) && $q[0][0] == ':') {
                    array_unshift($queries[$k], '*');
                }
                if ($q[0] != '>') {
                    array_unshift($queries[$k], ' ');
                }
            }
        }
        return $queries;
    }