You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

array.go 3.8KB

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