From 36f7b3b68ef4ab4205593cb85dc7dc0b40a4b38d Mon Sep 17 00:00:00 2001 From: jvoisin Date: Fri, 5 Jun 2026 22:35:48 +0200 Subject: [PATCH] cleanup: thread []*html.Node through winnow, drop temp Selection winnow only ever reads sel.Nodes; the *Selection parameter was incidental. Change its signature to winnow(nodes []*html.Node, ...) and update its three callers (FilterMatcher, NotMatcher, filterAndPush). filterAndPush no longer needs to fabricate a throwaway Selection to satisfy the call. While this change has o measurable runtime effect, it simplifies the code a bit, by making winnow's signature clearer, and removes a now-useless line and its associated comment in filterAndPush --- filter.go | 12 ++++++------ traversal.go | 5 +---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/filter.go b/filter.go index 7d2e8f9..2964b8a 100644 --- a/filter.go +++ b/filter.go @@ -12,7 +12,7 @@ func (s *Selection) Filter(selector string) *Selection { // the given matcher. It returns a new Selection object for this subset // of matching elements. func (s *Selection) FilterMatcher(m Matcher) *Selection { - return pushStack(s, winnow(s, m, true)) + return pushStack(s, winnow(s.Nodes, m, true)) } // Not removes elements from the Selection that match the selector string. @@ -24,7 +24,7 @@ func (s *Selection) Not(selector string) *Selection { // NotMatcher removes elements from the Selection that match the given matcher. // It returns a new Selection object with the matching elements removed. func (s *Selection) NotMatcher(m Matcher) *Selection { - return pushStack(s, winnow(s, m, false)) + return pushStack(s, winnow(s.Nodes, m, false)) } // FilterFunction reduces the set of matched elements to those that pass the function's test. @@ -142,14 +142,14 @@ func (s *Selection) End() *Selection { // Filter based on the matcher, and the indicator to keep (Filter) or // to get rid of (Not) the matching elements. -func winnow(sel *Selection, m Matcher, keep bool) []*html.Node { +func winnow(nodes []*html.Node, m Matcher, keep bool) []*html.Node { // Optimize if keep is requested if keep { - return m.Filter(sel.Nodes) + return m.Filter(nodes) } // Not path: call Match directly on each node, no Selection wrapper needed - result := make([]*html.Node, 0, len(sel.Nodes)) - for _, n := range sel.Nodes { + result := make([]*html.Node, 0, len(nodes)) + for _, n := range nodes { if !m.Match(n) { result = append(result, n) } diff --git a/traversal.go b/traversal.go index 44521b7..da41140 100644 --- a/traversal.go +++ b/traversal.go @@ -537,10 +537,7 @@ func (s *Selection) PrevMatcherUntilNodes(filter Matcher, nodes ...*html.Node) * // Filter and push filters the nodes based on a matcher, and pushes the results // on the stack, with the srcSel as previous selection. func filterAndPush(srcSel *Selection, nodes []*html.Node, m Matcher) *Selection { - // Create a temporary Selection with the specified nodes to filter using winnow - sel := &Selection{nodes, srcSel.document, nil} - // Filter based on matcher and push on stack - return pushStack(srcSel, winnow(sel, m, true)) + return pushStack(srcSel, winnow(nodes, m, true)) } // Internal implementation of Find that return raw nodes.