mirror of
https://github.com/PuerkitoBio/goquery.git
synced 2026-09-25 11:32:06 +00:00
IsMatcher handled multi-node selections by calling m.Filter(s.Nodes) and checking whether the returned slice was non-empty, forcing the matcher to walk the whole selection and materialize all matches even though the API only needs an existence check. This commit replaces this with a simple loop over s.Nodes that calls m.Match(n) and returns true on the first match. This also makes the single-node special case unnecessary. Benchmark results on arm64 over 10 runs: name old time/op new time/op delta Is-8 4.67µs 1.32µs -71.7% IsPositional-8 21.44µs 0.82µs -96.2% name old B/op new B/op delta Is-8 96 80 -16.7% IsPositional-8 1144 184 -83.9% name old allocs new allocs delta Is-8 5 4 -20.0% IsPositional-8 11 7 -36.4%
61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
package goquery
|
|
|
|
import "golang.org/x/net/html"
|
|
|
|
// Is checks the current matched set of elements against a selector and
|
|
// returns true if at least one of these elements matches.
|
|
func (s *Selection) Is(selector string) bool {
|
|
return s.IsMatcher(compileMatcher(selector))
|
|
}
|
|
|
|
// IsMatcher checks the current matched set of elements against a matcher and
|
|
// returns true if at least one of these elements matches.
|
|
func (s *Selection) IsMatcher(m Matcher) bool {
|
|
for _, n := range s.Nodes {
|
|
if m.Match(n) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsFunction checks the current matched set of elements against a predicate and
|
|
// returns true if at least one of these elements matches.
|
|
func (s *Selection) IsFunction(f func(int, *Selection) bool) bool {
|
|
for i, n := range s.Nodes {
|
|
if f(i, newSingleSelection(n, s.document)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsSelection checks the current matched set of elements against a Selection object
|
|
// and returns true if at least one of these elements matches.
|
|
func (s *Selection) IsSelection(sel *Selection) bool {
|
|
if sel == nil {
|
|
return false
|
|
}
|
|
return s.IsNodes(sel.Nodes...)
|
|
}
|
|
|
|
// IsNodes checks the current matched set of elements against the specified nodes
|
|
// and returns true if at least one of these elements matches.
|
|
func (s *Selection) IsNodes(nodes ...*html.Node) bool {
|
|
for _, n := range s.Nodes {
|
|
if isInSlice(nodes, n) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Contains returns true if the specified Node is within,
|
|
// at any depth, one of the nodes in the Selection object.
|
|
// It is NOT inclusive, to behave like jQuery's implementation, and
|
|
// unlike Javascript's .contains, so if the contained
|
|
// node is itself in the selection, it returns false.
|
|
func (s *Selection) Contains(n *html.Node) bool {
|
|
return sliceContains(s.Nodes, n)
|
|
}
|