github.com/godaddy-x/freego@v1.0.156/goquery/filter.go (about) 1 package goquery 2 3 import "golang.org/x/net/html" 4 5 // Filter reduces the set of matched elements to those that match the selector string. 6 // It returns a new Selection object for this subset of matching elements. 7 func (s *Selection) Filter(selector string) *Selection { 8 return s.FilterMatcher(compileMatcher(selector)) 9 } 10 11 // FilterMatcher reduces the set of matched elements to those that match 12 // the given matcher. It returns a new Selection object for this subset 13 // of matching elements. 14 func (s *Selection) FilterMatcher(m Matcher) *Selection { 15 return pushStack(s, winnow(s, m, true)) 16 } 17 18 // Not removes elements from the Selection that match the selector string. 19 // It returns a new Selection object with the matching elements removed. 20 func (s *Selection) Not(selector string) *Selection { 21 return s.NotMatcher(compileMatcher(selector)) 22 } 23 24 // NotMatcher removes elements from the Selection that match the given matcher. 25 // It returns a new Selection object with the matching elements removed. 26 func (s *Selection) NotMatcher(m Matcher) *Selection { 27 return pushStack(s, winnow(s, m, false)) 28 } 29 30 // FilterFunction reduces the set of matched elements to those that pass the function's test. 31 // It returns a new Selection object for this subset of elements. 32 func (s *Selection) FilterFunction(f func(int, *Selection) bool) *Selection { 33 return pushStack(s, winnowFunction(s, f, true)) 34 } 35 36 // NotFunction removes elements from the Selection that pass the function's test. 37 // It returns a new Selection object with the matching elements removed. 38 func (s *Selection) NotFunction(f func(int, *Selection) bool) *Selection { 39 return pushStack(s, winnowFunction(s, f, false)) 40 } 41 42 // FilterNodes reduces the set of matched elements to those that match the specified nodes. 43 // It returns a new Selection object for this subset of elements. 44 func (s *Selection) FilterNodes(nodes ...*html.Node) *Selection { 45 return pushStack(s, winnowNodes(s, nodes, true)) 46 } 47 48 // NotNodes removes elements from the Selection that match the specified nodes. 49 // It returns a new Selection object with the matching elements removed. 50 func (s *Selection) NotNodes(nodes ...*html.Node) *Selection { 51 return pushStack(s, winnowNodes(s, nodes, false)) 52 } 53 54 // FilterSelection reduces the set of matched elements to those that match a 55 // node in the specified Selection object. 56 // It returns a new Selection object for this subset of elements. 57 func (s *Selection) FilterSelection(sel *Selection) *Selection { 58 if sel == nil { 59 return pushStack(s, winnowNodes(s, nil, true)) 60 } 61 return pushStack(s, winnowNodes(s, sel.Nodes, true)) 62 } 63 64 // NotSelection removes elements from the Selection that match a node in the specified 65 // Selection object. It returns a new Selection object with the matching elements removed. 66 func (s *Selection) NotSelection(sel *Selection) *Selection { 67 if sel == nil { 68 return pushStack(s, winnowNodes(s, nil, false)) 69 } 70 return pushStack(s, winnowNodes(s, sel.Nodes, false)) 71 } 72 73 // Intersection is an alias for FilterSelection. 74 func (s *Selection) Intersection(sel *Selection) *Selection { 75 return s.FilterSelection(sel) 76 } 77 78 // Has reduces the set of matched elements to those that have a descendant 79 // that matches the selector. 80 // It returns a new Selection object with the matching elements. 81 func (s *Selection) Has(selector string) *Selection { 82 return s.HasSelection(s.document.Find(selector)) 83 } 84 85 // HasMatcher reduces the set of matched elements to those that have a descendant 86 // that matches the matcher. 87 // It returns a new Selection object with the matching elements. 88 func (s *Selection) HasMatcher(m Matcher) *Selection { 89 return s.HasSelection(s.document.FindMatcher(m)) 90 } 91 92 // HasNodes reduces the set of matched elements to those that have a 93 // descendant that matches one of the nodes. 94 // It returns a new Selection object with the matching elements. 95 func (s *Selection) HasNodes(nodes ...*html.Node) *Selection { 96 return s.FilterFunction(func(_ int, sel *Selection) bool { 97 // Add all nodes that contain one of the specified nodes 98 for _, n := range nodes { 99 if sel.Contains(n) { 100 return true 101 } 102 } 103 return false 104 }) 105 } 106 107 // HasSelection reduces the set of matched elements to those that have a 108 // descendant that matches one of the nodes of the specified Selection object. 109 // It returns a new Selection object with the matching elements. 110 func (s *Selection) HasSelection(sel *Selection) *Selection { 111 if sel == nil { 112 return s.HasNodes() 113 } 114 return s.HasNodes(sel.Nodes...) 115 } 116 117 // End ends the most recent filtering operation in the current chain and 118 // returns the set of matched elements to its previous state. 119 func (s *Selection) End() *Selection { 120 if s.prevSel != nil { 121 return s.prevSel 122 } 123 return newEmptySelection(s.document) 124 } 125 126 // Filter based on the matcher, and the indicator to keep (Filter) or 127 // to get rid of (Not) the matching elements. 128 func winnow(sel *Selection, m Matcher, keep bool) []*html.Node { 129 // Optimize if keep is requested 130 if keep { 131 return m.Filter(sel.Nodes) 132 } 133 // Use grep 134 return grep(sel, func(i int, s *Selection) bool { 135 return !m.Match(s.Get(0)) 136 }) 137 } 138 139 // Filter based on an array of nodes, and the indicator to keep (Filter) or 140 // to get rid of (Not) the matching elements. 141 func winnowNodes(sel *Selection, nodes []*html.Node, keep bool) []*html.Node { 142 if len(nodes)+len(sel.Nodes) < minNodesForSet { 143 return grep(sel, func(i int, s *Selection) bool { 144 return isInSlice(nodes, s.Get(0)) == keep 145 }) 146 } 147 148 set := make(map[*html.Node]bool) 149 for _, n := range nodes { 150 set[n] = true 151 } 152 return grep(sel, func(i int, s *Selection) bool { 153 return set[s.Get(0)] == keep 154 }) 155 } 156 157 // Filter based on a function test, and the indicator to keep (Filter) or 158 // to get rid of (Not) the matching elements. 159 func winnowFunction(sel *Selection, f func(int, *Selection) bool, keep bool) []*html.Node { 160 return grep(sel, func(i int, s *Selection) bool { 161 return f(i, s) == keep 162 }) 163 }