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  }