func hasDescendantMatch(n *html.Node, a Matcher) bool {
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		if a.Match(c) || (c.Type == html.ElementNode && hasDescendantMatch(c, a)) {
			return true
		}
	}
	return false
}
hasDescendantMatch performs a depth-first search of n's descendants,
testing whether any of them match a. It returns true as soon as a match is
found, or false if no match is found.
package cascadia
import (
	"bytes"
	"fmt"
	"regexp"
	"strings"
	"golang.org/x/net/html"
	"golang.org/x/net/html/atom"
)
type abstractPseudoClass struct{}
func (s abstractPseudoClass) Specificity() Specificity {
	return Specificity{0, 1, 0}
}
func (c abstractPseudoClass) PseudoElement() string {
	return ""
}
type relativePseudoClassSelector struct {
	name  string  
	match SelectorGroup
}
func (s relativePseudoClassSelector) Match(n *html.Node) bool {
	if n.Type != html.ElementNode {
		return false
	}
	switch s.name {
	case "not":
		return !s.match.Match(n)
	case "has":
		return hasDescendantMatch(n, s.match)
	case "haschild":
		return hasChildMatch(n, s.match)
	default:
		panic(fmt.Sprintf("unsupported relative pseudo class selector : %s", s.name))
	}
}
func hasChildMatch(n *html.Node, a Matcher) bool {
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		if a.Match(c) {
			return true
		}
	}
	return false
}