mirror of
https://github.com/PuerkitoBio/goquery
synced 2025-10-05 08:46:53 +08:00
87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package goquery
|
|
|
|
import (
|
|
"code.google.com/p/cascadia"
|
|
"exp/html"
|
|
"strings"
|
|
)
|
|
|
|
// TODO : Maybe make the Document's Root return a Selection, Find() on the
|
|
// Document is not very useful (would need all the same funcs as Selection)
|
|
func (this *Document) Find(selector string) *Selection {
|
|
return &Selection{findWithContext(selector, this.Root), this, nil}
|
|
}
|
|
|
|
// Find() gets the descendants of each element in the current set of matched
|
|
// elements, filtered by a selector. It returns a new Selection object
|
|
// containing these matched elements.
|
|
func (this *Selection) Find(selector string) *Selection {
|
|
return pushStack(this, findWithContext(selector, this.Nodes...))
|
|
}
|
|
|
|
func (this *Selection) FindSelection(sel *Selection) *Selection {
|
|
return nil
|
|
}
|
|
|
|
// Private internal implementation of the Find() methods
|
|
func findWithContext(selector string, nodes ...*html.Node) []*html.Node {
|
|
var matches []*html.Node
|
|
|
|
sel := cascadia.MustCompile(selector)
|
|
// Match the selector on each node
|
|
for _, n := range nodes {
|
|
// Go down one level, becausejQuery's Find() selects only within descendants
|
|
for _, c := range n.Child {
|
|
if c.Type == html.ElementNode {
|
|
matches = appendWithoutDuplicates(matches, sel.MatchAll(c))
|
|
}
|
|
}
|
|
}
|
|
return matches
|
|
}
|
|
|
|
// TODO : Filtered using Node and other Selection object
|
|
|
|
// Returns a new Selection object.
|
|
func (this *Document) Children() *Selection {
|
|
return this.ChildrenFiltered("")
|
|
}
|
|
|
|
// Returns a new Selection object.
|
|
func (this *Selection) Children() *Selection {
|
|
return this.ChildrenFiltered("")
|
|
}
|
|
|
|
// Returns a new Selection object.
|
|
func (this *Document) ChildrenFiltered(selector string) *Selection {
|
|
return &Selection{childrenWithContext(selector, this.Root), this, nil}
|
|
}
|
|
|
|
// Returns a new Selection object.
|
|
func (this *Selection) ChildrenFiltered(selector string) *Selection {
|
|
return &Selection{childrenWithContext(selector, this.Nodes...), this.document, nil}
|
|
}
|
|
|
|
func childrenWithContext(selector string, nodes ...*html.Node) []*html.Node {
|
|
var matches []*html.Node
|
|
var allChildren bool
|
|
var sel cascadia.Selector
|
|
|
|
selector = strings.TrimSpace(selector)
|
|
if selector == "*" || selector == "" {
|
|
// Get all children
|
|
allChildren = true
|
|
} else {
|
|
sel = cascadia.MustCompile(selector)
|
|
}
|
|
|
|
for _, n := range nodes {
|
|
for _, nchild := range n.Child {
|
|
if allChildren || sel(nchild) {
|
|
matches = append(matches, nchild)
|
|
}
|
|
}
|
|
}
|
|
return matches
|
|
}
|