Tag string might be complex and include id, class (classes) and attributes

This method takes such string as input and returns pure tag name and array of attributes

@param string $selector

@return array [$tag, $attributes]
339902
protected static function parse_tag_string ($selector) {
		$attributes = [];
		/**
		 * Attributes processing
		 */
		$pos = mb_strpos($selector, '[');
		if ($pos !== false) {
			$regular_attributes = explode('][', mb_substr($selector, $pos + 1, -1));
			$selector           = mb_substr($selector, 0, $pos);
			foreach ($regular_attributes as &$attr) {
				/**
				 * For attribute without value we just put `true`, as this will be treated as boolean attribute
				 */
				$attr                 = explode('=', $attr, 2);
				$attributes[$attr[0]] = isset($attr[1]) ? $attr[1] : true;
			}
			unset($regular_attributes, $attr);
		}
		/**
		 * Classes processing
		 */
		$pos = mb_strpos($selector, '.');
		if ($pos !== false) {
			$attributes['class'] = trim(str_replace('.', ' ', mb_substr($selector, $pos)));
			$selector            = mb_substr($selector, 0, $pos);
		}
		unset($pos);
		/**
		 * Id and tag determination
		 */
		$selector = explode('#', $selector);
		$tag      = $selector[0];
		/**
		 * Convenient support of custom tags for Web Components
		 *
		 * Allows to write BananaHTML::custom_tag() that will be translated to <custom-tag></custom-tag>
		 */
		if (isset($selector[1])) {
			$attributes['id'] = $selector[1];
		}
		return [$tag, $attributes];
	}
849455
public function index($selector=null)
    {
        if ($selector === null) {
            if ($node = $this->getFirstElmNode()) {
                $position = 0;
                while ($node && ($node = $node->previousSibling)) {
                    if ($node instanceof \DOMElement) {
                        $position++;
                    } else {
                        break;
                    }
                }
                return $position;
            }
        } else {
            foreach ($this as $key => $node) {
                if ($node->is($selector)) {
                    return $key;
                }
            }
        }

        return -1;
    }
339643
public function calculateSpecificityBasedOnASelector($selector)
    {
        $idSelectorsPattern = "  \#";
        $classAttributesPseudoClassesSelectorsPattern = "  (\.[\w]+)                     # classes
                        |
                        \[(\w+)                       # attributes
                        |
                        (\:(                          # pseudo classes
                          link|visited|active
                          |hover|focus
                          |lang
                          |target
                          |enabled|disabled|checked|indeterminate
                          |root
                          |nth-child|nth-last-child|nth-of-type|nth-last-of-type
                          |first-child|last-child|first-of-type|last-of-type
                          |only-child|only-of-type
                          |empty|contains
                        ))";

        $typePseudoElementsSelectorPattern = "  ((^|[\s\+\>\~]+)[\w]+       # elements
                        |
                        \:{1,2}(                    # pseudo-elements
                          after|before
                          |first-letter|first-line
                          |selection
                        )
                      )";

        return new Specificity(
            preg_match_all("/{$idSelectorsPattern}/ix", $selector, $matches),
            preg_match_all("/{$classAttributesPseudoClassesSelectorsPattern}/ix", $selector, $matches),
            preg_match_all("/{$typePseudoElementsSelectorPattern}/ix", $selector, $matches)
        );
    }
261889
protected function findById($selector)
    {
        if (preg_match('/^#[\w\-:]+$/', $selector)) {
            return $this->driver->findElement(WebDriverBy::id(substr($selector, 1)));
        }
    }
821641
protected function multiplySelectors($selectors)
    {
        // find parent selectors

        $parentSelectors = $this->findClosestSelectors();
        if (is_null($parentSelectors)) {
            // kill parent reference in top level selector
            foreach ($selectors as &$s) {
                $this->expandParentSelectors($s, '');
            }

            return $selectors;
        }

        $out = array();
        foreach ($parentSelectors as $parent) {
            foreach ($selectors as $child) {
                $count = $this->expandParentSelectors($child, $parent);

                // don't prepend the parent tag if & was used
                if ($count > 0) {
                    $out[] = trim($child);
                } else {
                    $out[] = trim($parent.' '.$child);
                }
            }
        }

        return $out;
    }
834829
public function hasRuleBySelector( $selector ){
		foreach( $this->rules as $rule )
			if( $selector == $rule->getSelector() )
				return TRUE;
		return FALSE;
	}
232436
public static function toXPath($selector)
    {
        if (isset(self::$compiled[$selector])){
            return self::$compiled[$selector];
        }

        // Select DOMText
        if ($selector === 'text') {
            return '//text()';
        }

        // Select DOMComment
        if ($selector === 'comment') {
            return '//comment()';
        }

        if (!class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
            throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector 2.8+ is not installed (you can use filterXPath instead).');
        }

        $converter = new CssSelectorConverter(true);

        $xPathQuery = $converter->toXPath($selector);
        self::$compiled[$selector] = $xPathQuery;

        return $xPathQuery;
    }
80761
public function all($selector)
    {
        try {
            return $this->driver->findElements(
                WebDriverBy::cssSelector($this->format($selector))
            );
        } catch (Exception $e) {
            //
        }

        return [];
    }
985227
function(selector) {
        var token = {},     // one token per simple selector (left selector holds combinator)
            tokens = [],    // array of tokens
            id,             // unique id for the simple selector (if found)
            found = false,  // whether or not any matches were found this pass
            patterns = Y.Selector._patterns,
            match;          // the regex match

        selector = Y.Selector._replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes

        /*
            Search for selector patterns, store, and strip them from the selector string
            until no patterns match (invalid selector) or we run out of chars.

            Multiple attributes and pseudos are allowed, in any order.
            for example:
                'form:first-child[type=button]:not(button)[lang|=en]'
        */
        do {
            found = false; // reset after full pass
            for (var re in patterns) {
                if (YAHOO.lang.hasOwnProperty(patterns, re)) {
                    if (re != 'tag' && re != 'combinator') { // only one allowed
                        token[re] = token[re] || [];
                    }
                    if ( (match = patterns[re].exec(selector)) ) { // note assignment
                        found = true;
                        if (re != 'tag' && re != 'combinator') { // only one allowed
                            // capture ID for fast path to element
                            if (re === 'attributes' && match[1] === 'id') {
                                token.id = match[3];
                            }

                            token[re].push(match.slice(1));
                        } else { // single selector (tag, combinator)
                            token[re] = match[1];
                        }
                        selector = selector.replace(match[0], ''); // strip current match from selector
                        if (re === 'combinator' || !selector.length) { // next token or done
                            token.attributes = Y.Selector._fixAttributes(token.attributes);
                            token.pseudos = token.pseudos || [];
                            token.tag = token.tag ? token.tag.toUpperCase() : '*';
                            tokens.push(token);

                            token = { // prep next token
                                previous: token
                            };
                        }
                    }
                }
            }
        } while (found);

        return tokens;
    }
978876
function (selector) {
		var score = [0, 0, 0];
		var parts = selector.split(' ');
		var part;
		var match;

		//TODO: clean the ':not' part since the last ELEMENT_RE will pick it up
		while (part = parts.shift(), typeof part === 'string') {
			// find all pseudo-elements
			match = _find(part, PSEUDO_ELEMENTS_RE);
			score[2] = match;
			// and remove them
			match && (part = part.replace(PSEUDO_ELEMENTS_RE, ''));
			// find all pseudo-classes
			match = _find(part, PSEUDO_CLASSES_RE);
			score[1] = match;
			// and remove them
			match && (part = part.replace(PSEUDO_CLASSES_RE, ''));
			// find all attributes
			match = _find(part, ATTR_RE);
			score[1] += match;
			// and remove them
			match && (part = part.replace(ATTR_RE, ''));
			// find all IDs
			match = _find(part, ID_RE);
			score[0] = match;
			// and remove them
			match && (part = part.replace(ID_RE, ''));
			// find all classes
			match = _find(part, CLASS_RE);
			score[1] += match;
			// and remove them
			match && (part = part.replace(CLASS_RE, ''));
			// find all elements
			score[2] += _find(part, ELEMENT_RE);
		}

		return parseInt(score.join(''), 10);
	}
1048874
public function querySelector($selector)
    {
        $converter = new CssSelectorConverter();

        $xpathQuery = $converter->toXPath($selector);

        $result = $this->xpath->query($xpathQuery);

        if (!$result->item(0)) {
            return null;
        }
        return new Node($result->item(0));
    }
736503
function(selector) {
            selector = selector || '';
            selector = Selector._replaceShorthand(Y.Lang.trim(selector)); 
            var token = Selector._getToken(),     // one token per simple selector (left selector holds combinator)
                query = selector, // original query for debug report
                tokens = [],    // array of tokens
                found = false,  // whether or not any matches were found this pass
                match,         // the regex match
                test,
                i, parser;

            /*
                Search for selector patterns, store, and strip them from the selector string
                until no patterns match (invalid selector) or we run out of chars.

                Multiple attributes and pseudos are allowed, in any order.
                for example:
                    'form:first-child[type=button]:not(button)[lang|=en]'
            */
            outer:
            do {
                found = false; // reset after full pass
                for (i = 0; (parser = Selector._parsers[i++]);) {
                    if ( (match = parser.re.exec(selector)) ) { // note assignment
                        if (parser.name !== COMBINATOR ) {
                            token.selector = selector;
                        }
                        selector = selector.replace(match[0], ''); // strip current match from selector
                        if (!selector.length) {
                            token.last = true;
                        }

                        if (Selector._attrFilters[match[1]]) { // convert class to className, etc.
                            match[1] = Selector._attrFilters[match[1]];
                        }

                        test = parser.fn(match, token);
                        if (test === false) { // selector not supported
                            found = false;
                            break outer;
                        } else if (test) {
                            token.tests.push(test);
                        }

                        if (!selector.length || parser.name === COMBINATOR) {
                            tokens.push(token);
                            token = Selector._getToken(token);
                            if (parser.name === COMBINATOR) {
                                token.combinator = Y.Selector.combinators[match[1]];
                            }
                        }
                        found = true;
                    }
                }
            } while (found && selector.length);

            if (!found || selector.length) { // not fully parsed
                tokens = [];
            }
            return tokens;
        }
331637
public function parent($selector=null)
    {
        $result = $this->createChildInstance();

        if (isset($this->document) && $this->length > 0) {
            foreach ($this->nodes as $node) {
                if ($node->parentNode) {
                    $result->addDomNode($node->parentNode);
                }
            }

            if ($selector) {
                $result = $result->filter($selector);
            }
        }

        return $result;
    }
907282
protected function getSelectedNode(\DOMDocument $dom, string $selector): \DOMNode
    {
        $xPath = new \DOMXPath($dom);

        return $xPath->query((new CssSelectorConverter())->toXPath($selector))->item(0);
    }
1248604
public function children($selector=null)
    {
        $result = $this->createChildInstance();

        if (isset($this->document) && $this->length > 0) {
            if (isset($this->root_instance) || $this->getXpathQuery()) {
                foreach ($this->nodes as $node) {
                    if ($node->hasChildNodes()) {
                        $result->loadDomNodeList($node->childNodes);
                    }
                }
            } else {
                $result->loadDomNodeList($this->document->childNodes);
            }

            if ($selector !== false) { // filter out text nodes
                $filtered_elements = array();
                foreach ($result->getElements() as $result_elm) {
                    $filtered_elements[] = $result_elm;
                }
                $result->nodes = $filtered_elements;
                $result->length = \count($result->nodes);
            }

            if ($selector) {
                $result = $result->filter($selector);
            }
        }

        return $result;
    }
426159
public function format($selector)
    {
        $sortedElements = collect($this->elements)->sortByDesc(function ($element, $key) {
            return strlen($key);
        })->toArray();

        $selector = str_replace(
            array_keys($sortedElements), array_values($sortedElements), $originalSelector = $selector
        );

        if (Str::startsWith($selector, '@') && $selector === $originalSelector) {
            $selector = '[dusk="'.explode('@', $selector)[1].'"]';
        }

        return trim($this->prefix.' '.$selector);
    }
952977
public function selector($selector)
    {
        if( is_scalar($selector) )
        {
            $this->selector = json_encode($selector);
        }
        else
        {
            $this->selector = Buffering\Callback::do($selector);
        }
        

        return $this;
    }