Skip to content
Open
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
69 changes: 37 additions & 32 deletions traversal.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,116 +271,116 @@ func (s *Selection) ParentsMatcherUntilNodes(filter Matcher, nodes ...*html.Node
// Siblings gets the siblings of each element in the Selection. It returns
// a new Selection object containing the matched elements.
func (s *Selection) Siblings() *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil))
return pushStack(s, getSiblingNodes(s.Nodes, siblingAll))
}

// SiblingsFiltered gets the siblings of each element in the Selection
// filtered by a selector. It returns a new Selection object containing the
// matched elements.
func (s *Selection) SiblingsFiltered(selector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), compileMatcher(selector))
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll), compileMatcher(selector))
}

// SiblingsMatcher gets the siblings of each element in the Selection
// filtered by a matcher. It returns a new Selection object containing the
// matched elements.
func (s *Selection) SiblingsMatcher(m Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), m)
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll), m)
}

// Next gets the immediately following sibling of each element in the
// Selection. It returns a new Selection object containing the matched elements.
func (s *Selection) Next() *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil))
return pushStack(s, getSiblingNodes(s.Nodes, siblingNext))
}

// NextFiltered gets the immediately following sibling of each element in the
// Selection filtered by a selector. It returns a new Selection object
// containing the matched elements.
func (s *Selection) NextFiltered(selector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), compileMatcher(selector))
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext), compileMatcher(selector))
}

// NextMatcher gets the immediately following sibling of each element in the
// Selection filtered by a matcher. It returns a new Selection object
// containing the matched elements.
func (s *Selection) NextMatcher(m Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), m)
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext), m)
}

// NextAll gets all the following siblings of each element in the
// Selection. It returns a new Selection object containing the matched elements.
func (s *Selection) NextAll() *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil))
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextAll))
}

// NextAllFiltered gets all the following siblings of each element in the
// Selection filtered by a selector. It returns a new Selection object
// containing the matched elements.
func (s *Selection) NextAllFiltered(selector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), compileMatcher(selector))
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll), compileMatcher(selector))
}

// NextAllMatcher gets all the following siblings of each element in the
// Selection filtered by a matcher. It returns a new Selection object
// containing the matched elements.
func (s *Selection) NextAllMatcher(m Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), m)
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll), m)
}

// Prev gets the immediately preceding sibling of each element in the
// Selection. It returns a new Selection object containing the matched elements.
func (s *Selection) Prev() *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil))
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrev))
}

// PrevFiltered gets the immediately preceding sibling of each element in the
// Selection filtered by a selector. It returns a new Selection object
// containing the matched elements.
func (s *Selection) PrevFiltered(selector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), compileMatcher(selector))
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev), compileMatcher(selector))
}

// PrevMatcher gets the immediately preceding sibling of each element in the
// Selection filtered by a matcher. It returns a new Selection object
// containing the matched elements.
func (s *Selection) PrevMatcher(m Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), m)
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev), m)
}

// PrevAll gets all the preceding siblings of each element in the
// Selection. It returns a new Selection object containing the matched elements.
func (s *Selection) PrevAll() *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil))
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevAll))
}

// PrevAllFiltered gets all the preceding siblings of each element in the
// Selection filtered by a selector. It returns a new Selection object
// containing the matched elements.
func (s *Selection) PrevAllFiltered(selector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), compileMatcher(selector))
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll), compileMatcher(selector))
}

// PrevAllMatcher gets all the preceding siblings of each element in the
// Selection filtered by a matcher. It returns a new Selection object
// containing the matched elements.
func (s *Selection) PrevAllMatcher(m Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), m)
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll), m)
}

// NextUntil gets all following siblings of each element up to but not
// including the element matched by the selector. It returns a new Selection
// object containing the matched elements.
func (s *Selection) NextUntil(selector string) *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return pushStack(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
compileMatcher(selector), nil))
}

// NextUntilMatcher gets all following siblings of each element up to but not
// including the element matched by the matcher. It returns a new Selection
// object containing the matched elements.
func (s *Selection) NextUntilMatcher(m Matcher) *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return pushStack(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
m, nil))
}

Expand All @@ -398,23 +398,23 @@ func (s *Selection) NextUntilSelection(sel *Selection) *Selection {
// including the element matched by the nodes. It returns a new Selection
// object containing the matched elements.
func (s *Selection) NextUntilNodes(nodes ...*html.Node) *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return pushStack(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
nil, nodes))
}

// PrevUntil gets all preceding siblings of each element up to but not
// including the element matched by the selector. It returns a new Selection
// object containing the matched elements.
func (s *Selection) PrevUntil(selector string) *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return pushStack(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
compileMatcher(selector), nil))
}

// PrevUntilMatcher gets all preceding siblings of each element up to but not
// including the element matched by the matcher. It returns a new Selection
// object containing the matched elements.
func (s *Selection) PrevUntilMatcher(m Matcher) *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return pushStack(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
m, nil))
}

Expand All @@ -432,23 +432,23 @@ func (s *Selection) PrevUntilSelection(sel *Selection) *Selection {
// including the element matched by the nodes. It returns a new Selection
// object containing the matched elements.
func (s *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection {
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return pushStack(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
nil, nodes))
}

// NextFilteredUntil is like NextUntil, with the option to filter
// the results based on a selector string.
// It returns a new Selection object containing the matched elements.
func (s *Selection) NextFilteredUntil(filterSelector, untilSelector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
compileMatcher(untilSelector), nil), compileMatcher(filterSelector))
}

// NextFilteredUntilMatcher is like NextUntilMatcher, with the option to filter
// the results based on a matcher.
// It returns a new Selection object containing the matched elements.
func (s *Selection) NextFilteredUntilMatcher(filter, until Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
until, nil), filter)
}

Expand All @@ -473,31 +473,31 @@ func (s *Selection) NextMatcherUntilSelection(filter Matcher, sel *Selection) *S
// option to filter the results based on a selector string. It returns a new
// Selection object containing the matched elements.
func (s *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
nil, nodes), compileMatcher(filterSelector))
}

// NextMatcherUntilNodes is like NextUntilNodes, with the
// option to filter the results based on a matcher. It returns a new
// Selection object containing the matched elements.
func (s *Selection) NextMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingNextUntil,
nil, nodes), filter)
}

// PrevFilteredUntil is like PrevUntil, with the option to filter
// the results based on a selector string.
// It returns a new Selection object containing the matched elements.
func (s *Selection) PrevFilteredUntil(filterSelector, untilSelector string) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
compileMatcher(untilSelector), nil), compileMatcher(filterSelector))
}

// PrevFilteredUntilMatcher is like PrevUntilMatcher, with the option to filter
// the results based on a matcher.
// It returns a new Selection object containing the matched elements.
func (s *Selection) PrevFilteredUntilMatcher(filter, until Matcher) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
until, nil), filter)
}

Expand All @@ -522,15 +522,15 @@ func (s *Selection) PrevMatcherUntilSelection(filter Matcher, sel *Selection) *S
// option to filter the results based on a selector string. It returns a new
// Selection object containing the matched elements.
func (s *Selection) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
nil, nodes), compileMatcher(filterSelector))
}

// PrevMatcherUntilNodes is like PrevUntilNodes, with the
// option to filter the results based on a matcher. It returns a new
// Selection object containing the matched elements.
func (s *Selection) PrevMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
return filterAndPush(s, getSiblingNodesUntil(s.Nodes, siblingPrevUntil,
nil, nodes), filter)
}

Expand Down Expand Up @@ -580,15 +580,15 @@ func getParentsNodes(nodes []*html.Node, stopm Matcher, stopNodes []*html.Node)
}

// Internal implementation of sibling nodes that return a raw slice of matches.
func getSiblingNodes(nodes []*html.Node, st siblingType, untilm Matcher, untilNodes []*html.Node) []*html.Node {
func getSiblingNodesUntil(nodes []*html.Node, st siblingType, untilMatcher Matcher, untilNodes []*html.Node) []*html.Node {
var f func(*html.Node) bool

// If the requested siblings are ...Until, create the test function to
// determine if the until condition is reached (returns true if it is)
if st == siblingNextUntil || st == siblingPrevUntil {
f = func(n *html.Node) bool {
if untilm != nil {
return untilm.Match(n)
if untilMatcher != nil {
return untilMatcher.Match(n)
} else if len(untilNodes) > 0 {
return isInSlice(untilNodes, n)
}
Expand All @@ -601,6 +601,11 @@ func getSiblingNodes(nodes []*html.Node, st siblingType, untilm Matcher, untilNo
})
}

// getSiblingNodes is the no-until-criteria variant of getSiblingNodesUntil.
func getSiblingNodes(nodes []*html.Node, st siblingType) []*html.Node {
return getSiblingNodesUntil(nodes, st, nil, nil)
}

// Gets the children nodes of each node in the specified slice of nodes,
// based on the sibling type request.
func getChildrenNodes(nodes []*html.Node, st siblingType) []*html.Node {
Expand Down
Loading