mirror of
https://github.com/ericchiang/pup
synced 2025-01-14 17:50:59 +00:00
not and parent-of selectors added
This commit is contained in:
parent
007f862673
commit
e4043764a0
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
dist/
|
||||
testpages/*
|
||||
tests/test_results.txt
|
||||
robots.html
|
||||
|
59
selector.go
59
selector.go
@ -378,6 +378,14 @@ func ParsePseudo(selector *CSSSelector, s scanner.Scanner) error {
|
||||
if selector.Pseudo, err = parseNthPseudo(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
case strings.HasPrefix(cmd, "not("):
|
||||
if selector.Pseudo, err = parseNotPseudo(cmd[len("not("):]); err != nil {
|
||||
return err
|
||||
}
|
||||
case strings.HasPrefix(cmd, "parent-of("):
|
||||
if selector.Pseudo, err = parseParentOfPseudo(cmd[len("parent-of("):]); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("%s not a valid pseudo class", cmd)
|
||||
}
|
||||
@ -583,3 +591,54 @@ func parseContainsPseudo(cmd string) (PseudoClass, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse a :not(selector) selector
|
||||
// expects the input to be everything after the open parenthesis
|
||||
// e.g. for `not(div#id)` the argument would be `div#id)`
|
||||
func parseNotPseudo(cmd string) (PseudoClass, error) {
|
||||
if len(cmd) < 2 {
|
||||
return nil, fmt.Errorf("malformed ':not' selector")
|
||||
}
|
||||
endQuote, cmd := cmd[len(cmd)-1], cmd[:len(cmd)-1]
|
||||
selector, err := ParseSelector(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if selector.Pseudo != nil {
|
||||
return nil, fmt.Errorf("selector within ':not' may not contain a pseudo class")
|
||||
}
|
||||
if endQuote != ')' {
|
||||
return nil, fmt.Errorf("unmatched '('")
|
||||
}
|
||||
return func(n *html.Node) bool {
|
||||
return !selector.Match(n)
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Parse a :parent-of(selector) selector
|
||||
// expects the input to be everything after the open parenthesis
|
||||
// e.g. for `parent-of(div#id)` the argument would be `div#id)`
|
||||
func parseParentOfPseudo(cmd string) (PseudoClass, error) {
|
||||
if len(cmd) < 2 {
|
||||
return nil, fmt.Errorf("malformed ':parent-of' selector")
|
||||
}
|
||||
endQuote, cmd := cmd[len(cmd)-1], cmd[:len(cmd)-1]
|
||||
selector, err := ParseSelector(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if selector.Pseudo != nil {
|
||||
return nil, fmt.Errorf("selector within ':parent-of' may not contain a pseudo class")
|
||||
}
|
||||
if endQuote != ')' {
|
||||
return nil, fmt.Errorf("unmatched '('")
|
||||
}
|
||||
return func(n *html.Node) bool {
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
if c.Type == html.ElementNode && selector.Match(c) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, nil
|
||||
}
|
||||
|
@ -38,3 +38,4 @@ td:empty
|
||||
#toc li + a + span
|
||||
#toc li + span
|
||||
#toc li > li
|
||||
li a:not([rel])
|
||||
|
@ -38,3 +38,4 @@ dbc580de40eeb8448f0dbe1b98d74cf799a6868b #toc li + a
|
||||
0cd687baaf08605bf6a68e3c285c5e8a41e0c9b2 #toc li + a + span
|
||||
da39a3ee5e6b4b0d3255bfef95601890afd80709 #toc li + span
|
||||
5d6e3ed3cfe310cde185cbfe1bba6aa7ec2a7f8d #toc li > li
|
||||
87eee1189dd5296d6c010a1ad329fc53c6099d72 li a:not([rel])
|
||||
|
Loading…
Reference in New Issue
Block a user