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