Every time you call element.matches('.active[type="submit"]'), the browser parses that selector and checks the element against it — no tree walk, just a yes/no on one node. Event delegation, closest(), and most UI libraries lean on it constantly. Here you'll build the core of it for a compound selector: a run of simple selectors glued together with no combinators (no spaces, >, +, or ~), like input.btn.primary[type="submit"].
Implement cssSelectorMatches(element, selector). Return true only if the element satisfies every part of the compound. See MDN: Element.matches.
function cssSelectorMatches(element, selector) {
// returns true if `element` satisfies the compound selector
}
// <input class="btn primary" type="submit" />
cssSelectorMatches(el, 'input.btn.primary'); // true
cssSelectorMatches(el, 'input.btn.ghost'); // false — one class is absent
cssSelectorMatches(el, '[type="submit"]'); // true
// <a href="https://example.com/docs">
cssSelectorMatches(el, '[href^="https://"]'); // true — prefix match
cssSelectorMatches(el, '[href$="/docs"]'); // true — suffix match
cssSelectorMatches(el, '*'); // true — universal
#id, .class, [attr], *. All must match the same element.[a=v], [a~=v] (word in a space list), [a^=v] (prefix), [a$=v] (suffix), [a*=v] (substring), [a|=v] (v or v-…). Values may be quoted or not..x matches if x is one of them. Tag comparison is case-insensitive.null, comments all return false.