mirror of
https://github.com/PuerkitoBio/goquery
synced 2025-10-07 01:33:06 +08:00
lint
This commit is contained in:
76
array.go
76
array.go
@@ -4,89 +4,89 @@ import (
|
||||
"code.google.com/p/go.net/html"
|
||||
)
|
||||
|
||||
// First() reduces the set of matched elements to the first in the set.
|
||||
// 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 (this *Selection) First() *Selection {
|
||||
return this.Eq(0)
|
||||
func (s *Selection) First() *Selection {
|
||||
return s.Eq(0)
|
||||
}
|
||||
|
||||
// Last() reduces the set of matched elements to the last in the set.
|
||||
// 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 (this *Selection) Last() *Selection {
|
||||
return this.Eq(-1)
|
||||
func (s *Selection) Last() *Selection {
|
||||
return s.Eq(-1)
|
||||
}
|
||||
|
||||
// Eq() reduces the set of matched elements to the one at the specified index.
|
||||
// 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 (this *Selection) Eq(index int) *Selection {
|
||||
func (s *Selection) Eq(index int) *Selection {
|
||||
if index < 0 {
|
||||
index += len(this.Nodes)
|
||||
index += len(s.Nodes)
|
||||
}
|
||||
|
||||
if index >= len(this.Nodes) || index < 0 {
|
||||
return newEmptySelection(this.document)
|
||||
if index >= len(s.Nodes) || index < 0 {
|
||||
return newEmptySelection(s.document)
|
||||
}
|
||||
|
||||
return this.Slice(index, index+1)
|
||||
return s.Slice(index, index+1)
|
||||
}
|
||||
|
||||
// Slice() reduces the set of matched elements to a subset specified by a range
|
||||
// Slice reduces the set of matched elements to a subset specified by a range
|
||||
// of indices.
|
||||
func (this *Selection) Slice(start int, end int) *Selection {
|
||||
func (s *Selection) Slice(start int, end int) *Selection {
|
||||
if start < 0 {
|
||||
start += len(this.Nodes)
|
||||
start += len(s.Nodes)
|
||||
}
|
||||
if end < 0 {
|
||||
end += len(this.Nodes)
|
||||
end += len(s.Nodes)
|
||||
}
|
||||
return pushStack(this, this.Nodes[start:end])
|
||||
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
|
||||
// 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 (this *Selection) Get(index int) *html.Node {
|
||||
func (s *Selection) Get(index int) *html.Node {
|
||||
if index < 0 {
|
||||
index += len(this.Nodes) // Negative index gets from the end
|
||||
index += len(s.Nodes) // Negative index gets from the end
|
||||
}
|
||||
return this.Nodes[index]
|
||||
return s.Nodes[index]
|
||||
}
|
||||
|
||||
// Index() returns the position of the first element within the Selection object
|
||||
// Index returns the position of the first element within the Selection object
|
||||
// relative to its sibling elements.
|
||||
func (this *Selection) Index() int {
|
||||
if len(this.Nodes) > 0 {
|
||||
return newSingleSelection(this.Nodes[0], this.document).PrevAll().Length()
|
||||
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
|
||||
// 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 (this *Selection) IndexSelector(selector string) int {
|
||||
if len(this.Nodes) > 0 {
|
||||
sel := this.document.Find(selector)
|
||||
return indexInSlice(sel.Nodes, this.Nodes[0])
|
||||
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
|
||||
}
|
||||
|
||||
// IndexOfNode() returns the position of the specified node within the Selection
|
||||
// IndexOfNode returns the position of the specified node within the Selection
|
||||
// object, or -1 if not found.
|
||||
func (this *Selection) IndexOfNode(node *html.Node) int {
|
||||
return indexInSlice(this.Nodes, node)
|
||||
func (s *Selection) IndexOfNode(node *html.Node) int {
|
||||
return indexInSlice(s.Nodes, node)
|
||||
}
|
||||
|
||||
// IndexOfSelection() returns the position of the first node in the specified
|
||||
// IndexOfSelection returns the position of the first node in the specified
|
||||
// Selection object within this Selection object, or -1 if not found.
|
||||
func (this *Selection) IndexOfSelection(s *Selection) int {
|
||||
if s != nil && len(s.Nodes) > 0 {
|
||||
return indexInSlice(this.Nodes, s.Nodes[0])
|
||||
func (s *Selection) IndexOfSelection(sel *Selection) int {
|
||||
if sel != nil && len(sel.Nodes) > 0 {
|
||||
return indexInSlice(s.Nodes, sel.Nodes[0])
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
26
doc.go
26
doc.go
@@ -23,15 +23,27 @@
|
||||
|
||||
/*
|
||||
Package goquery implements features similar to jQuery, including the chainable
|
||||
syntax, to manipulate and query an HTML document (the modification functions of jQuery are not included).
|
||||
syntax, to manipulate and query an HTML document.
|
||||
|
||||
It uses Cascadia as CSS selector (similar to Sizzle for jQuery).
|
||||
GoQuery brings a syntax and a set of features similar to jQuery to the Go language.
|
||||
It is based on Go's net/html package and the CSS Selector library cascadia. Since
|
||||
the net/html parser returns tokens (nodes), and not a full-featured DOM object,
|
||||
jQuery's manipulation and modification functions have been left off (no point in
|
||||
modifying data in the parsed tree of the HTML, it has no effect).
|
||||
|
||||
To provide a chainable interface, error management is strict, and goquery panics
|
||||
if an invalid Cascadia selector is used (this is consistent with the behavior of
|
||||
jQuery/Sizzle/document.querySelectorAll, where an error is thrown). This is
|
||||
necessary since multiple return values cannot be used to allow a chainable
|
||||
interface.
|
||||
Also, because the net/html parser requires UTF-8 encoding, so does goquery: it is
|
||||
the caller's responsibility to ensure that the source document provides UTF-8 encoded HTML.
|
||||
|
||||
Supported functions are query-oriented features (`hasClass()`, `attr()` and the likes),
|
||||
as well as traversing functions that make sense given what we have to work with.
|
||||
This makes GoQuery a great library for scraping web pages.
|
||||
|
||||
Syntax-wise, it is as close as possible to jQuery, with the same function names when
|
||||
possible, and that warm and fuzzy chainable interface. jQuery being the
|
||||
ultra-popular library that it is, I felt that writing a similar HTML-manipulating
|
||||
library was better to follow its API than to start anew (in the same spirit as
|
||||
Go's fmt package), even though some of its methods are less than intuitive (looking
|
||||
at you, index()...).
|
||||
|
||||
It is hosted on GitHub, along with additional documentation in the README.md
|
||||
file: https://github.com/puerkitobio/goquery
|
||||
|
32
expand.go
32
expand.go
@@ -4,37 +4,37 @@ import (
|
||||
"code.google.com/p/go.net/html"
|
||||
)
|
||||
|
||||
// Add() adds the selector string's matching nodes to those in the current
|
||||
// Add adds the selector string's matching nodes to those in the current
|
||||
// selection and returns a new Selection object.
|
||||
// The selector string is run in the context of the document of the current
|
||||
// Selection object.
|
||||
func (this *Selection) Add(selector string) *Selection {
|
||||
return this.AddNodes(findWithSelector([]*html.Node{this.document.rootNode}, selector)...)
|
||||
func (s *Selection) Add(selector string) *Selection {
|
||||
return s.AddNodes(findWithSelector([]*html.Node{s.document.rootNode}, selector)...)
|
||||
}
|
||||
|
||||
// AddSelection() adds the specified Selection object's nodes to those in the
|
||||
// AddSelection adds the specified Selection object's nodes to those in the
|
||||
// current selection and returns a new Selection object.
|
||||
func (this *Selection) AddSelection(sel *Selection) *Selection {
|
||||
func (s *Selection) AddSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.AddNodes()
|
||||
return s.AddNodes()
|
||||
}
|
||||
return this.AddNodes(sel.Nodes...)
|
||||
return s.AddNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// Union() is an alias for AddSelection().
|
||||
func (this *Selection) Union(sel *Selection) *Selection {
|
||||
return this.AddSelection(sel)
|
||||
// Union is an alias for AddSelection.
|
||||
func (s *Selection) Union(sel *Selection) *Selection {
|
||||
return s.AddSelection(sel)
|
||||
}
|
||||
|
||||
// AddNodes() adds the specified nodes to those in the
|
||||
// AddNodes adds the specified nodes to those in the
|
||||
// current selection and returns a new Selection object.
|
||||
func (this *Selection) AddNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, appendWithoutDuplicates(this.Nodes, nodes))
|
||||
func (s *Selection) AddNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, appendWithoutDuplicates(s.Nodes, nodes))
|
||||
}
|
||||
|
||||
// AndSelf() adds the previous set of elements on the stack to the current set.
|
||||
// AndSelf adds the previous set of elements on the stack to the current set.
|
||||
// It returns a new Selection object containing the current Selection combined
|
||||
// with the previous one.
|
||||
func (this *Selection) AndSelf() *Selection {
|
||||
return this.AddSelection(this.prevSel)
|
||||
func (s *Selection) AndSelf() *Selection {
|
||||
return s.AddSelection(s.prevSel)
|
||||
}
|
||||
|
94
filter.go
94
filter.go
@@ -5,82 +5,82 @@ import (
|
||||
"code.google.com/p/go.net/html"
|
||||
)
|
||||
|
||||
// Filter() reduces the set of matched elements to those that match the selector string.
|
||||
// Filter reduces the set of matched elements to those that match the selector string.
|
||||
// It returns a new Selection object for this subset of matching elements.
|
||||
func (this *Selection) Filter(selector string) *Selection {
|
||||
return pushStack(this, winnow(this, selector, true))
|
||||
func (s *Selection) Filter(selector string) *Selection {
|
||||
return pushStack(s, winnow(s, selector, true))
|
||||
}
|
||||
|
||||
// Not() removes elements from the Selection that match the selector string.
|
||||
// Not removes elements from the Selection that match the selector string.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (this *Selection) Not(selector string) *Selection {
|
||||
return pushStack(this, winnow(this, selector, false))
|
||||
func (s *Selection) Not(selector string) *Selection {
|
||||
return pushStack(s, winnow(s, selector, false))
|
||||
}
|
||||
|
||||
// FilterFunction() reduces the set of matched elements to those that pass the function's test.
|
||||
// FilterFunction reduces the set of matched elements to those that pass the function's test.
|
||||
// It returns a new Selection object for this subset of elements.
|
||||
func (this *Selection) FilterFunction(f func(int, *Selection) bool) *Selection {
|
||||
return pushStack(this, winnowFunction(this, f, true))
|
||||
func (s *Selection) FilterFunction(f func(int, *Selection) bool) *Selection {
|
||||
return pushStack(s, winnowFunction(s, f, true))
|
||||
}
|
||||
|
||||
// Not() removes elements from the Selection that pass the function's test.
|
||||
// Not removes elements from the Selection that pass the function's test.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (this *Selection) NotFunction(f func(int, *Selection) bool) *Selection {
|
||||
return pushStack(this, winnowFunction(this, f, false))
|
||||
func (s *Selection) NotFunction(f func(int, *Selection) bool) *Selection {
|
||||
return pushStack(s, winnowFunction(s, f, false))
|
||||
}
|
||||
|
||||
// FilterNodes() reduces the set of matched elements to those that match the specified nodes.
|
||||
// FilterNodes reduces the set of matched elements to those that match the specified nodes.
|
||||
// It returns a new Selection object for this subset of elements.
|
||||
func (this *Selection) FilterNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, winnowNodes(this, nodes, true))
|
||||
func (s *Selection) FilterNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, winnowNodes(s, nodes, true))
|
||||
}
|
||||
|
||||
// Not() removes elements from the Selection that match the specified nodes.
|
||||
// Not removes elements from the Selection that match the specified nodes.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (this *Selection) NotNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, winnowNodes(this, nodes, false))
|
||||
func (s *Selection) NotNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, winnowNodes(s, nodes, false))
|
||||
}
|
||||
|
||||
// FilterSelection() reduces the set of matched elements to those that match a
|
||||
// FilterSelection reduces the set of matched elements to those that match a
|
||||
// node in the specified Selection object.
|
||||
// It returns a new Selection object for this subset of elements.
|
||||
func (this *Selection) FilterSelection(s *Selection) *Selection {
|
||||
if s == nil {
|
||||
return pushStack(this, winnowNodes(this, nil, true))
|
||||
func (s *Selection) FilterSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return pushStack(s, winnowNodes(s, nil, true))
|
||||
}
|
||||
return pushStack(this, winnowNodes(this, s.Nodes, true))
|
||||
return pushStack(s, winnowNodes(s, sel.Nodes, true))
|
||||
}
|
||||
|
||||
// Not() removes elements from the Selection that match a node in the specified
|
||||
// Not removes elements from the Selection that match a node in the specified
|
||||
// Selection object.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (this *Selection) NotSelection(s *Selection) *Selection {
|
||||
if s == nil {
|
||||
return pushStack(this, winnowNodes(this, nil, false))
|
||||
func (s *Selection) NotSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return pushStack(s, winnowNodes(s, nil, false))
|
||||
}
|
||||
return pushStack(this, winnowNodes(this, s.Nodes, false))
|
||||
return pushStack(s, winnowNodes(s, sel.Nodes, false))
|
||||
}
|
||||
|
||||
// Intersection() is an alias for FilterSelection().
|
||||
func (this *Selection) Intersection(s *Selection) *Selection {
|
||||
return this.FilterSelection(s)
|
||||
// Intersection is an alias for FilterSelection.
|
||||
func (s *Selection) Intersection(sel *Selection) *Selection {
|
||||
return s.FilterSelection(sel)
|
||||
}
|
||||
|
||||
// Has() reduces the set of matched elements to those that have a descendant
|
||||
// Has reduces the set of matched elements to those that have a descendant
|
||||
// that matches the selector.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (this *Selection) Has(selector string) *Selection {
|
||||
return this.HasSelection(this.document.Find(selector))
|
||||
func (s *Selection) Has(selector string) *Selection {
|
||||
return s.HasSelection(s.document.Find(selector))
|
||||
}
|
||||
|
||||
// HasNodes() reduces the set of matched elements to those that have a
|
||||
// HasNodes reduces the set of matched elements to those that have a
|
||||
// descendant that matches one of the nodes.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (this *Selection) HasNodes(nodes ...*html.Node) *Selection {
|
||||
return this.FilterFunction(func(_ int, s *Selection) bool {
|
||||
func (s *Selection) HasNodes(nodes ...*html.Node) *Selection {
|
||||
return s.FilterFunction(func(_ int, sel *Selection) bool {
|
||||
// Add all nodes that contain one of the specified nodes
|
||||
for _, n := range nodes {
|
||||
if s.Contains(n) {
|
||||
if sel.Contains(n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -88,23 +88,23 @@ func (this *Selection) HasNodes(nodes ...*html.Node) *Selection {
|
||||
})
|
||||
}
|
||||
|
||||
// HasSelection() reduces the set of matched elements to those that have a
|
||||
// HasSelection reduces the set of matched elements to those that have a
|
||||
// descendant that matches one of the nodes of the specified Selection object.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (this *Selection) HasSelection(sel *Selection) *Selection {
|
||||
func (s *Selection) HasSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.HasNodes()
|
||||
return s.HasNodes()
|
||||
}
|
||||
return this.HasNodes(sel.Nodes...)
|
||||
return s.HasNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// End() ends the most recent filtering operation in the current chain and
|
||||
// End ends the most recent filtering operation in the current chain and
|
||||
// returns the set of matched elements to its previous state.
|
||||
func (this *Selection) End() *Selection {
|
||||
if this.prevSel != nil {
|
||||
return this.prevSel
|
||||
func (s *Selection) End() *Selection {
|
||||
if s.prevSel != nil {
|
||||
return s.prevSel
|
||||
}
|
||||
return newEmptySelection(this.document)
|
||||
return newEmptySelection(s.document)
|
||||
}
|
||||
|
||||
// Filter based on a selector string, and the indicator to keep (Filter) or
|
||||
|
34
iteration.go
34
iteration.go
@@ -1,32 +1,32 @@
|
||||
package goquery
|
||||
|
||||
// Each() iterates over a Selection object, executing a function for each
|
||||
// Each iterates over a Selection object, executing a function for each
|
||||
// matched element. It returns the current Selection object.
|
||||
func (this *Selection) Each(f func(int, *Selection)) *Selection {
|
||||
for i, n := range this.Nodes {
|
||||
f(i, newSingleSelection(n, this.document))
|
||||
func (s *Selection) Each(f func(int, *Selection)) *Selection {
|
||||
for i, n := range s.Nodes {
|
||||
f(i, newSingleSelection(n, s.document))
|
||||
}
|
||||
return this
|
||||
return s
|
||||
}
|
||||
|
||||
// EachWithBreak() iterates over a Selection object, executing a function for each
|
||||
// matched element. It is identical to `Each()` except that it is possible to break
|
||||
// out of the loop by returning `false` in the callback function. It returns the
|
||||
// EachWithBreak iterates over a Selection object, executing a function for each
|
||||
// matched element. It is identical to Each except that it is possible to break
|
||||
// out of the loop by returning false in the callback function. It returns the
|
||||
// current Selection object.
|
||||
func (this *Selection) EachWithBreak(f func(int, *Selection) bool) *Selection {
|
||||
for i, n := range this.Nodes {
|
||||
if !f(i, newSingleSelection(n, this.document)) {
|
||||
return this
|
||||
func (s *Selection) EachWithBreak(f func(int, *Selection) bool) *Selection {
|
||||
for i, n := range s.Nodes {
|
||||
if !f(i, newSingleSelection(n, s.document)) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return this
|
||||
return s
|
||||
}
|
||||
|
||||
// Map() passes each element in the current matched set through a function,
|
||||
// Map passes each element in the current matched set through a function,
|
||||
// producing a slice of string holding the returned values.
|
||||
func (this *Selection) Map(f func(int, *Selection) string) (result []string) {
|
||||
for i, n := range this.Nodes {
|
||||
result = append(result, f(i, newSingleSelection(n, this.document)))
|
||||
func (s *Selection) Map(f func(int, *Selection) string) (result []string) {
|
||||
for i, n := range s.Nodes {
|
||||
result = append(result, f(i, newSingleSelection(n, s.document)))
|
||||
}
|
||||
|
||||
return result
|
||||
|
41
property.go
41
property.go
@@ -2,50 +2,51 @@ package goquery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"code.google.com/p/go.net/html"
|
||||
)
|
||||
|
||||
// Attr() gets the specified attribute's value for the first element in the
|
||||
// Attr gets the specified attribute's value for the first element in the
|
||||
// Selection. To get the value for each element individually, use a looping
|
||||
// construct such as Each() or Map() method.
|
||||
func (this *Selection) Attr(attrName string) (val string, exists bool) {
|
||||
if len(this.Nodes) == 0 {
|
||||
// construct such as Each or Map method.
|
||||
func (s *Selection) Attr(attrName string) (val string, exists bool) {
|
||||
if len(s.Nodes) == 0 {
|
||||
return
|
||||
}
|
||||
return getAttributeValue(attrName, this.Nodes[0])
|
||||
return getAttributeValue(attrName, s.Nodes[0])
|
||||
}
|
||||
|
||||
// Text() gets the combined text contents of each element in the set of matched
|
||||
// Text gets the combined text contents of each element in the set of matched
|
||||
// elements, including their descendants.
|
||||
func (this *Selection) Text() string {
|
||||
func (s *Selection) Text() string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
// Slightly optimized vs calling Each(): no single selection object created
|
||||
for _, n := range this.Nodes {
|
||||
// Slightly optimized vs calling Each: no single selection object created
|
||||
for _, n := range s.Nodes {
|
||||
buf.WriteString(getNodeText(n))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Size() is an alias for Length().
|
||||
func (this *Selection) Size() int {
|
||||
return this.Length()
|
||||
// Size is an alias for Length.
|
||||
func (s *Selection) Size() int {
|
||||
return s.Length()
|
||||
}
|
||||
|
||||
// Length() returns the number of elements in the Selection object.
|
||||
func (this *Selection) Length() int {
|
||||
return len(this.Nodes)
|
||||
// Length returns the number of elements in the Selection object.
|
||||
func (s *Selection) Length() int {
|
||||
return len(s.Nodes)
|
||||
}
|
||||
|
||||
// Html() gets the HTML contents of the first element in the set of matched
|
||||
// Html gets the HTML contents of the first element in the set of matched
|
||||
// elements. It includes text and comment nodes.
|
||||
func (this *Selection) Html() (ret string, e error) {
|
||||
func (s *Selection) Html() (ret string, e error) {
|
||||
// Since there is no .innerHtml, the HTML content must be re-created from
|
||||
// the nodes usint html.Render().
|
||||
// the nodes using html.Render.
|
||||
var buf bytes.Buffer
|
||||
|
||||
if len(this.Nodes) > 0 {
|
||||
for c := this.Nodes[0].FirstChild; c != nil; c = c.NextSibling {
|
||||
if len(s.Nodes) > 0 {
|
||||
for c := s.Nodes[0].FirstChild; c != nil; c = c.NextSibling {
|
||||
e = html.Render(&buf, c)
|
||||
if e != nil {
|
||||
return
|
||||
|
49
query.go
49
query.go
@@ -1,53 +1,54 @@
|
||||
package goquery
|
||||
|
||||
import (
|
||||
"code.google.com/p/cascadia"
|
||||
"code.google.com/p/go.net/html"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"code.google.com/p/cascadia"
|
||||
"code.google.com/p/go.net/html"
|
||||
)
|
||||
|
||||
var rxClassTrim = regexp.MustCompile("[\t\r\n]")
|
||||
|
||||
// Is() checks the current matched set of elements against a selector and
|
||||
// Is checks the current matched set of elements against a selector and
|
||||
// returns true if at least one of these elements matches.
|
||||
func (this *Selection) Is(selector string) bool {
|
||||
if len(this.Nodes) > 0 {
|
||||
func (s *Selection) Is(selector string) bool {
|
||||
if len(s.Nodes) > 0 {
|
||||
// Attempt a match with the selector
|
||||
cs := cascadia.MustCompile(selector)
|
||||
if len(this.Nodes) == 1 {
|
||||
return cs.Match(this.Nodes[0])
|
||||
if len(s.Nodes) == 1 {
|
||||
return cs.Match(s.Nodes[0])
|
||||
} else {
|
||||
return len(cs.Filter(this.Nodes)) > 0
|
||||
return len(cs.Filter(s.Nodes)) > 0
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsFunction() checks the current matched set of elements against a predicate and
|
||||
// IsFunction checks the current matched set of elements against a predicate and
|
||||
// returns true if at least one of these elements matches.
|
||||
func (this *Selection) IsFunction(f func(int, *Selection) bool) bool {
|
||||
return this.FilterFunction(f).Length() > 0
|
||||
func (s *Selection) IsFunction(f func(int, *Selection) bool) bool {
|
||||
return s.FilterFunction(f).Length() > 0
|
||||
}
|
||||
|
||||
// IsSelection() checks the current matched set of elements against a Selection object
|
||||
// IsSelection checks the current matched set of elements against a Selection object
|
||||
// and returns true if at least one of these elements matches.
|
||||
func (this *Selection) IsSelection(s *Selection) bool {
|
||||
return this.FilterSelection(s).Length() > 0
|
||||
func (s *Selection) IsSelection(sel *Selection) bool {
|
||||
return s.FilterSelection(sel).Length() > 0
|
||||
}
|
||||
|
||||
// IsNodes() checks the current matched set of elements against the specified nodes
|
||||
// IsNodes checks the current matched set of elements against the specified nodes
|
||||
// and returns true if at least one of these elements matches.
|
||||
func (this *Selection) IsNodes(nodes ...*html.Node) bool {
|
||||
return this.FilterNodes(nodes...).Length() > 0
|
||||
func (s *Selection) IsNodes(nodes ...*html.Node) bool {
|
||||
return s.FilterNodes(nodes...).Length() > 0
|
||||
}
|
||||
|
||||
// HasClass() determines whether any of the matched elements are assigned the
|
||||
// HasClass determines whether any of the matched elements are assigned the
|
||||
// given class.
|
||||
func (this *Selection) HasClass(class string) bool {
|
||||
func (s *Selection) HasClass(class string) bool {
|
||||
class = " " + class + " "
|
||||
for _, n := range this.Nodes {
|
||||
for _, n := range s.Nodes {
|
||||
// Applies only to element nodes
|
||||
if n.Type == html.ElementNode {
|
||||
if elClass, ok := getAttributeValue("class", n); ok {
|
||||
@@ -61,11 +62,11 @@ func (this *Selection) HasClass(class string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Contains() returns true if the specified Node is within,
|
||||
// Contains returns true if the specified Node is within,
|
||||
// at any depth, one of the nodes in the Selection object.
|
||||
// It is NOT inclusive, to behave like jQuery's implementation, and
|
||||
// unlike Javascript's .contains(), so if the contained
|
||||
// unlike Javascript's .contains, so if the contained
|
||||
// node is itself in the selection, it returns false.
|
||||
func (this *Selection) Contains(n *html.Node) bool {
|
||||
return sliceContains(this.Nodes, n)
|
||||
func (s *Selection) Contains(n *html.Node) bool {
|
||||
return sliceContains(s.Nodes, n)
|
||||
}
|
||||
|
284
traversal.go
284
traversal.go
@@ -20,85 +20,85 @@ const (
|
||||
siblingAllIncludingNonElements
|
||||
)
|
||||
|
||||
// Find() gets the descendants of each element in the current set of matched
|
||||
// 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.
|
||||
func (this *Selection) Find(selector string) *Selection {
|
||||
return pushStack(this, findWithSelector(this.Nodes, selector))
|
||||
func (s *Selection) Find(selector string) *Selection {
|
||||
return pushStack(s, findWithSelector(s.Nodes, selector))
|
||||
}
|
||||
|
||||
// FindSelection() gets the descendants of each element in the current
|
||||
// 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 (this *Selection) FindSelection(sel *Selection) *Selection {
|
||||
func (s *Selection) FindSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return pushStack(this, nil)
|
||||
return pushStack(s, nil)
|
||||
}
|
||||
return this.FindNodes(sel.Nodes...)
|
||||
return s.FindNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// FindNodes() gets the descendants of each element in the current
|
||||
// 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 (this *Selection) FindNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, mapNodes(nodes, func(i int, n *html.Node) []*html.Node {
|
||||
if sliceContains(this.Nodes, n) {
|
||||
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,
|
||||
// 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 (this *Selection) Contents() *Selection {
|
||||
return pushStack(this, getChildrenNodes(this.Nodes, siblingAllIncludingNonElements))
|
||||
func (s *Selection) Contents() *Selection {
|
||||
return pushStack(s, getChildrenNodes(s.Nodes, siblingAllIncludingNonElements))
|
||||
}
|
||||
|
||||
// ContentsFiltered() gets the children of each element in the Selection,
|
||||
// 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 (this *Selection) ContentsFiltered(selector string) *Selection {
|
||||
// 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 this.ChildrenFiltered(selector)
|
||||
return s.ChildrenFiltered(selector)
|
||||
}
|
||||
return this.Contents()
|
||||
return s.Contents()
|
||||
}
|
||||
|
||||
// Children() gets the child elements of each element in the Selection.
|
||||
// Children gets the child elements of each element in the Selection.
|
||||
// It returns a new Selection object containing these elements.
|
||||
func (this *Selection) Children() *Selection {
|
||||
return pushStack(this, getChildrenNodes(this.Nodes, siblingAll))
|
||||
func (s *Selection) Children() *Selection {
|
||||
return pushStack(s, getChildrenNodes(s.Nodes, siblingAll))
|
||||
}
|
||||
|
||||
// ChildrenFiltered() gets the child elements of each element in the Selection,
|
||||
// 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 (this *Selection) ChildrenFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getChildrenNodes(this.Nodes, siblingAll), selector)
|
||||
func (s *Selection) ChildrenFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), selector)
|
||||
}
|
||||
|
||||
// Parent() gets the parent of each element in the Selection. It returns a
|
||||
// Parent gets the parent of each element in the Selection. It returns a
|
||||
// new Selection object containing the matched elements.
|
||||
func (this *Selection) Parent() *Selection {
|
||||
return pushStack(this, getParentNodes(this.Nodes))
|
||||
func (s *Selection) Parent() *Selection {
|
||||
return pushStack(s, getParentNodes(s.Nodes))
|
||||
}
|
||||
|
||||
// ParentFiltered() gets the parent of each element in the Selection filtered by a
|
||||
// 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 (this *Selection) ParentFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getParentNodes(this.Nodes), selector)
|
||||
func (s *Selection) ParentFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getParentNodes(s.Nodes), selector)
|
||||
}
|
||||
|
||||
// Closest() gets the first element that matches the selector by testing the
|
||||
// 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 (this *Selection) Closest(selector string) *Selection {
|
||||
func (s *Selection) Closest(selector string) *Selection {
|
||||
cs := cascadia.MustCompile(selector)
|
||||
|
||||
return pushStack(this, mapNodes(this.Nodes, func(i int, n *html.Node) []*html.Node {
|
||||
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 {
|
||||
@@ -110,10 +110,10 @@ func (this *Selection) Closest(selector string) *Selection {
|
||||
}))
|
||||
}
|
||||
|
||||
// ClosestNodes() gets the first element that matches one of the nodes by testing the
|
||||
// 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 (this *Selection) ClosestNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, mapNodes(this.Nodes, func(i int, n *html.Node) []*html.Node {
|
||||
func (s *Selection) ClosestNodes(nodes ...*html.Node) *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 {
|
||||
@@ -125,242 +125,242 @@ func (this *Selection) ClosestNodes(nodes ...*html.Node) *Selection {
|
||||
}))
|
||||
}
|
||||
|
||||
// ClosestSelection() gets the first element that matches one of the nodes in the
|
||||
// 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 (this *Selection) ClosestSelection(s *Selection) *Selection {
|
||||
if s == nil {
|
||||
return pushStack(this, nil)
|
||||
func (s *Selection) ClosestSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return pushStack(s, nil)
|
||||
}
|
||||
return this.ClosestNodes(s.Nodes...)
|
||||
return s.ClosestNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// Parents() gets the ancestors of each element in the current Selection. It
|
||||
// Parents gets the ancestors of each element in the current Selection. It
|
||||
// returns a new Selection object with the matched elements.
|
||||
func (this *Selection) Parents() *Selection {
|
||||
return pushStack(this, getParentsNodes(this.Nodes, "", nil))
|
||||
func (s *Selection) Parents() *Selection {
|
||||
return pushStack(s, getParentsNodes(s.Nodes, "", nil))
|
||||
}
|
||||
|
||||
// ParentsFiltered() gets the ancestors of each element in the current
|
||||
// ParentsFiltered gets the ancestors of each element in the current
|
||||
// Selection. It returns a new Selection object with the matched elements.
|
||||
func (this *Selection) ParentsFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getParentsNodes(this.Nodes, "", nil), selector)
|
||||
func (s *Selection) ParentsFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getParentsNodes(s.Nodes, "", nil), selector)
|
||||
}
|
||||
|
||||
// ParentsUntil() gets the ancestors of each element in the Selection, up to but
|
||||
// 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 (this *Selection) ParentsUntil(selector string) *Selection {
|
||||
return pushStack(this, getParentsNodes(this.Nodes, selector, nil))
|
||||
func (s *Selection) ParentsUntil(selector string) *Selection {
|
||||
return pushStack(s, getParentsNodes(s.Nodes, selector, nil))
|
||||
}
|
||||
|
||||
// ParentsUntilSelection() gets the ancestors of each element in the Selection,
|
||||
// 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 (this *Selection) ParentsUntilSelection(sel *Selection) *Selection {
|
||||
func (s *Selection) ParentsUntilSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.Parents()
|
||||
return s.Parents()
|
||||
}
|
||||
return this.ParentsUntilNodes(sel.Nodes...)
|
||||
return s.ParentsUntilNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// ParentsUntilNodes() gets the ancestors of each element in the Selection,
|
||||
// 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 (this *Selection) ParentsUntilNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, getParentsNodes(this.Nodes, "", nodes))
|
||||
func (s *Selection) ParentsUntilNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, getParentsNodes(s.Nodes, "", nodes))
|
||||
}
|
||||
|
||||
// ParentsFilteredUntil() is like ParentsUntil(), with the option to filter the
|
||||
// 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 (this *Selection) ParentsFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(this, getParentsNodes(this.Nodes, untilSelector, nil), filterSelector)
|
||||
func (s *Selection) ParentsFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(s, getParentsNodes(s.Nodes, untilSelector, nil), filterSelector)
|
||||
}
|
||||
|
||||
// ParentsFilteredUntilSelection() is like ParentsUntilSelection(), with the
|
||||
// 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 (this *Selection) ParentsFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
func (s *Selection) ParentsFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.ParentsFiltered(filterSelector)
|
||||
return s.ParentsFiltered(filterSelector)
|
||||
}
|
||||
return this.ParentsFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
return s.ParentsFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
}
|
||||
|
||||
// ParentsFilteredUntilNodes() is like ParentsUntilNodes(), with the
|
||||
// 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 (this *Selection) ParentsFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(this, getParentsNodes(this.Nodes, "", nodes), filterSelector)
|
||||
func (s *Selection) ParentsFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(s, getParentsNodes(s.Nodes, "", nodes), filterSelector)
|
||||
}
|
||||
|
||||
// Siblings() gets the siblings of each element in the Selection. It returns
|
||||
// Siblings gets the siblings of each element in the Selection. It returns
|
||||
// a new Selection object containing the matched elements.
|
||||
func (this *Selection) Siblings() *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingAll, "", nil))
|
||||
func (s *Selection) Siblings() *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingAll, "", nil))
|
||||
}
|
||||
|
||||
// SiblingsFiltered() gets the siblings of each element in the Selection
|
||||
// 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 (this *Selection) SiblingsFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingAll, "", nil), selector)
|
||||
func (s *Selection) SiblingsFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, "", nil), selector)
|
||||
}
|
||||
|
||||
// Next() gets the immediately following sibling of each element in the
|
||||
// Next gets the immediately following sibling of each element in the
|
||||
// Selection. It returns a new Selection object containing the matched elements.
|
||||
func (this *Selection) Next() *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingNext, "", nil))
|
||||
func (s *Selection) Next() *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingNext, "", nil))
|
||||
}
|
||||
|
||||
// NextFiltered() gets the immediately following sibling of each element in the
|
||||
// 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 (this *Selection) NextFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingNext, "", nil), selector)
|
||||
func (s *Selection) NextFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, "", nil), selector)
|
||||
}
|
||||
|
||||
// NextAll() gets all the following siblings of each element in the
|
||||
// NextAll gets all the following siblings of each element in the
|
||||
// Selection. It returns a new Selection object containing the matched elements.
|
||||
func (this *Selection) NextAll() *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingNextAll, "", nil))
|
||||
func (s *Selection) NextAll() *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextAll, "", nil))
|
||||
}
|
||||
|
||||
// NextAllFiltered() gets all the following siblings of each element in the
|
||||
// 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 (this *Selection) NextAllFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingNextAll, "", nil), selector)
|
||||
func (s *Selection) NextAllFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, "", nil), selector)
|
||||
}
|
||||
|
||||
// Prev() gets the immediately preceding sibling of each element in the
|
||||
// Prev gets the immediately preceding sibling of each element in the
|
||||
// Selection. It returns a new Selection object containing the matched elements.
|
||||
func (this *Selection) Prev() *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingPrev, "", nil))
|
||||
func (s *Selection) Prev() *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrev, "", nil))
|
||||
}
|
||||
|
||||
// PrevFiltered() gets the immediately preceding sibling of each element in the
|
||||
// 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 (this *Selection) PrevFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingPrev, "", nil), selector)
|
||||
func (s *Selection) PrevFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, "", nil), selector)
|
||||
}
|
||||
|
||||
// PrevAll() gets all the preceding siblings of each element in the
|
||||
// PrevAll gets all the preceding siblings of each element in the
|
||||
// Selection. It returns a new Selection object containing the matched elements.
|
||||
func (this *Selection) PrevAll() *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingPrevAll, "", nil))
|
||||
func (s *Selection) PrevAll() *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevAll, "", nil))
|
||||
}
|
||||
|
||||
// PrevAllFiltered() gets all the preceding siblings of each element in the
|
||||
// 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 (this *Selection) PrevAllFiltered(selector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingPrevAll, "", nil), selector)
|
||||
func (s *Selection) PrevAllFiltered(selector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, "", nil), selector)
|
||||
}
|
||||
|
||||
// NextUntil() gets all following siblings of each element up to but not
|
||||
// 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 (this *Selection) NextUntil(selector string) *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingNextUntil,
|
||||
func (s *Selection) NextUntil(selector string) *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
|
||||
selector, nil))
|
||||
}
|
||||
|
||||
// NextUntilSelection() gets all following siblings of each element up to but not
|
||||
// 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 (this *Selection) NextUntilSelection(sel *Selection) *Selection {
|
||||
func (s *Selection) NextUntilSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.NextAll()
|
||||
return s.NextAll()
|
||||
}
|
||||
return this.NextUntilNodes(sel.Nodes...)
|
||||
return s.NextUntilNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// NextUntilNodes() gets all following siblings of each element up to but not
|
||||
// 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 (this *Selection) NextUntilNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingNextUntil,
|
||||
func (s *Selection) NextUntilNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
|
||||
"", nodes))
|
||||
}
|
||||
|
||||
// PrevUntil() gets all preceding siblings of each element up to but not
|
||||
// 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 (this *Selection) PrevUntil(selector string) *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingPrevUntil,
|
||||
func (s *Selection) PrevUntil(selector string) *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
|
||||
selector, nil))
|
||||
}
|
||||
|
||||
// PrevUntilSelection() gets all preceding siblings of each element up to but not
|
||||
// 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 (this *Selection) PrevUntilSelection(sel *Selection) *Selection {
|
||||
func (s *Selection) PrevUntilSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.PrevAll()
|
||||
return s.PrevAll()
|
||||
}
|
||||
return this.PrevUntilNodes(sel.Nodes...)
|
||||
return s.PrevUntilNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// PrevUntilNodes() gets all preceding siblings of each element up to but not
|
||||
// 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 (this *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(this, getSiblingNodes(this.Nodes, siblingPrevUntil,
|
||||
func (s *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
|
||||
"", nodes))
|
||||
}
|
||||
|
||||
// NextFilteredUntil() is like NextUntil(), with the option to filter
|
||||
// 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 (this *Selection) NextFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingNextUntil,
|
||||
func (s *Selection) NextFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
|
||||
untilSelector, nil), filterSelector)
|
||||
}
|
||||
|
||||
// NextFilteredUntilSelection() is like NextUntilSelection(), with the
|
||||
// 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 (this *Selection) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
func (s *Selection) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.NextFiltered(filterSelector)
|
||||
return s.NextFiltered(filterSelector)
|
||||
}
|
||||
return this.NextFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
return s.NextFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
}
|
||||
|
||||
// NextFilteredUntilNodes() is like NextUntilNodes(), with the
|
||||
// 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 (this *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingNextUntil,
|
||||
func (s *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
|
||||
"", nodes), filterSelector)
|
||||
}
|
||||
|
||||
// PrevFilteredUntil() is like PrevUntil(), with the option to 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 (this *Selection) PrevFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingPrevUntil,
|
||||
func (s *Selection) PrevFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
|
||||
untilSelector, nil), filterSelector)
|
||||
}
|
||||
|
||||
// PrevFilteredUntilSelection() is like PrevUntilSelection(), with the
|
||||
// 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 (this *Selection) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
func (s *Selection) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.PrevFiltered(filterSelector)
|
||||
return s.PrevFiltered(filterSelector)
|
||||
}
|
||||
return this.PrevFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
return s.PrevFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
}
|
||||
|
||||
// PrevFilteredUntilNodes() is like PrevUntilNodes(), with the
|
||||
// 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 (this *Selection) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingPrevUntil,
|
||||
func (s *Selection) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
|
||||
"", nodes), filterSelector)
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ func findWithSelector(nodes []*html.Node, selector string) []*html.Node {
|
||||
sel := cascadia.MustCompile(selector)
|
||||
// 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
|
||||
// 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, sel.MatchAll(c)...)
|
||||
@@ -416,7 +416,7 @@ func getParentsNodes(nodes []*html.Node, stopSelector string, stopNodes []*html.
|
||||
func getSiblingNodes(nodes []*html.Node, st siblingType, untilSelector string, untilNodes []*html.Node) []*html.Node {
|
||||
var f func(*html.Node) bool
|
||||
|
||||
// If the requested siblings are ...Until(), create the test function to
|
||||
// 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 {
|
||||
@@ -497,7 +497,7 @@ func getChildrenWithSiblingType(parent *html.Node, st siblingType, skipNode *htm
|
||||
}
|
||||
|
||||
for c := iter(nil); c != nil; c = iter(c) {
|
||||
// If this is an ...Until() case, test before append (returns true
|
||||
// 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) {
|
||||
|
27
type.go
27
type.go
@@ -1,10 +1,11 @@
|
||||
package goquery
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/html"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"code.google.com/p/go.net/html"
|
||||
)
|
||||
|
||||
// Document represents an HTML document to be manipulated. Unlike jQuery, which
|
||||
@@ -18,30 +19,30 @@ type Document struct {
|
||||
rootNode *html.Node
|
||||
}
|
||||
|
||||
// NewDocumentFromNode() is a Document constructor that takes a root html Node
|
||||
// NewDocumentFromNode is a Document constructor that takes a root html Node
|
||||
// as argument.
|
||||
func NewDocumentFromNode(root *html.Node) (d *Document) {
|
||||
func NewDocumentFromNode(root *html.Node) *Document {
|
||||
return newDocument(root, nil)
|
||||
}
|
||||
|
||||
// NewDocument() is a Document constructor that takes a string URL as argument.
|
||||
// NewDocument is a Document constructor that takes a string URL as argument.
|
||||
// It loads the specified document, parses it, and stores the root Document
|
||||
// node, ready to be manipulated.
|
||||
func NewDocument(url string) (d *Document, e error) {
|
||||
func NewDocument(url string) (*Document, error) {
|
||||
// Load the URL
|
||||
res, e := http.Get(url)
|
||||
if e != nil {
|
||||
return
|
||||
return nil, e
|
||||
}
|
||||
return NewDocumentFromResponse(res)
|
||||
}
|
||||
|
||||
// NewDocumentFromReader() returns a Document from a generic reader.
|
||||
// NewDocumentFromReader returns a Document from a generic reader.
|
||||
// It returns an error as second value if the reader's data cannot be parsed
|
||||
// as html. It does *not* check if the reader is also an io.Closer, so the
|
||||
// provided reader is never closed by this call, it is the responsibility
|
||||
// of the caller to close it if required.
|
||||
func NewDocumentFromReader(r io.Reader) (d *Document, e error) {
|
||||
func NewDocumentFromReader(r io.Reader) (*Document, error) {
|
||||
root, e := html.Parse(r)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
@@ -49,16 +50,16 @@ func NewDocumentFromReader(r io.Reader) (d *Document, e error) {
|
||||
return newDocument(root, nil), nil
|
||||
}
|
||||
|
||||
// NewDocumentFromResponse() is another Document constructor that takes an http resonse as argument.
|
||||
// NewDocumentFromResponse is another Document constructor that takes an http resonse as argument.
|
||||
// It loads the specified response's document, parses it, and stores the root Document
|
||||
// node, ready to be manipulated.
|
||||
func NewDocumentFromResponse(res *http.Response) (d *Document, e error) {
|
||||
// node, ready to be manipulated. The response's body is closed on return.
|
||||
func NewDocumentFromResponse(res *http.Response) (*Document, error) {
|
||||
defer res.Body.Close()
|
||||
|
||||
// Parse the HTML into nodes
|
||||
root, e := html.Parse(res.Body)
|
||||
if e != nil {
|
||||
return
|
||||
return nil, e
|
||||
}
|
||||
|
||||
// Create and fill the document
|
||||
@@ -74,7 +75,7 @@ func newDocument(root *html.Node, url *url.URL) *Document {
|
||||
}
|
||||
|
||||
// Selection represents a collection of nodes matching some criteria. The
|
||||
// initial Selection can be created by using Document.Find(), and then
|
||||
// initial Selection can be created by using Document.Find, and then
|
||||
// manipulated using the jQuery-like chainable syntax and methods.
|
||||
type Selection struct {
|
||||
Nodes []*html.Node
|
||||
|
15
utilities.go
15
utilities.go
@@ -8,7 +8,7 @@ func getChildren(n *html.Node) (result []*html.Node) {
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
result = append(result, c)
|
||||
}
|
||||
return
|
||||
return result
|
||||
}
|
||||
|
||||
// Loop through all container nodes to search for the target node.
|
||||
@@ -55,9 +55,7 @@ func indexInSlice(slice []*html.Node, node *html.Node) int {
|
||||
// There is no check to the original state of the target slice, so it may still
|
||||
// contain duplicates. The target slice is returned because append() may create
|
||||
// a new underlying array.
|
||||
func appendWithoutDuplicates(target []*html.Node,
|
||||
nodes []*html.Node) []*html.Node {
|
||||
|
||||
func appendWithoutDuplicates(target []*html.Node, nodes []*html.Node) []*html.Node {
|
||||
for _, n := range nodes {
|
||||
if !isInSlice(target, n) {
|
||||
target = append(target, n)
|
||||
@@ -70,18 +68,17 @@ func appendWithoutDuplicates(target []*html.Node,
|
||||
// Loop through a selection, returning only those nodes that pass the predicate
|
||||
// function.
|
||||
func grep(sel *Selection, predicate func(i int, s *Selection) bool) (result []*html.Node) {
|
||||
|
||||
for i, n := range sel.Nodes {
|
||||
if predicate(i, newSingleSelection(n, sel.document)) {
|
||||
result = append(result, n)
|
||||
}
|
||||
}
|
||||
return
|
||||
return result
|
||||
}
|
||||
|
||||
// Creates a new Selection object based on the specified nodes, and keeps the
|
||||
// source Selection object on the stack (linked list).
|
||||
func pushStack(fromSel *Selection, nodes []*html.Node) (result *Selection) {
|
||||
result = &Selection{nodes, fromSel.document, fromSel}
|
||||
return
|
||||
func pushStack(fromSel *Selection, nodes []*html.Node) *Selection {
|
||||
result := &Selection{nodes, fromSel.document, fromSel}
|
||||
return result
|
||||
}
|
||||
|
Reference in New Issue
Block a user