Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions traversal.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,19 @@ func (s *Selection) FindSelection(sel *Selection) *Selection {
// Selection, filtered by some nodes. It returns a new Selection object
// containing these matched elements.
func (s *Selection) FindNodes(nodes ...*html.Node) *Selection {
return pushStack(s, mapNodes(nodes, func(i int, n *html.Node) []*html.Node {
if sliceContains(s.Nodes, n) {
return []*html.Node{n}
// Each source node maps to at most itself (when it is a descendant of the
// current selection), so there is nothing to deduplicate across distinct
// sources. Skip mapNodes' callback indirection and append matches directly,
// while still discarding duplicate input nodes so the resulting Selection
// stays a proper set. The cheap isInSlice check runs first so duplicate
// inputs short-circuit before the more expensive sliceContains tree walk.
var result []*html.Node
for _, n := range nodes {
if !isInSlice(result, n) && sliceContains(s.Nodes, n) {
result = append(result, n)
}
return nil
}))
}
return pushStack(s, result)
}

// Contents gets the children of each element in the Selection,
Expand Down
10 changes: 10 additions & 0 deletions traversal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ func TestFindBig(t *testing.T) {
assertLength(t, sel3.Nodes, 248)
}

func TestFindNodesDuplicateInput(t *testing.T) {
doc := DocW()
sel := doc.Find("body")
span := doc.Find("span").Nodes[0]
// Duplicate input nodes must be discarded so the resulting Selection
// stays a proper set.
sel2 := sel.FindNodes(span, span)
assertLength(t, sel2.Nodes, 1)
}

func TestChainedFind(t *testing.T) {
sel := Doc().Find("div.hero-unit").Find(".row-fluid")
assertLength(t, sel.Nodes, 4)
Expand Down
Loading