mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 07:32:26 -05:00 
			
		
		
		
	Vendor
This commit is contained in:
		
					parent
					
						
							
								6169351d22
							
						
					
				
			
			
				commit
				
					
						d11efa1e2f
					
				
			
		
					 27 changed files with 5255 additions and 18 deletions
				
			
		
							
								
								
									
										704
									
								
								vendor/github.com/PuerkitoBio/goquery/traversal.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										704
									
								
								vendor/github.com/PuerkitoBio/goquery/traversal.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,704 @@ | |||
| package goquery | ||||
| 
 | ||||
| import "golang.org/x/net/html" | ||||
| 
 | ||||
| type siblingType int | ||||
| 
 | ||||
| // Sibling type, used internally when iterating over children at the same | ||||
| // level (siblings) to specify which nodes are requested. | ||||
| const ( | ||||
| 	siblingPrevUntil siblingType = iota - 3 | ||||
| 	siblingPrevAll | ||||
| 	siblingPrev | ||||
| 	siblingAll | ||||
| 	siblingNext | ||||
| 	siblingNextAll | ||||
| 	siblingNextUntil | ||||
| 	siblingAllIncludingNonElements | ||||
| ) | ||||
| 
 | ||||
| // Find gets the descendants of each element in the current set of matched | ||||
| // elements, filtered by a selector. It returns a new Selection object | ||||
| // containing these matched elements. | ||||
| // | ||||
| // Note that as for all methods accepting a selector string, the selector is | ||||
| // compiled and applied by the cascadia package and inherits its behavior and | ||||
| // constraints regarding supported selectors. See the note on cascadia in | ||||
| // the goquery documentation here: | ||||
| // https://github.com/PuerkitoBio/goquery?tab=readme-ov-file#api | ||||
| func (s *Selection) Find(selector string) *Selection { | ||||
| 	return pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector))) | ||||
| } | ||||
| 
 | ||||
| // FindMatcher gets the descendants of each element in the current set of matched | ||||
| // elements, filtered by the matcher. It returns a new Selection object | ||||
| // containing these matched elements. | ||||
| func (s *Selection) FindMatcher(m Matcher) *Selection { | ||||
| 	return pushStack(s, findWithMatcher(s.Nodes, m)) | ||||
| } | ||||
| 
 | ||||
| // FindSelection gets the descendants of each element in the current | ||||
| // Selection, filtered by a Selection. It returns a new Selection object | ||||
| // containing these matched elements. | ||||
| func (s *Selection) FindSelection(sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return pushStack(s, nil) | ||||
| 	} | ||||
| 	return s.FindNodes(sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // FindNodes gets the descendants of each element in the current | ||||
| // 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} | ||||
| 		} | ||||
| 		return nil | ||||
| 	})) | ||||
| } | ||||
| 
 | ||||
| // Contents gets the children of each element in the Selection, | ||||
| // including text and comment nodes. It returns a new Selection object | ||||
| // containing these elements. | ||||
| func (s *Selection) Contents() *Selection { | ||||
| 	return pushStack(s, getChildrenNodes(s.Nodes, siblingAllIncludingNonElements)) | ||||
| } | ||||
| 
 | ||||
| // ContentsFiltered gets the children of each element in the Selection, | ||||
| // filtered by the specified selector. It returns a new Selection | ||||
| // object containing these elements. Since selectors only act on Element nodes, | ||||
| // this function is an alias to ChildrenFiltered unless the selector is empty, | ||||
| // in which case it is an alias to Contents. | ||||
| func (s *Selection) ContentsFiltered(selector string) *Selection { | ||||
| 	if selector != "" { | ||||
| 		return s.ChildrenFiltered(selector) | ||||
| 	} | ||||
| 	return s.Contents() | ||||
| } | ||||
| 
 | ||||
| // ContentsMatcher gets the children of each element in the Selection, | ||||
| // filtered by the specified matcher. It returns a new Selection | ||||
| // object containing these elements. Since matchers only act on Element nodes, | ||||
| // this function is an alias to ChildrenMatcher. | ||||
| func (s *Selection) ContentsMatcher(m Matcher) *Selection { | ||||
| 	return s.ChildrenMatcher(m) | ||||
| } | ||||
| 
 | ||||
| // Children gets the child elements of each element in the Selection. | ||||
| // It returns a new Selection object containing these elements. | ||||
| func (s *Selection) Children() *Selection { | ||||
| 	return pushStack(s, getChildrenNodes(s.Nodes, siblingAll)) | ||||
| } | ||||
| 
 | ||||
| // ChildrenFiltered gets the child elements of each element in the Selection, | ||||
| // filtered by the specified selector. It returns a new | ||||
| // Selection object containing these elements. | ||||
| func (s *Selection) ChildrenFiltered(selector string) *Selection { | ||||
| 	return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), compileMatcher(selector)) | ||||
| } | ||||
| 
 | ||||
| // ChildrenMatcher gets the child elements of each element in the Selection, | ||||
| // filtered by the specified matcher. It returns a new | ||||
| // Selection object containing these elements. | ||||
| func (s *Selection) ChildrenMatcher(m Matcher) *Selection { | ||||
| 	return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), m) | ||||
| } | ||||
| 
 | ||||
| // Parent gets the parent of each element in the Selection. It returns a | ||||
| // new Selection object containing the matched elements. | ||||
| func (s *Selection) Parent() *Selection { | ||||
| 	return pushStack(s, getParentNodes(s.Nodes)) | ||||
| } | ||||
| 
 | ||||
| // ParentFiltered gets the parent of each element in the Selection filtered by a | ||||
| // selector. It returns a new Selection object containing the matched elements. | ||||
| func (s *Selection) ParentFiltered(selector string) *Selection { | ||||
| 	return filterAndPush(s, getParentNodes(s.Nodes), compileMatcher(selector)) | ||||
| } | ||||
| 
 | ||||
| // ParentMatcher gets the parent of each element in the Selection filtered by a | ||||
| // matcher. It returns a new Selection object containing the matched elements. | ||||
| func (s *Selection) ParentMatcher(m Matcher) *Selection { | ||||
| 	return filterAndPush(s, getParentNodes(s.Nodes), m) | ||||
| } | ||||
| 
 | ||||
| // Closest gets the first element that matches the selector by testing the | ||||
| // element itself and traversing up through its ancestors in the DOM tree. | ||||
| func (s *Selection) Closest(selector string) *Selection { | ||||
| 	cs := compileMatcher(selector) | ||||
| 	return s.ClosestMatcher(cs) | ||||
| } | ||||
| 
 | ||||
| // ClosestMatcher gets the first element that matches the matcher by testing the | ||||
| // element itself and traversing up through its ancestors in the DOM tree. | ||||
| func (s *Selection) ClosestMatcher(m Matcher) *Selection { | ||||
| 	return pushStack(s, mapNodes(s.Nodes, func(i int, n *html.Node) []*html.Node { | ||||
| 		// For each node in the selection, test the node itself, then each parent | ||||
| 		// until a match is found. | ||||
| 		for ; n != nil; n = n.Parent { | ||||
| 			if m.Match(n) { | ||||
| 				return []*html.Node{n} | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	})) | ||||
| } | ||||
| 
 | ||||
| // ClosestNodes gets the first element that matches one of the nodes by testing the | ||||
| // element itself and traversing up through its ancestors in the DOM tree. | ||||
| func (s *Selection) ClosestNodes(nodes ...*html.Node) *Selection { | ||||
| 	set := make(map[*html.Node]bool) | ||||
| 	for _, n := range nodes { | ||||
| 		set[n] = true | ||||
| 	} | ||||
| 	return pushStack(s, mapNodes(s.Nodes, func(i int, n *html.Node) []*html.Node { | ||||
| 		// For each node in the selection, test the node itself, then each parent | ||||
| 		// until a match is found. | ||||
| 		for ; n != nil; n = n.Parent { | ||||
| 			if set[n] { | ||||
| 				return []*html.Node{n} | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	})) | ||||
| } | ||||
| 
 | ||||
| // ClosestSelection gets the first element that matches one of the nodes in the | ||||
| // Selection by testing the element itself and traversing up through its ancestors | ||||
| // in the DOM tree. | ||||
| func (s *Selection) ClosestSelection(sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return pushStack(s, nil) | ||||
| 	} | ||||
| 	return s.ClosestNodes(sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // Parents gets the ancestors of each element in the current Selection. It | ||||
| // returns a new Selection object with the matched elements. | ||||
| func (s *Selection) Parents() *Selection { | ||||
| 	return pushStack(s, getParentsNodes(s.Nodes, nil, nil)) | ||||
| } | ||||
| 
 | ||||
| // ParentsFiltered gets the ancestors of each element in the current | ||||
| // Selection. It returns a new Selection object with the matched elements. | ||||
| func (s *Selection) ParentsFiltered(selector string) *Selection { | ||||
| 	return filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), compileMatcher(selector)) | ||||
| } | ||||
| 
 | ||||
| // ParentsMatcher gets the ancestors of each element in the current | ||||
| // Selection. It returns a new Selection object with the matched elements. | ||||
| func (s *Selection) ParentsMatcher(m Matcher) *Selection { | ||||
| 	return filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), m) | ||||
| } | ||||
| 
 | ||||
| // ParentsUntil gets the ancestors of each element in the Selection, up to but | ||||
| // not including the element matched by the selector. It returns a new Selection | ||||
| // object containing the matched elements. | ||||
| func (s *Selection) ParentsUntil(selector string) *Selection { | ||||
| 	return pushStack(s, getParentsNodes(s.Nodes, compileMatcher(selector), nil)) | ||||
| } | ||||
| 
 | ||||
| // ParentsUntilMatcher gets the ancestors of each element in the Selection, up to but | ||||
| // not including the element matched by the matcher. It returns a new Selection | ||||
| // object containing the matched elements. | ||||
| func (s *Selection) ParentsUntilMatcher(m Matcher) *Selection { | ||||
| 	return pushStack(s, getParentsNodes(s.Nodes, m, nil)) | ||||
| } | ||||
| 
 | ||||
| // ParentsUntilSelection gets the ancestors of each element in the Selection, | ||||
| // up to but not including the elements in the specified Selection. It returns a | ||||
| // new Selection object containing the matched elements. | ||||
| func (s *Selection) ParentsUntilSelection(sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return s.Parents() | ||||
| 	} | ||||
| 	return s.ParentsUntilNodes(sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // ParentsUntilNodes gets the ancestors of each element in the Selection, | ||||
| // up to but not including the specified nodes. It returns a | ||||
| // new Selection object containing the matched elements. | ||||
| func (s *Selection) ParentsUntilNodes(nodes ...*html.Node) *Selection { | ||||
| 	return pushStack(s, getParentsNodes(s.Nodes, nil, nodes)) | ||||
| } | ||||
| 
 | ||||
| // ParentsFilteredUntil is like ParentsUntil, 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) ParentsFilteredUntil(filterSelector, untilSelector string) *Selection { | ||||
| 	return filterAndPush(s, getParentsNodes(s.Nodes, compileMatcher(untilSelector), nil), compileMatcher(filterSelector)) | ||||
| } | ||||
| 
 | ||||
| // ParentsFilteredUntilMatcher is like ParentsUntilMatcher, with the option to filter the | ||||
| // results based on a matcher. It returns a new Selection object containing the matched elements. | ||||
| func (s *Selection) ParentsFilteredUntilMatcher(filter, until Matcher) *Selection { | ||||
| 	return filterAndPush(s, getParentsNodes(s.Nodes, until, nil), filter) | ||||
| } | ||||
| 
 | ||||
| // ParentsFilteredUntilSelection is like ParentsUntilSelection, 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) ParentsFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { | ||||
| 	return s.ParentsMatcherUntilSelection(compileMatcher(filterSelector), sel) | ||||
| } | ||||
| 
 | ||||
| // ParentsMatcherUntilSelection is like ParentsUntilSelection, with the | ||||
| // option to filter the results based on a matcher. It returns a new | ||||
| // Selection object containing the matched elements. | ||||
| func (s *Selection) ParentsMatcherUntilSelection(filter Matcher, sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return s.ParentsMatcher(filter) | ||||
| 	} | ||||
| 	return s.ParentsMatcherUntilNodes(filter, sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // ParentsFilteredUntilNodes is like ParentsUntilNodes, 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) ParentsFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { | ||||
| 	return filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), compileMatcher(filterSelector)) | ||||
| } | ||||
| 
 | ||||
| // ParentsMatcherUntilNodes is like ParentsUntilNodes, with the | ||||
| // option to filter the results based on a matcher. It returns a new | ||||
| // Selection object containing the matched elements. | ||||
| func (s *Selection) ParentsMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection { | ||||
| 	return filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), filter) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| // 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) | ||||
| } | ||||
| 
 | ||||
| // 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, | ||||
| 		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, | ||||
| 		m, nil)) | ||||
| } | ||||
| 
 | ||||
| // NextUntilSelection gets all following siblings of each element up to but not | ||||
| // including the element matched by the Selection. It returns a new Selection | ||||
| // object containing the matched elements. | ||||
| func (s *Selection) NextUntilSelection(sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return s.NextAll() | ||||
| 	} | ||||
| 	return s.NextUntilNodes(sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // NextUntilNodes gets all following siblings of each element up to but not | ||||
| // 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, | ||||
| 		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, | ||||
| 		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, | ||||
| 		m, nil)) | ||||
| } | ||||
| 
 | ||||
| // PrevUntilSelection gets all preceding siblings of each element up to but not | ||||
| // including the element matched by the Selection. It returns a new Selection | ||||
| // object containing the matched elements. | ||||
| func (s *Selection) PrevUntilSelection(sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return s.PrevAll() | ||||
| 	} | ||||
| 	return s.PrevUntilNodes(sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // PrevUntilNodes gets all preceding siblings of each element up to but not | ||||
| // 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, | ||||
| 		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, | ||||
| 		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, | ||||
| 		until, nil), filter) | ||||
| } | ||||
| 
 | ||||
| // NextFilteredUntilSelection is like NextUntilSelection, 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) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { | ||||
| 	return s.NextMatcherUntilSelection(compileMatcher(filterSelector), sel) | ||||
| } | ||||
| 
 | ||||
| // NextMatcherUntilSelection is like NextUntilSelection, with the | ||||
| // option to filter the results based on a matcher. It returns a new | ||||
| // Selection object containing the matched elements. | ||||
| func (s *Selection) NextMatcherUntilSelection(filter Matcher, sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return s.NextMatcher(filter) | ||||
| 	} | ||||
| 	return s.NextMatcherUntilNodes(filter, sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // NextFilteredUntilNodes is like NextUntilNodes, 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) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { | ||||
| 	return filterAndPush(s, getSiblingNodes(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, | ||||
| 		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, | ||||
| 		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, | ||||
| 		until, nil), filter) | ||||
| } | ||||
| 
 | ||||
| // PrevFilteredUntilSelection is like PrevUntilSelection, 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) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { | ||||
| 	return s.PrevMatcherUntilSelection(compileMatcher(filterSelector), sel) | ||||
| } | ||||
| 
 | ||||
| // PrevMatcherUntilSelection is like PrevUntilSelection, with the | ||||
| // option to filter the results based on a matcher. It returns a new | ||||
| // Selection object containing the matched elements. | ||||
| func (s *Selection) PrevMatcherUntilSelection(filter Matcher, sel *Selection) *Selection { | ||||
| 	if sel == nil { | ||||
| 		return s.PrevMatcher(filter) | ||||
| 	} | ||||
| 	return s.PrevMatcherUntilNodes(filter, sel.Nodes...) | ||||
| } | ||||
| 
 | ||||
| // PrevFilteredUntilNodes is like PrevUntilNodes, 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) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { | ||||
| 	return filterAndPush(s, getSiblingNodes(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, | ||||
| 		nil, nodes), filter) | ||||
| } | ||||
| 
 | ||||
| // Filter and push filters the nodes based on a matcher, and pushes the results | ||||
| // on the stack, with the srcSel as previous selection. | ||||
| func filterAndPush(srcSel *Selection, nodes []*html.Node, m Matcher) *Selection { | ||||
| 	// Create a temporary Selection with the specified nodes to filter using winnow | ||||
| 	sel := &Selection{nodes, srcSel.document, nil} | ||||
| 	// Filter based on matcher and push on stack | ||||
| 	return pushStack(srcSel, winnow(sel, m, true)) | ||||
| } | ||||
| 
 | ||||
| // Internal implementation of Find that return raw nodes. | ||||
| func findWithMatcher(nodes []*html.Node, m Matcher) []*html.Node { | ||||
| 	// Map nodes to find the matches within the children of each node | ||||
| 	return mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) { | ||||
| 		// Go down one level, becausejQuery's Find selects only within descendants | ||||
| 		for c := n.FirstChild; c != nil; c = c.NextSibling { | ||||
| 			if c.Type == html.ElementNode { | ||||
| 				result = append(result, m.MatchAll(c)...) | ||||
| 			} | ||||
| 		} | ||||
| 		return | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Internal implementation to get all parent nodes, stopping at the specified | ||||
| // node (or nil if no stop). | ||||
| func getParentsNodes(nodes []*html.Node, stopm Matcher, stopNodes []*html.Node) []*html.Node { | ||||
| 	return mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) { | ||||
| 		for p := n.Parent; p != nil; p = p.Parent { | ||||
| 			sel := newSingleSelection(p, nil) | ||||
| 			if stopm != nil { | ||||
| 				if sel.IsMatcher(stopm) { | ||||
| 					break | ||||
| 				} | ||||
| 			} else if len(stopNodes) > 0 { | ||||
| 				if sel.IsNodes(stopNodes...) { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if p.Type == html.ElementNode { | ||||
| 				result = append(result, p) | ||||
| 			} | ||||
| 		} | ||||
| 		return | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // 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 { | ||||
| 	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 { | ||||
| 				// Matcher-based condition | ||||
| 				sel := newSingleSelection(n, nil) | ||||
| 				return sel.IsMatcher(untilm) | ||||
| 			} else if len(untilNodes) > 0 { | ||||
| 				// Nodes-based condition | ||||
| 				sel := newSingleSelection(n, nil) | ||||
| 				return sel.IsNodes(untilNodes...) | ||||
| 			} | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return mapNodes(nodes, func(i int, n *html.Node) []*html.Node { | ||||
| 		return getChildrenWithSiblingType(n.Parent, st, n, f) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // 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 { | ||||
| 	return mapNodes(nodes, func(i int, n *html.Node) []*html.Node { | ||||
| 		return getChildrenWithSiblingType(n, st, nil, nil) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Gets the children of the specified parent, based on the requested sibling | ||||
| // type, skipping a specified node if required. | ||||
| func getChildrenWithSiblingType(parent *html.Node, st siblingType, skipNode *html.Node, | ||||
| 	untilFunc func(*html.Node) bool) (result []*html.Node) { | ||||
| 
 | ||||
| 	// Create the iterator function | ||||
| 	var iter = func(cur *html.Node) (ret *html.Node) { | ||||
| 		// Based on the sibling type requested, iterate the right way | ||||
| 		for { | ||||
| 			switch st { | ||||
| 			case siblingAll, siblingAllIncludingNonElements: | ||||
| 				if cur == nil { | ||||
| 					// First iteration, start with first child of parent | ||||
| 					// Skip node if required | ||||
| 					if ret = parent.FirstChild; ret == skipNode && skipNode != nil { | ||||
| 						ret = skipNode.NextSibling | ||||
| 					} | ||||
| 				} else { | ||||
| 					// Skip node if required | ||||
| 					if ret = cur.NextSibling; ret == skipNode && skipNode != nil { | ||||
| 						ret = skipNode.NextSibling | ||||
| 					} | ||||
| 				} | ||||
| 			case siblingPrev, siblingPrevAll, siblingPrevUntil: | ||||
| 				if cur == nil { | ||||
| 					// Start with previous sibling of the skip node | ||||
| 					ret = skipNode.PrevSibling | ||||
| 				} else { | ||||
| 					ret = cur.PrevSibling | ||||
| 				} | ||||
| 			case siblingNext, siblingNextAll, siblingNextUntil: | ||||
| 				if cur == nil { | ||||
| 					// Start with next sibling of the skip node | ||||
| 					ret = skipNode.NextSibling | ||||
| 				} else { | ||||
| 					ret = cur.NextSibling | ||||
| 				} | ||||
| 			default: | ||||
| 				panic("Invalid sibling type.") | ||||
| 			} | ||||
| 			if ret == nil || ret.Type == html.ElementNode || st == siblingAllIncludingNonElements { | ||||
| 				return | ||||
| 			} | ||||
| 			// Not a valid node, try again from this one | ||||
| 			cur = ret | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for c := iter(nil); c != nil; c = iter(c) { | ||||
| 		// If this is an ...Until case, test before append (returns true | ||||
| 		// if the until condition is reached) | ||||
| 		if st == siblingNextUntil || st == siblingPrevUntil { | ||||
| 			if untilFunc(c) { | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		result = append(result, c) | ||||
| 		if st == siblingNext || st == siblingPrev { | ||||
| 			// Only one node was requested (immediate next or previous), so exit | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Internal implementation of parent nodes that return a raw slice of Nodes. | ||||
| func getParentNodes(nodes []*html.Node) []*html.Node { | ||||
| 	return mapNodes(nodes, func(i int, n *html.Node) []*html.Node { | ||||
| 		if n.Parent != nil && n.Parent.Type == html.ElementNode { | ||||
| 			return []*html.Node{n.Parent} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Internal map function used by many traversing methods. Takes the source nodes | ||||
| // to iterate on and the mapping function that returns an array of nodes. | ||||
| // Returns an array of nodes mapped by calling the callback function once for | ||||
| // each node in the source nodes. | ||||
| func mapNodes(nodes []*html.Node, f func(int, *html.Node) []*html.Node) (result []*html.Node) { | ||||
| 	set := make(map[*html.Node]bool) | ||||
| 	for i, n := range nodes { | ||||
| 		if vals := f(i, n); len(vals) > 0 { | ||||
| 			result = appendWithoutDuplicates(result, vals, set) | ||||
| 		} | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue