1package goquery
2
3import (
4 "golang.org/x/net/html"
5)
6
7const (
8 maxUint = ^uint(0)
9 maxInt = int(maxUint >> 1)
10
11 // ToEnd is a special index value that can be used as end index in a call
12 // to Slice so that all elements are selected until the end of the Selection.
13 // It is equivalent to passing (*Selection).Length().
14 ToEnd = maxInt
15)
16
17// First reduces the set of matched elements to the first in the set.
18// It returns a new Selection object, and an empty Selection object if the
19// the selection is empty.
20func (s *Selection) First() *Selection {
21 return s.Eq(0)
22}
23
24// Last reduces the set of matched elements to the last in the set.
25// It returns a new Selection object, and an empty Selection object if
26// the selection is empty.
27func (s *Selection) Last() *Selection {
28 return s.Eq(-1)
29}
30
31// Eq reduces the set of matched elements to the one at the specified index.
32// If a negative index is given, it counts backwards starting at the end of the
33// set. It returns a new Selection object, and an empty Selection object if the
34// index is invalid.
35func (s *Selection) Eq(index int) *Selection {
36 if index < 0 {
37 index += len(s.Nodes)
38 }
39
40 if index >= len(s.Nodes) || index < 0 {
41 return newEmptySelection(s.document)
42 }
43
44 return s.Slice(index, index+1)
45}
46
47// Slice reduces the set of matched elements to a subset specified by a range
48// of indices. The start index is 0-based and indicates the index of the first
49// element to select. The end index is 0-based and indicates the index at which
50// the elements stop being selected (the end index is not selected).
51//
52// The indices may be negative, in which case they represent an offset from the
53// end of the selection.
54//
55// The special value ToEnd may be specified as end index, in which case all elements
56// until the end are selected. This works both for a positive and negative start
57// index.
58func (s *Selection) Slice(start, end int) *Selection {
59 if start < 0 {
60 start += len(s.Nodes)
61 }
62 if end == ToEnd {
63 end = len(s.Nodes)
64 } else if end < 0 {
65 end += len(s.Nodes)
66 }
67 return pushStack(s, s.Nodes[start:end])
68}
69
70// Get retrieves the underlying node at the specified index.
71// Get without parameter is not implemented, since the node array is available
72// on the Selection object.
73func (s *Selection) Get(index int) *html.Node {
74 if index < 0 {
75 index += len(s.Nodes) // Negative index gets from the end
76 }
77 return s.Nodes[index]
78}
79
80// Index returns the position of the first element within the Selection object
81// relative to its sibling elements.
82func (s *Selection) Index() int {
83 if len(s.Nodes) > 0 {
84 return newSingleSelection(s.Nodes[0], s.document).PrevAll().Length()
85 }
86 return -1
87}
88
89// IndexSelector returns the position of the first element within the
90// Selection object relative to the elements matched by the selector, or -1 if
91// not found.
92func (s *Selection) IndexSelector(selector string) int {
93 if len(s.Nodes) > 0 {
94 sel := s.document.Find(selector)
95 return indexInSlice(sel.Nodes, s.Nodes[0])
96 }
97 return -1
98}
99
100// IndexMatcher returns the position of the first element within the
101// Selection object relative to the elements matched by the matcher, or -1 if
102// not found.
103func (s *Selection) IndexMatcher(m Matcher) int {
104 if len(s.Nodes) > 0 {
105 sel := s.document.FindMatcher(m)
106 return indexInSlice(sel.Nodes, s.Nodes[0])
107 }
108 return -1
109}
110
111// IndexOfNode returns the position of the specified node within the Selection
112// object, or -1 if not found.
113func (s *Selection) IndexOfNode(node *html.Node) int {
114 return indexInSlice(s.Nodes, node)
115}
116
117// IndexOfSelection returns the position of the first node in the specified
118// Selection object within this Selection object, or -1 if not found.
119func (s *Selection) IndexOfSelection(sel *Selection) int {
120 if sel != nil && len(sel.Nodes) > 0 {
121 return indexInSlice(s.Nodes, sel.Nodes[0])
122 }
123 return -1
124}