aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/PuerkitoBio/goquery/array.go
blob: 1b1f6cbe66983a4bb9d1f483e11a901af18c9016 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package goquery

import (
	"golang.org/x/net/html"
)

const (
	maxUint = ^uint(0)
	maxInt  = int(maxUint >> 1)

	// ToEnd is a special index value that can be used as end index in a call
	// to Slice so that all elements are selected until the end of the Selection.
	// It is equivalent to passing (*Selection).Length().
	ToEnd = maxInt
)

// First reduces the set of matched elements to the first in the set.
// It returns a new Selection object, and an empty Selection object if the
// the selection is empty.
func (s *Selection) First() *Selection {
	return s.Eq(0)
}

// Last reduces the set of matched elements to the last in the set.
// It returns a new Selection object, and an empty Selection object if
// the selection is empty.
func (s *Selection) Last() *Selection {
	return s.Eq(-1)
}

// Eq reduces the set of matched elements to the one at the specified index.
// If a negative index is given, it counts backwards starting at the end of the
// set. It returns a new Selection object, and an empty Selection object if the
// index is invalid.
func (s *Selection) Eq(index int) *Selection {
	if index < 0 {
		index += len(s.Nodes)
	}

	if index >= len(s.Nodes) || index < 0 {
		return newEmptySelection(s.document)
	}

	return s.Slice(index, index+1)
}

// Slice reduces the set of matched elements to a subset specified by a range
// of indices. The start index is 0-based and indicates the index of the first
// element to select. The end index is 0-based and indicates the index at which
// the elements stop being selected (the end index is not selected).
//
// The indices may be negative, in which case they represent an offset from the
// end of the selection.
//
// The special value ToEnd may be specified as end index, in which case all elements
// until the end are selected. This works both for a positive and negative start
// index.
func (s *Selection) Slice(start, end int) *Selection {
	if start < 0 {
		start += len(s.Nodes)
	}
	if end == ToEnd {
		end = len(s.Nodes)
	} else if end < 0 {
		end += len(s.Nodes)
	}
	return pushStack(s, s.Nodes[start:end])
}

// Get retrieves the underlying node at the specified index.
// Get without parameter is not implemented, since the node array is available
// on the Selection object.
func (s *Selection) Get(index int) *html.Node {
	if index < 0 {
		index += len(s.Nodes) // Negative index gets from the end
	}
	return s.Nodes[index]
}

// Index returns the position of the first element within the Selection object
// relative to its sibling elements.
func (s *Selection) Index() int {
	if len(s.Nodes) > 0 {
		return newSingleSelection(s.Nodes[0], s.document).PrevAll().Length()
	}
	return -1
}

// IndexSelector returns the position of the first element within the
// Selection object relative to the elements matched by the selector, or -1 if
// not found.
func (s *Selection) IndexSelector(selector string) int {
	if len(s.Nodes) > 0 {
		sel := s.document.Find(selector)
		return indexInSlice(sel.Nodes, s.Nodes[0])
	}
	return -1
}

// IndexMatcher returns the position of the first element within the
// Selection object relative to the elements matched by the matcher, or -1 if
// not found.
func (s *Selection) IndexMatcher(m Matcher) int {
	if len(s.Nodes) > 0 {
		sel := s.document.FindMatcher(m)
		return indexInSlice(sel.Nodes, s.Nodes[0])
	}
	return -1
}

// IndexOfNode returns the position of the specified node within the Selection
// object, or -1 if not found.
func (s *Selection) IndexOfNode(node *html.Node) int {
	return indexInSlice(s.Nodes, node)
}

// IndexOfSelection returns the position of the first node in the specified
// Selection object within this Selection object, or -1 if not found.
func (s *Selection) IndexOfSelection(sel *Selection) int {
	if sel != nil && len(sel.Nodes) > 0 {
		return indexInSlice(s.Nodes, sel.Nodes[0])
	}
	return -1
}