| package goquery |
| |
| import ( |
| "golang.org/x/net/html" |
| ) |
| |
| func getChildren(n *html.Node) (result []*html.Node) { |
| for c := n.FirstChild; c != nil; c = c.NextSibling { |
| result = append(result, c) |
| } |
| return result |
| } |
| |
| // Loop through all container nodes to search for the target node. |
| func sliceContains(container []*html.Node, contained *html.Node) bool { |
| for _, n := range container { |
| if nodeContains(n, contained) { |
| return true |
| } |
| } |
| |
| return false |
| } |
| |
| // Checks if the contained node is within the container node. |
| func nodeContains(container *html.Node, contained *html.Node) bool { |
| // Check if the parent of the contained node is the container node, traversing |
| // upward until the top is reached, or the container is found. |
| for contained = contained.Parent; contained != nil; contained = contained.Parent { |
| if container == contained { |
| return true |
| } |
| } |
| return false |
| } |
| |
| // Checks if the target node is in the slice of nodes. |
| func isInSlice(slice []*html.Node, node *html.Node) bool { |
| return indexInSlice(slice, node) > -1 |
| } |
| |
| // Returns the index of the target node in the slice, or -1. |
| func indexInSlice(slice []*html.Node, node *html.Node) int { |
| if node != nil { |
| for i, n := range slice { |
| if n == node { |
| return i |
| } |
| } |
| } |
| return -1 |
| } |
| |
| // Appends the new nodes to the target slice, making sure no duplicate is added. |
| // There is no check to the original state of the target slice, so it may still |
| // contain duplicates. The target slice is returned because append() may create |
| // a new underlying array. |
| func appendWithoutDuplicates(target []*html.Node, nodes []*html.Node) []*html.Node { |
| for _, n := range nodes { |
| if !isInSlice(target, n) { |
| target = append(target, n) |
| } |
| } |
| |
| return target |
| } |
| |
| // Loop through a selection, returning only those nodes that pass the predicate |
| // function. |
| func grep(sel *Selection, predicate func(i int, s *Selection) bool) (result []*html.Node) { |
| for i, n := range sel.Nodes { |
| if predicate(i, newSingleSelection(n, sel.document)) { |
| result = append(result, n) |
| } |
| } |
| return result |
| } |
| |
| // Creates a new Selection object based on the specified nodes, and keeps the |
| // source Selection object on the stack (linked list). |
| func pushStack(fromSel *Selection, nodes []*html.Node) *Selection { |
| result := &Selection{nodes, fromSel.document, fromSel} |
| return result |
| } |