diff --git a/query.go b/query.go index e8fb0cd..62ea686 100644 --- a/query.go +++ b/query.go @@ -1,25 +1,60 @@ package goquery import ( + "code.google.com/p/cascadia" "exp/html" "regexp" "strings" ) +var rxNeedsContext = `^[\x20\t\r\n\f]*[>+~]|:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\)|)(?:[^-]|$)` + +// 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 { + // The selector must be done on the document if it has positional criteria + if ok, e := regexp.MatchString(rxNeedsContext, selector); ok { + sel := this.document.Find(selector) + for _, n := range this.Nodes { + if sel.IndexOfNode(n) > -1 { + return true + } + } + } else if e != nil { + panic(e.Error()) + + } else { + // Attempt a match with the selector + cs := cascadia.MustCompile(selector) + if len(this.Nodes) == 1 { + return cs.Match(this.Nodes[0]) + } else { + return len(cs.Filter(this.Nodes)) > 0 + } + } + } + + return false } -func (this *Selection) IsFunction(func(int, *Selection) bool) bool { - +// Is() 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 } +// Is() 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 } +// Is() 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 } // HasClass() determines whether any of the matched elements are assigned the diff --git a/query_test.go b/query_test.go index 6462f14..cfc49c2 100644 --- a/query_test.go +++ b/query_test.go @@ -4,6 +4,64 @@ import ( "testing" ) +func TestIs(t *testing.T) { + sel := Doc().Find(".footer p:nth-child(1)") + if !sel.Is("p") { + t.Error("Expected .footer p:nth-child(1) to be p.") + } +} + +func TestIsPositional(t *testing.T) { + sel := Doc().Find(".footer p:nth-child(2)") + if !sel.Is("p:nth-child(2)") { + t.Error("Expected .footer p:nth-child(2) to be p:nth-child(2).") + } +} + +func TestIsPositionalNot(t *testing.T) { + sel := Doc().Find(".footer p:nth-child(1)") + if sel.Is("p:nth-child(2)") { + t.Error("Expected .footer p:nth-child(1) NOT to be p:nth-child(2).") + } +} + +func TestIsFunction(t *testing.T) { + ok := Doc().Find("div").IsFunction(func(i int, s *Selection) bool { + return s.HasClass("container-fluid") + }) + + if !ok { + t.Error("Expected some div to have a container-fluid class.") + } +} + +func TestIsSelection(t *testing.T) { + sel := Doc().Find("div") + sel2 := Doc().Find(".pvk-gutter") + + if !sel.IsSelection(sel2) { + t.Error("Expected some div to have a pvk-gutter class.") + } +} + +func TestIsSelectionNot(t *testing.T) { + sel := Doc().Find("div") + sel2 := Doc().Find("a") + + if sel.IsSelection(sel2) { + t.Error("Expected some div NOT to be an anchor.") + } +} + +func TestIsNodes(t *testing.T) { + sel := Doc().Find("div") + sel2 := Doc().Find(".footer") + + if !sel.IsNodes(sel2.Nodes[0]) { + t.Error("Expected some div to have a footer class.") + } +} + func TestHasClass(t *testing.T) { sel := Doc().Find("div") if !sel.HasClass("span12") {